BackTrader 中文文档(十一)(4)

简介: BackTrader 中文文档(十一)

BackTrader 中文文档(十一)(3)https://developer.aliyun.com/article/1505310

实时数据源和重采样/重播

关于何时为实时数据源交付条的设计决策是:

  • 尽可能实时地交付它们

这可能看起来很明显,对于Ticks的时间框架来说是这样,但如果重采样/重播起作用,延迟可能会发生。用例:

  • 重采样配置为Seconds/5,具有:
cerebro.resampledata(data, timeframe=bt.TimeFrame.Seconds, compression=5)` 
  • 一个时间为23:05:27.325000的 tick 被交付
  • 在市场上交易速度很慢,下一个 tick 将在23:05:59.025000时到达

也许并不明显,但backtrader并不知道交易速度非常慢,下一个 tick 大约会在32秒后到来。如果没有适当的措施,一个时间为23:05:30.000000的重采样条可能会被延迟约29 秒

这就是为什么实时数据源每隔x秒(float值)唤醒一次重采样器/重播器并让它知道没有新数据输入。这是在创建实时数据源时通过参数qcheck(默认值:0.5秒)来控制的。

这意味着重采样器每隔qcheck秒就有机会交付一个条,如果本地时钟显示,重采样周期已经结束。这样一来,上述情景(23:05:30.000000)的重采样条最多会在报告时间后qcheck秒交付。

因为默认值是0.5,所以最晚时间是:23:05:30.500000。几乎比以前早了 29 秒。

缺点:

  • 有些 tick 可能会对已经交付的重采样/重播的条造成延迟

如果在交付后,TWS 从服务器收到一个时间戳为23:05:29.995\000的延迟消息,这对于已经向系统报告的时间23:05.30.000000`来说就太晚了

这通常发生在以下情况下:

  • timeoffsetIBStore\中被禁用(设置为False),IB报告的时间与本地时钟的时间差很大。

避免大部分延迟样本的最佳方法是:

  • 增加qcheck值,以考虑延迟消息:
data = ibstore.getdata('TWTR', qcheck=2.0, ...)` 

这应该增加额外的空间,即使延迟了重采样/重播条的交付

注意

当然,对于Seconds/5的重采样来说,2.0 秒的延迟意义不同于Minutes/10的重采样

如果由于某种原因,最终用户希望禁用timeoffset并且不通过qcheck进行管理,则仍然可以接受延迟样本:

  • getdata / IBData的参数中设置_latethroughTrue
data = ibstore.getdata('TWTR', _latethrough=True, ...)` 
  • 重采样/重播时设置takelateTrue
cerebro.resampledata(data, takelate=True)` 

IBBroker - 实时交易

注意

backtrader中的经纪人模拟中实现了tradeid功能。这允许正确地跟踪在同一资产上并行执行的交易,并将佣金正确地分配给适当的tradeid

此概念在此实时经纪人中不受支持,因为佣金是由经纪人报告的,而在某些情况下,不可能将其分离为不同的tradeid值。

tradeid仍然可以指定,但不再有意义。

使用经纪人

要使用IB Broker,必须替换由cerebro创建的标准经纪人模拟实例。

使用Store模型(首选):

import backtrader as bt
cerebro = bt.Cerebro()
ibstore = bt.stores.IBStore(host='127.0.0.1', port=7496, clientId=35)
cerebro.broker = ibstore.getbroker()  # or cerebro.setbroker(...)

使用直接方法:

import backtrader as bt
cerebro = bt.Cerebro()
cerebro.broker = bt.brokers.IBBroker(host='127.0.0.1', port=7496, clientId=35)

经纪人参数

不管是直接还是通过getbrokerIBBroker经纪人都不支持任何参数。这是因为经纪人只是一个真实经纪人的代理。真实经纪人给予的,不应被剥夺。

一些限制

现金和价值报告

当内部的backtrader经纪人模拟在调用策略的next方法之前对value(净清算价值)和cash进行计算时,无法保证与实时经纪人相同。

  • 如果请求了值,则可能会延迟next的执行,直到回答到达
  • 经纪人可能尚未计算出这些值

backtrader告诉 TWS 在它们更改时提供更新的值(backtrader订阅accounUpdate消息),但它不知道消息何时到达。

IBBrokergetcashgetvalue方法报告的值始终是从 IB 接收到的最新值。

注意

进一步的限制是,即使有更多货币的值可用,这些值也以帐户的基本货币报告。这是一个设计选择。

位置

backtrader使用 TWS 报告的资产的Position(价格和大小)。在order executionorder status消息后,内部计算可以被使用,但是如果其中一些消息被错过(套接字有时会丢失数据包),则计算将无法进行。

当然,如果连接到 TWS 时将执行交易的资产已经有一个开放的头寸,由于初始偏移,策略所做的Trades的计算将不会像通常一样工作

与其进行交易

就标准用法而言,没有变化。只需使用策略中可用的方法(有关完整说明,请参阅Strategy参考资料)

  • buy
  • sell
  • close
  • cancel

返回的订单对象

  • 与 backtrader 的Order对象兼容(在同一层次结构中的子类)

订单执行类型

IB 支持各种执行类型,其中一些由 IB 模拟,一些由交易所本身支持。最初支持哪些订单执行类型的决定有一个动机:

  • backtrader中可用的经纪人模拟兼容性
    这是因为经过回测的内容将会投入生产。

因此,订单执行类型仅限于broker simulation中可用的类型:

  • Order.Market
  • Order.Close
  • Order.Limit
  • Order.Stop(当Stop触发时,Market订单跟随)
  • Order.StopLimit(当Stop触发时,Limit订单跟随)

注意

停止触发是根据不同的策略由 IB 执行的。backtrader不修改默认设置,即为0

0 - the default value. The "double bid/ask" method will be used for
orders for OTC stocks and US options. All other orders will use the
"last" method.

如果用户希望修改此项,可以根据 IB 文档提供的额外**kwargsbuysell提供。例如,在策略的next方法中:

def next(self):
    # some logic before
    self.buy(data, m_triggerMethod=2)

这已更改策略为2“last”方法,其中停止订单基于最后价格触发

请参阅 IB API 文档以获取有关停止触发的进一步澄清

订单有效期

在回测期间可用的相同有效性概念(使用validbuysell)也可用,并具有相同的含义。因此,对于以下IB 订单valid参数翻译如下:

  • None -> GTC(Good Til Cancelled)
    因为没有指定有效期,所以理解为订单必须有效直到取消
  • datetime/date翻译为GTD(Good Til Date)
    传递datetime.datetime/datetime.date实例表示订单必须有效直到给定时间点。
  • timedelta(x)翻译为GTD(这里timedelta(x) != timedelta()
    这被解释为指示订单从now + timedelta(x)开始有效
  • float翻译为GTD
    如果该值来自backtrader使用的原始float日期时间存储,则订单必须有效直到由该float指示的日期时间
  • timedelta() or 0翻译为DAY
    已有一个值(而不是None),但是为空,被解释为当前day(session)有效的订单

通知

标准的Order状态将通过方法notify_order(如果已重写)通知给strategy

  • Submitted - 订单已发送到 TWS
  • Accepted - 订单已下达
  • Rejected - 订单放置失败或在其生命周期内被系统取消
  • Partial - 已经部分执行
  • Completed - 订单已完全执行
  • Canceled(或Cancelled)这在 IB 下有几个意思:
  • 手动用户取消
  • 服务器/交易所取消了订单
  • 订单有效期已过期
    将应用启发式方法,如果已从 TWS 接收到带有orderState指示为PendingCancelCanceledopenOrder消息,则订单将被标记为已过期
  • 已过期 - 请参阅上文的解释

参考

IBStore

类 backtrader.stores.IBStore()

封装一个 ibpy ibConnection 实例的单例类。

参数也可以在使用此存储的类中指定,如IBDataIBBroker

参数:

  • host(默认:127.0.0.1):IB TWS 或 IB Gateway 实际运行的位置。尽管这通常是本地主机,但不应该是
  • port(默认值:7496):连接的端口。演示系统使用7497
  • clientId(默认值:None):要用于连接到 TWS 的客户端 ID。
    None:生成 1 到 65535 之间的随机 ID。一个整数:将作为要使用的值传递。
  • notifyall(默认值:False
    如果为False,则只会将error消息发送到CerebroStrategynotify_store方法。
    如果为True,则会通知从 TWS 接收到的每条消息
  • _debug(默认值:False
    打印从 TWS 接收到的所有消息到标准输出
  • reconnect(默认值:3
    在第 1 次连接尝试失败后,尝试重新连接的次数。
    将其设置为-1值以永远保持重新连接
  • timeout(默认值:3.0
    重新连接尝试之间的秒数
  • timeoffset(默认值:True
    如果为 True,则将从reqCurrentTime(IB 服务器时间)获得的时间用于计算到本地时间的偏移量,并且此偏移量将用于价格通知(例如用于 CASH 市场的 tickPrice 事件)以修改本地计算的时间戳。
    时间偏移将传播到backtrader生态系统的其他部分,例如重新采样,以使用计算出的偏移量对齐重新采样时间戳。
  • timerefresh(默认值:60.0
    秒数:时间偏移量必须刷新的频率
  • indcash(默认值:True
    将 IND 代码视为现金进行价格检索

IBBroker

backtrader.brokers.IBBroker(**kwargs)

用于 Interactive Brokers 的经纪实现。

此类将 Interactive Brokers 的订单/持仓映射到backtrader的内部 API。

注意

  • 实际上不支持tradeid,因为利润和损失直接来自 IB。因为(如预期的那样)以 FIFO 方式计算,所以对于tradeid,利润和损失并不准确。
  • 仓位

如果在操作开始时有资产的持仓或通过其他方式给出的订单改变了持仓,那么在cerebro中计算的交易将不反映现实。

为了避免这种情况,该经纪商将不得不进行自己的持仓管理,这也将允许使用多个 ID 进行交易(利润和损失也将在本地计算),但可能被认为是与实时经纪商合作的目的相悖。

IBData

backtrader.feeds.IBData(**kwargs)

Interactive Brokers 数据源。

支持参数dataname中的以下合同规格:

  • TICKER # 股票类型和 SMART 交易所
  • TICKER-STK # 股票和 SMART 交易所
  • TICKER-STK-EXCHANGE # 股票
  • TICKER-STK-EXCHANGE-CURRENCY # 股票
  • TICKER-CFD # 差价合约和 SMART 交易所
  • TICKER-CFD-EXCHANGE # 差价合约
  • TICKER-CDF-EXCHANGE-CURRENCY # 股票
  • TICKER-IND-EXCHANGE # 指数
  • TICKER-IND-EXCHANGE-CURRENCY # 指数
  • TICKER-YYYYMM-EXCHANGE # 期货
  • TICKER-YYYYMM-EXCHANGE-CURRENCY # 期货
  • TICKER-YYYYMM-EXCHANGE-CURRENCY-MULT # 期货
  • TICKER-FUT-EXCHANGE-CURRENCY-YYYYMM-MULT # 期货
  • TICKER-YYYYMM-EXCHANGE-CURRENCY-STRIKE-RIGHT # 期权
  • TICKER-YYYYMM-EXCHANGE-CURRENCY-STRIKE-RIGHT-MULT # 期权
  • TICKER-FOP-EXCHANGE-CURRENCY-YYYYMM-STRIKE-RIGHT # 期权组合
  • TICKER-FOP-EXCHANGE-CURRENCY-YYYYMM-STRIKE-RIGHT-MULT # 期权组合
  • CUR1.CUR2-CASH-IDEALPRO # 外汇
  • TICKER-YYYYMMDD-EXCHANGE-CURRENCY-STRIKE-RIGHT # 期权
  • TICKER-YYYYMMDD-EXCHANGE-CURRENCY-STRIKE-RIGHT-MULT # 期权
  • TICKER-OPT-EXCHANGE-CURRENCY-YYYYMMDD-STRIKE-RIGHT # 期权
  • TICKER-OPT-EXCHANGE-CURRENCY-YYYYMMDD-STRIKE-RIGHT-MULT # 期权

Params:

  • sectype(默认:STK
    如果在dataname规范中未提供证券类型,则应用的默认值
  • exchange(默认:SMART
    如果在dataname规范中未提供交易所,则应用的默认值
  • currency(默认:''
    如果在dataname规范中未提供货币,则应用的默认值
  • historical(默认:False
    如果设置为True,数据源将在第一次下载数据后停止。
    将使用标准数据源参数fromdatetodate作为参考。
    如果请求的持续时间大于由 IB 给定的允许的数据时间段/压缩,则数据源将发出多个请求。
  • what(默认:None)如果为None,则历史数据请求将使用不同资产类型的默认值:
  • 对于 CASH 资产,为‘BID’
  • 对于任何其他交易
  • 如果希望使用另一个值,请查看 IB API 文档
  • rtbar(默认:False
    如果为True,则将使用由 Interactive Brokers 提供的5 秒实时数据条作为最小刻度。根据文档,它们对应于实时值(一旦被 IB 整理和筛选)
    如果为False,则将使用基于接收到的刻度的RTVolume价格。对于CASH资产(例如 EUR.JPY),将始终使用RTVolume,并从中获取bid价格(根据互联网上零散的文献,这是 IB 的行业事实标准)
    即使设置为True,如果数据被重新采样/保留到低于秒/5 的时间段/压缩,也不会使用实时数据,因为 IB 不会在该级别以下提供它们
  • qcheck(默认:0.5
    如果未收到数据,等待的时间(秒)以便适当地对数据包进行重新采样/重播并将通知传递给链上
  • backfill_start(默认:True
    在开始时执行回填。将在单个请求中获取尽可能多的历史数据。
  • backfill(默认:True
    在断开连接/重新连接周期后执行回填。间隙持续时间将用于下载尽可能少的数据
  • backfill_from(默认:None
    可以传递附加数据源来进行初始回填。一旦数据源用尽,并且如果需要,将从 IB 进行回填。理想情况下,这意味着从已存储的源(如磁盘上的文件)进行回填,但不限于此。
  • latethrough(默认:False
    如果数据源被重采样/重播,一些 ticks 可能来得太晚,已经交付的重采样/重播 bar 了。如果设置为 True,那些 ticks 将无论如何通过。
    检查重采样文档以了解如何考虑这些 ticks。
    这种情况可能特别发生在 IBStore 实例中 timeoffset 设置为 False,且 TWS 服务器时间与本地计算机时间不同步时
  • tradename(默认:None)对于某些特定情况很有用,比如CFD,其中价格由一种资产提供,交易发生在另一种资产上。
  • SPY-STK-SMART-USD -> 标普 500 ETF(将被指定为 dataname
  • SPY-CFD-SMART-USD -> 对应的 CFD 提供的不是价格跟踪,而是交易资产(指定为 tradename

参数中的默认值是允许类似 \TICKER这样的东西,其中参数sectype(默认:STK)和 exchange(默认:SMART`)被应用。

一些资产如 AAPL 需要完整的规范,包括 currency(默认:‘’),而其他资产如 TWTR 可以直接传递。

  • AAPL-STK-SMART-USD 将是 dataname 的完整规范
    或者:IBData 作为 IBData(dataname='AAPL', currency='USD'),它使用默认值(STKSMART),并覆盖货币为 USD

Oanda

原文:www.backtrader.com/docu/live/oanda/oanda/

与 Oanda 的集成支持:

  • 实时数据馈送
  • 实时交易

要求

  • oandapy
    使用以下命令安装:pip install git+https://github.com/oanda/oandapy.git
  • pytz(可选且不推荐)
    鉴于外汇市场的全球性和 24 小时运作的特点,选择使用UTC时间。如果愿意,您仍然可以使用您期望的输出时区。

示例代码

源代码包含完整示例:

  • samples/oandatest/oandatest.py

Oanda - 存储

存储是实时数据提要/交易支持的关键,提供了Oanda API 与数据提要和经纪人代理的需求之间的适配层。

  • 提供访问使用方法获取经纪人实例:
  • OandaStore.getbroker(*args, **kwargs)
  • 提供访问数据提要实例的方法
  • OandaStore.getedata(\*args, **kwargs)
  • 在这种情况下,许多**kwargs与数据提要(例如datanamefromdatetodatesessionstartsessionendtimeframecompression)是共同的
    数据可能提供其他参数。请查看下面的参考资料。

强制性参数

为了成功连接到Oanda,以下参数是强制性的:

  • token(默认值:None):API 访问令牌
  • account(默认值:None):账户 ID

这些由Oanda提供

是否连接到测试服务器或真实服务器,请使用:

  • practice(默认值:False):使用测试环境

必须定期检查账户以获取现金价值。刷新周期可以通过以下方式控制:

  • account_tmout(默认值:10.0):帐户价值/现金刷新周期

Oanda 提要

实例化数据:

  • 根据 Oanda 的指南传递符号
  • 根据 Oanda 的指南,EUR/USDD必须指定为EUR_USD。实例化如下:
data = oandastore.getdata(dataname='EUR_USD', ...)` 

时间管理

除非将tz参数(pytz 兼容对象)传递给数据提要,否则所有时间输出均为UTC格式,如上所述。

回填

backtraderOanda没有特殊要求。对于小时间框架,在测试服务器上由Oanda返回的回填长度为500

OandaBroker - 实时交易

使用经纪人

要使用OandaBroker,必须替换由cerebro创建的标准经纪人模拟实例。

使用Store模型(首选):

import backtrader as bt
cerebro = bt.Cerebro()
oandastore = bt.stores.OandaStore()
cerebro.broker = oandastore.getbroker()  # or cerebro.setbroker(...)

经纪人 - 初始持仓

经纪人支持一个参数:

  • use_positions(默认值:True):连接到经纪人提供商时,使用现有持仓来启动经纪人。
    在实例化时设置为False,以忽略任何现有持仓
操作

关于标准用法没有变化。只需使用策略中可用的方法(详见Strategy参考资料以获取完整解释)

  • buy
  • sell
  • close
  • cancel

订单执行类型

Oanda几乎支持backtrader所需的所有订单执行类型,但不包括Close

因此,订单执行类型受到限制:

  • Order.Market
  • Order.Limit
  • Order.Stop
  • Order.StopLimit(使用 StopupperBound / lowerBound 价格)
  • Order.StopTrail
  • Bracket 订单受到支持,使用 takeprofitstoploss 订单成员并在内部创建模拟订单。

订单有效性

在回测期间(使用 validbuysell)可用的相同的有效性概念可用,并且具有相同的含义。因此,对于以下值,Oanda Ordersvalid 参数将如下翻译:

  • None 转换为 Good Til Cancelled
    因为未指定有效性,所以理解为订单必须有效直至取消
  • datetime/date 转换为 Good Til Date
  • timedelta(x) 转换为 Good Til Date(这里 timedelta(x) != timedelta()
    这被解释为信号,要求订单从 now + timedelta(x) 开始有效。
  • timedelta() 或 0 转换为 Session
    已传递一个值(而不是 None)但为 Null,并被解释为当前 day(会话)有效的订单

通知

标准的 Order 状态将通过 notify_order 方法(如果已重写)通知到策略

  • Submitted - 订单已发送到 TWS
  • Accepted - 订单已下达
  • Rejected - 用于实际拒绝和在订单创建期间未知其他状态时使用
  • Partial - 部分执行已经发生
  • Completed - 订单已完全执行
  • Canceled(或 Cancelled
  • Expired - 当订单因到期而取消时

参考

OandaStore

class backtrader.stores.OandaStore()

单例类,用于控制与 Oanda 的连接。

参数:

  • token(默认值:None):API 访问令牌
  • account(默认值:None):账户 ID
  • practice(默认值:False):使用测试环境
  • account_tmout(默认值:10.0):账户价值/现金刷新的刷新周期

OandaBroker

class backtrader.brokers.OandaBroker(**kwargs)

Oanda 的经纪人实现。

此类将来自 Oanda 的订单/持仓映射到 backtrader 的内部 API。

参数:

  • use_positions(默认值:True):连接到经纪人提供者时,使用现有仓位启动经纪人。
    在实例化期间设置为 False 以忽略任何现有仓位

OandaData

class backtrader.feeds.OandaData(**kwargs)

Oanda 数据源。

参数:

  • qcheck(默认值:0.5
    如果未收到数据,则在苏醒的秒数内将给出重新采样/重播数据包的机会,并将通知传递给链上
  • historical(默认值:False
    如果设置为 True,数据源将在第一次下载数据后停止。
    将使用标准数据源参数 fromdatetodate 作为参考。
    如果请求的持续时间大于 IB 允许的时间跨度/压缩所选择的数据的持续时间,数据源将进行多次请求。
  • backfill_start(默认值:True
    在开始时执行回填。将通过单个请求获取最大可能的历史数据。
  • backfill(默认:True
    在断开/重新连接周期后执行回填。间隙持续时间将用于下载可能的最小数据量
  • backfill_from(默认:None
    可以传递额外的数据源来进行初始的回填层。一旦数据源用尽并且如果请求,将从 IB 进行回填。理想情况下,这是为了从已存储的源(如磁盘上的文件)进行回填,但不限于此。
  • bidask(默认:True
    如果为True,则历史/回填请求将从服务器请求bid/ask价格
    如果为False,则将请求midpoint
  • useask(默认:False
    如果为True,则将使用bidask价格的ask部分,而不是默认的bid使用方式
  • includeFirst(默认:True
    通过直接设置参数到 Oanda API 调用来影响历史/回填请求的第一个柱条的交付
  • reconnect(默认:True
    当网络连接断开时重新连接
  • reconnections(默认:-1
    重新连接尝试的次数:-1表示永远
  • reconntimeout(默认:5.0
    在重新连接尝试之间等待的时间(秒)

此数据源仅支持timeframecompression的以下映射,这些映射符合 OANDA API 开发人员指南中的定义:

(TimeFrame.Seconds, 5): 'S5',
(TimeFrame.Seconds, 10): 'S10',
(TimeFrame.Seconds, 15): 'S15',
(TimeFrame.Seconds, 30): 'S30',
(TimeFrame.Minutes, 1): 'M1',
(TimeFrame.Minutes, 2): 'M3',
(TimeFrame.Minutes, 3): 'M3',
(TimeFrame.Minutes, 4): 'M4',
(TimeFrame.Minutes, 5): 'M5',
(TimeFrame.Minutes, 10): 'M10',
(TimeFrame.Minutes, 15): 'M15',
(TimeFrame.Minutes, 30): 'M30',
(TimeFrame.Minutes, 60): 'H1',
(TimeFrame.Minutes, 120): 'H2',
(TimeFrame.Minutes, 180): 'H3',
(TimeFrame.Minutes, 240): 'H4',
(TimeFrame.Minutes, 360): 'H6',
(TimeFrame.Minutes, 480): 'H8',
(TimeFrame.Days, 1): 'D',
(TimeFrame.Weeks, 1): 'W',
(TimeFrame.Months, 1): 'M',

任何其他组合都将被拒绝

相关文章
|
5天前
|
Oracle 关系型数据库 测试技术
BackTrader 中文文档(十一)(1)
BackTrader 中文文档(十一)
14 0
|
5天前
|
存储 API 索引
BackTrader 中文文档(十一)(2)
BackTrader 中文文档(十一)
21 0
|
5天前
|
存储 编解码 算法
BackTrader 中文文档(十一)(3)
BackTrader 中文文档(十一)
16 0
|
5天前
BackTrader 中文文档(十二)(4)
BackTrader 中文文档(十二)
9 0
|
5天前
|
索引 Python
BackTrader 中文文档(十二)(2)
BackTrader 中文文档(十二)
9 0
|
5天前
|
存储 测试技术 API
BackTrader 中文文档(十二)(1)
BackTrader 中文文档(十二)
26 0
|
5天前
|
存储 编解码
BackTrader 中文文档(十二)(3)
BackTrader 中文文档(十二)
20 0
|
5天前
BackTrader 中文文档(十五)(3)
BackTrader 中文文档(十五)
12 0
|
5天前
|
编解码 算法 开发者
BackTrader 中文文档(十五)(1)
BackTrader 中文文档(十五)
10 0
|
5天前
|
调度
BackTrader 中文文档(十五)(2)
BackTrader 中文文档(十五)
9 0