量化投资系列文章:Backtrader教程——Python量化投资实战教程(一)Python量化投资实战教程(二)——MACD策略(+26.9%)Python量化投资实战教程(三)——A股回测MACD策略Python量化投资实战教程(四)——KDJ策略Github仓库:https://github.com/Ckend/pythondict-quant很多技术投资教材,经常有几本上升图表用于显示某些指标的有用性,而实际上这些上升图表很可能是幻觉。为了证明他所强调的指标的作用,笔者选取了符合指标策略的股票上涨趋势图,但实际上这些策略并不一定适用于所有股票。很多人都被骗了,赔了钱。因此,判断一个策略的好坏,必须要有回测证据。我们将在A股中随机抽取1000只股票,使用上期Python量化投资实战教程(四)-KDJ策略在2010年1月1日至2020年5月10日进行交易,计算最终收益率。最后看正收益和负收益的对比,据此判断策略是否具有普适性。1.在开始之前,您需要确保您的计算机上已经成功安装了Python和pip。如果没有,请访问这篇文章:超级详细的Python安装指南进行安装。如果使用Python进行数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手-AnacondaWindows环境打开Cmd(开始-运行-CMD),苹果系统环境请打开Terminal(命令+空格输入Terminal),准备开始输入命令来安装依赖。当然,我更推荐你使用VSCode编辑器,将本文代码复制,在编辑器下方的终端中运行命令安装依赖模块。多么惬意的一件事:Python编程的最佳搭档——VSCode详解指南。在终端输入如下命令安装我们需要的依赖模块:pipinstallbacktrader如果看到Successfullyinstalledxxx,则安装成功。Backtrader的基本使用可以参考我们之前的文章:Backtrader教程——实战量化投资教程(一)本文所有代码请在Python实战宝典后台回复:量化投资5下载。2.写策略的部分和Python量化投资实战教程(三)-A股回测MACD策略很像,但是很多读者反映看不懂。其实,真的很简单。可能是因为要显示的交易日志比较多。每个人都对代码感到困惑。因此,在本文中,我将详细分析每个步骤。为了阅读方便,我把所有的日志展示代码都去掉了,以清晰展示代码逻辑。不过值得一提的是,我们这里使用的投资回报率的计算是静态的,即本金的多少,和最终的比较盈余作为我们的回报率,每笔交易只买入100股。这是非常不明智的。下一篇我们将通过动态买入股票实现投资回报率的计算。2.1计算指标第一步是构建我们的KDJ指标。在上一篇PythonKDJ量化投资中,我们提到了KDJ的几种计算方法。另外,我们优化了基于MACD指标的买入策略,详细教程可以看PythonMACD量化投资。根据这两篇文章,我们知道KDJ指标的计算方法是:RSV=(收盘价-N期最低价)/(N期最高价-N期最低价)*100K值=NRSV的周期加权移动平均线(EMA)D值=N周期K值的加权移动平均线(EMA)J值=3_K-2_DMACD指标计算如下(EMA后面的括号表示周期):MACD=价格EMA(12)-价格EMA(26)。信号线=MACD的EMA(9)这样,我们就可以开始计算这些指标了。在Backtrader中计算这些指标非常方便。最高价、最低价、EMA均有内置函数计算,如bt.indicators.EMA用于计算EMA的值,period参数表示周期。计算方法如下:importdatetimeimportos.pathimportsysimportpickleimportbacktraderasbtfrombacktrader.indicatorsimportEMAclassTestStrategy(bt.Strategy):def__init__(self):self.dataclose=self.datas[0].closeself.volume=自我。datas[0].volumeself.order=Noneself.buyprice=Noneself.buycomm=None#9个交易日内最高价self.high_nine=bt.indicators.Highest(self.data.high,period=9)#9一个交易日内最低价self.low_nine=bt.indicators.Lowest(self.data.low,period=9)#计算rsv值self.rsv=100*bt.DivByZero(self.data_close-self.low_nine,self.high_nine-self.low_nine,zero=None)#计算rsv的3周期加权平均值,即K值self.K=bt.indicators.EMA(self.rsv,period=3,plot=False)#Dvalue=Kvalue3-periodweightedaverageself.D=bt.indicators.EMA(self.K,period=3,plot=False)#J=3*K-2*Dself.J=3*self.K-2*self.D#MACD策略参数me1=EMA(self.data,period=12)me2=EMA(self.data,period=26)self.macd=me1-me2self.signal=EMA(self.macd,period=9)bt.indicators.MACDHisto(self.data)2.2策略买入买入卖出运行上篇文章中提到:#继续部分代码#Python实战合集defnext(self):ifnotself.position:#Buy:基于MACD策略condition1=self.macd[-1]-self.signal[-1]condition2=self.macd[0]-self.signal[0]ifcondition1<0andcondition2>0:self.order=self.buy()else:#卖出:基于KDJ策略condition1=self.J[-1]-self.D[-1]condition2=self.J[0]-self.D[0]ifcondition1>0orcondition2<0:self.order=self.sell()这样我们的策略就构建好了,TestStrategy类到此结束接下来,让策略运行。为了方便回测A股,我们将运行策略部分封装成一个函数,方便回测大量数据:defrun_cerebro(stock_file,result):"""运行策略:paramstock_file:stock数据文件位置:paramresult:回测结果存储变量"""cerebro=bt.Cerebro()cerebro.addstrategy(TestStrategy)#加载数据到模型data=bt.feeds.GenericCSVData(dataname=stock_file,fromdate=datetime.datetime(2010,1,1),todate=datetime.datetime(2020,5,10),dtformat="%Y%m%d",datetime=2,open=3,high=4,low=5,close=6,volume=10、reverse=True,)cerebro.adddata(data)#本金10000,每笔交易100股cerebro.broker.setcash(10000)cerebro.addsizer(bt.sizers.FixedSize,stake=100)#一万零五佣金cerebro.broker.setcommission(commission=0.0005)#运行策略cerebro.run()#剩余本金cerebro.broker.get_value()money_left=cerebro.broker.getvalue()#获取股票名称stock_name=库存文件。split("\\")[-1].split(".csv")[0]#以百分比形式返回最终收益率result[stock_name]=float(money_left-10000)/10000将股票数据文件和一个变量传给这个函数,就可以用这个策略得到股票的整体收益率。这里计算收益率其实是不准确的,因为我们只交易了100股。有些股票其实走势不错,但如果买的太少,投资回报率会很低。有的股票甚至100股的价格都会超过本金,交易无法进行。我们将在下一篇文章中解决这些问题。本文仅考虑此策略在A股的整体盈亏。3、A股回测我们将遍历提取的1000只股票数据,计算本策略对这些股票的投资回报率。我们关注盈利股票的数量和亏损股票的数量。files_path="./thhoudsand_stocks/"result={}#遍历os.listdir(files_path)中stock的所有股票数据:modpath=os.path.dirname(os.path.abspath(sys.argv[0]))datapath=os.path.join(modpath,files_path+stock)print(datapath)try:run_cerebro(datapath,result)exceptExceptionase:print(e)这样每只股票都会运行一次策略,然后将最终的剩余值放入result变量中。然后我们对result变量进行最简单的分析:#calculatepos=[]neg=[]fordatainresult:res=result[data]ifres>0:pos.append(res)else:neg.append(res)print(f'正收益个数:{len(pos)},负收益个数:{len(neg)}')得到的结果如下,部分股票数据不足被放弃:正收益个数:430,负收益个数:568从结果可以看出,如果不考虑基本面而单纯的买入符合这个策略的股票,很可能最后亏本。许多技术投资教科书使用几个上升图来显示这些指标的有用性。其实那些上涨的图形只是假象,只是很多人上当受骗,亏了钱。量化投资就是为了避免这种情况的发生。如果你认为某些技术策略是可靠的,那么你需要进行回测以找出证据。依靠几张上升图表来强调一个指标的好坏是没有说服力的。根据没有证据的技术策略进行投资与赌博没有太大区别。这是我们文章的结尾。如果喜欢我们今天的Python实战教程,请继续关注我们。如果对您有帮助,请在下方点赞/观看。有什么问题可以在下方评论留言,我们会耐心解答!Python实战宝典不只是收藏欢迎关注公众号:Python实战宝典原文来自Python实战宝典:Python量化投资实战教程(五)——A股回测KDJ策略
