BackTrader 中文文档(五)(1)

简介: BackTrader 中文文档(五)

策略

策略

原文:www.backtrader.com/docu/strategy/

Cerebro 实例是 backtrader 的泵心和控制大脑。对于平台用户来说,Strategy 是相同的。

策略 在方法中表达的生命周期

注意

策略可以通过从模块 backtrader.errors 中引发 StrategySkipError 异常来在出生期间中断

这将避免在回测过程中执行策略。请参阅Exceptions 部分

  1. 概念:__init__
    显然这是在实例化期间调用的:indicators 将在此处创建以及其他所需的属性。例如:
def __init__(self):
    self.sma = btind.SimpleMovingAverage(period=15)` 
  1. 出生:start
    世界(cerebro)告诉策略是时候开始行动了。存在一个默认的空方法。
  2. 童年期:prenext
    在概念阶段声明的 indicators 将对策略需要成熟的时间施加限制:这称为最小周期。在 __init__ 中创建了一个带有 period=15SimpleMovingAverage
    只要系统看到的条数少于 15 条,将调用 prenext(默认实现是空操作)
  3. 成年期:next
    一旦系统看到了 15 条数据,并且 SimpleMovingAverage 有足够大的缓冲区开始产生值,策略就足够成熟以实际执行。
    有一个 nextstart 方法,它被调用一次,标记从 prenextnext 的切换。nextstart 的默认实现只是调用 next
  4. 繁殖:None
    好的,策略实际上并没有繁殖。但从某种意义上来说,它们确实如此,因为系统将会多次实例化它们(使用不同的参数)如果优化
  5. 死亡: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 方法没有被覆盖
  • prenextnexstart 没有被覆盖
  • 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 以了解store通知的说明。即使它们也已经传递给了一个cerebro实例(通过覆盖notify_store方法或通过回调传递),这些通知也将传递给策略

而且策略也像交易员一样在next方法期间有机会在市场中操作,以尝试获得利润

  • buy方法,用于做多或减少/平仓空头头寸
  • sell方法,用于做空或减少/平仓多头头寸
  • close方法,显然关闭现有头寸
  • cancel方法,用于取消尚未执行的订单

如何购买/出售/平仓

BuySell方法生成订单。调用时,它们返回一个Order(或子类)实例,可用作引用。此订单具有唯一的ref标识符,可用于比较

注意

特定经纪人实现的Order子类可能携带经纪人提供的其他唯一标识符

要创建订单,请使用以下参数:

  • data(默认值:None
    必须为其创建订单的数据。如果是None,那么系统中的第一个数据,self.datas[0] or self.data0(又名self.data)将被使用
  • size(默认值:None
    要使用的数据单位(正数)的大小,用于订单
    如果是None,则将使用通过getsizer检索的sizer实例来确定大小。
  • price(默认值:None
    要使用的价格(现实经纪人可能对实际格式施加限制,如果不符合最低跳动大小要求)
    对于MarketClose订单,None是有效的(市场确定价格)
    对于LimitStopStopLimit订单,此值确定触发点(在Limit的情况下,触发显然是订单应该匹配的价格)
  • plimit(默认值:None
    仅适用于StopLimit订单。这是触发Limit订单的价格,一旦Stop被触发(使用了price
  • exectype(默认值:None)可能的值:
  • Order.MarketNone。市价单将以下一个可用价格执行。在回测中,它将是下一个柱的开盘价
  • Order.Limit。只能以给定的price或更好的价格执行的订单
  • Order.Stop。当价格达到price时触发的订单,并像Order.Market订单一样执行
  • Order.StopLimit。当价格达到price时触发的订单,并作为隐式Limit订单以由pricelimit给出的价格执行
  • valid(默认值:None)可能的值:
  • None:这将生成一个不会过期的订单(又称Good til cancel),并保持在市场上直到匹配或取消。实际上,经纪人倾向于强加一个时间限制,但通常是在很远的时间内,可以考虑它不会过期
  • datetime.datetimedatetime.date实例:将使用该日期生成订单,有效期直到给定的日期时间(又称截止日期
  • Order.DAY0timedelta(): 生成到 Session End(又名 day 订单)为止的一天有效订单
  • numeric value: 假设这是对应于 matplotlib 编码中的日期时间的值(backtrader 使用的日期时间编码),将用于生成直到该时间有效的订单(good til date
  • tradeid(默认值: 0
    这是 backtrader 应用的内部值,用于跟踪同一资产上的重叠交易。当通知订单状态变化时,此 tradeid 将发送回 strategy
  • **kwargs: 其他经纪人实现可能支持额外的参数。 backtrader 将这些 kwargs 传递给创建的订单对象
    例如: 如果 backtrader 直接支持的 4 种订单执行类型不够用,例如 Interactive Brokers 的情况下可以将以下内容作为 kwargs 传递:
orderType='LIT', lmtPrice=10.0, auxPrice=9.8` 
  • 这将覆盖 backtrader 创建的设置,并生成一个 touched 价格为 9.8, limit 价格为 10.0 的 LIMIT IF TOUCHED 订单。

信息位:

  • 策略具有与主数据(datas[0])长度相等的 length,当然可以用 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)  # or self.dnames['days']
smaweeks = bt.ind.SMA(self.dnames.weeks, period=10)  # or self.dnames['weeks']
...` 
  • broker: 引用与此策略相关联的经纪人(从 cerebro 接收)
  • stats: 保存由 cerebro 为该策略创建的观察者的列表/类似命名元组序列
  • analyzers: 保存由 cerebro 为该策略创建的分析器的列表/类似命名元组序列
  • position: 实际上是一个属性,用于给出 data0 的当前持仓。
    有用于检索所有仓位的方法(参见参考资料)

成员属性(用于统计/观察者/分析器):

  • _orderspending: 将在调用 next 之前通知给策略的订单列表
  • _tradespending: 将在调用 next 之前通知给策略的交易列表
  • _orders: 已经通知的订单列表。订单可以以不同的状态和不同的执行位多次出现在列表中。此列表用于保留历史记录。
  • _trades: 已通知的订单列表。交易可以像订单一样多次出现在列表中。

注意

请记住,prenextnextstartnext 可能会针对同一时间点被多次调用(当使用日线时,每次 ticks 更新价格时)

参考:Strategy

backtrader.Strategy(*args, **kwargs)

用于用户定义策略的基类。

next()

此方法将在满足所有数据/指标的最小期限后,为所有剩余数据点调用。

nextstart()

此方法将被调用一次,确切地在所有数据/指标的最小期限已满足时。默认行为是调用 next

prenext()

此方法将在策略开始执行之前,所有数据/指标的最小期限已满足时调用

start()

在回测即将开始之前调用。

stop()

在回测即将停止之前调用

notify_order(order)

每当有变化时接收订单

notify_trade(trade)

每当有变化时接收交易

notify_cashvalue(cash, value)

接收策略经纪人的当前基金价值、价值状态

notify_fund(cash, value, fundvalue, shares)

接收当前现金、价值、基金价值和基金份额

notify_store(msg, *args, **kwargs)

接收来自存储提供程序的通知

buy(data=None, size=None, price=None, plimit=None, exectype=None, valid=None, tradeid=0, oco=None, trailamount=None, trailpercent=None, parent=None, transmit=True, **kwargs)

创建买入(做多)订单并发送到经纪人

  • data(默认为 None
    为哪个数据创建订单。如果为 None,则系统中的第一个数据,self.datas[0] 或 self.data0(又名 self.data)将被使用
  • size(默认为 None
    要使用的数据单位(正数)来用于订单。
    如果为 None,则将使用通过 getsizer 获取的 sizer 实例来确定大小。
  • price(默认为 None
    用于价格(实时经纪人可能对实际格式施加限制,如果不符合最小 tick 大小要求)
    对于 MarketClose 订单,None 是有效的(市场决定价格)
    对于 LimitStopStopLimit 订单,此值确定触发点(在 Limit 的情况下,触发显然是订单应匹配的价格)
  • plimit(默认为 None
    仅适用于 StopLimit 订单。这是触发隐含 Limit 订单的价格,一旦 Stop 被触发(price 已被使用)
  • trailamount(默认为 None
    如果订单类型是 StopTrailStopTrailLimit,这是一个绝对数值,用于确定距离价格的距离(对于卖单是下方,对于买单是上方)以保持跟踪止损
  • trailpercent(默认为 None
    如果订单类型是 StopTrailStopTrailLimit,这是一个百分比数值,用于确定距离价格的距离(对于卖单是下方,对于买单是上方)以保持跟踪止损(如果还指定了 trailamount,它将被使用)
  • exectype(默认值:None)可能的值:
  • Order.MarketNone. 一个市价订单将以下一个可用价格执行。 在回测中,它将是下一个 bar 的开盘价
  • Order.Limit. 一个只能以给定的price或更好的价格执行的订单
  • Order.Stop. 一个在price处触发并像Order.Market订单一样执行的订单
  • Order.StopLimit. 一个在price处触发并以隐式Limit订单形式执行的订单,价格由pricelimit给出
  • Order.Close. 一个只能在会话结束时(通常在收盘竞价时)执行的订单
  • Order.StopTrail. 一个在price减去trailamount(或trailpercent)处触发并在价格远离停止时更新的订单
  • Order.StopTrailLimit. 一个在price减去trailamount(或trailpercent)处触发并在价格远离停止时更新的订单
  • valid(默认值:None)可能的值:
  • None: 这将生成一个不会过期的订单(又称Good till cancel),并保持在市场上直到匹配或取消。 实际上,经纪人往往会强加一个时间限制,但这通常是如此遥远的时间,以至于可以视为不会过期。
  • datetime.datetimedatetime.date 实例:日期将用于生成一个直到给定日期时间(又称good till date)的有效订单
  • Order.DAY0timedelta(): 一个有效期至会话结束(又称day订单)的订单将被生成
  • numeric value: 这被假设为与matplotlib编码中的日期时间对应的值(backtrader使用的编码方式),并将用于生成一个有效订单,直到该时间(good till date
  • tradeid (默认值: 0)
    这是backtrader应用的内部值,用于跟踪同一资产上的重叠交易。 当通知订单状态变化时,此tradeid将发送回strategy
  • oco (默认值: None)
    另一个order实例。 这个订单将成为 OCO(Order Cancel Others)组的一部分。 一个订单的执行会立即取消同一组中的所有其他订单
  • parent (默认值: None)
    控制一组订单的关系,例如一个由高限价卖出和低止损卖出所包围的买入订单。高/低侧订单保持不活跃,直到父订单被执行(它们变为活动状态)或取消/过期(子订单也取消)bracket 订单具有相同的大小
  • transmit (默认值: True)
    指示订单是否必须发送,即不仅在经纪人处放置,而且发出。 例如,这用于控制 bracket 订单,其中一个禁用父订单和第 1 组子订单的传输,并激活最后一组子订单的传输,这会触发所有 bracket 订单的完全放置。
  • **kwargs:其他经纪人实现可能支持额外的参数。backtraderkwargs传递给创建的订单对象
    示例:如果直接由backtrader支持的 4 种订单执行类型不够,例如Interactive Brokers的情况下,可以将以下内容作为kwargs传递:
orderType='LIT', lmtPrice=10.0, auxPrice=9.8` 
  • 这将覆盖backtrader创建的设置,并生成一个touched价格为 9.8,limit价格为 10.0 的LIMIT IF TOUCHED订单。
  • 返回
  • 提交的订单
sell(data=None, size=None, price=None, plimit=None, exectype=None, valid=None, tradeid=0, oco=None, trailamount=None, trailpercent=None, parent=None, transmit=True, **kwargs)

创建一个卖出(做空)订单并将其发送给经纪人

查看buy的文档以了解参数的解释

返回:提交的订单

close(data=None, size=None, **kwargs)

抵消长/短持仓

查看buy的文档以了解参数的解释

注意

  • size: 如果调用者没有提供,则自动从现有位置计算(默认值:None

返回:提交的订单

cancel(order)

在经纪人处取消订单

buy_bracket(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)

创建一个支架订单组(低端 - 买单 - 高端)。默认行为如下:

  • 发出buy带有执行Limit的订单
  • 发出一个low side支架sell带有执行Stop的订单
  • 发出一个high side支架sell带有执行Limit的订单。

有关不同参数的详细信息,请参见下文

  • data(默认值:None
    要为哪些数据创建订单。如果为None,则将使用系统中的第一个数据,self.datas[0]或 self.data0(又名self.data
  • size(默认值:None
    要使用的大小(正)以用于订单的数据单位。
    如果为None,则将使用通过getsizer检索到的sizer实例确定大小。
    注意
    同样的大小适用于支架的所有 3 个订单
  • price(默认值:None
    使用价格(实时经纪人可能会对实际格式施加限制,如果不符合最小跳动大小要求)
    None适用于MarketClose订单(市场确定价格)
    对于LimitStopStopLimit订单,此值确定触发点(在Limit情况下,触发显然是订单应匹配的价格)
  • plimit(默认值:None
    仅适用于StopLimit订单。这是设置隐含Limit订单的价格,一旦Stop已被触发(已使用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_bracket(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)

创建一个括号订单组(低侧 - 买入订单 - 高侧)。默认行为如下:

  • 发出一个卖出订单,执行限价
  • 发出一个高侧括号买入订单,执行停止
  • 发出一个低侧括号买入订单,执行限价

查看bracket_buy以了解参数的含义

可以通过以下方式抑制高/低侧订单:

  • stopexec=None以抑制高侧
  • limitexec=None以抑制低侧
  • 返回
  • 包含 3 个订单的列表[订单,停止侧,限价侧]
  • 如果高/低订单已被抑制,则返回值仍将包含 3 个订单,但被抑制的订单将值为None
order_target_size(data=None, target=0, **kwargs)

下达订单以将头寸重新平衡为target的最终大小

当前position大小被视为实现target的起始点

  • 如果target > pos.size -> 买入 target - pos.size
  • 如果target < pos.size -> 卖出 pos.size - target

它返回以下之一:

  • 生成的订单

  • 如果没有下达订单则为Nonetarget == position.size)
order_target_value(data=None, target=0.0, price=None, **kwargs)

下达订单以将头寸重新平衡为target的最终价值

当前value被视为实现target的起始点

  • 如果没有target,则在数据上关闭头寸
  • 如果target > value则在数据上买入
  • 如果target < value则在数据上卖出

它返回以下之一:

  • 生成的订单

  • 如果没有下达订单则为None
order_target_percent(data=None, target=0.0, **kwargs)

下达订单以将头寸重新平衡为当前投资组合valuetarget百分比的最终价值

target以小数表示:0.05 -> 5%

它使用order_target_value来执行订单。

示例

  • target=0.05且投资组合价值为100
  • 要达到的value0.05 * 100 = 5
  • 5作为target值传递给order_target_value

当前value被视为实现target的起始点

使用position.size来确定头寸是多头/空头

  • 如果target>value
  • 如果pos.size >= 0则买入(增加多头头寸)
  • 如果pos.size < 0则卖出(增加空头头寸)
  • 如果target<value
  • 如果pos.size >= 0则卖出(减少多头头寸)
  • 如果pos.size < 0则买入(减少空头头寸)

它返回以下之一:

  • 生成的订单

  • 如果没有下达订单,则为Nonetarget == position.size
getsizer()

返回正在使用的 sizer,如果使用自动��注计算

也可用作sizer

setsizer(sizer)

替换默认(固定赌注)sizer

getsizing(data=None, isbuy=True)

返回由 sizer 实例计算的当前情况下的赌注

getposition(data=None, broker=None)

返回给定经纪人中给定数据的当前头寸。

如果两者都为 None,则将使用主要数据和默认经纪人

也可用的属性position

getpositionbyname(name=None, broker=None)

返回给定经纪人中给定名称的当前头寸。

如果两者都为 None,则将使用主要数据和默认经纪人

也可用的属性positionbyname

getpositionsbyname(broker=None)

直接从经纪人那里返回当前名称的头寸

如果给定的broker为 None,则将使用默认经纪人

也可用的属性positionsbyname

getdatanames()

返回现有数据名称的列表

getdatabyname(name)

通过名称使用环境(cerebro)返回给定数据

add_timer(when, 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

  • 参数when(-) – 可以是
  • datetime.time 实例(参见下面的 tzdata
  • bt.timer.SESSION_START 用于引用会话开始
  • bt.timer.SESSION_END 用于引用会话结束
  • offset 必须是一个 datetime.timedelta 实例
  • 用于偏移值 when。与 SESSION_STARTSESSION_END 结合使用具有有意义的用途,以指示会话开始后 15 分钟 调用计时器的情况。
  • repeat 必须是一个 datetime.timedelta 实例
    指示在第一次调用后,进一步的调用是否会在同一会话中按计划的 repeat 间隔进行安排
    一旦计时器超过会话结束,它将被重置为 when 的原始值
  • weekdays:一个排序的可迭代对象,其中的整数表示可以实际调用计时器的日期(ISO 代码,星期一为 1,星期日为 7)
    如果未指定,则计时器将在所有日期都处于活动状态
  • weekcarry(默认:False)。如果为 True 并且没有看到周几(例如:交易假期),则计时器将在下一天执行(即使是在新的一周)
  • monthdays:一个排序的可迭代对象,其中的整数表示要执行计时器的月份中的哪些日期。例如,每月的第 15 天
    如果未指定,则计时器将在所有日期都处于活动状态
  • monthcarry(默认:True)。如果未看到该天(周末,交易假期),则计时器将在下一个可用日期执行。
  • allow(默认:None)。一个回调函数,接收一个 datetime.date 实例,如果日期允许计时器,则返回True,否则返回False
  • tzdata 可以是 None(默认值),一个 pytz 实例或一个数据源实例。
    Nonewhen按照面值解释(即使它不是 UTC 时间也会被处理为 UTC 时间)
    pytz 实例:when 将被解释为由时区实例指定的本地时间。
    data feed 实例:when 将被解释为数据源实例参数 tz 指定的本地时间。
    注意
    如果 whenSESSION_STARTSESSION_END,并且 tzdataNone,则系统中的第一个数据源(即 self.data0)将被用作查找会话时间的参考。
  • cheat(默认为 False)如果为 True,则在经纪人有机会评估订单之前将调用计时器。这打开了在会话开始之前根据开盘价发出订单的可能性
  • *args:任何额外的参数将被传递给 notify_timer
  • **kwargs:任何额外的 kwargs 将被传递给 notify_timer

BackTrader 中文文档(五)(2)https://developer.aliyun.com/article/1489255

相关文章
|
6月前
|
Unix 索引 Python
BackTrader 中文文档(一)(2)
BackTrader 中文文档(一)
156 0
|
6月前
|
存储 编解码 API
BackTrader 中文文档(四)(1)
BackTrader 中文文档(四)
71 1
|
6月前
|
Python
BackTrader 中文文档(六)(4)
BackTrader 中文文档(六)
83 0
|
6月前
|
存储
BackTrader 中文文档(四)(4)
BackTrader 中文文档(四)
44 0
|
6月前
|
Python
BackTrader 中文文档(五)(4)
BackTrader 中文文档(五)
73 0
|
6月前
|
索引 Python
BackTrader 中文文档(五)(3)
BackTrader 中文文档(五)
69 0
|
6月前
|
存储 缓存 Shell
BackTrader 中文文档(二)(3)
BackTrader 中文文档(二)
136 0
|
6月前
|
Python
BackTrader 中文文档(一)(3)
BackTrader 中文文档(一)
75 0
|
6月前
|
存储 C++ 索引
BackTrader 中文文档(二)(1)
BackTrader 中文文档(二)
70 0
|
6月前
|
存储 安全 Unix
BackTrader 中文文档(四)(2)
BackTrader 中文文档(四)
57 0