在博客上发表评论之后,对绘图做了一点补充(幸运的是只有几行代码)。
- 在任何其他指针上绘制任何指针的能力
一个潜在的用例:
通过将一些指针绘制在一起并有更多空间来欣赏 OHLC 条来节省宝贵的屏幕空间
示例:连接随机和 RSI 图
当然必须考虑一些事情:
如果指针的缩放比例差异太大,则某些指针将不可见。
示例:MACD 在 0.0 正负 0.5 附近振荡,绘制在 0-100 范围内移动的随机指针上。
第一个实现是在提交时的开发分支中…14252c6
一个示例脚本(完整代码见下文)让我们看看效果
笔记
因为示例策略什么都不做,除非通过命令行开关激活,否则标准观察者将被删除。
首先脚本在没有开关的情况下运行。
在数据上绘制一个简单移动平均线
MACD、随机指针和 RSI 绘制在自己的轴/子图上
运行:
$ ./plot-same-axis.py
还有图表。
第二次运行改变了全景图:
简单移动平均线移至子图
MACD 隐藏
RSI 在随机指针上绘制(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
图表。
标签很清楚,但 RSI 中剩下的只是 SMA 图底部的一条淡蓝色线。
笔记
添加了在另一个指针上绘制的多线指针
在另一个方向上,让我们在另一个指针上绘制一个多线指针。让我们在 RSI 上绘制随机指针:
$ ./plot-same-axis.py --stocrsi
有用。 Stochastic
标签出现,2行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()