pyalgotrade量化交易回测

转载请注明出处:https://blog.csdn.net/xuezoutianya/article/details/104059649

pyalgotrade官网文档http://gbeced.github.io/pyalgotrade/docs/v0.20/html/

官方给的教程很容易上手,初学者可以参考官方文档中的示例策略,唯一的问题是例程中的下载方法不适用于下载国内股票数据。

本博文介绍如何下载国内股票数据,以及如何定制化你自己的交易策略并显示回测结果。

如何下载国内股票数据

在网上查了不少博文,找到两种方式,但第一种方式我自己用会报错,这里还是列出来

  • 使用pyalgotrade_tushare模块

安装方法

pip install pyalgotrade_tushare

使用代码

# 导入pyalgotrade_tushare模块
from pyalgotrade_tushare import tools

'''
其他代码段
'''

# 股票代码,str类型,如"399300"(沪深300)
instruments = ["399300"]
# 第二个参数是起始日期,第三个参数是结束日期,第四个参数是下载目录,如"."(当前目录)
feeds = tools.build_feed(instruments, 2018, 2019, ".")
  • 自己封装函数或者模块

MyDownload.py

原代码出处https://blog.csdn.net/lawme/article/details/51495349,我添加了临时文件删除,以及格式修正

import tushare as ts
import pandas as pd
import os
 
def download_csv(code, start_date, end_date, filepath):
    data = ts.get_hist_data(code, start=start_date, end=end_date)

    # 数据存盘
    data.to_csv('temp.csv')

    # 读出数据,DataFrame格式
    df = pd.read_csv('temp.csv')

    # 从df中选取数据段,改变段名;新段'Adj Close'使用原有段'close'的数据  
    df2 = pd.DataFrame({'Date' : df['date'], 'Open' : df['open'],
                        'High' : df['high'],'Close' : df['close'],
                        'Low' : df['low'],'Volume' : df['volume'],
                        'Adj Close':df['close']})

    # 按照Yahoo格式的要求,调整df2各段的顺序
    dt = df2.pop('Date')
    df2.insert(0,'Date',dt)
    o = df2.pop('Open')
    df2.insert(1,'Open',o)
    h = df2.pop('High')
    df2.insert(2,'High',h)
    l = df2.pop('Low')
    df2.insert(3,'Low',l)
    c = df2.pop('Close')
    df2.insert(4,'Close',c)
    v = df2.pop('Volume')
    df2.insert(5,'Volume',v)

    # 新格式数据存盘,不保存索引编号  
    df2.to_csv(filepath, index=False)
    os.remove("temp.csv")

在同目录主代码中使用上述模块

from pyalgotrade.barfeed import quandlfeed
# 导入自定义模块
import MyDownload

'''
其他代码段
'''

instrument = "399300"
# 下载股票数据
MyDownload.download_csv(instrument, "2017-01-01", "2020-01-01", instrument+".csv")

# 从CSV文件加载bar feed
feed = quandlfeed.Feed()
feed.addBarsFromCSV(instrument, instrument+".csv")

注:由于pyalgotrade与pandas存在兼容性问题,使用第二种方法会出现警告,但不影响使用

如何定制化交易策略

交易策略的定制是为了解决一下问题:

在什么时候买?买多少?

在什么时候卖?卖多少?

以下以日线交易数据为例进行说明

onBar函数在遍历到每天的交易数据都会被调用一次,所以上述问题的具体解决是在这个函数中实现。但是除了定投以外,股票的买卖需要择时,需要参考股票的指标数据,pyalgotrade提供了很多股票分析常用的指标计算函数,具体请参考pyalgotrade.technical库。

我将默认金额即$1000000分成10层仓位,并按照MACD的金叉买入3层,死叉卖出3层制定的交易策略代码如下(其中还计算了很多其他指标但尚未用于交易策略的制定),可以通过修改加入新的股票指标,股票指标计算函数的参数,买卖判断条件和仓位买卖层数自定义交易策略。

from pyalgotrade import strategy, broker, plotter
from pyalgotrade.barfeed import quandlfeed
from pyalgotrade.stratanalyzer import returns, sharpe
from pyalgotrade.technical import ma, macd, rsi, stoch, bollinger
from pyalgotrade import broker as basebroker

class MyStrategy(strategy.BacktestingStrategy):
    def __init__(self, feed, instrument, bBandsPeriod):
        super(MyStrategy, self).__init__(feed)
        self.__instrument = instrument
        # 使用调整后的数据
        if feed.barsHaveAdjClose():
            self.setUseAdjustedValues(True)
        # 持有仓位
        self.__holdPosition = 0.0
        # 空闲仓位
        self.__emptyPosition = 10.0
        # 单元持仓金额
        self.__unit = self.getBroker().getCash(False) / 10
        # 统计收盘价
        self.__priceDS = feed[instrument].getPriceDataSeries()
        # 计算macd指标
        self.__macd = macd.MACD(self.__priceDS, 12, 26, 9)
        # 计算KD指标
        self.__stoch = stoch.StochasticOscillator(feed[instrument], 9, 3)
        # 计算rsi指标
        self.__rsi7 = rsi.RSI(self.__priceDS, 7)
        self.__rsi14 = rsi.RSI(self.__priceDS, 14)
        # 计算布林线
        self.__bbands = bollinger.BollingerBands(self.__priceDS, bBandsPeriod, 2)

    def getPriceDS(self):
        return self.__priceDS
        
    def getMACD(self):
        return self.__macd

    def getStoch(self):
        return self.__stoch
        
    def getRSI7(self):
        return self.__rsi7
        
    def getRSI14(self):
        return self.__rsi14

    def getBollingerBands(self):
        return self.__bbands
    
    def onOrderUpdated(self, order):
        if order.isBuy():
            orderType = "Buy"
        else:
            orderType = "Sell"
        self.info("%s order %d updated - Status: %s" % (
            orderType, order.getId(), basebroker.Order.State.toString(order.getState())
        ))

    def onBars(self, bars):
        lower = self.__bbands.getLowerBand()[-1]
        middle = self.__bbands.getMiddleBand()[-1]
        upper = self.__bbands.getUpperBand()[-1]
        
        if lower is None:
            return

        bar = bars[self.__instrument]
        # 持有股票份额
        shares = self.getBroker().getShares(self.__instrument)
        # 最新股价
        price = bar.getPrice()
        
        # 买入策略
        if self.__macd.getHistogram()[-1] is None or self.__macd.getHistogram()[-2] is None:
            return
        # 金叉形成
        if self.__macd.getHistogram()[-2] < 0 and self.__macd.getHistogram()[-1] > 0:
            PositionToBuy = 0
            if self.__emptyPosition >= 3:
                PositionToBuy = 3
            else:
                PositionToBuy = self.__emptyPosition
            sharesToBuy = int(PositionToBuy * self.__unit / price)
            if(self.marketOrder(self.__instrument, sharesToBuy)):
                self.__holdPosition += PositionToBuy
                self.__emptyPosition -= PositionToBuy
                self.info("Placing buy market order for %s shares" % sharesToBuy)
        # 死叉形成
        elif self.__macd.getHistogram()[-2] > 0 and self.__macd.getHistogram()[-1] < 0:
            PositionToSell = 0
            if self.__holdPosition >= 3:
                PositionToSell = -3
            else:
                PositionToSell = self.__holdPosition
            sharesToSell = int(PositionToSell * self.__unit / price)
            if(self.marketOrder(self.__instrument, sharesToSell)):
                self.__holdPosition += PositionToSell
                self.__emptyPosition -= PositionToSell
                self.info("Placing sell market order for %s shares" % sharesToSell)

如何显示回测结果

图表显示

输出股票日线的折线图

# 创建MyStrategy实例
myStrategy = MyStrategy(feed, instrument, bBandsPeriod)

plt = plotter.StrategyPlotter(myStrategy, True, True, True)
plt.plot()

在股票日线上添加指标曲线

# 图表中添加BOLL
plt.getInstrumentSubplot(instrument).addDataSeries("upper", myStrategy.getBollingerBands().getUpperBand())
plt.getInstrumentSubplot(instrument).addDataSeries("middle", myStrategy.getBollingerBands().getMiddleBand())
plt.getInstrumentSubplot(instrument).addDataSeries("lower", myStrategy.getBollingerBands().getLowerBand())

为MACD,STOCH,RSI各新建一个图表

# 图表添加MACD
plt.getOrCreateSubplot("macd").addDataSeries("DIF", myStrategy.getMACD())
plt.getOrCreateSubplot("macd").addDataSeries("DEA", myStrategy.getMACD().getSignal())
plt.getOrCreateSubplot("macd").addDataSeries("MACD", myStrategy.getMACD().getHistogram())

# 图表添加KD
plt.getOrCreateSubplot("stoch").addDataSeries("K", myStrategy.getStoch())
plt.getOrCreateSubplot("stoch").addDataSeries("D", myStrategy.getStoch().getD())

# 图表添加RSI
plt.getOrCreateSubplot("rsi").addDataSeries("RSI7", myStrategy.getRSI7())
plt.getOrCreateSubplot("rsi").addDataSeries("RSI14", myStrategy.getRSI14())
plt.getOrCreateSubplot("rsi").addLine("Overbought", 70)
plt.getOrCreateSubplot("rsi").addLine("Oversold", 30)

文本输出

# 添加回测分析
returnsAnalyzer = returns.Returns()
myStrategy.attachAnalyzer(returnsAnalyzer)

# 添加夏普比率分析
sharpeRatioAnalyzer = sharpe.SharpeRatio()
myStrategy.attachAnalyzer(sharpeRatioAnalyzer)

# 运行策略
myStrategy.run()
    
# 输出投资组合的最终资产总值
print("最终资产总值: $%.2f" % myStrategy.getBroker().getEquity())
# 输出总收益
print("总收益: %.2f %%" % (returnsAnalyzer.getCumulativeReturns()[-1] * 100))
# 输出夏普比率
print("夏普比率: %.2f" % sharpeRatioAnalyzer.getSharpeRatio(0))

运行结果示例

命令行输出结果如下:

最终资产总值: $955164.54
总收益: -4.48 %
夏普比率: -0.12

注:这个是完整代码的运行结果,从回测结果来看,我目前的交易策略并不给力,哈哈。

完整代码见https://github.com/beyondyouth/pyal/tree/master/test01

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
## 讲师介绍: 近 5 年个人投资理财年化收益平均超 25%。如果你也想提升自己的睡后收入,轻松赚钱,那么这门课就是为你量身打造。课程基于一个完整真实的量化交易业务来讲授,并融入老师的理财经验以及使用编程技术辅助投资的技巧,让你面对各种复杂投资情况也能做到游刃有余。 ## 学习目标: 从不懂“理财”开始到实现自动交易,成为一个“技术流”理财高手 编程技术 + 核心量化策略 + 交易系统开发 + 讲师经验分享,学会用技术辅助理财 本课程从最基础的什么是量化开始讲起,即使对投资理财不了解同样可以学习,轻松入门无压力。 从如何获取数据开始,到实现实盘交易,课程对量化交易的每一步都进行细致讲解,为你铺开量化交易的每一个细节。 不仅仅只是教你学会使用某种工具,更会教给你量化交易的投资思想,让你面对各种情况都游刃有余。 ## 课程亮点: 设计适合自己并能适应市场的交易策略,才是量化交易的灵魂 课程亲手带你设计并实现两种交易策略,快速培养你的策略思维能力 1. 择时策略:通过这个策略学会如何利用均线,创建择时策略,优化股票买入卖出的时间点。2. 选股策略:掌握选股策略的核心逻辑,并基于收益率创建动量选股策略,并验证其有效性。 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 第三方平台大而全,不易扩展,效率还差,信息安全也是大问题,打造自己的交易平台才是更优解

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值