“发布”1.9.44.116
添加了对 Cheat-On-Open
的支持。这似乎是那些全力以赴的人的需求功能,他们在酒吧 close 后进行了计算,但希望与 open
价格相匹配。
当开盘价跳空(上涨或下跌,取决于是否buy
sell
有效)并且现金不足以进行全面运营时,这样的用例就会失败。这将强制代理拒绝该操作。
尽管人们可以尝试使用正[1]
指数方法展望未来,但这需要预加载并不总是可用的数据。
模式:
cerebro = bt.Cerebro(cheat_on_open=True)
这:
-
激活系统中调用策略
next_open
中的方法的额外循环,nextstart_open
以及prenext_open
已经决定增加一系列方法,以便在常规方法之间明确区分,这些方法的运作依据是所审查的价格不再可用,未来是未知的,并且操作处于作弊模式。
这也避免了对常规
next
方法的 2 次调用。
在方法中xxx_open
,以下内容true:
-
指针尚未重新计算,并保持在等效
xxx
常规方法中上一个周期中last的值 -
经纪人尚未评估新周期的挂单,可以引入新订单,如果可能的话,将对其进行评估。
请注意:
-
Cerebro
还有一个broker_coo
(缺省:True
)参数,告诉 cerebro ,如果cheat-on-open
已经启动,如果可能的话,它应该尝试在代理中启动它。模拟代理有一个名为:
coo
的参数和一个将其设置为set_coo
尝试作弊open
下面的示例具有具有 2 种不同行为的策略:
-
如果作弊openTrue,则只能从
next_open
-
如果作弊openFalse,则只能从
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 之后 close
-
运行于 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 之前 open
-
运行于 2005-04-11
open
价格3088.47
图表上显示的总体结果也是相同的。
结论
open作弊允许在open例如可以精确计算全力以赴场景的赌注。
示例用法
$ ./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()