美文网首页量化投资python
量化投资——利用 Pyalgotrade 进行 SMA策略回测

量化投资——利用 Pyalgotrade 进行 SMA策略回测

作者: 夜晚要读书 | 来源:发表于2019-02-13 18:39 被阅读131次

    过年前忙于其它项目,过年期间又贪玩偷懒了,今天简要的将几段学习代码更新上来,供大家参交流。
    量化交易在实盘交易之前,必须对量化交易策略进行回测。在此,我们主要介绍其中比较优秀的 Pyalgotrade 框架。

    Pyalgotrade 简介

    Pyalgotrade是事件驱动的回测框架,支持虚盘和实盘两种交易。文档完整,整合了TA-Lib(技术分析库)。在速度和灵活方面都表现出众。但它的一大硬伤是不支持 Pandas 的模块和对象,而且数据格式不支持国内股票数据,需要我们自己实现数据转换。

    PyAlgoTrade 六大组件:

    • Strategies策略: 定义的实现交易逻辑的类:何时买、何时卖,等等;
    • Feeds数据源:These are data providing abstractions. 例如,你可以使用CSV数据源从一个格式化后的csv(以逗号分割)文件中加载数据推送给策略。 数据源不仅限于bars。
    • Brokers经纪商:经纪商模块负责执行订单。
    • DataSeries数据序列:DataSeries 是用于管理时间序列的抽象类
    • Technicals指标计算:这是你用来对DataSeries进行计算的一组过滤(指标)器。 例如简单移动平均线(SMA),相对强弱指标(RSI)等. 这些过滤(指标)器被建模为DataSeries 的装饰器。
    • Optimizer优化:这是能让你在不同电脑之间、或多进程、或二者结合以加快回测效率的一组类。

    自定义回归策略

    这里不废话了,我们直接上代码,我们的交易策略类 MyStrategy 继承自Pyalgotrade.strategy.BacktestingStrategy 类:

    # 基于 pyalgotrade 的交易策略类
    class MyStrategy(strategy.BacktestingStrategy):
        def __init__(self, feed, instrument, smaPeriod):
            super(MyStrategy, self).__init__(feed)
            self.__instrument = instrument
            self.__closed = feed[instrument].getCloseDataSeries()
            self.__sma = ma.SMA(self.__closed, smaPeriod)
            self.__position = None
            self.getBroker()
           
        def getSMA(self):
            return self.__sma
       
        def onEnterLong(self, position):
            print("onEnterLong", position.getShares())
    
        def onEnterOk(self, position):
            execInfo = position.getEntryOrder().getExecutionInfo()
            self.info("BUY at %.2f" % (execInfo.getPrice()))
           
        def onEnterCanceled(self, position):
            self.__position = None
            print("onEnterCanceled", position.getShares())
           
        def onExitOk(self, position):
            execInfo = position.getExitOrder().getExecutionInfo()
            self.info("SELL at $%.2f" % (execInfo.getPrice()))
            self.__position = None
            print("onExitOk", position.getShares())
           
        def onExitCanceled(self, position):
            self.__position.exitMarket()
            print("onExitCanceled", position.getShares())
           
        def onBars(self, bars):
            if self.__position is None:
                if cross.cross_above(self.__closed, self.__sma) > 0:
                    shares = int(self.getBroker().getCash() * 0.9 / bars[self.__instrument].getPrice())
                    print("cross_above shares,", shares)
                    # Enter a buy market order. The order is good till canceled.
                    self.__position = self.enterLong(self.__instrument, shares, True)
            elif not self.__position.exitActive() and cross.cross_below(self.__closed, self.__sma) > 0:
                print("cross_below")
                self.__position.exitMarket()
               
    
        def getClose(self):
            return self.__closed
    
    

    对股票进行策略回溯

    示例代码,以 格力电器(000651)为例,初始资本 100万,回溯时间 2018年1月1日 至 2019年 2月 12日,SMA周期 30:

    code = "000651" # 格力电器
    feed = tsfeed.Feed()
    feed.addBarsFromCode(code,start='2018-01-01',end='2019-02-12')
    
    # Evaluate the strategy with the feed's bars.
    myStrategy = MyStrategy(feed, code, 30) # SMA周期 30
    returnsAnalyzer = returns.Returns()
    myStrategy.attachAnalyzer(returnsAnalyzer)
    sharpe_ratio = sharpe.SharpeRatio()
    myStrategy.attachAnalyzer(sharpe_ratio)
    
    plt = plotter.StrategyPlotter(myStrategy)
    plt.getInstrumentSubplot(code).addDataSeries("SMA", myStrategy.getSMA())
    plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())
    
    myStrategy.run()
    myStrategy.info("Final portfolio value: $%.2f" % myStrategy.getResult())
    
    plt.plot()
    

    最终回测结果如下图:


    格力电器,2018-01-01 至 2019-02-12 回溯

    不同周期的策略回测结果

    如上图所示,格力电器 2018年 初始资本 100万,末期资本 72.88 万,亏损近 30%。如此看来,是否交易策略无效呢?
    我们不妨进行更长时间的回测,从 2009年01月01日开始,进行10年时间的回测,结果如下:


    格力电器,2009-01-01 至 2019-02-12 回溯

    可见,格力电器 10 年时间回测结果,末期资本为 340.66 万元, 10年收益 240%。此外,经过我们测试,SMA 不同周期对收益也有明显影响,下面,直接给出我们针对 格力电器和工商银行 不同周期,不同SMA频率的回测结果:

    格力电器收益率 1年(2018-01-01~ 2019-02-12) 10 年(2009-01-01~ 2019-02-12 )
    SMA 5 -18.32% 116.41%
    SMA 10 -26.01% 166.57%
    SMA 15 -28.76% 127.1%
    SMA 20 -25.44% 347.41%
    SMA 30 -27.12% 240.66%
    SMA 50 -3.12% 229.2%
    工商银行收益率 1年(2018-01-01~ 2019-02-12) 10 年(2009-01-01~ 2019-02-12 )
    SMA 5 0% 110.65%
    SMA 10 -16.41% 88.34%
    SMA 15 -8.43% 113.07%
    SMA 20 -11.74% 30%
    SMA 30 -14.44% 66.24%
    SMA 50 -6.39% 40.90%

    结论

    根据我们基于自定义策略对格力电器和 工商银行的回测分析,初步可以得到如下结论:

    1. 基于我们的策略,坚持长期策略投资,其最大收益高于大盘表现(最大收益率 347% :格力电器,10年期,SMA 20);
    2. 选取SMA 周期,在 20 左右(在15 ~ 30 之间),其收益最大,相对亏损风险较小;
    3. 选取SMA 周期越大(等于 50 时),风险越小;
    4. 综合来看,投资格力电器收益率更大,而风险在可控范围内。

    注:以上结论只是作为对策略历史数据回测的结果分析,不可作为实际投资参考。

    相关文章

      网友评论

        本文标题:量化投资——利用 Pyalgotrade 进行 SMA策略回测

        本文链接:https://www.haomeiwen.com/subject/ldjreqtx.html