BackTrader 中文文档(二十六)(1)https://developer.aliyun.com/article/1505464
在同一轴线上绘图。
原文:
www.backtrader.com/blog/posts/2015-09-21-plotting-same-axis/plotting-same-axis/
根据博客上的评论稍微增加了一点(幸运的是只是几行代码)来进行绘图。
- 能够在任何其他指标上绘制任何指标。
一个潜在的用例:
- 节省宝贵的屏幕空间,将一些指标绘制在一起,有更多的空间来欣赏 OHLC 柱状图。
示例:将 Stochastic 和 RSI 绘图合并。
当然,有些事情必须考虑进去:
- 如果指标的缩放差异太大,一些指标可能不可见。
示例:一个围绕 0.0 加/减 0.5 波动的 MACD 绘制在一个横跨 0-100 范围的 Stochastic 上。
第一个实现在提交的开发分支上是 …14252c6
一个示例脚本(见下面的完整代码)让我们看到了效果。
注意
因为示例策略什么都不做,标准观察者被移除了,除非通过命令行开关激活。
首先,脚本在没有任何开关的情况下运行。
- 简单移动平均线绘制在数据上。
- MACD、Stochastic 和 RSI 分别绘制在各自的轴线/子图上。
执行:
$ ./plot-same-axis.py
和图表。
第二次执行改变了全景:
- 简单移动平均线移动到了一个子图上。
- MACD 被隐藏了。
- RSI 绘制在 Stochastic 之上(y 轴范围兼容:0-100)。
这通过将指标的plotinfo.plotmaster值设置为要绘制到的其他指标来实现。
在这种情况下,由于__init__中的局部变量被命名为stoc代表 Stochastic 和rsi代表 RSI,看起来像是:
rsi.plotinfo.plotmaster = stoc`
执行:
$ ./plot-same-axis.py --smasubplot --nomacdplot --rsioverstoc
图表。
为了检查尺度的不兼容性,让我们尝试在 SMA 上绘制 RSI:
$ ./plot-same-axis.py --rsiovermacd
图表。
RSI 标签显示出数据和 SMA,但是尺度在 3400-4200 范围内,因此……RSI 没有任何迹象。
进一步的徒劳尝试是将 SMA 放在一个子图上,然后再次在 SMA 上绘制 RSI。
$ ./plot-same-axis.py –rsiovermacd –smasubplot
图表。
标签清晰,但是除了 SMA 图中底部的一条淡蓝线外,RSI 的所有东西都消失了。
注意
添加了在另一个指标上绘制的多行指标。
沿着另一个方向,让我们在另一个指标上绘制多行指标。让我们将 Stochastic 绘制在 RSI 上:
$ ./plot-same-axis.py --stocrsi
它有效。Stochastic标签显示出来了,K%和D%这两条线也是如此。但是这些线没有“名称”,因为我们得到了指标的名称。
在代码中,当前的设置将是:
stoc.plotinfo.plotmaster = rsi
要显示随机线的名称而不是名称,我们还需要:
stoc.plotinfo.plotlinelabels = True
这已经被参数化,新的执行结果显示如下:
$ ./plot-same-axis.py --stocrsi --stocrsilabels
现在图表显示了随机线的名称在 RSI 线的名称下方。
脚本用法:
$ ./plot-same-axis.py --help usage: plot-same-axis.py [-h] [--data DATA] [--fromdate FROMDATE] [--todate TODATE] [--stdstats] [--smasubplot] [--nomacdplot] [--rsioverstoc | --rsioversma | --stocrsi] [--stocrsilabels] [--numfigs NUMFIGS] Plotting Example 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 --stdstats, -st Show standard observers --smasubplot, -ss Put SMA on own subplot/axis --nomacdplot, -nm Hide the indicator from the plot --rsioverstoc, -ros Plot the RSI indicator on the Stochastic axis --rsioversma, -rom Plot the RSI indicator on the SMA axis --stocrsi, -strsi Plot the Stochastic indicator on the RSI axis --stocrsilabels Plot line names instead of indicator name --numfigs NUMFIGS, -n NUMFIGS Plot using numfigs figures
以及代码。
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import datetime # The above could be sent to an independent module import backtrader as bt import backtrader.feeds as btfeeds import backtrader.indicators as btind class PlotStrategy(bt.Strategy): ''' The strategy does nothing but create indicators for plotting purposes ''' params = dict( smasubplot=False, # default for Moving averages nomacdplot=False, rsioverstoc=False, rsioversma=False, stocrsi=False, stocrsilabels=False, ) def __init__(self): sma = btind.SMA(subplot=self.params.smasubplot) macd = btind.MACD() # In SMA we passed plot directly as kwarg, here the plotinfo.plot # attribute is changed - same effect macd.plotinfo.plot = not self.params.nomacdplot # Let's put rsi on stochastic/sma or the other way round stoc = btind.Stochastic() rsi = btind.RSI() if self.params.stocrsi: stoc.plotinfo.plotmaster = rsi stoc.plotinfo.plotlinelabels = self.p.stocrsilabels elif self.params.rsioverstoc: rsi.plotinfo.plotmaster = stoc elif self.params.rsioversma: rsi.plotinfo.plotmaster = sma def runstrategy(): args = parse_args() # Create a cerebro cerebro = bt.Cerebro() # Get the dates from the args fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d') todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d') # Create the 1st data data = btfeeds.BacktraderCSVData( dataname=args.data, fromdate=fromdate, todate=todate) # Add the 1st data to cerebro cerebro.adddata(data) # Add the strategy cerebro.addstrategy(PlotStrategy, smasubplot=args.smasubplot, nomacdplot=args.nomacdplot, rsioverstoc=args.rsioverstoc, rsioversma=args.rsioversma, stocrsi=args.stocrsi, stocrsilabels=args.stocrsilabels) # And run it cerebro.run(stdstats=args.stdstats) # Plot cerebro.plot(numfigs=args.numfigs, volume=False) def parse_args(): parser = argparse.ArgumentParser(description='Plotting Example') parser.add_argument('--data', '-d', default='../../datas/2006-day-001.txt', help='data to add to the system') parser.add_argument('--fromdate', '-f', default='2006-01-01', help='Starting date in YYYY-MM-DD format') parser.add_argument('--todate', '-t', default='2006-12-31', help='Starting date in YYYY-MM-DD format') parser.add_argument('--stdstats', '-st', action='store_true', help='Show standard observers') parser.add_argument('--smasubplot', '-ss', action='store_true', help='Put SMA on own subplot/axis') parser.add_argument('--nomacdplot', '-nm', action='store_true', help='Hide the indicator from the plot') group = parser.add_mutually_exclusive_group(required=False) group.add_argument('--rsioverstoc', '-ros', action='store_true', help='Plot the RSI indicator on the Stochastic axis') group.add_argument('--rsioversma', '-rom', action='store_true', help='Plot the RSI indicator on the SMA axis') group.add_argument('--stocrsi', '-strsi', action='store_true', help='Plot the Stochastic indicator on the RSI axis') parser.add_argument('--stocrsilabels', action='store_true', help='Plot line names instead of indicator name') parser.add_argument('--numfigs', '-n', default=1, help='Plot using numfigs figures') return parser.parse_args() if __name__ == '__main__': runstrategy()
Writers - 写下来
原文:
www.backtrader.com/blog/posts/2015-09-14-write-it-down/write-it-down/
随着 1.1.7.88 版本的发布,backtrader 增加了一个新的功能:writers
这可能是早该做的事情,应该一直都有,并且在问题#14的讨论中也应该促进了发展。
迟做总比不做好。
Writer实现试图与backtrader环境中的其他对象保持一致
- 添加到 Cerebro
- 提供最合理的默认值
- 不要强迫用户做太多事情
当然,更重要的是理解写手实际上写了什么。 这就是:
- CSV 输出
- `datas` added to the system (can be switched off) - `strategies` (a Strategy can have named lines) - `indicators` inside the strategies (only 1st level) - `observers` inside the strategies (only 1st level) Which `indicators` and `observers` output data to the CSV stream is controlled by the attribute: `csv` in each instance The defaults are: - Observers have `csv = True` - Indicators have `csv = False` The value can be overriden for any instance created inside a strategy`
一旦回测阶段结束,Writers为Cerebro实例添加一个新的部分,并添加以下子部分:
- 系统中
datas的属性(名称、压缩、时间框架) - 系统中
strategies的属性(行、参数)
- 策略中
indicators的属性(行、参数) - 策略中
observers的属性(行、参数) - 具有以下特性的分析器
- 参数
- 分析
在考虑所有这些的同时,一个例子可能是展示writers的功能(或弱点)的最简单方法。
但是在了解如何将它们添加到 cerebro 之前。
- 使用
writer参数到cerebro:
cerebro = bt.Cerebro(writer=True)`
- 这创建了一个默认实例。
- 具体添加:
cerebro = bt.Cerebro() cerebro.addwriter(bt.WriterFile, csv=False)`
- 添加(现在是唯一的作者)一个
WriterFile类到作者列表中,稍后用csv=False实例化(输出中不会生成 csv 流。
具有多空策略的长期示例(请参阅下面的完整代码),使用 Close-SMA 交叉作为信号进行执行:
$ ./writer-test.py
图表:
具有以下输出:
=============================================================================== Cerebro: ----------------------------------------------------------------------------- - Datas: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Data0: - Name: 2006-day-001 - Timeframe: Days - Compression: 1 ----------------------------------------------------------------------------- - Strategies: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - LongShortStrategy: ************************************************************************* - Params: - csvcross: False - printout: False - onlylong: False - stake: 1 - period: 15 ************************************************************************* - Indicators: ....................................................................... - SMA: - Lines: sma ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Params: - period: 15 ....................................................................... - CrossOver: - Lines: crossover - Params: None ************************************************************************* - Observers: ....................................................................... - Broker: - Lines: cash, value - Params: None ....................................................................... - BuySell: - Lines: buy, sell - Params: None ....................................................................... - Trades: - Lines: pnlplus, pnlminus - Params: None ************************************************************************* - Analyzers: ....................................................................... - Value: - Begin: 100000 - End: 100826.1 ....................................................................... - SQN: - Params: None ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Analysis: - sqn: 0.05 - trades: 22
运行后,我们有了一个完整的摘要,显示系统的设置以及分析器的意见。 在这种情况下,分析器是
Value是策略内部的一个虚拟分析器,它收集了组合的起始值和结束值SQN(或 SystemQualityNumber)由 Van K. Tharp 定义(增加到backtrader1.1.7.88,告诉我们它已经看到了 22 笔交易,并且计算了sqn为 0.05。
这实际上相当低。 我们本可以通过观察完整一年后的微薄利润来发现这一点(幸运的是,系统不会亏损)
测试脚本允许我们调整策略以变为仅多头:
$ ./writer-test.py --onlylong --plot
图表:
现在的输出是:
=============================================================================== Cerebro: ----------------------------------------------------------------------------- - Datas: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Data0: - Name: 2006-day-001 - Timeframe: Days - Compression: 1 ----------------------------------------------------------------------------- - Strategies: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - LongShortStrategy: ************************************************************************* - Params: - csvcross: False - printout: False - onlylong: True - stake: 1 - period: 15 ************************************************************************* - Indicators: ....................................................................... - SMA: - Lines: sma ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Params: - period: 15 ....................................................................... - CrossOver: - Lines: crossover - Params: None ************************************************************************* - Observers: ....................................................................... - Broker: - Lines: cash, value - Params: None ....................................................................... - BuySell: - Lines: buy, sell - Params: None ....................................................................... - Trades: - Lines: pnlplus, pnlminus - Params: None ************************************************************************* - Analyzers: ....................................................................... - Value: - Begin: 100000 - End: 102795.0 ....................................................................... - SQN: - Params: None ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Analysis: - sqn: 0.91 - trades: 11
“params”对策略的更改可见(onlylong 已转为 True),分析器讲述了一个不同的故事:
- 结束值从 100826.1 提高到 102795.0
- SQN 看到的交易从 22 减少到 11
- SQN 分数从 0.05 增长到 0.91,好得多得多
但是仍然看不到 CSV 输出。 让我们运行脚本来打开它:
$ ./writer-test.py --onlylong --writercsv
BackTrader 中文文档(二十六)(3)https://developer.aliyun.com/article/1505466