在同一轴上绘图
原文: https://www.backtrader.com/blog/posts/2015-09-21-plotting-same-axis/plotting-same-axis/
在博客上发表评论之后,对 plotting 做了一点补充(幸运的是只添加了几行代码)。
- 在任何其他指示器上绘制任何指示器的能力
一个潜在的用例:
-
通过将一些指标标绘在一起,并有更多空间欣赏 OHLC 条,节省宝贵的屏幕不动产
示例:连接随机图和 RSI 图
当然,必须考虑一些因素:
-
如果指标的比例差异太大,一些指标将不可见。
示例:在 0-100 范围内移动的随机曲线上绘制的 MACD 在 0.0 正/负 0.5 左右振荡。
第一个实现是在提交…14252c6的开发分支中
一个示例脚本(完整代码见下文)让我们看看效果
笔记
由于示例策略不起任何作用,除非通过命令行开关激活,否则将删除标准观察者。
首先,脚本在没有开关的情况下运行。
-
在数据上绘制一个简单的移动平均值
-
MACD、随机和 RSI 绘制在自己的轴/子地块上
执行:
$ ./plot-same-axis.py
还有图表。
第二次执行将更改全景:
-
简单移动平均线移动到一个子地块
-
MACD 是隐藏的
-
RSI 在随机曲线上绘制(y 轴范围兼容:0-100)
这是通过将指示器的
plotinfo.plotmaster
值设置为要绘制到的其他指示器来实现的。在这种情况下,由于
__init__
中的局部变量被命名为stoc
表示随机变量,被命名为rsi
表示 RSI,因此它看起来像:py 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–sma 子地块
图表。
标签是清晰的,但 RSI 剩下的只是 SMA 图底部的一条微弱的蓝线。
笔记
添加了绘制在另一个指示器上的多行指示器
在另一个方向,让我们在另一个指示器上绘制一个多线指示器。让我们绘制 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()