如何消除Oanda API股票历史数据绘图中的周末间隙?
解决Oanda API回测图表周末间隙问题
我是编程新手,正在基于Oanda API编写回测代码。绘图时图表出现周末间隙,但检查数据的index(time)并未包含周末数据,请问如何消除这些间隙?

以下是我的代码:
class Backtester(): def __init__(self, symbol, timeframe, SMA_S, SMA_L, start, end): self.symbol = symbol self.timeframe = timeframe self.SMA_S = SMA_S self.SMA_L = SMA_L self.start = start self.end = end self.results = None self.get_data() def get_data(self): api = tpqoa.tpqoa('oanda.cfg') raw = api.get_history(instrument = self.symbol, \ start = self.start, \ end = self.end, \ granularity = self.timeframe, \ price = 'B') # raw = raw.dropna(inplace =True) # raw.rename(column = {'c':'close'}) raw['returns'] = np.log(raw['c'] / raw['c'].shift(1)) raw['SMA_S'] = raw['c'].rolling(self.SMA_S).mean() raw['SMA_L'] = raw['c'].rolling(self.SMA_L).mean() raw.dropna(inplace = True) self.data = raw return raw def test_strategy(self): data = self.data.copy().dropna() data["position"] = np.where(data["SMA_S"] > data["SMA_L"], 1, -1) data["strategy"] = data["position"].shift(1) * data["returns"] data.dropna(inplace=True) data["creturns"] = data["returns"].cumsum().apply(np.exp) data["cstrategy"] = data["strategy"].cumsum().apply(np.exp) self.results = data perf = data["cstrategy"].iloc[-1] # absolute performance outperf = perf - data["creturns"].iloc[-1] # outperformance return round(perf, 6), round(outperf, 6) def plot_data(self): data = self.data.copy().dropna() candle = go.Candlestick(x = data.index,\ open = data['o'],\ close = data['c'],\ high = data['h'],\ low = data['l'], name = 'Candlestick') fsma = go.Scatter(x = data.index,\ y = data['SMA_S'],\ name = 'SMA Short',\ line = dict(color = ('rgba(102, 207, 255, 50)'))) lsma = go.Scatter(x = data.index,\ y = data['SMA_L'],\ name = 'SMA Long',\ line = dict(color = ('rgba(102, 107, 255, 50)'))) data = [candle, fsma, lsma] data = [candle] layout = go.Layout(title = self.symbol) fig = go.Figure(data = data, layout = layout) plot(fig, filename = self.symbol)
解决方法
出现间隙的核心原因是:Plotly的时间轴默认会自动填充时间序列中的缺失区间,哪怕你的数据里没有周末记录,它也会按连续时间逻辑绘制,从而产生空白间隙。可以通过两种方式解决:
方法1:使用rangebreaks跳过周末(推荐,保留时间轴特性)
修改plot_data方法中的layout,给x轴添加rangebreaks配置,明确指定跳过周六到周一的区间:
layout = go.Layout( title = self.symbol, xaxis=dict( rangebreaks=[ dict(bounds=["sat", "mon"]) # 跳过周六至周一的空白间隙 # 可选:添加特定节假日,比如 dict(values=["2024-01-01", "2024-12-25"]) ] ) )
方法2:将x轴设为分类类型(简单但失去时间轴缩放特性)
直接把x轴类型改为category,让图表只渲染数据中实际存在的时间点:
layout = go.Layout( title = self.symbol, xaxis=dict(type='category') )
修改后的完整plot_data方法示例(采用方法1):
def plot_data(self): data = self.data.copy().dropna() candle = go.Candlestick(x = data.index,\ open = data['o'],\ close = data['c'],\ high = data['h'],\ low = data['l'], name = 'Candlestick') fsma = go.Scatter(x = data.index,\ y = data['SMA_S'],\ name = 'SMA Short',\ line = dict(color = ('rgba(102, 207, 255, 50)'))) lsma = go.Scatter(x = data.index,\ y = data['SMA_L'],\ name = 'SMA Long',\ line = dict(color = ('rgba(102, 107, 255, 50)'))) data = [candle, fsma, lsma] layout = go.Layout( title = self.symbol, xaxis=dict( rangebreaks=[dict(bounds=["sat", "mon"])] ) ) fig = go.Figure(data = data, layout = layout) plot(fig, filename = self.symbol)
内容的提问来源于stack exchange,提问作者Han J
相关产品推荐
相关产品推荐

