即使是次要版本,也有一些有趣的事情可能会为他们提供专门的博客文章。
linealias
Pull-Request #320包括指针RelativeMomentumIndex
(或RMI
),根据文献,它是RSI
的演变,其中:
- 考虑回溯大于
1
的上升和下降周期
因此,与其让指针重复RSI
的大部分功能,不如做两件事:
扩展
RSI
(以及UpDay
和DownDay
等子指针,以支持大于 1 的回溯期RMI
然后可以实现为具有一些不同默认值的子类。RMI
指针线的逻辑名称是rmi
,但RSI
已经决定名称为rsi
。这可以通过添加一个名为linealias
的新功能来解决
RMI
实现如下所示:
class RelativeMomentumIndex(RSI): alias = ('RMI', ) linealias = (('rsi', 'rmi',),) # add an alias for this class rmi -> rsi plotlines = dict(rsi=dict(_name='rmi')) # change line plotting name
添加了来自基类的行rsi
的别名,名称为rmi
。如果有人想创建一个子类并使用名称rmi
现在是可能的。
此外, rsi
线的绘图名称也更改为rmi
。另一种实现是可能的:
class RelativeMomentumIndex(RSI): alias = ('RMI', ) linesoverrride = True # allow redefinition of the lines hierarcy lines = ('rmi',) # define the line linealias = (('rmi', 'rsi',),) # add an alias for base class rsi -> rmi
这里不再考虑来自RSI
的现有层次结构,并且使用lines
来定义唯一名为rmi
的行。不需要定义绘图名称,因为现在唯一的行具有预期的名称。
但是基类将无法填充这些值,因为它期望名称为rsi
的行就位。因此添加了一个反向别名来让它找到line 。
盈透证券优化
没有预见到使用与 Interactive Brokers 的实时连接作为优化的数据源。然而,一位用户尝试了它并开始遇到起搏违规行为。原因是盈透证券数据馈送将自己标记为live
馈送,从而允许系统绕过某些事情,例如数据预加载。
在没有预加载的情况下,每个优化实例都会重新尝试从盈透证券重新下载相同的历史数据。考虑到这一点,很明显,Feed 可以查看用户是否仅请求历史下载,在这种情况下不报告自己为live
,从而允许平台预加载数据并在优化实例之间共享它。
请参阅社区线程。使用 IBStore 进行优化会导致冗余连接/下载
Heikin-Ashi 烛台
另一个社区线程正在寻求开发 Heikin-Ashi 烛台作为指针:开发 Heikinashi 指针,面临递归定义的一些问题,因为需要种子值,这可以在指针的prenext
阶段完成。
作为传统烛台的一种有趣的显示替代品,它已作为过滤器实现,它允许修改数据源以真正提供 Heikin-Ashi 烛台。像这样:
data0 = MyDataFeed(dataname='xxx', timeframe=bt.TimeFrame.Days, compression=1) data0.addfilter(bt.filters.HeikinAshi) cerebro.adddata(data0)
任何人都可以使用以下代码快速比较蜡烛:
data0 = MyDataFeed(dataname='xxx', timeframe=bt.TimeFrame.Days, compression=1) cerebro.adddata(data0) data1 = data0.clone() data1.addfilter(bt.filters.HeikinAshi) cerebro.adddata(data1)
要绘制蜡烛图,请记住:
cerebro.plot(style='candle')
使用来源中 2005 年和 2006 年的每日样本数据。
并放大一点以更好地了解差异
允许次要角色重新缩放 y 轴
数据源的轴一直使用主数据源作为比例所有者,因为数据始终是视图中最重要的部分。例如,如果我们考虑BollingerBands
,则顶部波段可能远离数据的最大值,并且允许该波段重新缩放图表,将减少图表中数据占用的大小,这将不希望。
现在可以使用plotylimited
控制行为,如下所示:
... data0 = MyDataFeed(dataname='xxx', timeframe=bt.TimeFrame.Days, compression=1) data0.plotinfo.plotlog = False # allow other actors to resize the axis ...
在下图中,底部的数据馈送用plotylimited= False
绘制。布尔带并没有脱离图表,因为它们有助于缩放并且一切都适合图表。
社区中也对此进行了评论。如何设置最大 - 最小绘图边界?
半对数图(又名对数)
现在可以使用半对数刻度(y 刻度)绘制单个轴。例如:
... data0 = MyDataFeed(dataname='xxx', timeframe=bt.TimeFrame.Days, compression=1) data0.plotinfo.plotlog = True data0.plotinfo.plotylimited = True cerebro.adddata(data0) ...
这意味着由该数据馈送控制的用于绘图的轴将使用对数刻度,但其他轴不会,因此
绘制在数据上的移动平均线也将使用该比例绘制
随机指针(位于不同的轴并具有不同的比例)仍将线性绘制
笔记
请注意,使用了plotylimited= True
。这是为了让matplotlib
正确计算对数图表的限制(因为刻度是 10 的幂)以将事物放入图表中。
一个简单地比较雅虎长期数据的样本。
允许 plotmaster 指向自己
在同一轴上绘制多个数据馈送已经是可能的,但是一个小麻烦不允许干净的循环来设置plotinfo.plotmaster
值。之前必须完成以下工作:
mydatas = [] data = MyDataFeed(dataname=mytickers[0], timeframe=..., compression=...) mydatafeeds.append(data) for ticker in mytickers[1:] data = MyDataFeed(dataname=ticker, timeframe=..., compression=...) mydatafeeds.append(data) data.plotinfo.plotmaster = mydatas[0]
现在可以使用这个更清洁的循环:
mydatas = [] for ticker in mytickers: data = MyDataFeed(dataname=ticker, timeframe=..., compression=...) mydatafeeds.append(data) data.plotinfo.plotmaster = mydatas[0]
并且dnames
被记录在案
按名称引用数据馈送已经可用,但它已跳过将其写入文档,因此它是一个隐藏的宝石。策略中的dnames
属性支持点表示法和 [] 表示法(它实际上是一个dict
子类)。如果我们首先添加一些数据提要:
mytickers = ['YHOO', 'IBM', 'AAPL'] for t in mytickers: d = bt.feeds.YahooFinanceData(dataname=t, fromdate=..., name=t.lower())
稍后在策略中可以运行以下操作:
def __init__(self): yhoosma = bt.ind.SMA(self.dnames.yhoo, period=20) aaplsma = bt.ind.SMA(self.dnames['aapl'], period=30) # or even go over the keys/items/values like in a regular dict # for example with a dictionary comprehension stocs = {name: bt.ind.Stochastic(data) for name, data in self.dnames.items()}
结论
一个带有小改动的小版本,增加了一些漂亮的功能。