策略如下:

回测区间为2016年10月10日至2017年10月13日,选择沪深300进行回测。

记录所有当天5日滑动平均价格高于20日滑动平均价格的股票

将总资金额的一半n/2用于买入股票,每一支股票按照等额购入

买入后的第二天清仓

回测过程:

数据获取(获取股票收盘价stock_price、大盘收盘价benchmark_price以及公司名称stocks):

def getPrice():

stocks_name='沪深300'

start_date='2016-10-01'

end_date='2017-10-13'

fields=['ClosingPx']

#选择沪深300里面所有的股票代码

stocks=index_components(stocks_name)

#正式获取股票价格

stock_price=get_price(stocks,start_date=start_date,end_date=end_date,fields=fields)

#获得沪深300指数

benchmark_name='399300.XSHE'

benchmark_price=get_price(benchmark_name,start_date=start_date,end_date=end_date,fields=fields)

return stock_price,benchmark_price,stocks

这里对沪深300指数解释一下:对样本空间内股票在最近一年(新股为上市以来)的日均成交金额由高到低进行排名,剔除排名在后50%的股票,然后对剩余股票按照日均总市值由高到低进行排名,选取排名在前300名的股票作为指数样本。

数据处理——计算滑动平均数(长短期):

def getRolling(data,shortPeriod,longPeriod):

for i in range(len(data.ix[1])):

col=data.ix[:,i]

name=data.columns[i]

data[name+'_'+str(shortPeriod)+'days']=col.rolling(window=shortPeriod).mean()

data[name+'_'+str(longPeriod)+'days']=col.rolling(window=longPeriod).mean()

return data

主体计算过程:由于每次仅用总资金额的一半即n/2,而且购买后第二天卖出,因此每次购买时资金额都是充足。而且每一支股票投入相同资金,因此直接将所有股票当天收益率取平均作为当天整体的收益率。循环过程从20天滑动平均收盘价开始,第i天作为得到信息的时间,第i+1天购入,第i+2天卖出。

def calculate(data,benchmark_price,stocks):

#初始化累积收益率等

IRR=1

benchmark_revenue=1

victories=0

profits=[]

benchmark_profits=[]

#计算交易的日数

length=0

for i in range(len(data.index)-2):

portfolio=[]

print(data.index[i])

for j,company in enumerate(stocks):

if(data.ix[i,company+'_5days']>data.ix[i,company+'_20days']):

portfolio.append(company)

#如果当天存在出现该信号的公司,则购买

if(portfolio):

length=length+1

#计算策略当日收益率

new=data.ix[i+2,portfolio]/data.ix[i+1,portfolio]

#计算大盘当日收益率

benchmark_new=benchmark_price.ix[i+2]/benchmark_price.ix[i+1]

benchmark_revenue=benchmark_revenue*benchmark_new

data.ix[i+2,'benchmark_profits']=benchmark_revenue

#计算胜率

if(new.mean()>(benchmark_new)):

victories=victories+1

#固定印花说0.1%,手续费0.08%和滑点0.246%

IRR=IRR*(new.mean()-(0.001+0.0008+0.00246))

data.ix[i+2,'profits']=IRR

#如果当天不出现信号,策略的累计收益率不变,大盘的依然要更新

else:

data.ix[i+2,'profits']=data.ix[i+1,'profits']

benchmark_new=benchmark_price.ix[i+2]/benchmark_price.ix[i+1]

benchmark_revenue=benchmark_revenue*benchmark_new

data.ix[i+2,'benchmark_profits']=benchmark_revenue

#计算最大回撤

Max_drawdown=max_drawdown(data['profits'])

#为了便于画图,我先将策略累计收益率和大盘结合

plotData=pd.concat([data['profits'],data['benchmark_profits']],axis=1)

plotData.plot()

#计算夏普率

Sharpo_Ratio=Sharpo(data['profits'],data['benchmark_profits'])

return [IRR,victories/length,Sharpo_Ratio,Max_drawdown]

最大回撤计算:

def max_drawdown(timeseries):

max=-100

for i in np.arange(0,len(timeseries)-1,1):

for j in np.arange(i,len(timeseries),1):

if((timeseries.iloc[i]-timeseries.iloc[j])/timeseries.iloc[j])>max:

max=(timeseries.iloc[i]-timeseries.iloc[j])/timeseries.iloc[j]

return max

夏普率:

def Sharpo(strategy_profits,benchmark_profits):

Sharpo_ratio=(np.mean(strategy_profits)-np.mean(benchmark_profits))/np.std(strategy_profits)

return Sharpo_ratio*np.sqrt(252)

胜率计算:VictoryRatio=日收益率大于大盘的日数\策略真正交易的日数

讲解结束,全部代码如下:

import pandas as pd

import numpy as np

def max_drawdown(timeseries):

max=-100

for i in np.arange(0,len(timeseries)-1,1):

for j in np.arange(i,len(timeseries),1):

if((timeseries.iloc[i]-timeseries.iloc[j])/timeseries.iloc[j])>max:

max=(timeseries.iloc[i]-timeseries.iloc[j])/timeseries.iloc[j]

return max

def Sharpo(strategy_profits,benchmark_profits):

Sharpo_ratio=(np.mean(strategy_profits)-np.mean(benchmark_profits))/np.std(strategy_profits)

return Sharpo_ratio

def getPrice():

stocks_name='沪深300'

start_date='2016-10-01'

end_date='2017-10-13'

fields=['ClosingPx']

#选择沪深300里面所有的股票代码

stocks=index_components(stocks_name)

#正式获取股票价格(不过不知道为什么只能从2016-10-10开始)

stock_price=get_price(stocks,start_date=start_date,end_date=end_date,fields=fields)

#获得沪深300指数(对样本空间内股票在最近一年(新股为上市以来)的日均成交金额由高到低进行排名,剔除排名在后50%的股票,然后对剩余股票按照日均总市值由高到低进行排名,选取排名在前300名的股票作为指数样本。)

benchmark_name='399300.XSHE'

benchmark_price=get_price(benchmark_name,start_date=start_date,end_date=end_date,fields=fields)

return stock_price,benchmark_price,stocks

def getRolling(data,shortPeriod,longPeriod):

for i in range(len(data.ix[1])):

col=data.ix[:,i]

name=data.columns[i]

data[name+'_'+str(shortPeriod)+'days']=col.rolling(window=shortPeriod).mean()

data[name+'_'+str(longPeriod)+'days']=col.rolling(window=longPeriod).mean()

return data

def calculate(data,benchmark_price,stocks):

#初始化累积收益率等

IRR=1

benchmark_revenue=1

victories=0

profits=[]

benchmark_profits=[]

#计算交易的日数

length=0

for i in range(len(data.index)-2):

portfolio=[]

print(data.index[i])

for j,company in enumerate(stocks):

if(data.ix[i,company+'_5days']>data.ix[i,company+'_20days']):

portfolio.append(company)

#如果当天存在出现该信号的公司,则购买

if(portfolio):

length=length+1

#计算策略当日收益率

new=data.ix[i+2,portfolio]/data.ix[i+1,portfolio]

#计算大盘当日收益率

benchmark_new=benchmark_price.ix[i+2]/benchmark_price.ix[i+1]

benchmark_revenue=benchmark_revenue*benchmark_new

data.ix[i+2,'benchmark_profits']=benchmark_revenue

#计算胜率

if(new.mean()>(benchmark_new)):

victories=victories+1

#固定印花说0.1%,手续费0.08%和滑点0.246%

IRR=IRR*(new.mean()-(0.001+0.0008+0.00246))

data.ix[i+2,'profits']=IRR

#如果当天不出现信号,策略的累计收益率不变,大盘的依然要更新

else:

data.ix[i+2,'profits']=data.ix[i+1,'profits']

benchmark_new=benchmark_price.ix[i+2]/benchmark_price.ix[i+1]

benchmark_revenue=benchmark_revenue*benchmark_new

data.ix[i+2,'benchmark_profits']=benchmark_revenue

#计算最大回撤

Max_drawdown=max_drawdown(data['profits'])

#为了便于画图,我先将策略累计收益率和大盘结合

plotData=pd.concat([data['profits'],data['benchmark_profits']],axis=1)

plotData.plot()

#计算夏普率

Sharpo_Ratio=Sharpo(data['profits'],data['benchmark_profits'])

return [IRR,victories/length,Sharpo_Ratio,Max_drawdown]

stock_price,benchmark_price,stocks=getPrice()

stock_price_rolling=getRolling(stock_price,5,20)

IRR,victories,Sharpo_Ratio,Max_drawdown=calculate(stock_price_rolling[19:],benchmark_price[19:],stocks)

print([IRR,victories,Sharpo_Ratio*np.sqrt(252),Max_drawdown])

输出结果为:[0.42318161427509665, 0.5043859649122807, -37.242237755917365, 1.395223166619767]

最后计算得到年化收益率为-57.7%,胜率为50.4%,夏普率为-37.2,最大回撤为139.5%

策略和大盘的累计收益图片:

滑动平均累积收益率(加入交易成本).png

忽略了交易成本,输出结果为:[1.1195674560662801, 0.5043859649122807, -8.8431527706262312, 0.092890344378694187]

最后计算得到年化收益率为11.9%,胜率为50.4%,夏普率为-8.84,最大回撤为9.2%

滑动平均累积收益率(不加入交易成本).png

总结:从不计交易成本的输出结果我们可以看出,最终策略的累积收益率还是跑不赢大盘,策略本身对于累积收益率提升的贡献并不大。同时由于策略交易过于频繁,持有时间过于短暂(一天),每次交易的获益基本都会被交易成本吸收掉,导致累积收益率一路走低。

python量化回测结果分析53课_#滑动平均策略——python回测结果 (中山大学岭南学院量化投资协会)...相关推荐

  1. 2021寒假赋能!Python网络爬虫与文本分析直播课

    Python网络爬虫与文本分析课 在过去的两年间,Python一路高歌猛进,成功窜上"最火编程语言"的宝座.惊奇的是使用Python最多的人群其实不是程序员,而是数据科学家,尤其是 ...

  2. python 趣味编程课_青少年编程:Python趣味编程基础入门课程

    课程目录 章节1:编程课前说明试看 课时1 编程课前说明07:49可试看 章节2:第一章 Python基础-认识环境试看 课时2 1.什么是计算机程序和编程?08:48可试看 课时3 2.为什么学习编 ...

  3. python底层是用什么语言实现的_我为何说Python是全栈式开发语言?

    Python 的排名从去年开始就借助人工智能持续上升,如今它已经成为了第一名.但排在前四名的语言 Python.C.Java 和 C++都拥有广大的用户群体,而且他们的用户总量也十分相近.实际上,Di ...

  4. python 图像分析自然纹理方向与粗细代码_数字图像处理与Python实现笔记之基础知识...

    数字图像处理与Python实现笔记之基础知识 摘要 绪论 1 数字图像处理基础知识 1.1 数字图像简介 1.1.1 数字图像处理的目的 1.1.2 数字图像处理的应用 1.1.3 数字图像处理的特点 ...

  5. python 用if判断一个数是不是整数_五天学会Python基础02(下)

    函数和模块的使用 在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解. 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案.想到这一点问题的答案就呼之 ...

  6. 为什么python打开pygame秒关闭后在运行_当我运行Python程序时,pygame窗口打开片刻,然后退出 - python...

    我是一个刚开始尝试通过在线课程使用python和pygame制作游戏的程序员.但是,当我运行以下代码时,pygame窗口将打开一秒钟,然后关闭. import pygame pygame.init() ...

  7. python是什么和c++是什么区别_编程c++和python的区别

    展开全部 论坛 活动 招聘 专题 打开2113CSDN APP Copyright © 1999-2020, CSDN.NET, All Rights Reserved 登录 一颗日成 关注 浅谈52 ...

  8. 零基础python入门密歇根大学安娜堡分校_零基础:Python入门,看这篇就够了~ 王磊...

    Python在设计上坚持了清晰划一的风格,这使得Python成为一门易读.易维护,并且被大量用户所欢迎的.用途广泛的语言. 设计者开发时总的指导思想是,对于一个特定的问题,只要有一种最好的方法来解决就 ...

  9. python编程快速上手-----让繁琐工作自动化_每周一书《Python编程快速上手 让繁琐工作自动化》分享!...

    内容简介 如今,人们面临的大多数任务都可以通过编写计算机软件来完成.Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.通过Python编程,我们能够解决现实生活中的很多任务. 本书是 ...

最新文章

  1. 读书:有趣 -- 萨摩亚人的成年
  2. MySQL EXPLAIN Extra列的信息
  3. CF1060D Social Circles
  4. 一次性掌握JDK、JRE、JVM的概念以及三者之间的关系【2021整理】
  5. ebp 函数堆栈esp_函数堆栈调用过程
  6. nginx ngx_http_index_module(默认初始页)
  7. 进击的程序媛:毕业于斯坦福,Google 元老级员工,曾任雅虎 CEO | 人物志
  8. 数据分析师必学第一课:构建完整的指标体系
  9. 微信到 Obsidian 2.0
  10. MBA——mba的9堂课
  11. 管理感悟:一种招聘考试的想法
  12. Vuejs路由出现‘login/12/login/12/login/12/test’重复地址的解决办法
  13. Unity Unlit ShaderGraph实现与PBR的自发光贴图类似的叠加效果
  14. 云计算概念及Linux系统详解
  15. 吉大19年9月计算机应用,吉大19年9月《计算机应用基础》作业考核试题(100分)
  16. (石头、剪刀、布)shell脚本,随机对比,case的应用
  17. Bat批处理命令使用教程(完整篇)
  18. 苹果iBook笔记本曝设计缺陷 使用中突然断电
  19. 第一章 管理与管理学 第一节 笔记2018
  20. 新概念英语第二册课文电子版_如何正确使用《新概念英语》(New Concept English)提高英语水平?...

热门文章

  1. eclipse rcp
  2. 达梦数据库安装学习总结--DCA下篇
  3. img使用usemap时快速获取锚点坐标
  4. Python基础操作真题(三)
  5. 编写一个应用程序,利用代理模式,模拟中介和购房者完成房屋购买过程。
  6. Hacking The Box----Awkward
  7. Microsoft Office 2007安装过程及密钥
  8. 用最简单的原理做最不简单的事——电磁流量计
  9. 微信游戏 微信公众号小说的微信域名防封方案
  10. linux上安装php phpredis扩展