BackTrader 中文文档(二)(3)

简介: BackTrader 中文文档(二)

BackTrader 中文文档(二)(2)https://developer.aliyun.com/article/1489215

策略是Lines对象,这些对象支持参数,这些参数使用标准 Python kwargs 参数进行收集:

class MyStrategy(bt.Strategy):
    params = (('period', 20),)
    def __init__(self):
        self.sma = btind.SimpleMovingAverage(self.data, period=self.params.period)
    ...
    ...

注意SimpleMovingAverage如何不再以固定值 20 进行实例化,而是使用已为策略定义的参数“period”进行实例化。

一个 Cerebro

一旦数据源可用并且策略已定义,Cerebro 实例就是将所有内容汇集在一起并执行操作的工具。实例化一个很容易:

cerebro = bt.Cerebro()

如果没有特殊要求,则默认情况下会进行处理。

  • 创建默认经纪人
  • 操作无佣金
  • 数据源将被预加载
  • 默认执行模式将是 runonce(批量操作),这是更快的模式
    所有指标必须支持runonce模式以实现全速运行。平台中包含的指标可以。
    自定义指标不需要实现 runonce 功能。Cerebro将模拟它,这意味着那些不兼容 runonce 的指标将运行得更慢。但大部分系统仍将以批处理模式运行。

由于数据源已经可用,策略也已经创建(之前创建),将它们组合在一起并使其运行的标准方法是:

cerebro.adddata(data)
cerebro.addstrategy(MyStrategy, period=25)
cerebro.run()

请注意以下内容:

  • 数据源“实例”被添加
  • MyStrategy“类”被添加以及将传递给它的参数(kwargs)。
    MyStrategy 的实例化将由 cerebro 在后台完成,并且“addstrategy”中的任何 kwargs 将被传递给它

用户可以根据需要添加任意多的策略和数据源。策略如何相互通信以实现协调(如果需要)并不受平台的强制/限制。

当然,Cerebro 提供了额外的可能性:

  • 决定预加载和操作模式:
cerebro = bt.Cerebro(runonce=True, preload=True)`
  • 这里有一个约束:runonce需要预加载(如果不是,批处理操作将无法运行)。当然,预加载数据源并不强制执行runonce
  • setbroker / getbroker(以及broker属性)
    如果需要,可以设置自定义经纪人。实际经纪人实例也可以被访问
  • 绘图。在常规情况下,就像这样简单:
cerebro.run()
cerebro.plot()` 
  • 绘图需要一些参数进行自定义
  • numfigs=1
    如果图表过于密集,可以将其拆分为多个图表
  • plotter=None
    可以传递自定义绘图器实例,cerebro 将不会实例化默认绘图器
  • **kwargs - 标准关键字参数
    这将传递给绘图器。
  • 请查看绘图部分获取更多信息。
  • 优化策略。
    如上所述,Cerebro 获得一个派生自 Strategy 的类(而不是实例),以及将在调用“run”时传递给它的关键字参数。
    这样可以实现优化。相同的 Strategy 类将根据需要实例化多次,并使用新参数。如果一个实例已经传递给 cerebro…这将是不可能的。
    请求优化如下:
cerebro.optstrategy(MyStrategy, period=xrange(10, 20))` 
  • 方法optstrategy具有与addstrategy相同的签名,但会进行额外的管理工作以确保优化按预期运行。一个策略可能期望一个范围作为策略的正常参数,而addstrategy不会对传递的参数做任何假设。
    另一方面,optstrategy将理解可迭代对象是一组值,必须按顺序传递给每个 Strategy 类的实例化。
    注意,传递的不是单个值,而是一系列值。在这个简单的情况下,将尝试这个策略的 10 个值 10 -> 19(20 是上限)。
    如果开发了更复杂的策略并具有额外的参数,它们都可以传递给optstrategy。必须不经过优化的参数可以直接传递,而无需最终用户创建一个仅包含一个值的虚拟可迭代对象。例如:
cerebro.optstrategy(MyStrategy, period=xrange(10, 20), factor=3.5)` 
  • optstrategy方法看到因子并在后台为具有单个元素的因子创建(所需的)虚拟可迭代对象(例如 3.5 中的示例)。
    注意
    交互式 Python shell 和某些类型的在Windows下的冻结可执行文件对 Python 的multiprocessing模块存在问题。
    请阅读有关multiprocessing的 Python 文档。

大脑

Cerebro

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

这个类是backtrader的基石,因为它作为以下方面的中心点:

  1. 收集所有输入(数据源)、行动者(策略)、旁观者(观察员)、评论者(分析器)和文档编制者(写作者),确保节目随时进行。
  2. 执行回测/或实时数据提供/交易
  3. 返回结果
  4. 提供对绘图设施的访问

收集输入

  1. 首先创建一个cerebro
cerebro = bt.Cerebro(**kwargs)` 
  1. 支持一些**kwargs来控制执行,参见参考文献(这些参数后来也可以应用于run方法)
  2. 添加数据源
    最常见的模式是cerebro.adddata(data),其中data已经实例化为数据源。例如:
data = bt.BacktraderCSVData(dataname='mypath.days', timeframe=bt.TimeFrame.Days)
cerebro.adddata(data)` 
  1. 重新采样回放数据是可能的,遵循相同的模式:
data = bt.BacktraderCSVData(dataname='mypath.min', timeframe=bt.TimeFrame.Minutes)
cerebro.resampledata(data, timeframe=bt.TimeFrame.Days)` 
  1. 或:
data = bt.BacktraderCSVData(dataname='mypath.min', timeframe=bt.TimeFrame.Minutes)
cerebro.replaydatadata(data, timeframe=bt.TimeFrame.Days)` 
  1. 系统可以接受任意数量的数据源,包括混合常规数据与重新采样和/或重放数据。当然,其中一些组合肯定毫无意义,因此在能够组合数据时会应用一些限制:时间对齐。请参阅数据-多时间框架、数据重新采样-重新采样和数据-重播部分。
  2. 添加Strategies
    与已经是类实例的数据源不同,cerebro直接接受Strategy类和传递给它的参数。背后的原理是:在优化场景中,该类将被实例化多次并传递不同的参数
    即使没有运行优化,该模式仍然适用:
cerebro.addstrategy(MyStrategy, myparam1=value1, myparam2=value2)` 
  1. 优化参数时,必须添加为可迭代对象。详细说明请参见优化部分。基本模式:
cerebro.optstrategy(MyStrategy, myparam1=range(10, 20))` 
  1. 运行MyStrategy 10 次,其中myparam1的值从 10 到 19(请记住,Python 中的范围是半开放的,20不会被包含)
  2. 其他元素还有一些其他元素可以添加以增强回测体验。查看相应的部分以了解详情。方法包括:
  • addwriter
  • addanalyzer
  • addobserver(或addobservermulti
  1. 更改经纪人
    Cerebro 将在backtrader中使用默认经纪人,但可以被覆盖:
broker = MyBroker()
cerebro.broker = broker  # property using getbroker/setbroker methods` 
  1. 接收通知如果数据源和/或经纪人发送通知(或创建它们的存储提供程序),它们将通过Cerebro.notify_store方法接收。有三(3)种处理这些通知的方法
  • 通过addnotifycallback(callback)调用向cerebro实例添加回调。回调函数必须支持此签名:
callback(msg, *args, **kwargs)` 
  1. 实际的msg*args**kwargs接收的内容是实现定义的(完全取决于数据/经纪人/存储),但一般可以期望它们是可打印的,以便接收和实验。
  • 在添加到cerebro实例的Strategy子类中覆盖notify_store方法。
  1. 签名:notify_store(self, msg, *args, **kwargs)
  • 子类Cerebro并覆盖notify_store(与Strategy中的签名相同)
  1. 这应该是最不受欢迎的方法

执行回测

有一个单一的方法可以做到这一点,但它支持几个选项(也可以在实例化时指定),以决定如何运行:

result = cerebro.run(**kwargs)

请参阅下面的参考文献,了解可用的参数。

标准观察者

cerebro(除非另有说明)会自动实例化三个标准观察者

  • 一个Broker观察者,用于跟踪cashvalue(投资组合)
  • 一个Trades观察者,应显示每次交易的有效性如何
  • 一个Buy/Sell观察者,应记录操作何时执行

如果希望更干净的绘图,只需使用stdstats=False禁用它们

返回结果

cerebro在回测期间返回所创建的策略实例。这允许分析它们的操作,因为可以访问策略中的所有元素:

result = cerebro.run(**kwargs)

run返回的result的格式取决于是否使用了优化(使用optstrategy添加了一个策略):

  • 所有使用addstrategy添加的策略
    result将是在回测期间运行的实例的list
  • 使用optstrategy添加了 1 个或多个策略
    result将是listlist。每个内部列表将包含每次优化运行后的策略

注意

优化的默认行为已更改为仅返回系统中存在的分析器,以减轻跨计算机核心的消息传递负担。

如果希望返回完整的策略集,请将参数optreturn设置为False

提供对绘图功能的访问

如果安装了matplotlib,则可以绘制策略图。通常的模式是:

cerebro.plot()

请参阅下文的参考文献和绘图部分

回测逻辑

事物流程的简要概述:

  1. 传递任何存储通知
  2. 要求数据源提供下一组 ticks/bars
    **版本更改:**版本 1.9.0.99 中已更改:新行为
    数据源通过查看下一个将提供的datetime来同步。在新周期中尚未交易的数据源仍提供旧数据点,而具有新数据的数据源则提供此数据(以及指标的计算)
    旧行为(在Cerebro中使用oldsync=True时保留)
    第 1 个插入系统的数据是datamaster,系统将等待它提供一个 tick
    其他数据源或多或少是datamaster的从属,且:
* If the next tick to deliver is newer (datetime-wise) than the one
   delivered by the `datamaster` it will not be delivered
 * May return without delivering a new tick for a number of reasons` 
  1. 逻辑被设计为轻松同步多个数据源和具有不同时间框架的数据源
  2. 通知策略有关已排队的经纪人订单、交易和现金/价值的通知
  3. 告诉经纪人接受排队的订单,并使用新数据执行待处理的订单
  4. 调用策略的 next 方法以使策略评估新数据(并可能发出在经纪人中排队的订单)
    根据阶段,策略/指标的最小周期要求可能在满足之前是 prenext 还是 nextstart
    在内部,策略还会触发 observersindicatorsanalyzers 和其他活动元素
  5. 告诉任何 writers 将数据写入其目标

注意:

注意

在上述第 1 步中,当 数据源 传递新的柱集时,这些柱是 关闭 的。 这意味着数据已经发生了。

因此,在第 4 步中策略发出的 订单 无法使用第 1 步的数据 执行

这意味着订单将使用 x + 1 的概念执行。 其中 x 是订单执行的柱时刻,而 x + 1 是下一个,它是可能的订单执行的最早时刻

参考

类 backtrader.Cerebro()

参数:

  • preload(默认:True

是否预加载传递给 cerebro 的不同 data feeds 用于策略

  • runonce(默认:True

在向量化模式下运行 Indicators 以加速整个系统。 策略和观察器将始终基于事件运行。

  • live(默认:False

如果没有数据通过数据的 islive 方法报告自身为 live,但最终用户仍希望以 live 模式运行,可以将此参数设置为 true

这将同时停用 preloadrunonce。 对内存节省方案没有影响。

在向量化模式下运行 Indicators 以加速整个系统。 策略和观察器将始终基于事件运行。

  • maxcpus(默认:无->所有可用核心)
    同时使用多少核心进行优化
  • stdstats(默认:True

如果为 True,默认观察者将被添加:经纪人(现金和价值)、交易和买卖

  • oldbuysell(默认:False

如果 stdstatsTrue 并且观察者自动添加,则此开关控制 BuySell 观察者的主要行为

  • False:使用现代行为,在低/高价格的下方/上方分别绘制买入/卖出信号,以避免图表混乱
  • True:使用已弃用的行为,在给定时刻的订单执行的平均价格绘制买入/卖出信号。 这当然会在 OHLC 柱或 Cloe 柱上方绘制,难以识别图的内容。
  • oldtrades(默认:False

如果 stdstatsTrue 并且观察者自动添加,则此开关控制 Trades 观察者的主要行为

  • False:使用现代行为,其中所有数据的交易都用不同的标记绘制
  • True:使用旧的交易观察器,它使用相同的标记绘制交易,仅在它们是正数还是负数时有所区别。
  • exactbars(默认:False

默认情况下,每个值都会存储在内存中的一行中。

可能的值:

* `True` or `1`: all “lines” objects reduce memory usage to the
  automatically calculated minimum period.
  If a Simple Moving Average has a period of 30, the underlying data
  will have always a running buffer of 30 bars to allow the
  calculation of the Simple Moving Average
  * This setting will deactivate `preload` and `runonce`
  * Using this setting also deactivates **plotting**
* `-1`: datafreeds and indicators/operations at strategy level will
  keep all data in memory.
  For example: a `RSI` internally uses the indicator `UpDay` to
  make calculations. This subindicator will not keep all data in
  memory
  * This allows to keep `plotting` and `preloading` active.
  * `runonce` will be deactivated
* `-2`: data feeds and indicators kept as attributes of the
  strategy will keep all points in memory.
  For example: a `RSI` internally uses the indicator `UpDay` to
  make calculations. This subindicator will not keep all data in
  memory
  If in the `__init__` something like
  `a = self.data.close - self.data.high` is defined, then `a`
  will not keep all data in memory
  * This allows to keep `plotting` and `preloading` active.
  * `runonce` will be deactivated
  • objcache(默认:False

实验选项,用于实现线条对象的缓存并减少它们的数量。从 UltimateOscillator 示例:

bp = self.data.close - TrueLow(self.data)
tr = TrueRange(self.data)  # -> creates another TrueLow(self.data)

如果这是True,则TrueRange内的第 2 个TrueLow(self.data)将与bp计算中的签名匹配。它将被重用。

边缘情况可能会发生,其中这会使线条对象超出其最小周期并且导致故障,因此已禁用。

  • writer(默认:False

如果设置为True,将创建一个默认的 WriterFile,它将打印到 stdout。它将被添加到策略中(除了用户代码添加的任何其他写入器)

  • tradehistory(默认:False

如果设置为True,它将激活每个策略的每次交易的更新事件记录。这也可以通过策略方法set_tradehistory逐个策略地完成。

  • optdatas(默认:True

如果为True且正在优化(并且系统可以preload并使用runonce,数据预加载将仅在主进程中执行一次,以节省时间和资源。

测试显示,从在83秒的样本执行中移动到66秒的执行速度提高了约20%

  • optreturn(默认:True

如果为True,则优化结果将不是完整的Strategy对象(以及所有datasindicatorsobservers…),而是具有以下属性的对象(与Strategy中相同):

* `params` (or `p`) the strategy had for the execution
* `analyzers` the strategy has executed

在大多数情况下,只有分析器和与之相关的参数是评估策略性能所需的内容。如果需要对生成的值(例如指标)进行详细分析,则关闭此选项。

测试显示执行时间提高了13% - 15%。与optdatas结合使用,总增益增加到了优化运行的32%的总体加速。

  • oldsync(默认:False

从版本 1.9.0.99 开始,多个数据的同步(相同或不同的时间框架)已更改为允许长度不同的数据。

如果希望保留旧的行为,并将 data0 设置为系统的主要数据,则将此参数设置为 true。

  • tz(默认:None

为策略添加全局时区。参数tz可以是

* `None`: in this case the datetime displayed by strategies will be
  in UTC, which has been always the standard behavior
* `pytz` instance. It will be used as such to convert UTC times to
  the chosen timezone
* `string`. Instantiating a `pytz` instance will be attempted.
* `integer`. Use, for the strategy, the same timezone as the
  corresponding `data` in the `self.datas` iterable (`0` would
  use the timezone from `data0`)
  • cheat_on_open(默认:False

在调用策略的next_open方法之前将会调用它。这发生在next之前,也发生在经纪人有机会评估订单之前。指标尚未重新计算。这允许发出一个订单,该订单考虑了前一天的指标,但使用open价格进行股份计算。

对于cheat_on_open订单执行,还需要调用cerebro.broker.set_coo(True)或使用BackBroker(coo=True)实例化一个经纪人(其中coo代表 cheat-on-open),或者将broker_coo参数设置为True。除非在下面禁用,否则 Cerebro 将自动执行此操作。

  • broker_coo(默认:True

这将自动调用经纪人的set_coo方法,并使用True来激活cheat_on_open执行。仅当cheat_on_open也为True时才执行。

  • quicknotify(默认值:False

经纪人通知将在下一个价格传递之前立即传递。 对于回测,这没有任何影响,但对于实时经纪人,通知可能会在交付柱形图之前很久就发生了。 当设置为 True 时,通知将尽快传递(请参阅实时数据源中的 qcheck

设置为 False 以实现兼容性。 可能会更改为 True

addstorecb(callback)

添加一个回调来获取将由 notify_store 方法处理的消息

回调函数的签名必须支持以下内容:

  • callback(msg, *args, **kwargs)

实际接收到的 msg*args**kwargs 取决于实现(完全依赖于 数据/经纪人/存储),但通常应该期望它们是可打印的,以便接收和实验。

notify_store(msg, *args, **kwargs)

在 cerebro 中接收存储通知

此方法可以在 Cerebro 的子类中重写

如果 name 不为 None,则将其放入 data._name 中,该参数用于装饰/绘图目的。

adddatacb(callback)

adddata(data, name=None)

向获取将由 notify_data 方法处理的消息添加一个回调

  • callback(data, status, *args, **kwargs)

实际接收到的 *args**kwargs 取决于实现(完全依赖于 数据/经纪人/存储),但通常应该期望它们是可打印的,以便接收和实验。

实际接收到的 msg*args**kwargs 取决于实现(完全依赖于 数据/经纪人/存储),但通常应该期望它们是可打印的,以便接收和实验。

在 cerebro 中接收数据通知

此方法可以在 Cerebro 的子类中重写

回调函数的签名必须支持以下内容:

notify_data(data, status, *args, **kwargs)

向组合中添加一个 Data Feed 实例。

添加一个 callback 来获取将由 notify_store 方法处理的消息

resampledata(dataname, name=None, **kwargs)

向系统添加一个将由系统重新采样的 Data Feed

如果 name 不为 None,则将其放入 data._name 中,该参数用于装饰/绘图目的。

任何其他支持重新采样过滤器的 kwargs,如 timeframecompressiontodate,都将被透明地传递

replaydata(dataname, name=None, **kwargs)

向系统添加一个将由系统重播的 Data Feed

如果 name 不为 None,则将其放入 data._name 中,该参数用于装饰/绘图目的。

任何其他支持回放过滤器的 kwargs,如 timeframecompressiontodate,都将被透明地传递

chaindata(*args, **kwargs)

将几个数据源串联成一个

如果 name 被传递为命名参数且不为 None,则将其放入 data._name 中,该参数用于装饰/绘图目的。

如果为 None,则将使用第 1 个数据的名称

rolloverdata(*args, **kwargs)

将几个数据源链接到一个数据源中

如果将 name 作为命名参数传递,并且不为 None,则将放入 data._name 中,用于装饰/绘图目的。

如果为 None,则将使用第 1 个数据的名称

任何其他的 kwargs 将传递给 RollOver 类

addstrategy(strategy, *args, **kwargs)

Strategy 类添加到混合中,以进行单次运行。实例化将在运行时发生。

args 和 kwargs 将像在实例化期间一样传递给策略。

返回用于引用其他对象(如调整器)的添加索引

optstrategy(strategy, *args, **kwargs)

Strategy 类添加到混合中以进行优化。实例化将在运行时发生。

args 和 kwargs 必须是可迭代的,其中包含要检查的值。

示例:如果一个策略接受一个参数 period,为了优化目的,optstrategy 的调用如下所示:

  • cerebro.optstrategy(MyStrategy, period=(15, 25))

这将为值 15 和 25 执行优化。而

  • cerebro.optstrategy(MyStrategy, period=range(15, 25))

将使用 period 值 15 -> 25(因为 Python 中的范围是半开放的,所以不包括 25)执行 MyStrategy

如果传递了一个参数,但不应该进行优化,则调用如下:

  • cerebro.optstrategy(MyStrategy, period=(15,))

请注意,period 仍然传递为可迭代对象 … 只有 1 个元素

backtrader 将尝试识别诸如以下情况:

  • cerebro.optstrategy(MyStrategy, period=15)

并在可能的情况下创建内部伪可迭代对象

optcallback(cb)

callback 添加到将在每个策略运行时调用的回调列表中进行优化

签名:cb(strategy)

addindicator(indcls, *args, **kwargs)

Indicator 类添加到混合中。实例化将在传递的策略的运行时完成

addobserver(obscls, *args, **kwargs)

Observer 类添加到混合中。实例化将在运行时完成

addobservermulti(obscls, *args, **kwargs)

Observer 类添加到混合中。实例化将在运行时完成

它将每个“数据”系统中添加一次。一个用例是观察单个数据的买入/卖出观察者。

反例是 CashValue,它观察系统范围的值

addanalyzer(ancls, *args, **kwargs)

Analyzer 类添加到混合中。实例化将在运行时完成

addwriter(wrtcls, *args, **kwargs)

Writer 类添加到混合中。实例化将在运行时在 cerebro 中完成

run(**kwargs)

执行回测的核心方法。传递给它的任何 kwargs 都会影响实例化时 Cerebro 的标准参数的值。

如果 cerebro 没有数据,则该方法将立即退出。

它具有不同的返回值:

  • 对于无优化:包含使用 addstrategy 添加的策略类实例的列表
  • 用于优化:包含使用addstrategy添加的 Strategy 类实例的列表的列表
runstop()

如果从策略内部或其他任何地方调用,包括其他线程,执行将尽快停止。

setbroker(broker)

为此策略设置特定的broker实例,替换从 cerebro 继承的实例。

getbroker()

返回经纪人实例。

这也可以作为名为brokerproperty使用

绘图(plotter=None,numfigs=1,iplot=True,start=None,end=None,width=16,height=9,dpi=300,tight=True,use=None,**kwargs)

在 cerebro 内部绘制策略

如果plotter为 None,则会创建一个默认的Plot实例,并在实例化期间将kwargs传递给它。

numfigs将绘图分成指定数量的图表,如果需要,可以减少图表密度

iplot:如果为True并在notebook中运行,则图表将内联显示

use:将其设置为所需 matplotlib 后端的名称。它将优先于iplot

start:策略或datetime.datedatetime.datetime实例的日期时间线数组的索引,指示绘图的开始

end:策略的日期时间线数组的索引或datetime.datedatetime.datetime实例,指示绘图的结束

width:保存图形的英寸

height:保存图形的英寸

dpi:保存图形的每英寸点数的质量

tight:仅保存实际内容而不是图形的框架

添加 sizer(sizercls,*args,**kwargs)

添加一个Sizer类(和 args),它是添加到 cerebro 的任何策略的默认 sizer

addsizer_byidx(idx,sizercls,*args,**kwargs)

按 idx 添加一个Sizer类。此 idx 是与addstrategy返回的兼容引用。只有由idx引用的策略将接收此大小

add_signal(sigtype,sigcls,*sigargs,**sigkwargs)

向系统添加一个信号,稍后将其添加到SignalStrategy中。

signal_concurrent(onoff)

如果向系统添加信号并且将concurrent值设置为 True,则将允许并发订单

signal_accumulate(onoff)

如果向系统添加信号并且将accumulate值设置为 True,则在已经进入市场时进入市场,将允许增加头寸

signal_strategy(stratcls,*args,**kwargs)

添加一个可以接受信号的 SignalStrategy 子类

addcalendar(cal)

向系统添加全局交易日历。个别数据源可能具有覆盖全局日历的单独日历

cal可以是TradingCalendar的实例、字符串或pandas_market_calendars的实例。字符串将被实例化为PandasMarketCalendar(需要系统中安装pandas_market_calendar模块。

如果传递的是 TradingCalendarBase 的子类(而不是实例),它将被实例化

BackTrader 中文文档(二)(4)https://developer.aliyun.com/article/1489219

相关文章
|
6月前
|
Unix 索引 Python
BackTrader 中文文档(一)(2)
BackTrader 中文文档(一)
155 0
|
6月前
|
索引
BackTrader 中文文档(六)(2)
BackTrader 中文文档(六)
87 0
|
6月前
BackTrader 中文文档(五)(2)
BackTrader 中文文档(五)
81 0
|
6月前
BackTrader 中文文档(一)(4)
BackTrader 中文文档(一)
69 0
|
6月前
|
数据可视化
BackTrader 中文文档(三)(3)
BackTrader 中文文档(三)
54 0
|
6月前
|
存储 编解码 网络架构
BackTrader 中文文档(二)(4)
BackTrader 中文文档(二)
107 0
|
6月前
|
Python
BackTrader 中文文档(六)(3)
BackTrader 中文文档(六)
84 0
|
6月前
|
索引
BackTrader 中文文档(三)(4)
BackTrader 中文文档(三)
64 0
|
6月前
|
存储 C++ 索引
BackTrader 中文文档(二)(1)
BackTrader 中文文档(二)
70 0
|
6月前
|
存储 API 索引
BackTrader 中文文档(四)(3)
BackTrader 中文文档(四)
51 0