Backtest.py双SMA策略回测时交易入场点偏离实际价格问题
回测交易入场点偏离K线问题解决
问题描述
我从public.bybit.com获取AXSUSDT的15分钟K线数据生成DataFrame,用9周期和3周期SMA交叉策略做回测,但交易入场点标记显示在收盘价/实际K线的上方或下方,偏离了真实K线区间。
相关代码
import pandas as pd from backtesting import Strategy, Backtest from backtesting.lib import crossover from backtesting.test import SMA datasetURL = 'https://public.bybit.com/kline_for_metatrader4/AXSUSDT/2023/AXSUSDT_15_2023-01-01_2023-01-31.csv.gz' class daStrategy(Strategy): def init(self) -> None: super().init() self.firstSMA = self.I(SMA, self.data['Close'], 9) self.secondSMA = self.I(SMA, self.data['Close'], 3) def next(self): if crossover(self.firstSMA, self.secondSMA): self.position.close() self.buy() elif crossover(self.secondSMA, self.firstSMA): self.position.close() self.sell() data = pd.read_csv( datasetURL, names = [ 'datetime', 'Open', 'High', 'Low', 'Close', 'Volume' ], compression = 'gzip', index_col = 'datetime', parse_dates= True ) bt = Backtest( data, daStrategy, cash = 10000, margin = 1 / 1, #leverage of 1 commission =0.025 ) stat = bt.run() print(stat) bt.plot()
问题现象

问题原因与修复方案
核心原因
backtesting库默认在触发信号的下一根K线开盘价执行交易,而可视化时会把入场标记绘制在触发信号的当前K线末端,导致视觉上看起来偏离了当前K线的价格范围。另外,SMA信号基于当前K线收盘价计算,信号触发时当前K线已经结束,实盘里只能在下一根K线成交,这是真实交易逻辑,但视觉呈现会有错位。
修复选项
模拟理想化入场(贴合当前K线价格)
如果你想让标记贴合当前K线收盘价,可以在buy()和sell()时指定成交价格为当前K线收盘价,修改next()方法:def next(self): if crossover(self.firstSMA, self.secondSMA): self.position.close() # 指定用当前K线收盘价买入 self.buy(price=self.data.Close[-1]) elif crossover(self.secondSMA, self.firstSMA): self.position.close() # 指定用当前K线收盘价卖出 self.sell(price=self.data.Close[-1])注意:这种设置是模拟理想情况,实盘无法在K线结束瞬间以收盘价成交,回测收益会比真实情况更乐观。
保留真实回测逻辑
若追求回测的真实性,无需修改代码。视觉上的偏离只是标记位置的问题,实际成交价格是下一根K线的开盘价,可通过回测统计结果里的EntryPrice字段验证成交价格的准确性。验证数据完整性
检查K线数据的时间戳和价格列是否对应,可通过print(data.head())确认数据没有时间错位或格式错误。
内容的提问来源于stack exchange,提问作者Shahar Brandman
相关产品推荐
相关产品推荐

