公开作弊
原文: https://www.backtrader.com/docu/cerebro/cheat-on-open/cheat-on-open/
发布版1.9.44.116
增加了对Cheat-On-Open
的支持。这似乎是那些在酒吧关门后进行了计算,但希望与open
价格相匹配的全部加入的人所需要的功能。
当期初价差(上升或下降,取决于buy
或sell
是否有效)且现金不足以进行全包操作时,该用例失败。这将强制代理拒绝该操作。
尽管人们可以尝试用积极的[1]
指数方法展望未来,但这需要预加载数据,而这些数据并不总是可用的。
模式:
cerebro = bt.Cerebro(cheat_on_open=True)
这:
-
在系统中激活一个额外的循环,该循环调用策略
next_open
、nextstart_open
和prenext_open
中的方法已决定增加一系列方法,以明确区分常规方法和欺诈模式下的操作。常规方法的操作依据是,所检查的价格不再可用,未来未知。
这也避免了对常规
next
方法的两次调用。
在xxx_open
方法中,以下情况适用:
-
这些指标尚未重新计算,并保留了上一个周期中最后一次使用等效
xxx
常规方法看到的值 -
经纪人尚未评估新周期的未决订单,可以引入新订单,如果可能,将对新订单进行评估。
请注意:
-
Cerebro
还有一个broker_coo
(默认值:True
)参数,告诉脑波如果cheat-on-open
已经被激活,如果可能的话,它也应该尝试在代理中激活它。simulation broker 有一个名为
coo
的参数和一个名为set_coo
的设置方法
试图在公开场合作弊
下面的示例有一个包含两种不同行为的策略:
-
如果开启时作弊为真,则仅从
next_open
开始操作 -
如果开启时作弊为假,则只在
next
开始操作
在这两种情况下,匹配价格必须是相同
-
如果没有作弊,订单将在前一天结束时发出,并将与下一个进货价格匹配,即
open
价格 -
如果作弊,命令将在执行当天发出。因为订单是在经纪人评估订单之前发出的,所以它也将与下一个传入价格
open
匹配。第二种情况允许计算所有策略的确切赌注,因为可以直接访问当前
open
价格。
在这两种情况下
- 当前的
open
和close
价格将从next
开始打印。
定期执行:
$ ./cheat-on-open.py --cerebro cheat_on_open=False
...
2005-04-07 next, open 3073.4 close 3090.72
2005-04-08 next, open 3092.07 close 3088.92
Strat Len 68 2005-04-08 Send Buy, fromopen False, close 3088.92
2005-04-11 Buy Executed at price 3088.47
2005-04-11 next, open 3088.47 close 3080.6
2005-04-12 next, open 3080.42 close 3065.18
...
命令:
-
在关闭后于 2005-04-08 发布
-
于 2005-04-11 执行,
open
价格为3088.47
作弊执行:
$ ./cheat-on-open.py --cerebro cheat_on_open=True
...
2005-04-07 next, open 3073.4 close 3090.72
2005-04-08 next, open 3092.07 close 3088.92
2005-04-11 Send Buy, fromopen True, close 3080.6
2005-04-11 Buy Executed at price 3088.47
2005-04-11 next, open 3088.47 close 3080.6
2005-04-12 next, open 3080.42 close 3065.18
...
命令:
-
在开启之前于 2005-04-11 发布
-
于 2005-04-11 执行,
open
价格为3088.47
从图表上看,整体结果也是一样的。
结论
在公开赛中作弊允许在公开赛之前发布命令,例如,允许在场景中精确计算的赌注。
样本使用
$ ./cheat-on-open.py --help
usage: cheat-on-open.py [-h] [--data0 DATA0] [--fromdate FROMDATE]
[--todate TODATE] [--cerebro kwargs] [--broker kwargs]
[--sizer kwargs] [--strat kwargs] [--plot [kwargs]]
Cheat-On-Open Sample
optional arguments:
-h, --help show this help message and exit
--data0 DATA0 Data to read in (default:
../../datas/2005-2006-day-001.txt)
--fromdate FROMDATE Date[time] in YYYY-MM-DD[THH:MM:SS] format (default: )
--todate TODATE Date[time] in YYYY-MM-DD[THH:MM:SS] format (default: )
--cerebro kwargs kwargs in key=value format (default: )
--broker kwargs kwargs in key=value format (default: )
--sizer kwargs kwargs in key=value format (default: )
--strat kwargs kwargs in key=value format (default: )
--plot [kwargs] kwargs in key=value format (default: )
样本源
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import argparse
import datetime
import backtrader as bt
class St(bt.Strategy):
params = dict(
periods=[10, 30],
matype=bt.ind.SMA,
)
def __init__(self):
self.cheating = self.cerebro.p.cheat_on_open
mas = [self.p.matype(period=x) for x in self.p.periods]
self.signal = bt.ind.CrossOver(*mas)
self.order = None
def notify_order(self, order):
if order.status != order.Completed:
return
self.order = None
print('{} {} Executed at price {}'.format(
bt.num2date(order.executed.dt).date(),
'Buy' * order.isbuy() or 'Sell', order.executed.price)
)
def operate(self, fromopen):
if self.order is not None:
return
if self.position:
if self.signal < 0:
self.order = self.close()
elif self.signal > 0:
print('{} Send Buy, fromopen {}, close {}'.format(
self.data.datetime.date(),
fromopen, self.data.close[0])
)
self.order = self.buy()
def next(self):
print('{} next, open {} close {}'.format(
self.data.datetime.date(),
self.data.open[0], self.data.close[0])
)
if self.cheating:
return
self.operate(fromopen=False)
def next_open(self):
if not self.cheating:
return
self.operate(fromopen=True)
def runstrat(args=None):
args = parse_args(args)
cerebro = bt.Cerebro()
# Data feed kwargs
kwargs = dict()
# Parse from/to-date
dtfmt, tmfmt = '%Y-%m-%d', 'T%H:%M:%S'
for a, d in ((getattr(args, x), x) for x in ['fromdate', 'todate']):
if a:
strpfmt = dtfmt + tmfmt * ('T' in a)
kwargs[d] = datetime.datetime.strptime(a, strpfmt)
# Data feed
data0 = bt.feeds.BacktraderCSVData(dataname=args.data0, **kwargs)
cerebro.adddata(data0)
# Broker
cerebro.broker = bt.brokers.BackBroker(**eval('dict(' + args.broker + ')'))
# Sizer
cerebro.addsizer(bt.sizers.FixedSize, **eval('dict(' + args.sizer + ')'))
# Strategy
cerebro.addstrategy(St, **eval('dict(' + args.strat + ')'))
# Execute
cerebro.run(**eval('dict(' + args.cerebro + ')'))
if args.plot: # Plot if requested to
cerebro.plot(**eval('dict(' + args.plot + ')'))
def parse_args(pargs=None):
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description=(
'Cheat-On-Open Sample'
)
)
parser.add_argument('--data0', default='../../datas/2005-2006-day-001.txt',
required=False, help='Data to read in')
# Defaults for dates
parser.add_argument('--fromdate', required=False, default='',
help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')
parser.add_argument('--todate', required=False, default='',
help='Date[time] in YYYY-MM-DD[THH:MM:SS] format')
parser.add_argument('--cerebro', required=False, default='',
metavar='kwargs', help='kwargs in key=value format')
parser.add_argument('--broker', required=False, default='',
metavar='kwargs', help='kwargs in key=value format')
parser.add_argument('--sizer', required=False, default='',
metavar='kwargs', help='kwargs in key=value format')
parser.add_argument('--strat', required=False, default='',
metavar='kwargs', help='kwargs in key=value format')
parser.add_argument('--plot', required=False, default='',
nargs='?', const='{}',
metavar='kwargs', help='kwargs in key=value format')
return parser.parse_args(pargs)
if __name__ == '__main__':
runstrat()