全部版块 我的主页
论坛 金融投资论坛 六区 金融学(理论版) 量化投资
10090 12
2016-01-23

在这一讲中我们将会对一个非常简单的策略回测实例进行讲解,让大家对简单的回测框架有一个最直观的认识。

在这里选用了一个均线策略,该策略属于趋势策略,即通过技术指标的状态改变来捕获开仓或平仓信号。均线策略采用的是技术指标MA( Moving Average),关于它的详细解释可以参看:https://en.wikipedia.org/wiki/Moving_average


该策略的逻辑是:选取两条周期不同的MA曲线,一条为周期比较短的SMA,另一条则是周期比较长的LMA,如果SMA上穿LMA说明未来短期有向上趋势因此作为买入信号,反之作为卖出信号。信号产生规则用表达式写出来就是:

if sma(t)>lma(t)&sma(t-1)<lma(t-1) then signal=1(buy)

if sma(t)<lma(t)&sma(t-1)>lma(t-1) then signal=-1(sell)

else signal=0(hold)


  • 策略模块


在策略模块中我们需要解决的是信号的识别,因此输入是bars,输出是信号。在该模块中提供了两个方法,一个是计算MA指标,另一个是根据策略规则产生信号。

MA指标的可以采用Pandas中的rolling_mean进行计算,参数window可设置移动窗口的大小,min_periods可确定需要有值的最小观测数,如果把min_peridos设置为1那么在ma序列中就不会出现NA的数据。关于该方法的其他参数可以参见Pandas的文档pandas.pydata.org/ 。


def MA(self, price, windows = 5, period = 1):

        MAprice = pd.rolling_mean(price, windows, period)

        return MAprice


信号生成方法是策略模块中最为核心的部分。对于该均线策略,我们信号产生的算法是通过flag来标示T=t时sma是否大于lma,然后对flag做差分。如果flag(t)=1 & flag(t-1)=0 ,那么signal(t)=flag(t)-flag(t-1)=1,即产生了买入信号。


def gen_signal(self):

        signals = pd.DataFrame(index=self.bars.index)

        signals['flag'] = 0

        signals['sma'] = self.MA(self.bars['close'],self.short_window,1)

        signals['lma'] = self.MA(self.bars['close'],self.long_window,1)

        signals['flag'][self.short_window:] = np.where(signals['sma'][self.short_window:]

       > signals['lma'][self.short_window:], 1, 0)  

        signals['signal'] = signals['flag'].diff().fillna(signals['flag'][0])

        return signals


  • 交易模块


策略模块将信号输入到交易模块中,交易模块提供了两个方法。第一个方法是通过信号产生各期买卖的头寸以及持有的头寸,第二个方法是追踪各期的资产情况,如持有头寸的市值、账户剩余的现金以及账户的总资产价值。


   def gen_positions(self):

        positions = self.signals['flag']*1000

        return positions

   

    def trade_positions(self):

        positions = self.signals['signal']*1000

        return positions

        

    def trade_tracing(self):

        capital = pd.DataFrame(index=self.signals.index)

        capital['hold'] = self.gen_positions()*self.bars['close']

        capital['rest'] = self.init_capital- (self.trade_positions()*bars['close']).cumsum()

        capital['total'] = capital['hold']+capital['rest']

        capital['return'] = capital['total'].pct_change().fillna(capital['total'][0]/self.init_capital-1)

        return capital


我们可以选取一只股票采用上述简单回测框架进行回测。


if __name__ == '__main__':

    bars = ts.get_h_data('002337',start='2012-01-01',end='2015-01-01').sort_index()

    test_strategy = MAStrategy(bars)

    signals = test_strategy.gen_signal()

    test_trade = MATrade(bars,signals)

    capital = test_trade.trade_tracing()


注意到该回测框架是一个最简单的策略回测系统,没有考虑各种交易成本,策略也进行了最简化的处理,选取该简单策略进行回测的目的是告诉大家回测系统建立的最基本要素和套路。最后,留下两个小问题留给大家思考:

1、该回测框架是针对单一交易品种进行的,如果对一个投资组合进行回测代码应该如何修改?

2、如果我们希望将所有股票都采用该策略一次性进行回测应该怎么做?


完整代码请关注我的微信公众号:我的微信公众号:会掘金的小鹿(NuggetsRoad)
是时候关注一波了!




二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2016-1-23 17:52:06
来个沙发,干货,我喜欢....
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2016-1-23 17:53:20
不好意思,网络慢,发多了一帖
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2016-1-25 09:26:44
写得挺不错的,而且明确是为了初学的写得比较细致,赞一下
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2016-2-15 18:08:39
楼主给力啊!!
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2016-2-16 15:31:04
是把股票的数据定义成一个类了吗?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群