策略
一个Cerebro
实例是backtrader
的心脏泵送和大脑控制。Strategy
对于平台用户也是一样的。
策略的以方法表示生命周期
笔记
在出生期间,可以通过从模块backtrader.errors
引发StrategySkipError
异常来中断策略
这将避免在回溯测试期间执行策略。见Exceptions
一节
-
概念:
__init__
这显然是在实例化过程中调用的:
indicators
将在此处创建,并且需要其他属性。例子:py def __init__(self): self.sma = btind.SimpleMovingAverage(period=15)
-
出生:
start
世界(
cerebro
告诉我们,是时候开始踢了。存在默认的空方法。 -
童年:
prenext
在构思期间宣布的
indicators
将限制策略需要多长时间才能成熟:这被称为minimum period
。上面的__init__
创建了一个带有period=15
的简单移动平均值。只要系统看到的条数少于
15
条,就会调用prenext
(默认实现为 no op) -
成年期:
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:
# Do something
pass
elif self.sma < self.data.close:
# Do something else
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)
有关商店通知的说明,请参见脑波。即使它们也已被传递到
cerebro
实例(使用覆盖的notify_store
方法或通过回调传递),也会被传递到策略中
而策略也像交易者一样,在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
)使用价格(如果实际格式不符合最小刻度大小要求,实时经纪人可能会对其进行限制)
None
对Market
和Close
订单有效(价格由市场决定)对于
Limit
、Stop
和StopLimit
订单,该值确定触发点(在Limit
的情况下,触发点显然是订单应匹配的价格) -
plimit
(默认为None
)仅适用于
StopLimit
订单。这是在触发停止后(已使用price
时)设置隐含限制订单的价格 -
exectype
(默认为None
)可能值:
-
Order.Market
或None
。市场订单将以下一个可用价格执行。在回溯测试中,它将是下一个酒吧的开盘价 -
Order.Limit
。只能在给定的price
或更好的条件下执行的命令 -
Order.Stop
。在price
触发并像Order.Market
指令一样执行的指令 -
Order.StopLimit
。在price
触发并作为隐含限额订单执行的订单,价格由pricelimit
给出
-
-
valid
(默认为None
)可能值:
-
None
:这将生成一个不会过期的订单(也称为在取消之前有效),并在匹配或取消之前保持在市场中。在现实中,经纪人倾向于施加时间限制,但通常情况下,在时间上远不及考虑到期。 -
datetime.datetime
或datetime.date
实例:该日期将用于生成在给定日期时间之前有效的订单(又名good til date) -
Order.DAY
或0
或timedelta()
:生成有效期至会话结束的一天(又名天订单) -
numeric value
:假设该值对应于matplotlib
编码中的日期时间(由backtrader
使用的日期时间),并将用于生成在该时间之前有效的订单(截止日期)
-
-
tradeid
(默认为0
)这是
backtrader
应用的内部值,用于跟踪同一资产上的重叠交易。此tradeid
在通知订单状态变更时被发送回策略。 -
**kwargs
:额外的代理实现可能支持额外的参数。backtrader
将kwargs传递给已创建的订单对象示例:如果
backtrader
直接支持的 4 种订单执行类型不够,例如交互经纪人的情况下,以下可以传递为kwargs:py orderType='LIT', lmtPrice=10.0, auxPrice=9.8
这将覆盖
backtrader
创建的设置并生成LIMIT IF TOUCHED
订单,其中触摸价格为 9.8,限制价格为 10.0。
信息位:
-
策略的长度总是等于主数据的长度(
datas[0]
,当然可以通过len(self)
得到如果正在重放数据或正在传递实时提要,并且到达相同时间点(长度)的新标记,则可以在不改变长度的情况下调用
next
成员属性:
-
env
:此策略所在的大脑实体 -
datas
:已传递给大脑的数据馈送数组-
data/data0
是数据[0]的别名 -
dataX
是数据[X]的别名
数据源也可以通过名称访问(参见参考资料),如果已经为其分配了名称
-
-
dnames
:通过名称(使用[name]
或.name
符号)访问数据源的替代方法例如,如果像这样对数据重新采样:
py ... data0 = bt.feeds.YahooFinanceData(datname='YHOO', fromdate=..., name='days') cerebro.adddata(data0) cerebro.resampledata(data0, timeframe=bt.TimeFrame.Weeks, name='weeks') ...
在战略的后面部分,我们可以创建如下各项指标:
py ... smadays = bt.ind.SMA(self.dnames.days, period=30) # or self.dnames['days'] smaweeks = bt.ind.SMA(self.dnames.weeks, period=10) # or self.dnames['weeks'] ...
-
broker
:对与该策略相关的经纪人的引用(从 Cerbero 收到) -
stats
:列出/命名的元组序列,其中包含大脑为此策略创建的观察者 -
analyzers
:列出/命名类似元组的序列,其中包含由 Cerbero 为此策略创建的分析器 -
position
:实际上是给出data0
当前位置的属性。检索所有 position 的方法都可用(请参阅参考资料)
成员属性(用于统计/观察/分析):
-
_orderspending
:调用next
前会通知策略的订单列表 -
_tradespending
:在调用next
之前将通知策略的交易列表 -
_orders
:已经通知的订单列表。一个订单可以在列表中多次使用不同的状态和不同的执行位。该列表是用来保存历史记录的。 -
_trades
:已经通知的订单列表。一笔交易可以像一笔订单一样多次出现在列表中。
笔记
请记住,对于同一时间点,prenext
、nextstart
和next
可以多次调用(当使用每日时间段时,勾号会更新每日酒吧的价格)
参考:战略
类 backtrader.Strategy(args,*kwargs)
要为用户定义的策略子类化的基类。
下一个()
当满足所有数据/指标的最短期限时,将对所有剩余数据点调用此方法。
nextstart()
此方法将被调用一次,正好在满足所有数据/指标的最短周期时调用。默认行为是调用 next
prenext()
在满足开始执行策略的所有数据/指标的最短期限之前,将调用此方法
开始()
在即将开始回溯测试之前调用。
停止()
在回溯测试即将停止之前调用
通知订单(订单)
在订单发生变化时接收订单
通知贸易部(贸易部)
每当一项交易发生变化时,接受一项交易
通知现金价值(现金、价值)
接收当前基金价值、战略经纪人的价值状态
通知基金(现金、价值、基金价值、股份)
接收当前现金、价值、基金价值和基金份额
通知门店(消息,args,*kwargs)
接收来自存储提供商的通知
购买(数据=None,大小=None,价格=None,plimit=None,exectype=None,valid=None,tradeid=0,oco=None,trailamount=None,trailpercent=None,父项=None,传输=True,**kwargs)
创建买入(多头)订单并将其发送给经纪人
-
data
(默认为None
)必须为其创建订单的数据。如果为
None
,则将使用系统中的第一个数据self.datas[0] or self.data0
(又名self.data
-
size
(默认为None
)要用于订单的数据单位的要使用的大小(正)。
如果
None
将使用getsizer
检索的sizer
实例来确定大小。 -
price
(默认为None
)使用价格(如果实际格式不符合最小刻度大小要求,实时经纪人可能会对其进行限制)
None
对Market
和Close
订单有效(价格由市场决定)对于
Limit
、Stop
和StopLimit
订单,该值确定触发点(在Limit
的情况下,触发点显然是订单应匹配的价格) -
plimit
(默认为None
)仅适用于
StopLimit
订单。这是在触发停止后(已使用price
时)设置隐含限制订单的价格 -
trailamount
(默认为None
)如果订单类型为 StopTrail 或 StopTrailLimit,则这是一个绝对量,它决定了与价格的距离(低于卖出订单,高于买入订单),以保持跟踪止损
-
trailpercent
(默认为None
)如果订单类型为 StopTrail 或 StopTrailLimit,则这是一个百分比金额,用于确定与价格的距离(低于卖出订单,高于买入订单),以保持跟踪止损(如果还指定了
trailamount
,则将使用该百分比金额) -
exectype
(默认为None
)可能值:
-
Order.Market
或None
。市场订单将以下一个可用价格执行。在回溯测试中,它将是下一个酒吧的开盘价 -
Order.Limit
。只能在给定的price
或更好的条件下执行的命令 -
Order.Stop
。在price
触发并像Order.Market
指令一样执行的指令 -
Order.StopLimit
。在price
触发并作为隐含限额订单执行的订单,价格由pricelimit
给出 -
Order.Close
。只能以该时段的收盘价执行的订单(通常在收盘拍卖期间) -
Order.StopTrail
。在price
减去trailamount
(或trailpercent
时触发的订单,如果价格偏离止损点,则更新该订单 -
Order.StopTrailLimit
。在price
减去trailamount
(或trailpercent
时触发的订单,如果价格偏离止损点,则更新该订单
-
-
valid
(默认为None
)可能值:
-
None
:这将生成一个不会过期的订单(也称为在取消之前有效),并在匹配或取消之前保持在市场中。在现实中,经纪人倾向于施加时间限制,但通常情况下,在时间上远不及考虑到期。 -
datetime.datetime
或datetime.date
实例:该日期将用于生成有效期至给定日期时间的订单(又名有效期至日期) -
Order.DAY
或0
或timedelta()
:生成有效期至会话结束的一天(又名天订单) -
numeric value
:假设该值对应于matplotlib
编码中的日期时间(由backtrader
使用的日期时间),并将用于生成在此时间之前有效的订单(截止日期)
-
-
tradeid
(默认为0
)这是
backtrader
应用的内部值,用于跟踪同一资产上的重叠交易。此tradeid
在通知订单状态变更时被发送回策略。 -
oco
(默认为None
)另一个
order
例子。此订单将成为 OCO(订单取消其他)组的一部分。其中一个订单的执行会立即取消同一组中的所有其他订单 -
parent
(默认为None
)控制一组订单的关系,例如,由高端限售和低端停售括起的买入。在父订单被执行(激活)或取消/到期(子订单也被取消)之前,高端/低端订单保持非活动状态。括号订单具有相同的大小
-
transmit
(默认为True
)指示订单是否必须传输,即:不仅放置在经纪人中,而且还发布。例如,这意味着控制括号顺序,其中一个禁用父级和 1st组子级的传输,并激活最后一个子级的传输,从而触发所有括号顺序的完全放置。
-
**kwargs
:额外的代理实现可能支持额外的参数。backtrader
将kwargs传递给已创建的订单对象示例:如果
backtrader
直接支持的 4 种订单执行类型不够,例如交互经纪人的情况下,以下可以传递为kwargs:py orderType='LIT', lmtPrice=10.0, auxPrice=9.8
这将覆盖
backtrader
创建的设置并生成LIMIT IF TOUCHED
订单,其中触摸价格为 9.8,限制价格为 10.0。 -
返回
- 提交的订单
销售(数据=None,大小=None,价格=None,plimit=None,exectype=None,valid=None,tradeid=0,oco=None,trailamount=None,trailpercent=None,父项=None,传输=True,**kwargs)
创建销售(短期)订单并将其发送给经纪人
有关参数的说明,请参见buy
文档
返回:提交的订单
关闭(数据=无,大小=无,**kwargs)
冲销多头/空头头寸并将其关闭
有关参数的说明,请参见buy
文档
笔记
size
:如果调用者未提供(默认为None
),则自动从现有位置计算
返回:提交的订单
取消(订单)
取消代理中的订单
buy_ 括号(data=None,size=None,price=None,plimit=None,exectype=2,valid=None,tradeid=0,trailamount=None,trailpercent=None,oargs={},stopperice=None,stoppexec=3,stoppergs={},limitprice=None,limitexec=2,limitargs={},**kwargs)
创建括号订单组(低端-采购订单-高端)。默认行为如下所示:
-
发出购买订单并执行
Limit
-
下发低端括号卖出订单并执行
Stop
-
发出高端括号卖出订单,执行
Limit
。
有关不同的参数,请参见下文
-
data
(默认为None
)必须为其创建订单的数据。如果为
None
,则将使用系统中的第一个数据self.datas[0] or self.data0
(又名self.data
-
size
(默认为None
)要用于订单的数据单位的要使用的大小(正)。
如果
None
将使用getsizer
检索的sizer
实例来确定大小。笔记
相同的大小应用于括号的所有 3 个订单
-
price
(默认为None
)使用价格(如果实际格式不符合最小刻度大小要求,实时经纪人可能会对其进行限制)
None
对Market
和Close
订单有效(价格由市场决定)对于
Limit
、Stop
和StopLimit
订单,该值确定触发点(在Limit
的情况下,触发点显然是订单应匹配的价格) -
plimit
(默认为None
)仅适用于
StopLimit
订单。这是在触发停止后(已使用price
时)设置隐含限制订单的价格 -
trailamount
(默认为None
)如果订单类型为 StopTrail 或 StopTrailLimit,则这是一个绝对量,它决定了与价格的距离(低于卖出订单,高于买入订单),以保持跟踪止损
-
trailpercent
(默认为None
)如果订单类型为 StopTrail 或 StopTrailLimit,则这是一个百分比金额,用于确定与价格的距离(低于卖出订单,高于买入订单),以保持跟踪止损(如果还指定了
trailamount
,则将使用该百分比金额) -
exectype
(默认为bt.Order.Limit
)可能值:(方法
buy
见文档) -
valid
(默认为None
)可能值:(方法
buy
见文档) -
tradeid
(默认为0
)可能值:(方法
buy
见文档) -
oargs
(默认为{}
)特定的关键字参数(在
dict
中)传递到主端顺序。来自默认值**kwargs
的参数将应用于此参数之上。 -
**kwargs
:额外的代理实现可能支持额外的参数。backtrader
将kwargs传递给已创建的订单对象可能值:(方法
buy
见文档)笔记
此
kwargs
将应用于括号中的 3 个订单。有关低端和高端订单的特定关键字参数,请参见下文 -
stopprice
(默认为None
)低端停单具体价格
-
stopexec
(默认为bt.Order.Stop
)低端订单的具体执行类型
-
stopargs
(默认为{}
)要传递到低端顺序的特定关键字参数(在
dict
中)。来自默认值**kwargs
的参数将应用于此参数之上。 -
limitprice
(默认为None
)高端停单具体价格
-
stopexec
(默认为bt.Order.Limit
)高端订单的具体执行类型
-
limitargs
(默认为{}
)要传递到高端顺序的特定关键字参数(在
dict
中)。来自默认值**kwargs
的参数将应用于此参数之上。
可以使用以下方法抑制高端/低端订单:
-
limitexec=None
抑制高侧 -
stopexec=None
抑制低端 -
返回
-
包含 3 个订单[订单、停止端、限制端]的列表
-
如果高/低订单已被抑制,返回值仍将包含 3 个订单,但被抑制的订单的值将为
None
-
sell_ 括号(data=None,size=None,price=None,plimit=None,exectype=2,valid=None,tradeid=0,trailamount=None,trailpercent=None,oargs={},stopprice=None,stopexec=3,stopargs={},limitprice=None,limitexec=2,limitargs={},**kwargs)
创建括号订单组(低端-采购订单-高端)。默认行为如下所示:
-
发出卖出指令并执行
Limit
-
发出高端支架购买订单并执行
Stop
-
发出低端支架购买订单,执行
Limit
。
参数含义见bracket_buy
可以使用以下方法抑制高端/低端订单:
-
stopexec=None
抑制高侧 -
limitexec=None
抑制低端 -
返回
-
包含 3 个订单[订单、停止端、限制端]的列表
-
如果高/低订单已被抑制,返回值仍将包含 3 个订单,但被抑制的订单的值将为
None
-
订单\目标\大小(数据=无,目标=0,**kwargs)
下订单重新平衡位置,使最终尺寸为target
以当前position
大小作为实现target
的起点
-
如果
target
>pos.size
->买入target - pos.size
-
如果
target
<pos.size
->卖出pos.size - target
它返回以下任一项:
- 生成的订单
或
None
如果没有发出订单(target == position.size
)
订单\目标\价值(数据=无,目标=0.0,价格=无,**kwargs)
下订单重新平衡位置,使最终值为target
考虑电流value
作为实现target
的起点
-
如果没有
target
,则关闭数据上的位置 -
如果
target
>value
则按数据买入 -
若
target
<value
则按数据卖出
它返回以下任一项:
- 生成的订单
或
None
如果没有发出订单
订单\目标\百分比(数据=无,目标=0.0,**kwargs)
下订单重新平衡头寸,使其最终价值达到当前投资组合value
的target
百分比
target
以十进制表示:0.05
->5%
它使用order_target_value
执行订单。
示例
-
target=0.05
且投资组合价值为100
-
要到达的
value
是0.05 * 100 = 5
-
5
作为target
值传递给order_target_value
考虑电流value
作为实现target
的起点
position.size
用于确定位置是否为long
/short
-
如果
target
>value
- 如果
pos.size >= 0
买入(增加多头头寸) - 如果
pos.size < 0
卖出(增加空头头寸) -
如果
target
<value
-
如果
pos.size >= 0
卖出(减少多头头寸) - 如果
pos.size < 0
买入(减少空头头寸)
- 如果
它返回以下任一项:
- 生成的订单
或
None
如果没有发出订单(target == position.size
)
getsizer()
如果使用自动桩计算,则返回正在使用的尺寸器
也可作为sizer
提供
设定器(施胶器)
替换默认(固定桩)尺寸测量器
getsizing(数据=None,isbuy=True)
返回 sizer 实例为当前情况计算的桩号
getposition(数据=无,代理=无)
返回给定代理中给定数据的当前位置。
如果两者都为无,则将使用主数据和默认代理
还提供了一个属性position
getpositionbyname(name=None,broker=None)
返回给定代理中给定名称的当前位置。
如果两者都为无,则将使用主数据和默认代理
还提供了一个属性positionbyname
getpositionsbyname(代理=无)
直接从代理返回当前的按名称位置
如果给定的broker
为无,则使用默认代理
还提供了一个属性positionsbyname
getdatanames()
返回现有数据名的列表
getdatabyname(名称)
使用环境(脑波)按名称返回给定数据
添加计时器(当,offset=datetime.timedelta(0),repeat=datetime.timedelta(0),weekdays=[],weekcarry=False,monthdays=[],monthcarry=True,allow=None,tzdata=None,cheat=False,args,*kwargs)
笔记
可在__init__
或start
期间调用
安排计时器调用指定的回调或一个或多个策略的notify_timer
。
-
参数
当(-)–可以
-
datetime.time
实例(见下文tzdata
) -
bt.timer.SESSION_START
引用会话开始 -
bt.timer.SESSION_END
引用会话结束 -
offset
必须是datetime.timedelta
实例
用于偏移值
when
。它与SESSION_START
和SESSION_END
结合使用,有意义地表示在会话开始后调用15 minutes
计时器之类的事情。-
repeat
必须是datetime.timedelta
实例指示在 1st呼叫后,是否会在同一会话中以预定的
repeat
增量安排更多呼叫一旦计时器在会话结束后被重置为
when
的原始值 -
weekdays
:一个排序的iterable,带有整数,表示可以实际调用计时器的日期(iso 代码,周一是 1,周日是 7)如果未指定,计时器将在所有日期都处于活动状态
-
weekcarry
(默认为False
)。如果True
和工作日不可见(例如:交易假日),计时器将在第二天执行(即使在新的一周内) -
monthdays
:一个排序的iterable,整数表示计时器必须在月份的哪几天执行。例如,始终在当月的第15天如果未指定,计时器将在所有日期都处于活动状态
-
monthcarry
(默认为True
)。如果看不到该日(周末、交易日),计时器将在下一个可用日执行。 -
allow
(默认为None
)。接收 datetime.date实例并返回
True的回调,如果允许计时器使用该日期,则返回
False` -
tzdata
可以是None
(默认)、一个pytz
实例或一个data feed
实例。None
:when
按面值解释(这意味着即使不是 UTC,也要像对待 UTC 一样处理)pytz
实例:when
将被解释为在时区实例指定的本地时间内指定。data feed
实例:when
将被解释为数据馈送实例的tz
参数指定的本地时间。笔记
如果
when
为SESSION_START
或SESSION_END
且tzdata
为None
,则系统中的 1st数据馈送(又名self.data0
)将作为查询会话时间的参考。 -
cheat
(默认False
)如果True
计时器将在经纪人有机会评估订单之前调用。这样就有机会根据开盘价发出订单,例如在会议开始之前 -
*args
:任何额外参数都将传递给notify_timer
-
**kwargs
:任何额外的 KWARG 将传递给notify_timer
-
返回值:
- 创建的计时器
通知计时器(计时器,时间,args,*kwargs)
接收定时器通知,timer
为add_timer
返回的定时器,when
为呼叫时间。args
和kwargs
是传递给add_timer
的任何附加参数
实际的when
时间可以晚一点,但系统之前可能无法调用计时器。该值为计时器值,不代表系统时间。