BackTrader 中文文档(三)(1)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: BackTrader 中文文档(三)

优化改进

原文:www.backtrader.com/docu/optimization-improvements/

backtrader 版本 1.8.12.99 包括了 数据源结果多进程中的管理改进。

注意

对两者的行为进行了调整

这些选项的行为可以通过两个新的 Cerebro 参数进行控制:

  • optdatas(默认:True
    如果为 True 并且正在优化(并且系统可以 preload 并使用 runonce,数据预加载将仅在主进程中执行一次,以节省时间和资源。
  • optreturn(默认:True)如果为True,则优化结果将不是完整的Strategy对象(以及所有数据指标观察器等),而是具有以下属性的对象(与Strategy中相同):
  • params(或 p)执行策略时的参数
  • analyzers 执行的策略
  • 在大多数情况下,只需要 analyzers 和使用哪些 params 来评估策略的表现。如果需要对生成的值(例如 指标)进行详细分析,请关闭此选项。

数据源管理

优化 场景中,这是 Cerebro 参数的可能组合:

  • preload=True(默认)
    在运行任何回测代码之前,数据源将被预加载
  • runonce=True(默认)
    指标 将以批处理模式计算在一个紧密的 for 循环中,而不是逐步进行。

如果两个条件都为 True 并且 optdatas=True,则:

  • 在生成新子进程(负责执行 回测 的子进程)之前,数据源 将在主进程中预加载

结果管理

优化 场景中,评估每个 策略 运行时使用的不同参数时,两件事应该起到最重要的作用:

  • strategy.params(或 strategy.p
    回测中使用的实际值集
  • strategy.analyzers
    负责提供 策略 实际表现评估的对象。示例:
    SharpeRatio_A(年化 SharpeRatio

optreturn=True 时,将创建占位符对象,而不是返回完整的 策略 实例,这些对象携带上述两个属性,以便进行评估。

这样可以避免传递大量生成的数据,例如 回测 期间指标生成的值

如果希望使用 完整的策略对象,只需在 cerebro 实例化 期间或进行 cerebro.run 时将 optreturn=False

一些测试运行

backtrader 源代码中的 优化 示例已经扩展,以添加对 optdatasoptreturn 的控制(实际上是禁用它们)

单核运行

作为参考,当 CPU 数量限制为 1 且未使用 multiprocessing 模块时发生了什么:

$ ./optimization.py --maxcpus 1
==================================================
**************************************************
--------------------------------------------------
OrderedDict([(u'smaperiod', 10), (u'macdperiod1', 12), (u'macdperiod2', 26), (u'macdperiod3', 9)])
**************************************************
--------------------------------------------------
OrderedDict([(u'smaperiod', 10), (u'macdperiod1', 13), (u'macdperiod2', 26), (u'macdperiod3', 9)])
...
...
OrderedDict([(u'smaperiod', 29), (u'macdperiod1', 19), (u'macdperiod2', 29), (u'macdperiod3', 14)])
==================================================
Time used: 184.922727833

多核运行

不限制 CPU 数量时,Python 的 multiprocessing 模块将尝试使用所有 CPU。optdatasoptreturn 将被禁用。

optdataoptreturn均处于激活状态

默认行为:

$ ./optimization.py
...
...
...
==================================================
Time used: 56.5889185394

多核和数据提供以及结果改进带来的总改进意味着从184.92秒降至56.58秒。

请注意,示例使用252根柱和指标仅生成长度为252点的值。这只是一个例子。

真正的问题是这有多少归因于新行为。

optreturn已停用

让我们将完整的策略对象传递给调用者:

$ ./optimization.py --no-optreturn
...
...
...
==================================================
Time used: 67.056914007

执行时间增加了18.50%(或加速比为15.62%)。

optdatas已停用

每个子进程被强制加载其自己的数据提供值集:

$ ./optimization.py --no-optdatas
...
...
...
==================================================
Time used: 72.7238112637

执行时间增加了28.52%(或加速比为22.19%)。

两者均已停用

仍然使用多核但保持旧的非改进行为:

$ ./optimization.py --no-optdatas --no-optreturn
...
...
...
==================================================
Time used: 83.6246643786

执行时间增加了47.79%(或加速比为32.34%)。

这表明使用多核是时间改进的主要贡献者。

注意

执行是在装有i7-4710HQ(4 核/8 逻辑)和 16 GBytes RAM 的 Windows 10 64 位笔记本电脑上进行的。在其他条件下情况可能会有所不同

结论

  • 优化期间减少时间的最大因素是使用多核
  • 使用optdatasoptreturn的示例运行显示每个的加速比约为22.19%15.62%(在测试中两者一起为32.34%

示例用法

$ ./optimization.py --help
usage: optimization.py [-h] [--data DATA] [--fromdate FROMDATE]
                       [--todate TODATE] [--maxcpus MAXCPUS] [--no-runonce]
                       [--exactbars EXACTBARS] [--no-optdatas]
                       [--no-optreturn] [--ma_low MA_LOW] [--ma_high MA_HIGH]
                       [--m1_low M1_LOW] [--m1_high M1_HIGH] [--m2_low M2_LOW]
                       [--m2_high M2_HIGH] [--m3_low M3_LOW]
                       [--m3_high M3_HIGH]
Optimization
optional arguments:
  -h, --help            show this help message and exit
  --data DATA, -d DATA  data to add to the system
  --fromdate FROMDATE, -f FROMDATE
                        Starting date in YYYY-MM-DD format
  --todate TODATE, -t TODATE
                        Starting date in YYYY-MM-DD format
  --maxcpus MAXCPUS, -m MAXCPUS
                        Number of CPUs to use in the optimization
                          - 0 (default): use all available CPUs
                          - 1 -> n: use as many as specified
  --no-runonce          Run in next mode
  --exactbars EXACTBARS
                        Use the specified exactbars still compatible with preload
                          0 No memory savings
                          -1 Moderate memory savings
                          -2 Less moderate memory savings
  --no-optdatas         Do not optimize data preloading in optimization
  --no-optreturn        Do not optimize the returned values to save time
  --ma_low MA_LOW       SMA range low to optimize
  --ma_high MA_HIGH     SMA range high to optimize
  --m1_low M1_LOW       MACD Fast MA range low to optimize
  --m1_high M1_HIGH     MACD Fast MA range high to optimize
  --m2_low M2_LOW       MACD Slow MA range low to optimize
  --m2_high M2_HIGH     MACD Slow MA range high to optimize
  --m3_low M3_LOW       MACD Signal range low to optimize
  --m3_high M3_HIGH     MACD Signal range high to optimize

异常

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

设计目标之一是尽早退出,并让用户完全透明地了解错误的发生情况。目标是迫使自己拥有会在异常情况下中断并强制重新访问受影响部分的代码。

但时机已经成熟,一些异常可能会慢慢添加到平台中。

层次结构

所有异常的基类是BacktraderError(它是Exception的直接子类)

位置

  1. 在模块errors内,例如可以通过以下方式访问:
import backtrader as bt
class Strategy(bt.Strategy):
    def __init__(self):
        if something_goes_wrong():
            raise bt.errors.StrategySkipError` 
  1. 直接来自backtrader,如下所示:
import backtrader as bt
class Strategy(bt.Strategy):
    def __init__(self):
        if something_goes_wrong():
            raise bt.StrategySkipError` 

异常

StrategySkipError

请求平台跳过此策略进行回测。在实例化(__init__)阶段引发

写入器

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

将以下内容写入流:

  • 包含数据源、策略、指标和观察器的 csv 流
    可以通过每个对象的 csv 属性控制哪些对象实际进入 csv 流(对于 数据源观察器 默认为 True / 对于 指标 默认为 False)
  • 属性摘要
  • 数据源
  • 策略(行数和参数)
  • 指标/观察器:(行数和参数)
  • 分析器:(参数和分析结果)

只定义了一个称为 WriterFile 的写入器,可以添加到系统中:

  • 通过将 cerebro 的 writer 参数设置为 True
    将实例化标准的 WriterFile
  • 通过调用 Cerebro.addwriter(writerclass, **kwargs)
    writerclass 将在回测执行期间使用给定的 kwargs 实例化
    鉴于标准的 WriterFile 不会默认输出 csv,以下 addwriter 调用将负责处理:
cerebro.addwriter(bt.WriterFile, csv=True)` 

参考文献

backtrader.WriterFile 类

系统范围的写入器类。

可以用以下方式进行参数化:

  • out(默认:sys.stdout):要写入的输出流
    如果传递了字符串,则将使用参数内容的文件名
  • close_out(默认:False
    如果 out 是一个流,则是否需要写入器显式关闭它
  • csv(默认:False
    如果在执行期间需要将数据源、策略、观察器和指标的 csv 流写入流
    可以通过每个对象的 csv 属性控制哪些对象实际进入 csv 流(对于 数据源观察器 默认为 True / 对于 指标 默认为 False)
  • csv_filternan(默认:True)是否需要将 nan 值从 csv 流中清除(替换为空字段)
  • csv_counter(默认:True)如果写入器应该保留并打印实际输出的行数计数器
  • indent(默认:2)每个级别的缩进空格数
  • separators(默认:['=', '-', '+', '*', '.', '~', '"', '^', '#']
    用于各个部分/子(子)部分的行分隔符使用的字符
  • seplen(默认:79
    包括缩进在内的一行分隔符的总长度
  • rounding(默认:None
    要将浮点数舍入到的小数位数。使用 None 时不执行舍入

数据提要

数据源

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

backtrader配备了一组数据源解析器(在撰写本文时全部基于 CSV),让您可以从不同来源加载数据。

  • Yahoo(在线或已保存到文件中)
  • VisualChart(请参阅www.visualchart.com
  • Backtrader CSV(用于测试的自有格式)
  • 通用 CSV 支持

从快速入门指南中应清楚地了解到,您可以将数据源添加到Cerebro实例中。稍后,不同策略将可以在以下位置访问数据源:

  • 一个数组 self.datas(插入顺序)
  • 数组对象的别名:
  • self.data 和 self.data0 指向第一个元素
  • self.dataX 指向数组中索引为 X 的元素

有关插入方式的快速提醒:

import backtrader as bt
import backtrader.feeds as btfeeds
data = btfeeds.YahooFinanceCSVData(dataname='wheremydatacsvis.csv')
cerebro = bt.Cerebro()
cerebro.adddata(data)  # a 'name' parameter can be passed for plotting purposes

数据源常见参数

此数据源可以直接从 Yahoo 下载数据并馈送到系统中。

参数:

  • dataname(默认值:None)必须提供
    其含义随数据源类型而异(文件位置、股票代码等)
  • name(默认值:‘’)
    用于绘图的装饰目的。如果未指定,可能会从dataname派生(例如:文件路径的最后部分)
  • fromdate(默认值:mindate)
    Python 日期时间对象,指示应忽略任何早于此日期时间的日期时间
  • todate(默认值:maxdate)
    Python 日期时间对象,指示应忽略任何晚于此日期时间的日期时间
  • timeframe(默认值:TimeFrame.Days)
    潜在值:TicksSecondsMinutesDaysWeeksMonthsYears
  • compression(默认值:1)
    每根柱子的实际条数。信息性的。仅在数据重采样/重播中有效。
  • sessionstart(默认值:None)
    数据的会话开始时间指示。可能被类用于重新采样等目的
  • sessionend(默认值:None)
    数据的会话结束时间指示。可能被类用于重新采样等目的

CSV 数据源常见参数

参数(除了常见的之外):

  • headers(默认值:True)
    表示传递的数据是否具有初始标题行
  • separator(默认值:“,”)
    考虑到每个 CSV 行的标记分隔符

GenericCSVData

该类提供了一个通用接口,允许解析几乎每种 CSV 文件格式。

根据参数定义的顺序和字段存在性解析 CSV 文件

特定参数(或特定含义):

  • dataname
    要解析的文件名或类似文件的对象
  • datetime(默认值:0)包含日期(或日期时间)字段的列
  • time(默认值:-1)包含时间字段的列,如果与日期时间字段分开(-1 表示不存在)
  • open(默认值:1),high(默认值:2),low(默认值:3),close(默认值:4),volume(默认值:5),openinterest(默认值:6)
    包含相应字段的列的索引
    如果传递了负值(例如:-1),表示 CSV 数据中不存在该字段
  • nullvalue(默认值:float(‘NaN’))
    如果应该有一个值缺失(CSV 字段为空),则使用的值
  • dtformat(默认:%Y-%m-%d %H:%M:%S)
    用于解析 datetime CSV 字段的格式
  • tmformat(默认:%H:%M:%S)
    如果“存在”,则用于解析时间 CSV 字段的格式(“时间” CSV 字段的默认设置是不存在)

一个覆盖以下要求的示例用法:

  • 限制输入至 2000 年
  • HLOC 顺序而不是 OHLC
  • 缺失值将被替换为零(0.0)
  • 提供日线数据,日期时间仅为格式为 YYYY-MM-DD 的日期
  • 没有 openinterest

代码:

import datetime
import backtrader as bt
import backtrader.feeds as btfeeds
...
...
data = btfeeds.GenericCSVData(
    dataname='mydata.csv',
    fromdate=datetime.datetime(2000, 1, 1),
    todate=datetime.datetime(2000, 12, 31),
    nullvalue=0.0,
    dtformat=('%Y-%m-%d'),
    datetime=0,
    high=1,
    low=2,
    open=3,
    close=4,
    volume=5,
    openinterest=-1
)
...

稍作修改的要求:

  • 限制输入至 2000 年
  • HLOC 顺序而不是 OHLC
  • 缺失值将被替换为零(0.0)
  • 提供分钟线数据,带有单独的日期和时间列
  • 日期的格式为 YYYY-MM-DD
  • 时间的格式为 HH.MM.SS(而不是通常的 HH:MM:SS)
  • 没有 openinterest

代码:

import datetime
import backtrader as bt
import backtrader.feeds as btfeed
...
...
data = btfeeds.GenericCSVData(
    dataname='mydata.csv',
    fromdate=datetime.datetime(2000, 1, 1),
    todate=datetime.datetime(2000, 12, 31),
    nullvalue=0.0,
    dtformat=('%Y-%m-%d'),
    tmformat=('%H.%M.%S'),
    datetime=0,
    time=1,
    high=2,
    low=3,
    open=4,
    close=5,
    volume=6,
    openinterest=-1
)

这也可以通过子类化来永久实现:

import datetime
import backtrader.feeds as btfeed
class MyHLOC(btfreeds.GenericCSVData):
  params = (
    ('fromdate', datetime.datetime(2000, 1, 1)),
    ('todate', datetime.datetime(2000, 12, 31)),
    ('nullvalue', 0.0),
    ('dtformat', ('%Y-%m-%d')),
    ('tmformat', ('%H.%M.%S')),
    ('datetime', 0),
    ('time', 1),
    ('high', 2),
    ('low', 3),
    ('open', 4),
    ('close', 5),
    ('volume', 6),
    ('openinterest', -1)
)

现在只需提供 dataname,就可以重用这个新类:

data = btfeeds.MyHLOC(dataname='mydata.csv')

扩展数据源

原文:www.backtrader.com/docu/extending-a-datafeed/

GitHub 上的问题实际上推动了完成文档部分或帮助我理解 backtrader 是否具有我最初设想的易用性和灵活性,以及沿途做出的决策。

在这种情况下是 问题 #9

最终问题似乎归结为:

  • 最终用户是否能轻松地扩展现有机制,以添加额外信息,比如像openhigh等的其他现有价格信息点呢?

据我所知,问题的答案是:是的

发帖人似乎有以下需求(来自问题 #6):

  • 正在解析为 CSV 格式的数据源
  • 使用 GenericCSVData 加载信息
    这种通用 csv 支持是针对这个 问题 #6 开发的。
  • 这是一个额外的字段,显然包含需要传递的 P/E 信息,这些信息将传递给解析后的 CSV 数据。

让我们继续 CSV 数据源开发和 GenericCSVData 示例帖子。

步骤:

  • 假设 P/E 信息被设置在解析后的 CSV 数据中。
  • 使用 GenericCSVData 作为基类
  • 将现有线(open/high/low/close/volumen/openinterest)扩展为 pe
  • 给调用者添加一个参数,让其确定 P/E 信息的列位置。

结果:

from backtrader.feeds import GenericCSVData
class GenericCSV_PE(GenericCSVData):
    # Add a 'pe' line to the inherited ones from the base class
    lines = ('pe',)
    # openinterest in GenericCSVData has index 7 ... add 1
    # add the parameter to the parameters inherited from the base class
    params = (('pe', 8),)

工作完成了…

稍后,在策略中使用这个数据源时:

import backtrader as bt
....
class MyStrategy(bt.Strategy):
    ...
    def next(self):
        if self.data.close > 2000 and self.data.pe < 12:
            # TORA TORA TORA --- Get off this market
            self.sell(stake=1000000, price=0.01, exectype=Order.Limit)
    ...

绘制那条额外的 P/E 线

显然,数据源中的这行额外信息没有自动化的绘图支持。

最好的替代方法是对该行进行简单移动平均,并在单独的轴上绘制它:

import backtrader as bt
import backtrader.indicators as btind
....
class MyStrategy(bt.Strategy):
    def __init__(self):
        # The indicator autoregisters and will plot even if no obvious
        # reference is kept to it in the class
        btind.SMA(self.data.pe, period=1, subplot=False)
    ...
    def next(self):
        if self.data.close > 2000 and self.data.pe < 12:
            # TORA TORA TORA --- Get off this market
            self.sell(stake=1000000, price=0.01, exectype=Order.Limit)
    ...

CSV 数据源开发

www.backtrader.com/docu/datafeed-develop-csv/

backtrader已经提供了通用 CSV 数据源和一些特定的 CSV 数据源。总结:

  • 通用 CSV 数据
  • VisualChartCSV 数据
  • YahooFinanceData(用于在线下载)
  • YahooFinanceCSVData(用于已下载的数据)
  • BacktraderCSVData(内部…用于测试目的,但可用)

但即使如此,最终用户可能希望为特定的 CSV 数据源开发支持。

通常的座右铭可能是:“说起来容易做起来难”。实际上,结构的目的是使其易于操作。

步骤:

  • 继承自backtrader.CSVDataBase
  • 如有必要,定义任何params
  • start方法中进行任何初始化
  • stop方法中进行任何清理
  • 定义一个_loadline方法,在其中进行实际工作
    此方法接收一个参数:linetokens。
    如其名,此数据包含根据separator参数(继承自基类)拆分当前行后的标记。
    如果完成工作后有新数据……填充相应行并返回True
    如果没有可用内容,因此解析已经结束:返回False
    如果在幕后代码中读取文件行时发现没有更多行可解析,则可能甚至不需要返回False

已经考虑到的事项:

  • 打开文件(或接收文件样式对象)
  • 如果指示存在,则跳过标题行
  • 读取行
  • 对行进行标记
  • 预加载支持(一次性在内存中加载整个数据源)

通常,一个例子胜过千言万语的需求描述。让我们使用BacktraderCSVData中定义的内部 CSV 解析代码的简化版本。这个版本不需要初始化或清理(例如,可以是打开套接字,然后稍后关闭)。

注意

backtrader数据源包含通常的行业标准数据源,需要填充。即:

  • 日期时间
  • 打开


  • 关闭
  • 成交量
  • 持仓量

如果您的策略/算法或简单的数据查看仅需要例如收盘价,则可以将其他值保持不变(每次迭代结束之前,它们会自动填充为 float(‘NaN’)值,以使最终用户代码有机会执行任何操作。

在此示例中,仅支持每日格式:

import itertools
...
import backtrader as bt
class MyCSVData(bt.CSVDataBase):
    def start(self):
        # Nothing to do for this data feed type
        pass
    def stop(self):
        # Nothing to do for this data feed type
        pass
    def _loadline(self, linetokens):
        i = itertools.count(0)
        dttxt = linetokens[next(i)]
        # Format is YYYY-MM-DD
        y = int(dttxt[0:4])
        m = int(dttxt[5:7])
        d = int(dttxt[8:10])
        dt = datetime.datetime(y, m, d)
        dtnum = date2num(dt)
        self.lines.datetime[0] = dtnum
        self.lines.open[0] = float(linetokens[next(i)])
        self.lines.high[0] = float(linetokens[next(i)])
        self.lines.low[0] = float(linetokens[next(i)])
        self.lines.close[0] = float(linetokens[next(i)])
        self.lines.volume[0] = float(linetokens[next(i)])
        self.lines.openinterest[0] = float(linetokens[next(i)])
        return True

代码期望所有字段已就位并可转换为浮点数,除日期时间外,日期时间具有固定的 YYYY-MM-DD 格式,并且可在不使用datetime.datetime.strptime的情况下解析。

只需添加几行代码,即可满足更复杂的需求,以处理空值,日期格式解析。GenericCSVData执行此操作。

购买者注意

使用GenericCSVData现有数据源和继承,可以完成很多工作以支持各种格式。

让我们为Sierra Chart每日格式添加支持(始终以 CSV 格式存储)。

定义(通过查看一个**‘.dly’**数据文件:

  • 字段:日期、开盘价、最高价、最低价、收盘价、成交量、持仓量
    行业标准和已经由GenericCSVData支持的标准顺序(也是行业标准)
  • 分隔符:,
  • 日期格式:YYYY/MM/DD

针对这些文件的解析器:

class SierraChartCSVData(backtrader.feeds.GenericCSVData):
    params = (('dtformat', '%Y/%m/%d'),)

params的定义只是重新定义基类中的一个现有参数。在这种情况下,只需更改日期的格式化字符串。

Et voilá … Sierra Chart 的解析器完成了。

下面是GenericCSVData的参数定义,以便提醒:

class GenericCSVData(feed.CSVDataBase):
    params = (
        ('nullvalue', float('NaN')),
        ('dtformat', '%Y-%m-%d %H:%M:%S'),
        ('tmformat', '%H:%M:%S'),
        ('datetime', 0),
        ('time', -1),
        ('open', 1),
        ('high', 2),
        ('low', 3),
        ('close', 4),
        ('volume', 5),
        ('openinterest', 6),
    )

二进制数据源开发

原文:www.backtrader.com/docu/datafeed-develop-general/datafeed-develop-general/

注意

示例中使用的二进制文件goog.fd属于 VisualChart,不能与backtrader一起分发。

VisualChart可以免费下载,供有兴趣直接使用二进制文件的人使用。

CSV 数据源开发展示了如何添加新的基于 CSV 的数据源。现有的基类 CSVDataBase 提供了框架,大多数情况下子类可以简单地执行以下操作:

def _loadline(self, linetokens):
  # parse the linetokens here and put them in self.lines.close,
  # self.lines.high, etc
  return True # if data was parsed, else ... return False

基类负责参数、初始化、文件打开、读取行、拆分行为标记和其他额外的事情,比如跳过不符合用户可能已定义的日期范围(fromdatetodate)的行。

开发非 CSV 数据源遵循相同的模式,而不是下降到已分割的行标记。

要做的事情:

  • 派生自backtrader.feed.DataBase
  • 添加任何你可能需要的参数
  • 如果需要初始化,请覆盖__init__(self)和/或start(self)
  • 如果需要任何清理代码,覆盖stop(self)
  • 工作发生在必须始终被覆盖的方法内:_load(self)

让我们使用backtrader.feed.DataBase已提供的参数:

from backtrader.utils.py3 import with_metaclass
...
...
class DataBase(with_metaclass(MetaDataBase, dataseries.OHLCDateTime)):
    params = (('dataname', None),
        ('fromdate', datetime.datetime.min),
        ('todate', datetime.datetime.max),
        ('name', ''),
        ('compression', 1),
        ('timeframe', TimeFrame.Days),
        ('sessionend', None))

具有以下含义:

  • dataname是数据源识别如何获取数据的参数。在CSVDataBase的情况下,此参数应为文件路径或已经是类似文件的对象。
  • fromdatetodate定义将传递给策略的日期范围。提供的任何值超出此范围的数据将被忽略。
  • name是为了绘图目的而设计的。
  • timeframe指示时间工作参考
    可能的值:TicksSecondsMinutesDaysWeeksMonthsYears
  • compression(默认值:1)
    每个柱子的实际条数。提供信息。仅在数据重采样/重播中有效。
  • compression
  • 如果传递了sessionend(一个 datetime.time 对象),将会添加到数据源datetime行中,以便识别会话结束。

BackTrader 中文文档(三)(2)https://developer.aliyun.com/article/1489228

相关文章
|
5月前
|
Unix 索引 Python
BackTrader 中文文档(一)(2)
BackTrader 中文文档(一)
114 0
|
5月前
|
索引
BackTrader 中文文档(六)(2)
BackTrader 中文文档(六)
79 0
|
5月前
|
存储 编解码 API
BackTrader 中文文档(四)(1)
BackTrader 中文文档(四)
64 1
|
5月前
|
测试技术 索引 Python
BackTrader 中文文档(二)(2)
BackTrader 中文文档(二)
61 0
|
5月前
|
索引 Python
BackTrader 中文文档(五)(3)
BackTrader 中文文档(五)
64 0
|
5月前
|
存储 C++ 索引
BackTrader 中文文档(二)(1)
BackTrader 中文文档(二)
59 0
|
5月前
|
存储 编解码 网络架构
BackTrader 中文文档(二)(4)
BackTrader 中文文档(二)
86 0
|
5月前
|
数据可视化
BackTrader 中文文档(三)(3)
BackTrader 中文文档(三)
45 0
|
5月前
|
存储 数据可视化 机器人
BackTrader 中文文档(六)(1)
BackTrader 中文文档(六)
95 0
|
5月前
|
机器学习/深度学习 算法 机器人
BackTrader 中文文档(一)(1)
BackTrader 中文文档(一)
356 0