BackTrader 中文文档(二十七)(1)https://developer.aliyun.com/article/1505475
Pandas DataFeed 支持
原文:
www.backtrader.com/blog/posts/2015-08-21-pandas-datafeed/pandas-datafeed/
在一些小的增强和一些有序字典调整以更好地支持 Python 2.6 的情况下,backtrader 的最新版本增加了对从 Pandas Dataframe 或时间序列分析数据的支持。
注意
显然必须安装 pandas
及其依赖项。
这似乎引起了很多人的关注,他们依赖于已经可用的用于不同数据源(包括 CSV)的解析代码。
class PandasData(feed.DataBase): ''' The ``dataname`` parameter inherited from ``feed.DataBase`` is the pandas Time Series ''' params = ( # Possible values for datetime (must always be present) # None : datetime is the "index" in the Pandas Dataframe # -1 : autodetect position or case-wise equal name # >= 0 : numeric index to the colum in the pandas dataframe # string : column name (as index) in the pandas dataframe ('datetime', None), # Possible values below: # None : column not present # -1 : autodetect position or case-wise equal name # >= 0 : numeric index to the colum in the pandas dataframe # string : column name (as index) in the pandas dataframe ('open', -1), ('high', -1), ('low', -1), ('close', -1), ('volume', -1), ('openinterest', -1), )
上述从 PandasData
类中摘录的片段显示了键:
- 实例化期间
dataname
参数对应 Pandas Dataframe
此参数继承自基类feed.DataBase
- 新参数使用了
DataSeries
中常规字段的名称,并遵循这些约定
datetime
(默认:无)- 无:datetime 是 Pandas Dataframe 中的“index”
- -1:自动检测位置或大小写相等的名称
= 0:Pandas 数据框中列的数值索引
- string:Pandas 数据框中的列名(作为索引)
open
,high
,low
,high
,close
,volume
,openinterest
(默认:全部为 -1)- 无:列不存在
- -1:自动检测位置或大小写相等的名称
= 0:Pandas 数据框中列的数值索引
- string:Pandas 数据框中的列名(作为索引)
一个小的样本应该能够加载标准 2006 样本,已被 Pandas
解析,而不是直接由 backtrader
解析。
运行示例以使用 CSV 数据中的现有“headers”:
$ ./panda-test.py -------------------------------------------------- Open High Low Close Volume OpenInterest Date 2006-01-02 3578.73 3605.95 3578.73 3604.33 0 0 2006-01-03 3604.08 3638.42 3601.84 3614.34 0 0 2006-01-04 3615.23 3652.46 3615.23 3652.46 0 0
相同,但告诉脚本跳过标题:
$ ./panda-test.py --noheaders -------------------------------------------------- 1 2 3 4 5 6 0 2006-01-02 3578.73 3605.95 3578.73 3604.33 0 0 2006-01-03 3604.08 3638.42 3601.84 3614.34 0 0 2006-01-04 3615.23 3652.46 3615.23 3652.46 0 0
第二次运行是使用 tells pandas.read_csv
:
- 跳过第一个输入行(
skiprows
关键字参数设置为 1) - 不要寻找标题行(
header
关键字参数设置为 None)
backtrader 对 Pandas 的支持尝试自动检测是否已使用列名,否则使用数值索引,并相应地采取行动,尝试提供最佳匹配。
以下图表是成功的致敬。Pandas Dataframe 已被正确加载(在两种情况下)。
测试的示例代码。
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import backtrader as bt import backtrader.feeds as btfeeds import pandas def runstrat(): args = parse_args() # Create a cerebro entity cerebro = bt.Cerebro(stdstats=False) # Add a strategy cerebro.addstrategy(bt.Strategy) # Get a pandas dataframe datapath = ('../datas/sample/2006-day-001.txt') # Simulate the header row isn't there if noheaders requested skiprows = 1 if args.noheaders else 0 header = None if args.noheaders else 0 dataframe = pandas.read_csv(datapath, skiprows=skiprows, header=header, parse_dates=True, index_col=0) if not args.noprint: print('--------------------------------------------------') print(dataframe) print('--------------------------------------------------') # Pass it to the backtrader datafeed and add it to the cerebro data = bt.feeds.PandasData(dataname=dataframe) cerebro.adddata(data) # Run over everything cerebro.run() # Plot the result cerebro.plot(style='bar') def parse_args(): parser = argparse.ArgumentParser( description='Pandas test script') parser.add_argument('--noheaders', action='store_true', default=False, required=False, help='Do not use header rows') parser.add_argument('--noprint', action='store_true', default=False, help='Print the dataframe') return parser.parse_args() if __name__ == '__main__': runstrat()
自动化 backtrader 回测。
到目前为止,所有 backtrader 的示例和工作样本都是从头开始创建一个主要的 Python 模块,加载数据、策略、观察者,并准备现金和佣金方案。
算法交易的一个目标是交易的自动化,鉴于 bactrader 是一个用于检查交易算法的回测平台(因此是一个算法交易平台),自动化使用 backtrader 是一个显而易见的目标。
注意
2015 年 8 月 22 日
bt-run.py
中包含了对 Analyzer
的支持。
backtrader
的开发版本现在包含了 bt-run.py
脚本,它自动化了大多数任务,并将作为常规软件包的一部分与 backtrader
一起安装。
bt-run.py
允许最终用户:
- 指明必须加载的数据。
- 设置加载数据的格式。
- 指定数据的日期范围
- 禁用标准观察者。
- 从内置的或 Python 模块中加载一个或多个观察者(例如:回撤)
- 为经纪人设置现金和佣金方案参数(佣金、保证金、倍数)
- 启用绘图,控制图表数量和数据呈现风格。
最后:
- 加载策略(内置的或来自 Python 模块)
- 向加载的策略传递参数。
请参阅下面关于脚本的用法*。
应用用户定义的策略。
让我们考虑以下策略:
- 简单地加载一个 SimpleMovingAverage(默认周期 15)
- 打印输出。
- 文件名为 mymod.py。
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import backtrader.indicators as btind class MyTest(bt.Strategy): params = (('period', 15),) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.data.datetime[0] if isinstance(dt, float): dt = bt.num2date(dt) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): sma = btind.SMA(period=self.p.period) def next(self): ltxt = '%d, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f' self.log(ltxt % (len(self), self.data.open[0], self.data.high[0], self.data.low[0], self.data.close[0], self.data.volume[0], self.data.openinterest[0]))
用通常的测试样本执行策略很容易:简单:
./bt-run.py --csvformat btcsv \ --data ../samples/data/sample/2006-day-001.txt \ --strategy ./mymod.py
图表输出。
控制台输出:
2006-01-20T23:59:59+00:00, 15, 3593.16, 3612.37, 3550.80, 3550.80, 0.00, 0.00 2006-01-23T23:59:59+00:00, 16, 3550.24, 3550.24, 3515.07, 3544.31, 0.00, 0.00 2006-01-24T23:59:59+00:00, 17, 3544.78, 3553.16, 3526.37, 3532.68, 0.00, 0.00 2006-01-25T23:59:59+00:00, 18, 3532.72, 3578.00, 3532.72, 3578.00, 0.00, 0.00 ... ... 2006-12-22T23:59:59+00:00, 252, 4109.86, 4109.86, 4072.62, 4073.50, 0.00, 0.00 2006-12-27T23:59:59+00:00, 253, 4079.70, 4134.86, 4079.70, 4134.86, 0.00, 0.00 2006-12-28T23:59:59+00:00, 254, 4137.44, 4142.06, 4125.14, 4130.66, 0.00, 0.00 2006-12-29T23:59:59+00:00, 255, 4130.12, 4142.01, 4119.94, 4119.94, 0.00, 0.00
同样的策略但是:
- 将参数
period
设置为 50。
命令行:
./bt-run.py --csvformat btcsv \ --data ../samples/data/sample/2006-day-001.txt \ --strategy ./mymod.py \ period 50
图表输出。
使用内置策略。
backtrader
将逐渐包含示例(教科书)策略。随着 bt-run.py
脚本一起,一个标准的简单移动平均线交叉策略已包含在内。名称:
SMA_CrossOver
- 参数。
- 快速(默认 10)快速移动平均的周期
- 慢(默认 30)慢速移动平均的周期
如果快速移动平均线向上穿过快速移动平均线并且在慢速移动平均线向下穿过快速移动平均线后卖出(仅在之前已购买的情况下)。
代码。
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import backtrader.indicators as btind class SMA_CrossOver(bt.Strategy): params = (('fast', 10), ('slow', 30)) def __init__(self): sma_fast = btind.SMA(period=self.p.fast) sma_slow = btind.SMA(period=self.p.slow) self.buysig = btind.CrossOver(sma_fast, sma_slow) def next(self): if self.position.size: if self.buysig < 0: self.sell() elif self.buysig > 0: self.buy()
标准执行:
./bt-run.py --csvformat btcsv \ --data ../samples/data/sample/2006-day-001.txt \ --strategy :SMA_CrossOver
注意‘:’。加载策略的标准表示法(见下文)是:
- 模块:策略。
遵循以下规则:
- 如果模块存在且指定了策略,则将使用该策略。
- 如果模块存在但未指定策略,则将返回模块中找到的第一个策略。
- 如果未指定模块,则假定“strategy”是指
backtrader
包中的策略
后者是我们的情况。
输出。
最后一个示例添加佣金方案、现金并更改参数:
./bt-run.py --csvformat btcsv \ --data ../samples/data/sample/2006-day-001.txt \ --cash 20000 \ --commission 2.0 \ --mult 10 \ --margin 2000 \ --strategy :SMA_CrossOver \ fast 5 slow 20
输出。
我们已经对策略进行了回测:
- 更改移动平均周期
- 设置新的起始资金
- 为期货类工具设置佣金方案
查看每根柱子中现金的连续变化,因为现金会根据期货类工具的每日变动进行调整。
添加分析器
注意
添加了分析器示例
bt-run.py
还支持使用与策略相同的语法添加Analyzers
来选择内部/外部分析器。
以SharpeRatio
分析 2005-2006 年为例:
./bt-run.py --csvformat btcsv \ --data ../samples/data/sample/2005-2006-day-001.txt \ --strategy :SMA_CrossOver \ --analyzer :SharpeRatio
输出:
==================== == Analyzers ==================== ## sharperatio -- sharperatio : 11.6473326097
良好的策略!!!(实际示例中纯粹是运气,而且也没有佣金)
图表(仅显示分析器不在图表中,因为分析器无法绘制,它们不是线对象)
脚本的用法
直接从脚本中:
$ ./bt-run.py --help usage: bt-run.py [-h] --data DATA [--csvformat {yahoocsv_unreversed,vchart,sierracsv,yahoocsv,vchartcsv,btcsv}] [--fromdate FROMDATE] [--todate TODATE] --strategy STRATEGY [--nostdstats] [--observer OBSERVERS] [--analyzer ANALYZERS] [--cash CASH] [--commission COMMISSION] [--margin MARGIN] [--mult MULT] [--noplot] [--plotstyle {bar,line,candle}] [--plotfigs PLOTFIGS] ... Backtrader Run Script positional arguments: args args to pass to the loaded strategy optional arguments: -h, --help show this help message and exit Data options: --data DATA, -d DATA Data files to be added to the system --csvformat {yahoocsv_unreversed,vchart,sierracsv,yahoocsv,vchartcsv,btcsv}, -c {yahoocsv_unreversed,vchart,sierracsv,yahoocsv,vchartcsv,btcsv} CSV Format --fromdate FROMDATE, -f FROMDATE Starting date in YYYY-MM-DD[THH:MM:SS] format --todate TODATE, -t TODATE Ending date in YYYY-MM-DD[THH:MM:SS] format Strategy options: --strategy STRATEGY, -st STRATEGY Module and strategy to load with format module_path:strategy_name. module_path:strategy_name will load strategy_name from the given module_path module_path will load the module and return the first available strategy in the module :strategy_name will load the given strategy from the set of built-in strategies Observers and statistics: --nostdstats Disable the standard statistics observers --observer OBSERVERS, -ob OBSERVERS This option can be specified multiple times Module and observer to load with format module_path:observer_name. module_path:observer_name will load observer_name from the given module_path module_path will load the module and return all available observers in the module :observer_name will load the given strategy from the set of built-in strategies Analyzers: --analyzer ANALYZERS, -an ANALYZERS This option can be specified multiple times Module and analyzer to load with format module_path:analzyer_name. module_path:analyzer_name will load observer_name from the given module_path module_path will load the module and return all available analyzers in the module :anaylzer_name will load the given strategy from the set of built-in strategies Cash and Commission Scheme Args: --cash CASH, -cash CASH Cash to set to the broker --commission COMMISSION, -comm COMMISSION Commission value to set --margin MARGIN, -marg MARGIN Margin type to set --mult MULT, -mul MULT Multiplier to use Plotting options: --noplot, -np Do not plot the read data --plotstyle {bar,line,candle}, -ps {bar,line,candle} Plot style for the input data --plotfigs PLOTFIGS, -pn PLOTFIGS Plot using n figures
BackTrader 中文文档(二十七)(3)https://developer.aliyun.com/article/1505479