Backtrader的作者在他的博客上写了一篇很有意思的文章。这个哥们从csdn上面找了backtrader的代码,然后改写了一下,提高了可读性,觉得还是很有意思的。
原始代码大概是这样的:
代码语言:javascript复制def __init__(self):
...
self.ma1 = bt.indicators.SMA(self.datas[0],
period=self.p.period
)
self.ma2 = bt.indicators.SMA(self.datas[1],
period=self.p.period
)
这是初始化部分,看出来大概就是一个双均线策略。然后我们看一下买卖的逻辑:
代码语言:javascript复制if (self.ma1[0]-self.ma1[-1])/self.ma1[-1]>(self.ma2[0]-self.ma2[-1])/self.ma2[-1]:
if (self.ma1[0]-self.ma1[-1])/self.ma1[-1]<=(self.ma2[0]-self.ma2[-1])/self.ma2[-1]:
这里我们发现,有点意思了。这个策略就是两个均线涨跌幅的大小比较。其实和双均线的上穿下穿没有什么本质的区别,就是一个趋势跟踪策略。当然,backreader作者的意图绝对不是研究策略,而是如何改进这个代码。
说真的,笔者真的很佩服backtrader的架构,几乎在写策略的时候能想到的东西,backtrader都提供了,即使不能提供也给了writer这个接口,让码农们可以随心所欲的分析。
Backtrader的作者略微怼了一下编程习惯,然后给出了它自己的等价写法:
代码语言:javascript复制def __init__(self):
...
# Let's create the moving averages as before
ma1 = bt.ind.SMA(self.data0, period=self.p.period)
ma2 = bt.ind.SMA(self.data1, period=self.p.period)
# Use line delay notation (-x) to get a ref to the -1 point
ma1_pct = ma1 / ma1(-1) - 1.0 # The ma1 percentage part
ma2_pct = ma2 / ma2(-1) - 1.0 # The ma2 percentage part
self.buy_sig = ma1_pct > ma2_pct # buy signal
self.sell_sig = ma1_pct <= ma2_pct # sell signal
代码语言:javascript复制def next(self):
...
# Not yet ... we MIGHT BUY if ...
if self.buy_sig:
...
...
# Already in the market ... we might sell
if self.sell_sig:
...
其实这里给大家很好的展示了backtrader中line的这个概念和延迟算子()的作用。说真的,在init方法里面编程,有一点FPGA编程的感觉,一种并行感油然而生。