滑点

滑点 #

回测无法保证真实市场条件。无论市场模拟有多好,在真实市场条件下滑点可能发生。这意味着,请求的价格可能无法匹配。

集成的回测经纪商支持滑点,以下参数可以传递给经纪商:

参数名默认值描述
slip_perc0.0应用于买卖订单的价格上下滑动的绝对百分比(且为正值),注意:0.01 是 1%,0.001 是 0.1%;
slip_fixed0.0应用于买卖订单的价格上下滑动的单位百分比(且为正值),注意:如果 slip_perc 非零,则优先于此。
slip_openFalse是否为专门使用下一个柱的开盘价执行的订单滑动价格。例如,市场订单将在下一个可用tick执行,即柱的开盘价。这也适用于其他一些执行,因为逻辑尝试检测开盘价是否会匹配请求的价格/执行类型在移动到新柱时。
slip_matchTrue- 如果为 True,经纪商将通过在高/低价位封顶滑点来提供匹配,以防它们超出。
- 如果为 False,经纪商将不会使用当前价格匹配订单,并将在下一次迭代中尝试执行
slip_limitTrue- 限价订单,给定确切的匹配价格请求,即使 slip_match 为 False,也会被匹配。
- 此选项控制该行为。
- 如果为 True,那么限价订单将通过在限价/高低价位封顶价格进行匹配。
- 如果为 False 且滑点超出上限,则不会有匹配
slip_outFalse即使价格超出高-低范围,也提供滑点。

工作原理 #

为了决定何时应用滑点,考虑了订单执行类型:

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

image

使用配置为 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个操作无法执行。

这些例子应该显示了不同滑点选项如何协同工作。