滑点 #
回测无法保证真实市场条件。无论市场模拟有多好,在真实市场条件下滑点可能发生。这意味着,请求的价格可能无法匹配。
集成的回测经纪商支持滑点,以下参数可以传递给经纪商:
参数名 | 默认值 | 描述 |
---|---|---|
slip_perc | 0.0 | 应用于买卖订单的价格上下滑动的绝对百分比(且为正值),注意:0.01 是 1%,0.001 是 0.1%; |
slip_fixed | 0.0 | 应用于买卖订单的价格上下滑动的单位百分比(且为正值),注意:如果 slip_perc 非零,则优先于此。 |
slip_open | False | 是否为专门使用下一个柱的开盘价执行的订单滑动价格。例如,市场订单将在下一个可用tick执行,即柱的开盘价。这也适用于其他一些执行,因为逻辑尝试检测开盘价是否会匹配请求的价格/执行类型在移动到新柱时。 |
slip_match | True | - 如果为 True,经纪商将通过在高/低价位封顶滑点来提供匹配,以防它们超出。 - 如果为 False,经纪商将不会使用当前价格匹配订单,并将在下一次迭代中尝试执行 |
slip_limit | True | - 限价订单,给定确切的匹配价格请求,即使 slip_match 为 False,也会被匹配。- 此选项控制该行为。 - 如果为 True,那么限价订单将通过在限价/高低价位封顶价格进行匹配。 - 如果为 False 且滑点超出上限,则不会有匹配 |
slip_out | False | 即使价格超出高-低范围,也提供滑点。 |
工作原理 #
为了决定何时应用滑点,考虑了订单执行类型:
Close
- 不应用滑点
- 这种订单匹配收盘价,而这个价格是当天的最后一个。滑点无法发生,因为订单只能在会话的最后一个tick发生,而这是唯一的价格,没有容忍度。
Market
- 应用滑点
- 请检查
slip_open
例外情况。因为市场订单将匹配下一个柱的开盘价。
Limit
- 按以下逻辑应用滑点
- 如果匹配价格是开盘价,则根据参数
slip_open
应用滑点。如果应用,价格不会比请求的限价更差。 - 如果匹配价格不是限价,则应用滑点在高/低点封顶。在这种情况下,
slip_limit
应用以决定在超过封顶时是否会发生匹配。 - 如果匹配价格是限价,则不应用滑点。
Stop
- 一旦订单触发,应用与市场订单相同的逻辑
StopLimit
- 一旦订单触发,应用与限价订单相同的逻辑
这种方法试图在模拟和可用数据的限制范围内提供最现实的方法。
配置滑点 #
每次运行时,Cerebro 引擎已实例化一个经纪商,使用默认参数。有两种方法配置滑点。
配置滑点为基于百分比的方法
BackBroker.set_slippage_perc(
perc,
slip_open=True,
slip_limit=True,
slip_match=True,
slip_out=False,
)
配置滑点为固定点数的方法:
BackBroker.set_slippage_fixed(
fixed,
slip_open=True,
slip_limit=True,
slip_match=True,
slip_out=False,
)
替换经纪商,例如:
import backtrader as bt
cerebro = bt.Cerebro()
cerebro.broker = bt.brokers.BackBroker(slip_perc=0.005) # 0.5%
实际示例 #
源码包含一个使用订单执行类型 Market 和使用信号的多/空方法的示例。这应该可以理解逻辑。
没有滑点的运行和初始图表供以后参考:
$ ./slippage.py --plot
01 2005-03-22 23:59:59 SELL Size: -1 / Price: 3040.55
02 2005-04-11 23:59:59 BUY Size: +1 / Price: 3088.47
03 2005-04-11 23:59:59 BUY Size: +1 / Price: 3088.47
04 2005-04-19 23:59:59 SELL Size: -1 / Price: 2948.38
05 2005-04-19 23:59:59 SELL Size: -1 / Price: 2948.38
06 2005-05-19 23:59:59 BUY Size: +1 / Price: 3034.88
...
35 2006-12-19 23:59:59 BUY Size: +1 / Price: 4121.01
使用配置为 1.5% 滑点的相同运行:
$ ./slippage.py --slip_perc 0.015
01 2005-03-22 23:59:59 SELL Size: -1 / Price: 3040.55
02 2005-04-11 23:59:59 BUY Size: +1 / Price: 3088.47
03 2005-04-11 23:59:59 BUY Size: +1 / Price: 3088.47
04 2005-04-19 23:59:59 SELL Size: -1 / Price: 2948.38
05 2005-04-19 23:59:59 SELL Size: -1 / Price: 2948.38
06 2005-05-19 23:59:59 BUY Size: +1 / Price: 3034.88
...
35 2006-12-19 23:59:59 BUY Size: +1 / Price: 4121.01
没有变化。这是预期的行为。
执行类型:Market
且未设置 slip_open
为 True
市场订单匹配下一个柱的开盘价,我们不允许开盘价移动。
设置 slip_open
为 True 的运行:
$ ./slippage.py --slip_perc 0.015 --slip_open
01 2005-03-22 23:59:59 SELL Size: -1 / Price: 3021.66
02 2005-04-11 23:59:59 BUY Size: +1 / Price: 3088.47
03 2005-04-11 23:59:59 BUY Size: +1 / Price: 3088.47
04 2005-04-19 23:59:59 SELL Size: -1 / Price: 2948.38
05 2005-04-19 23:59:59 SELL Size: -1 / Price: 2948.38
06 2005-05-19 23:59:59 BUY Size: +1 / Price: 3055.14
...
35 2006-12-19 23:59:59 BUY Size: +1 / Price: 4121.01
可以立即看到价格已经移动。分配的价格更差或相同,例如操作 35。打开和高点在 2016-12-19 是相同的。价格不能高于高点,因为这将返回不存在的价格。
当然,如果需要,Backtrader 允许在高-低范围之外匹配。启用 slip_out
的运行:
$ ./slippage.py --slip_perc 0.015 --slip_open --slip_out
01 2005-03-22 23:59:59 SELL Size: -1 / Price: 2994.94
02 2005-04-11 23:59:59 BUY Size: +1 / Price: 3134.80
03 2005-04-11 23:59:59 BUY Size: +1 / Price: 3134.80
04 2005-04-19 23:59:59 SELL Size: -1 / Price: 2904.15
05 2005-04-19 23:59:59 SELL Size: -1 / Price: 2904.15
06 2005-05-19 23:59:59 BUY Size: +1 / Price: 3080.40
...
35 2006-12-19 23:59:59 BUY Size: +1 / Price: 4182.83
匹配价格的表达式将是:OMG!(我的天!)。价格明显超出范围。足以看操作 35,匹配在 4182.83
。快速检查图表显示,资产从未接近过该价格。
slip_match
默认值为 True,这意味着 Backtrader 提供匹配,无论价格是封顶还是未封顶。禁用它:
$ ./slippage.py --slip_perc 0.015 --slip_open --no-slip_match
01 2005-04-15 23:59:59 SELL Size: -1 / Price: 3028.10
02 2005-05-18 23:59:59 BUY Size: +1 / Price: 3029.40
03 2005-06-01 23:59:59 BUY Size: +1 / Price: 3124.03
04 2005-10-06 23:59:59 SELL Size: -1 / Price: 3365.57
05 2005-10-06 23:59:59 SELL Size: -1 / Price: 3365.57
06 2005-12-01 23:59:59 BUY Size: +1 / Price: 3499.95
07 2005-12-01 23:59:59 BUY Size: +1 / Price: 3499.95
08 2006-02-28 23:59:59 SELL Size: -1 / Price: 3782.71
09 2006-02-28 23:59:59 SELL Size: -1 / Price: 3782.71
10 2006-05-23 23:59:59 BUY Size: +1 / Price: 3594.68
11 2006-05-23 23:59:59 BUY Size: +1 / Price: 3594.68
12 2006-11-27 23:59:59 SELL Size: -1 / Price: 3984.37
13 2006-11-27 23:59:59 SELL Size: -1 / Price: 3984.37
下滑至 13 从 35。原理:
禁用 slip_match
不允许在滑点会推高于高点或低于低点时匹配操作。似乎1.5%的请求滑点,有约22个操作无法执行。
这些例子应该显示了不同滑点选项如何协同工作。