策略#
Cerebro
实例是 backtrader
的泵心和控制脑。对于平台用户来说, Strategy
也是。
策略 的生命周期表达在方法中
Conception:
__init__
这在实例化时显然会被调用:在此处创建
indicators
和其他所需属性。示例:def __init__(self): self.sma = btind.SimpleMovingAverage(period=15)注意
一个策略在 出生 时可能会被抛出来自
backtrader.errors
模块的StrategySkipError
异常中断。这将避免在回测期间执行该策略。参见
Exceptions
部分。出生:
start
世界(cerebro
)告诉策略是时候开始行动了。存在一个默认的空方法。童年:
prenext
在概念阶段声明的
indicators
会对策略需要成熟的时间有一定的限制:这称为minimum period
。在上面的__init__
中创建了一个 SimpleMovingAverage ,其period=15
。只要系统看到的数据不到
15
个,就会调用prenext
(默认方法为空操作)。成年期:
next
一旦系统看到了
15
个数据,且SimpleMovingAverage
的缓冲区足够大,能够开始输出值,策略就已经足够成熟来执行了。还有一个
nextstart
方法,会被调用一次,来标志着从prenext
转向next
的转变。nextstart
的默认实现是简单地调用next
。繁殖:
None
好吧,策略实际上并不会繁殖。但在某种程度上它们会,因为系统会根据不同的参数多次实例化它们以进行*优化*。
死亡:
stop
系统告诉策略,是时候进行重置和整理了。已经存在一个默认的空方法。
在大多数情况下,正常使用模式如下所示:
class MyStrategy(bt.Strategy):
- def __init__(self):
self.sma = btind.SimpleMovingAverage(period=15)
- def next(self):
- if self.sma > self.data.close:
# 做某事 pass
- elif self.sma < self.data.close:
# 做其他事情 pass
在这个代码段中:
在
__init__
中,一个属性被赋予了一个指标默认空的
start
方法没有被覆盖
prenext
和nexstart
没有被覆盖在
next
中,将指标的值与收盘价进行比较以执行某些操作默认的空
stop
方法没有被覆盖
策略就像现实世界中的交易者一样,会在事件发生时收到通知。实际上,在回测过程中每次 next
周期都会通知策略。策略会:
通过
notify_order(order)
来接收订单状态的任何变化- 通过notify_trade(trade)
通知任何开立/更新/关闭的交易
通过
notify_cashvalue(cash, value)
通知经纪人当前的现金和投资组合通过
notify_fund(cash, value, fundvalue, shares)
通知经纪人当前的现金和投资组合,以及基金价值和份额的交易通过
notify_store(msg, *args, **kwargs)
通知特定实现的事件
有关 store 通知的详细说明,请参阅 Cerebro。即使这些通知已经发送到了 cerebro
实例(通过重写 notify_store
方法或通过 callback ),它们也会被发送到策略上。
和交易员一样,*策略*也有机会在 next
方法中操作市场,以试图获利
用
buy
方法开多头或减少/平仓空头仓位用
sell
方法开空头或减少/平仓多头仓位用
close
方法关闭现有仓位用
cancel
方法取消尚未执行的订单
购买/销售/关闭的方法#
Buy
和 Sell
方法会生成订单。当调用它们时,它们会返回一个 Order
(或子类)实例,可以用作参考。此订单具有唯一的 ref
标识符,可用于比较。
注意
特定经纪人实现的 Order
子类可能携带经纪人提供的其他 唯一标识符 。创建订单时,请使用以下参数:
data
(默认值:None
)指定要创建订单的数据。如果为
None
,则将使用系统中的第一个数据self.datas[0] or self.data0
(也就是self.data
)。size
(默认值:None
)指定要使用的数据单位的大小(必须为正数)。
如果为
None
,则会使用通过getsizer
方法检索到的sizer
实例来确定大小。price
(默认值:None
)指定要使用的价格(如果价格不符合最低变动点要求,则活动经纪人可能会设置限制)。
对于
Market
和Close
订单,None
是有效的(市场确定价格)。对于
Limit
,Stop
和StopLimit
订单,此值确定触发点(对于Limit
,触发点显然是订单应该匹配的价格)。 -plimit
(默认值:None
)仅适用于“StopLimit”订单。这是在 * Stop * 触发后(使用
price
)设置隐式 * Limit * 订单的价格exectype
(默认值:None
)可能的值:
Order.Market
或None
。市价订单将以下一个可用价格执行。在回测中,它将是下一个柱状图的开盘价Order.Limit
。只能以给定的price
或更好的价格执行的订单Order.Stop
。在price
触发的订单,并像Order.Market
订单一样执行Order.StopLimit
。在price
触发的订单,并作为由pricelimit
给出的隐式 * Limit * 订单执行
valid
(默认值:None
)可能的值:- None : 这将生成一个不会过期的订单(也被称为 Good til cancel ),并将一直在市场上等待匹配或取消。实际上,经纪人往往会设置一个时间上限,但通常这个时间距离现在还很遥远,所以可以视为不会过期
datetime.datetime 或 datetime.date 实例:将使用该日期生成一个有效期直到给定日期的订单(也被称为 good til date )
Order.DAY 或 0 或 ` timedelta()`:将生成一个有效期直到 交易日结束 的订单(也被称为 day 订单)
numeric value :默认假设为 matplotlib 编码中的一个日期时间值( backtrader 使用的编码方式),将使用该值生成一个有效期直到该时间的订单(也被称为 good til date )
tradeid (默认值:0)
这是 backtrader 应用于跟踪同一资产上交叉交易的内部值。当订单状态发生变化时,这个 tradeid 将发送回*策略*
**kwargs :其他经纪人实施可能支持额外的参数。 backtrader 将把 kwargs 传递给已创建的订单对象
例如:如果 backtrader 直接支持的四种订单执行类型对于某些情况不足够,比如在 交互经纪商 的情况下,可以将以下内容作为 kwargs 传递:
orderType=’LIT’, lmtPrice=10.0, auxPrice=9.8
这将覆盖 backtrader 创建的设置,并生成一个带有 触发*价格为9.8和 限价 价格为10.0的 当达到指定价格时触发*订单。信息细节:
策略具有一个*长度*,它始终等于主数据( datas[0] )的长度,当然可以使用 len(self) 获取
如果数据正在重播或正在传递实时数据源,并且同一时间点(长度)的新刻度正在到达,可以在不改变*长度*的情况下调用“next”
成员属性:#
env
:此策略所属的cerebro实体
datas
:传递给cerebro的数据源数组
data/data0
是datas[0]的别名
dataX
是 datas[X] 的别名数据源 也可以通过名称访问(参见参考资料),如果已经分配了名称
dnames
:通过名称(使用[name]
或.name
表示法)到达数据源的另一种方法例如,如果按此方式对数据进行重新取样:
… data0 = bt.feeds.YahooFinanceData(datname=’YHOO’, fromdate=…, name=’days’) cerebro.adddata(data0) cerebro.resampledata(data0, timeframe=bt.TimeFrame.Weeks, name=’weeks’) …后面在战略中可以像这样为每个指标创建指示器:
… smadays = bt.ind.SMA(self.dnames.days, period=30) # 或者 self.dnames[‘days’] smaweeks = bt.ind.SMA(self.dnames.weeks, period=10) # 或者 self.dnames[‘weeks’] …
broker
:与此策略相关联的经纪人的引用(从cerebro收到的)stats
:像元组一样的列表/命名元组序列,保存cerebro为此策略创建的观察者analyzers
:像元组一样的列表/命名元组序列,保存cerebro为此策略创建的分析器position
:实际上是一个属性,用于获取“data0”的当前持仓。可以使用一些方法来检索所有的持仓(参见参考资料)
成员属性(用于统计/观察者/分析器):#
_orderspending
:在调用next
之前将通知策略的订单列表-_tradespending
:在调用next
之前,策略将会通知的交易列表_orders
:已经通知的订单列表。一个订单在该列表中可以多次出现,具有不同的状态和不同的执行位。该列表用于保留历史记录。_trades
:已经通知的交易列表。一个交易在该列表中可以多次出现,就像一个订单一样。
注意
请记住,对于相同的时间点(更新每日价格的tick), prenext
、 nextstart
和 next
可能会被多次调用,当使用每日时间框架时。