Backtrader 文档学习-Strategy(上)

Backtrader 文档学习-Strategy(上)

策略通过方法的形式体现生命周期。
是BackTrader的核心模块,需要好好研读。

1.Strategy

  • (1)怀胎
    在init中创建indicator和需要的属性值
  • (2)出生
    start方法,策略启动,start默认是空方法
  • (3)儿童
    prenext方法,indicator 在init初始化的时候设置了成熟期的时间,称为最小周期。上面在 __init__创建了一个周期=15的SimpleMovingAverage。
  • (4)成人
    next方法,一旦系统生成15个bar,SMA缓存了足够的用于启动的数据,策略就可以真正执行。
    nextstart方法执行一次,是从prenext切换到next的标志,nextstart默认执行是调用next方法。
  • (5)生育
    策略中并没有真正的生育,但是从某种意义上来说是存在的,因为如果优化用不同的参数的话,系统会实例化多次。算是生育吧
  • (6)死亡
    stop方法,系统通知策略重启,恢复所有设置,默认是空方法。

策略就像现实世界中的交易员一样,会在事件发生时得到通知。实际上在每一个next循环在回测过程中 :

  • 通过notify_order(order)获得订单状态变化的通知
  • 通过notify_trade(trade)通知所有开仓/更新/平仓交易
  • 通过notify_cashvalue(cash,value)通知在broker中当前现金和投资组合
  • 通过notify_fund(cash,value,fundvalue,shares)跟踪broker中当前现金和投资组合,以及基金价值和份额
  • 通过notify_store(msg,*args,**kwargs)实现特定事件 ,请参见Cerebro的关于store的说明。event将被传递给策略,即使已经被传递给cerebro实例(通过重写notify_store方法或通过回调)

策略像交易者有机会在市场期间通过next方法试图实现获利

  • buy方法 是做多或减少/平仓空头的头寸
  • sell方法 是做空或减少/平仓多头的头寸
  • close方法 是平仓存在的仓位
  • cancel方法 是取消尚未执行的订单

2. How to Buy/Sell/Close

order常用的方法是Buy和Sell方法。当被调用时,它们返回一个订单(或子类)实例作参考。该订单具有唯一的参考标识符,可用于对比。

order的参数:

  • data(默认:无) 必须为其创建订单的数据。如果没有,则将使用系统中的第一个数据,即self.datas[0]或self.data0(也称为self.data)
  • size(默认值:无) 用于订单的数据单位的大小(正值)。 如果没有,将使用通过getsizer检索的sizer来确定大小。
  • price(默认值:无) 如要设置的价格(实时broker会对其进行限制,如果格式不符合最小报价单位要求)
    None对market订单和close订单是有效(市价决定价格)
    对于limit限价单、stop止损单和stoplimit单,该值price决定是否触发,(在限价单limit的情况下,触发点显然是订单应该匹配price)
  • exectype(默认值:None) 执行订单的类型:
    • Order.Market or None,市价单将以next可用价格执行。回测中,next使用第二天的开盘价执行订单。
    • Order.Limit,只能以给定价格或更低(好)价格执行的订单
    • Order.Stop,止损价格被触发,和订单一样执行。
    • Order.StopLimit,以价格触发的订单,隐含限价订单执行,价格由pricelimit执行,理解应该是止损单的止损价格。
    • numeric value: 如果是一个与matplotlib编码中的日期时间相对应的值(backtrader使用的日期时间),就是该数字能转换成正确的日期,可以生成一个在该时间(截止日期)之前有效的订单。

如果backtrader直接支持的4种订单执行类型还不够用,例如在交互时broker,可以将作为kwargs传递:

orderType='LIT', lmtPrice=10.0, auxPrice=9.8

将重写backtrader创建的设置,并生成一个触及限价单,触及价格为9.8,限价为10.0。

3.Information Bits

策略的长度总是等于主数据(datas[0])的长度,可以用len(self) 。
如果正在replay数据或正载入数据,并且新tick正在到达相同的时间点,调用next而不改变长度 。(没有理解 ?)

4.Member Attributes

  • env:加载策略的cerebro 实体
  • datas:加载到cerebro的数据,默认data/data0是data[0],dataX是data[X]
  • dnames:通过名称访问数据加载的替代方法。
    在数据加载时:
    data = bt.feeds.PandasData(dataname=stock_hfq_df, fromdate=start_date, todate=end_date,name='days')  # 加载数据

    # Add the Data Feed to Cerebro
    cerebro.adddata(data)
    cerebro.resampledata(data, timeframe=bt.TimeFrame.Weeks, name='weeks')

在策略的indicator中:

class MyStrategy(bt.Strategy):  
    def __init__(self):  
        self.dataclose = self.datas[0].close  

        smadays = bt.indicators.SMA(self.dnames.days, period=30)  # or self.dnames['days']
        smaweeks = bt.indicators.SMA(self.dnames.weeks, period=10)  # or self.dnames['weeks']
  • broker:策略所关联的broker
  • stats:由cerebro为相关策略创建的Observers ,保存为列表/命名的类似元组的序列
  • analyzers:由cerebro为相关策略创建的analyzers,保存为列表/命名的类似元组的序列
  • position:data0的仓位

5.Member Attributes (适用于statistics/observers/analyzers):

  • _orderspending: 在调用next方法将通知给策略的订单列表
  • _tradespending: 在调用next方法将通知给策略的交易列表
  • _orders:已经完成通知的订单列表。一个订单可以在列表中出现多次,具有不同的状态和不同的执行位,目的是记录历史。
  • _trades: 已经完成通知的订单列表。像订单一样,一笔交易可以列表上出现多次。

6.Strategy参考

next()

当满足所有data/indicators的最小周期后,执行将对所有剩余数据点调用。
如period是10 ,最小周期达到后,开始执行next方法。

nextstart()

方法执行一次,在最小周期的data/indicators满足时,默认执行next方法。
如period是10 ,在到达9执行最小周期达到后,执行一次nextstart,之后执行next方法。

prenext()

方法将在所有数据/指标的最小周期满足策略开始执行之前调用执行。
如period是10 ,在1到9执行最小周期之间,执行prenext。

start()

在回测即将开始之前调用,执行一次。

stop()

在回测即将结束之前调用,执行一次。

notify_order(order)

每当订单发生变化时,都会接收订单变化的通知

notify_trade(trade)

每当交易发生变化时,都会接收交易变化的通知

notify_cashvalue()

notify_cashvalue(cash, value)

接收当前使用的资金余额,broker的资金状态还是现金价值 ???
Receives the current fund value, value status of the strategy’s broker

notify_fund()

notify_fund(cash, value, fundvalue, shares)

策略的资金和价值发生变化时被调用。用于跟踪和记录策略的现金、价值、基金价值和持仓股票的数量。
notify_fund方法的参数:

  • cash: 当前策略的现金余额。
  • value: 当前策略的总价值(包括持有的股票价值)。
  • fundvalue: 策略基金的价值。这是另一个属性,与value不同,它可能代表策略的总资产,包括现金和股票,但不包括费用和税费等其他扣除。???
  • shares: 当前策略持有的股票数量。
notify_store()

notify_store(msg, *args, **kwargs)

接收broker的通知信息。

buy()重要!

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)

strategy重要的方法,buy方法的参数:

  • data: 可选参数,表示当前的数据对象。如果提供,它将在执行交易时使用该数据对象。

  • size: 可选参数,正数,表示要购买的合约数量或金额。如果没有指定,将使用默认值或策略中定义的size属性,getsizer 返回设置值。

  • price: 可选参数,表示买入的价格限制。如果实际格式不符合最小报价单位的要求,实时broker可以对其进行限制。

  • plimit: 可选参数,仅适用于停止限制订单。一旦止损被触发,设置隐含限价单的价格(已使用该价格)。

  • trailamount :可选参数,如果订单类型是StopTrail或StopTrailLimit,使用绝对金额,它决定了保持跟踪止损的价格距离(低于卖出订单,高于买入订单)

  • trailpercent :可选参数,如果订单类型是StopTrail或StopTrailLimit,使用百分比金额,它决定了保持跟踪止损的价格距离(低于卖出订单,高于买入订单),如果同时还指定了trailamount,优先使用trailpercent 。

  • exectype: 可选参数,表示执行类型。

    • Order.Market or None. Market或者不指定值,市价单将以下一个可用价格执行。在回测中它将是下一bar的开盘价
    • Order.Limit. 只能以给定价格或更好的价格执行的订单。(对于买单,更低的价格;对于卖单,更高的价格?)
    • Order.Stop. 在价格一旦被触发,像Order.Market一样被执行的止损订单
    • Order.StopLimit.以价格触发执行的隐含限价单订单,价格由限价单plimit决定
    • Order.Close. 只能以设定的平仓价格执行的订单
    • Order.StopTrail. 如果价格波动超过止损点,订单会更新,在价格减去trailamount 值(或减去trailpercent值) 时触发的订单
    • Order.StopTrailLimit. 如果价格波动超过止损点,订单会更新,在价格减去trailamount (或trailpercent)时触发的订单

Order.StopTrail和Order.StopTrailLimit ,从字面上看不出具体差异区别。

  • valid: 可选参数,表示交易的有效期。它可以是时间格式的字符串或一个 datetime.timedelta对象。默认情况下,它将使用策略中定义的valid属性。

    • None: 只要市场存在,数据持续,订单永不过期(除非上帝取消它),在现实中broker会施加一个临时 的时间限制,但通常是遥不可及的时间
    • datetime.datetime or datetime.date instance: 日期类型参数,订单到指定的时间停止。
    • Order.DAY or 0 or timedelta(): Order.DAY,timedelta()类型, 生成一个在会话结束前有效的日期(也称为日订单)
    • numeric value: 数字类型,假定为与matplotlib编码中的日期时间相对应的值,(backtrader中使用的日期时间),将用于生成在该时间之前有效的订单(有效截止日期) 。数字类型实际上是可以转换为matplotlib的日期类型。
  • tradeid: 可选参数,表示交易的唯一标识符。默认情况下,它将自动生成一个唯一的交易ID。backtrader应用的内部值,用于跟踪同一资产的重叠交易。当通知订单状态的变化时,该tradeid被发送回策略。

  • oco: 可选参数,表示是否使用OCO(One-Cancels-All)订单。如果提供,该订单将成为OCO(订单取消其他)组的一部分。其中一个订单的执行会立即取消同一组中的所有其他订单。

  • parent: 可选参数,表示父交易对象。如果提供,将将当前交易附加到父交易上。
    控制一组订单的关系,例如由高限价卖出和低止损卖出组成的买入。高/低价格的订单保持无效直到父订单被执行(它们变为有效)或被取消/到期(子订单也被取消)为止。(bracket orders have the same size)回测订单具有相同的大小?

  • transmit: 可选参数,表示是否传输交易请求。默认情况下为True,表示将传输交易请求到执行引擎。
    指示是否必须传输订单,即:不仅在broker中发出。这意味着,例如,控制bracket 订单,其中一个为父代和第一组子代禁用传输,并为最后的子代激活传输,将触发所有bracket 订单的完全设置。

  • **kwargs: 其他broker实现可能支持额外的参数。backtrader将把kwargs传递给创建的订单对象 例如:如果backtrader直接支持的4种订单执行类型还不够,例如在交互式经纪人的情况下,可以将以下类型作为kwargs传递:

orderType='LIT', lmtPrice=10.0, auxPrice=9.8

将覆盖backtrader创建的设置,并生成一个触及限价单,触及价格为9.8,限价为10.0。
(个人理解:应该是 在init初始化中定义的参数。)

  • Returns,返回提交的buy订单(数量?列表?)
sell()重要!

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)
创建卖出(卖空)订单并将其发送给broker 。
参数与buy一样,不再赘述。

close()

close(data=None, size=None, **kwargs)
结算多头/空头,平仓。
returns:提交的订单

cancel(order)

取消broker中的订单

buy_bracket()买组合单

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)和一个买入止损单(buy stop),或者同时发送一个买入限价单和一个卖出止损单(sell stop,作为保护性止损)。订单组合通常用于捕捉市场波动并设置相应的风险管理措施。

创建一个组合订单(低价端-订单-高价端)。默认操作如下:

  • 发出有执行限制的买单
  • 发出带执行止损的低价组合卖单
  • 发出有执行限制的高价组合卖单

方法参数:

  • data: 可选参数,表示当前的数据对象。如果提供,它将在执行交易时使用该数据对象。

  • size: 可选参数,正数,表示要购买的合约数量或金额。如果没有指定,将使用默认值或策略中定义的size属性,getsizer 返回设置值。

  • price: 可选参数,表示买入的价格限制。如果实际格式不符合最小报价单位的要求,实时broker可以对其进行限制。
    None 是有效的,对市价订单和平仓订单有效(市价决定价格)
    对于限价单、止损单和限价止损单,该值决定触发点价格。(在限价单的情况下,触发价显然是订单应该匹配的价格)

  • plimit: 可选参数,仅适用于停止限制订单。一旦止损被触发,设置隐含限价单的价格(已使用该价格)。

  • trailamount :可选参数,如果订单类型是StopTrail或StopTrailLimit,使用绝对金额,它决定了保持跟踪止损的价格距离(低于卖出订单,高于买入订单)

  • trailpercent :可选参数,如果订单类型是StopTrail或StopTrailLimit,使用百分比金额,它决定了保持跟踪止损的价格距离(低于卖出订单,高于买入订单),如果同时还指定了trailamount,优先使用trailpercent 。

  • exectype (default: bt.Order.Limit)
    可能值:参考buy的说明

  • valid (default: None) 参考buy的说明

  • tradeid (default: 0) 参考buy的说明

  • oargs (default: {}) 特定的关键字参数(在字典dict中)传递到主顺序。默认**kwargs中的参数将应用(优先??)于此之上。
    **kwargs: 其他broker实现可能支持额外的参数。backtrader将把kwargs传递给创建的订单对象。参考buy的说明。

  • stopprice (default: None) 设置低价止损价订单

  • stopexec (default: bt.Order.Stop) 设置低价订单的类型,默认是止损单

  • stopargs (default: {}) 传递给低价订单的特定关键字参数(在字典dict中)。默认**kwargs中的参数将应用于此之上。

  • limitprice (default: None) 设置高价止损单

  • stopexec (default: bt.Order.Limit) 设置高价限价订单 ,和上一个stopexec应该一样,只不过参数值不同。

  • limitargs (default: {}) 传递给高价订单的特定关键字参数(在字典dict中)。默认**kwargs中的参数将应用于此之上。

  • High/Low Side orders can be suppressed by using:
    高价/低价订单抑制设置:

    • limitexec=None 抑制高价
    • stopexec=None 抑制低价
  • Returns 返回值
    返回list对象,包括3个订单[订单,止损单,限价单]

If high/low orders have been suppressed the return value will still contain 3 orders, but those suppressed will have a value of None
如果高价/低价订单已被抑制(取消?),返回值仍将包含3个订单,但被取消的订单的值将为None 。

sell_bracket()卖组合单

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)

创建一个卖组合单(低价-订单-高价)。默认行为如下:

  • 发出限价的卖单
  • 发出止损高价买单
  • 发出限价低价买单

可以和buy_bracket()对比理解。

其他参数看 bracket_buy 说明。

  • 高价/低价 可通过以下方法抑制:

    • stopexec=None 抑制高价
    • limitexec=None 抑制低价
  • Returns 返回值
    返回list对象,包括3个订单[订单,止损单,限价单]
    如果高价/低价订单已被取消,返回值仍将包含3个订单,但被取消的订单的值将为None 。

order_target_size()

order_target_size(data=None, target=0, **kwargs)
基于目标持仓数量来发出订单。这个方法的目的是调整当前持仓以达到指定的目标持仓数量。
target: 必需参数,指定目标持仓数量。可以是正数(多头持仓),负数(空头持仓),默认值0(平仓)。

当前仓位值被视为实现目标的起点:

  • 如果没有目标仓位值,则在当前位置平仓
  • 如果目标仓位值>当前仓位,则买入
  • 如果目标仓位值<当前仓位,则卖出

返回值:
可能是生成的订单 或者 None 没有任何订单被触发

order_target_percent()

order_target_percent(data=None, target=0.0, **kwargs)
重新平衡头寸,使最终价值达到当前投资组合价值的目标百分比 。
根据目标持仓百分比来发出订单。用于根据资产配置或风险管理要求调整持仓比例。

target 必需参数,指定目标持仓百分比。这个值应该在0到1之间(不包括0和1),表示目标持仓占账户总资产的比例。

使用order_target_value来执行订单。
举例说明:

  • target=0.05 投资组合值 100
  • value= 0.05 * 100 = 5
  • 赋值order_target_value =5

The current value is taken into account as the start point to achieve target
当前值被视为实现目标的起点 。
position.size用于确定头寸是多头/空头

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

返回值:
生成的订单,或者如果(target == position.size),无订单,则None 。

getsizer()

自动计算返回持仓数量,也可以用sizer对象

setsizer()

设置持仓数量

getsizing()

getsizing(data=None, isbuy=True)
用于确定应该买入或卖出的资产数量。
isbuy: 必需参数,布尔值,指示是否计算买入订单的大小。如果为True,则计算买入订单的大小;如果为False,则计算卖出订单的大小。

getposition()

getposition(data=None, broker=None)
用于获取当前broker持仓信息
如果两个参数都是None,使用主data和默认broker 。

 ['__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'adjbase', 'clone', 'datetime', 'fix', 'price', 'price_orig', 'pseudoupdate', 'set', 'size', 'upclosed', 'update', 'updt', 'upopened']

Position对象可用属性,对象包含了当前持仓的详细信息。信息包括:

  • position.size:持仓数量
  • position.price:持仓成本单价
    可以直接打印输出position :
--- Position Begin
- Size: 10
- Price: 126.75585714285712
- Price orig: 126.74206349206348
- Closed: 0
- Opened: 1
- Adjbase: 126.04
--- Position End
getpositionbyname()
(1)getpositionbyname(name=None, broker=None)

返回指定broker的某个资产持仓情况
如果两个参数都是None,使用主data和默认broker 。

Position对象可用属性,同上。

(2)getpositionsbyname(broker=None)

返回某个broker下所有资产持仓情况(不区分资产?)

Position对象可用属性,同上。
网上找了个例子,先理解一下。

# 获取特定资产的持仓信息  
      position = self.getpositionbyname('AAPL')  
        
      # 检查持仓盈亏状况  
      if position.pnl > 0:  
          print("AAPL is in profit!")  
      elif position.pnl < 0:  
          print("AAPL is in loss!")  
      else:  
          print("AAPL is flat.")
getdatanames()

返回策略中存在的数据源名称

getdatabyname(name)

在当前使用cerebro中按名称返回给定数据

add_timer()

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)

调度一个计时器来调用指定的回测或一个或多个策略的notify_timer。
它允许在特定时间触发事件,例如在特定日期、时间或间隔内执行某些操作。

注意:

只能在 init or start 中设置执行

参数说明:

  • when :必选参数

    • 可以是 datetime.time实例(参见后面的tzdata)
    • t.timer.SESSION_START 引用会话开
    • timer.SESSION_END引用会话结束
    • offset 必须是datetime.timedelta实例的偏移量
      如指定偏移该值,它与SESSION_START和SESSION_END结合使用才有意义,可以指示诸如会话开始15分钟(offset)后调用计时器执行操作。
  • repeat: 可选参数
    指示在第一次调用后,是否将在同一会话中以预定的重复增量安排多次调用。 一旦定时器在会话结束时,它将被重置为原始值。
    指定事件的重复间隔,可以是datetime.timedelta对象或其他时间单位(例如天、小时等)。默认值为datetime.timedelta(0),即不重复。

  • weekdays: 可选参数
    一个包含星期几的整数列表(1代表星期一,2代表星期二,以此类推),用于指定仅在某些特定的星期几触发事件。默认值为空,即每天都有可能触发。

  • monthcarry: 可选参数,布尔值
    指定是否在每月某个日期不可用(周末,节假日),并延续到下一个可用日期。默认值为True,即延续下一个交易日。

  • allow: 可选参数
    是否调用函数,接收datetime.date数据类型,如果日期允许用于计时器,则返回True,否则返回False。
    用于过滤是否允许触发事件。如果该函数或方法返回True,则允许触发;如果返回False,则不允许触发。默认值为None,即无过滤条件。

  • tzdata: 可选参数
    指定时区数据。是时区对象、时区字符串或包含时区数据的字典。默认值为None,即使用当前系统时区。
    pytz实例:when将被解释为由timezone实例指定的本地时间。(pytz是时区数据类型 ?)

  • cheat: 可选参数,布尔值
    如果为true,将在broker调用计时器前有机会评估订单。提供了根据开盘价发出订单的机会,例如就在会话开始之前。指定是否在调用期间使用定时器事件。

  • *args: 其他可选参数列表
    用于传递给定时器事件notify_timer

  • **kwargs: 其他可选关键字参数列表
    用于传递给定时器事件的notify_timer

返回值
创建成功的timer

notify_timer()

notify_timer(timer, when, *args, **kwargs)

当指定的时间到达时,该方法将调用与定时器相关联的回调函数,并传递相应的参数。

以下是notify_timer方法的一些参数说明:

  • timer: 必选参数,指定要触发的定时器对象。
  • when: 必选参数,指定触发事件的时间。它可以是datetime.datetime对象或字符串表示的日期和时间。
  • *args: 可选参数,其他可选参数列表,用于传递给回调函数。
  • **kwargs: 可选参数,其他可选关键字参数列表,用于传递给回调函数。

接收计时器通知,其中timer是add_timer返回的计时器,而when是调用时间。
args和kwargs是传递给add_timer的任何附加参数。
实际when调用时间可能晚一些,但系统可能无法调用之前的计时器。
这个值是定时器值,而不是系统时间。

使用场景:可以在回调函数中执行交易操作、发送通知或更新策略状态等。

注意:notify_timer方法仅在Backtrader的回测或实时交易期间有效。在策略初始化或初始化之后的阶段调用该方法将不会产生任何效果。确保在适当的时间和上下文中使用该方法,以实现您想要的定时器功能。

终于完成了,strategy的方法、属性很多,是做好回测设计中最重要的一个步骤,需要后面做程序验证是否理解到位。

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值