Python量化交易实战-38使用开源项目回测双均线策略

auto-trade xuhss 1144℃ 0评论

使用PyAlgoTrade回测双均线策略

双均线策略:长短周期均线,通过金叉死叉的方式买入卖出股票,获取收益的策略。

回顾上节课代码的部分,上节课完成了可视化代码的部分, 主要使用PyAlgoTradeplotter模块,对SMA的数据,Simple Returns的数据进行了可视化,我们也利用了returns这个类来获取收益,然后将实例化的returns类去赋予给mystrategy

你会发现,所有的核心就是:我计算出来的数据,将这个数据作为mystrategy的属性,这样就可以在mystrategy里面给各个函数使用了。

现在是单均线,如果我要使用双均线应该怎么实现呢?

一、实操找到最优质双均线

创建变量 修改构造函数:

class MyStrategy(strategy.BacktestingStrategy):
    def __init__(self, feed, instrument, smaPeriod1, smaPeriod2):
        super(MyStrategy, self).__init__(feed, 10000)
        self.__position = None
        self.__instrument = instrument
        # # We'll use adjusted close values instead of regular close values.
        # self.setUseAdjustedValues(True)
        self.__sma1 = ma.SMA(feed[instrument].getPriceDataSeries(), smaPeriod1)
        self.__sma2 = ma.SMA(feed[instrument].getPriceDataSeries(), smaPeriod2)

设置2个返回值函数:

    def getSMA1(self):
        return self.__sma1

    def getSMA2(self):
        return self.__sma2

修改策略:

    def onBars(self, bars):
        # Wait for enough bars to be available to calculate a SMA.
        if self.__sma2[-1] is None:
            return

        bar = bars[self.__instrument]
        # If a position was not opened, check if we should enter a long position.
        if self.__position is None:
            #短期均价>长期均价 买入
            if self.__sma1[-1] > self.__sma2[-1]:
                # Enter a buy market order for 10 shares. The order is good till canceled.
                self.__position = self.enterLong(self.__instrument, 100, True)
        # 短期均价<长期均价卖出
        elif self.__sma1[-1] < self.__sma2[-1] and not self.__position.exitActive():
            self.__position.exitMarket()

运行策略:

def run_strategy(smaPeriod1, smaPeriod2):
    # Load the bar feed from the CSV file
    instruments = ["000001"]
    feeds = tools.build_feed(instruments, 2018, 2021, "histdata")
    #print(feeds)

    # Evaluate the strategy with the feed's bars.
    myStrategy = MyStrategy(feeds, instruments[0], smaPeriod1, smaPeriod2)
    myStrategy.run()
    # 打印总持仓:(cash + shares * price) (持有现金 + 股数*价格)
    print(smaPeriod1, smaPeriod2, "Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity())
    # Attach a returns analyzers to the strategy.
    # returnsAnalyzer = returns.Returns()
    # myStrategy.attachAnalyzer(returnsAnalyzer)

    # # Attach the plotter to the strategy.
    # plt = plotter.StrategyPlotter(myStrategy)
    # # Include the SMA in the instrument's subplot to get it displayed along with the closing prices.
    # plt.getInstrumentSubplot(instruments[0]).addDataSeries("SMA1", myStrategy.getSMA1())
    # plt.getInstrumentSubplot(instruments[0]).addDataSeries("SMA2", myStrategy.getSMA2())
    # # Plot the simple returns on each bar.
    # plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())

    # # Run the strategy.
    # myStrategy.run()
    # myStrategy.info("Final portfolio value: $%.2f" % myStrategy.getResult())

    # # Plot the strategy.
    # plt.plot()

调用运行策略:

ma1 = [5, 10, 15]
ma2 = [15, 20, 35]
for i in ma1:
    for j in ma2:
        if i<j:
            run_strategy(i, j)

运行:

20210703141057 - Python量化交易实战-38使用开源项目回测双均线策略

结果来看,数据表现最好的是10661

二、可视化最优双均线

#使用pyalgotrade进行数据回测
import pyalgotrade
from pyalgotrade import strategy
from pyalgotrade.barfeed import quandlfeed
from pyalgotrade_tushare import tools, barfeed
from pyalgotrade.technical import ma
from pyalgotrade import plotter
from pyalgotrade.barfeed import quandlfeed
from pyalgotrade.stratanalyzer import returns

def safe_round(value, digits):
    if value is not None:
        value = round(value, digits)
    return value

class MyStrategy(strategy.BacktestingStrategy):
    def __init__(self, feed, instrument, smaPeriod1, smaPeriod2):
        super(MyStrategy, self).__init__(feed, 10000)
        self.__position = None
        self.__instrument = instrument
        # # We'll use adjusted close values instead of regular close values.
        # self.setUseAdjustedValues(True)
        self.__sma1 = ma.SMA(feed[instrument].getPriceDataSeries(), smaPeriod1)
        self.__sma2 = ma.SMA(feed[instrument].getPriceDataSeries(), smaPeriod2)

    def getSMA1(self):
        return self.__sma1

    def getSMA2(self):
        return self.__sma2

    def onEnterOk(self, position):
        execInfo = position.getEntryOrder().getExecutionInfo()
        #self.info("BUY at $%.2f" % (execInfo.getPrice()))

    def onEnterCanceled(self, position):
        self.__position = None

    def onExitOk(self, position):
        execInfo = position.getExitOrder().getExecutionInfo()
        #self.info("SELL at $%.2f" % (execInfo.getPrice()))
        self.__position = None

    def onExitCanceled(self, position):
        # If the exit was canceled, re-submit it.
        self.__position.exitMarket()

    def onBars(self, bars):
        # Wait for enough bars to be available to calculate a SMA.
        if self.__sma2[-1] is None:
            return

        bar = bars[self.__instrument]
        # If a position was not opened, check if we should enter a long position.
        if self.__position is None:
            #短期均价>长期均价 买入
            if self.__sma1[-1] > self.__sma2[-1]:
                # Enter a buy market order for 10 shares. The order is good till canceled.
                self.__position = self.enterLong(self.__instrument, 100, True)
        # 短期均价<长期均价卖出
        elif self.__sma1[-1] < self.__sma2[-1] and not self.__position.exitActive():
            self.__position.exitMarket()

def run_strategy(smaPeriod1, smaPeriod2):
    # Load the bar feed from the CSV file
    instruments = ["000001"]
    feeds = tools.build_feed(instruments, 2018, 2021, "histdata")
    #print(feeds)

    # Evaluate the strategy with the feed's bars.
    myStrategy = MyStrategy(feeds, instruments[0], smaPeriod1, smaPeriod2)
    # myStrategy.run()
    # # 打印总持仓:(cash + shares * price) (持有现金 + 股数*价格)
    # print(smaPeriod1, smaPeriod2, "Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity())
    # Attach a returns analyzers to the strategy.
    returnsAnalyzer = returns.Returns()
    myStrategy.attachAnalyzer(returnsAnalyzer)

    # Attach the plotter to the strategy.
    plt = plotter.StrategyPlotter(myStrategy)
    # Include the SMA in the instrument's subplot to get it displayed along with the closing prices.
    plt.getInstrumentSubplot(instruments[0]).addDataSeries("SMA1", myStrategy.getSMA1())
    plt.getInstrumentSubplot(instruments[0]).addDataSeries("SMA2", myStrategy.getSMA2())
    # Plot the simple returns on each bar.
    plt.getOrCreateSubplot("returns").addDataSeries("Simple returns", returnsAnalyzer.getReturns())

    # Run the strategy.
    myStrategy.run()
    myStrategy.info("Final portfolio value: $%.2f" % myStrategy.getResult())

    # Plot the strategy.
    plt.plot()

run_strategy(5, 30)

运行:

20210703141533 - Python量化交易实战-38使用开源项目回测双均线策略

对于双均线可视化图表的部分

蓝色的颜色的是K线,浅蓝色是短期均线, 紫色是长期均线,更平缓,然后就是买入卖出标记,这里的买入卖出标记比起单均线的策略明显要少很多,也就是开仓次数要少很多

接着看单次收益率图,从图中看到,收益并没有很好,上下浮动差不多。所以在这个情况下,可以基于很多因素进行优化。

最后看一下累计收益图,可以看到整体曲线和行情数据表现差不多 那么以上就是关于如何去利用一个已有的开源框线对我们的双均线策略进行回测的内同。到这里如果说你完全知道代码是怎么写的,那么你应该也能够实现其他的策略,比如说布林策略,通过改写这里的开仓和平仓条件就能够快速的获得回测图谱。

转载请注明:xuhss » Python量化交易实战-38使用开源项目回测双均线策略

喜欢 (14)

您必须 登录 才能发表评论!