策略分析平台

在前两周的工作中,实现了股票价格低于门限值这一策略的event study,即根据门限值来看事件发生前后股票的价格。同时,完成了根据下单的指令来进行回测,计算策略执行期间每一天的价值,以及对投资结果的分析。这一周,要求把这三部分结合起来,能够实现根据门限值直接回测生成过去时间段的下单指令,并进行计算分析。

工具和方法

编程工具

编程语言是python,用到的开源量化分析软件包是QuantSoftware ToolKit,同时用到numpy和datetime等包。

Event Study

Event Study是指对一类事件前后股票的表现进行研究,根据价格变化来确定投资策略。
可以看到,取事件为股票跌破7美元,取事件前后各二十天股票叠加,2012年的SP500指数股票2008到2009年趋势如上图。很显然,当这一类事件发生后,立即买入,5天后卖出,是一种不错的方案。如果更长时间后卖出,方差更大,风险更大。据此,可以确定下单指令:
Date, AAPL, BUY, 100
Date + 5 days, AAPL, SELL, 100

股值计算

这一部分是相对比较简单的,要从csv格式的文件里面读取指令,执行指令,并计算实际交易期间的资产价值,即持有股票的价格和现金之和。下单指令的顺序并不是按照日期排列的,因此计算时要比较小心。
这一部分要将生成的日期和对应价值写入csv文件,如下:
2008,01,03,50000.0
2008,01,04,49893.0
2008,01,07,49875.0
2008,01,08,49846.0
2008,01,09,49801.0
2008,01,10,49844.0
2008,01,11,49844.0
2008,01,14,49844.0

注意,这个文件仅记录最初买入到最后一次卖出期间的价格。下一步进行策略评估也是根据这些数据来做的。

策略评估

这一部分要求根据策略执行期间的资产价值计算总收益率、日均收益率、收益率标准差和Sharp Ratio。
计算日收益率时,第一天为0,以后每日收益率为相对前一天的增值比率。日均和标准差都是根据日收益率来计算的,是最常用的评估指标。Sharp Ratio是日均收益率和标准差之比进行年化得到,用以衡量收益和风险的比例。
按照之前所说的时间期限和策略,各参数如下:
The final value of the portfolio using the sample file is -- 2009,12,28,54824.0Details of the Performance of the portfolioData Range :  2008-01-03 16:00:00  to  2009-12-28 16:00:00Sharpe Ratio of Fund : 0.527865227084
Sharpe Ratio of $SPX : -0.184202673931Total Return of Fund :  1.09648
Total Return of $SPX : 0.779305674563Standard Deviation of Fund :  0.0060854156452
Standard Deviation of $SPX : 0.022004631521Average Daily Return of Fund :  0.000202354576186
Average Daily Return of $SPX : -0.000255334653467

可以看到,与SPX,即标准普尔指数相比,这种投资策略在每个参数上面都有优势,是一种有效的投资策略。

平台实现

平台按照上文提到的功能模块划分为三部分。代码如下:

Event Study实现

这一部分除了对事件进行展示,还要按照之前提到的规则生成下单指令:

#how to work? evalate the command below in order
#execfile('hw4_event.py')
#execfile('hw4_order.py')
#execfile('hw4_anylize.py')#change edge_price to change eventimport pandas as pd
import numpy as np
import math
import copy
import QSTK.qstkutil.qsdateutil as du
import datetime as dt
import QSTK.qstkutil.DataAccess as da
import QSTK.qstkutil.tsutil as tsu
import QSTK.qstkstudy.EventProfiler as epdef find_events(ls_symbols, d_data):''' Finding the event dataframe '''df_close = d_data['actual_close']ts_market = df_close['SPY']print "Finding Events"#events defined hereedge_price=7.0buy_sell_order=''# Creating an empty dataframedf_events = copy.deepcopy(df_close)df_events = df_events * np.NAN# Time stamps for the event rangeldt_timestamps = df_close.indexfor s_sym in ls_symbols:for i in range(1, len(ldt_timestamps)):# Calculating the returns for this timestamp#f_symprice_today = df_close[s_sym].ix[ldt_timestamps[i]]#f_symprice_yest = df_close[s_sym].ix[ldt_timestamps[i - 1]]#f_marketprice_today = ts_market.ix[ldt_timestamps[i]]#f_marketprice_yest = ts_market.ix[ldt_timestamps[i - 1]]#f_symreturn_today = (f_symprice_today / f_symprice_yest) - 1#f_marketreturn_today = (f_marketprice_today / f_marketprice_yest) - 1# Event is found if the symbol is down more then 3% while the# market is up more then 2%#if f_symreturn_today <= -0.03 and f_marketreturn_today >= 0.02:if df_close[s_sym].ix[ldt_timestamps[i-1]]>=edge_price and df_close[s_sym].ix[ldt_timestamps[i]]<edge_price:df_events[s_sym].ix[ldt_timestamps[i]] = 1tmp_time=ldt_timestamps[i]tmp_day=dt.date(tmp_time.year,tmp_time.month,tmp_time.day)buy_sell_order+=str(tmp_day).replace('-',',')+','+s_sym+',Buy,'+str(100)+','if i+5<len(ldt_timestamps):tmp_time=ldt_timestamps[i+5]else:tmp_time=ldt_timestamps[-1]tmp_day=dt.date(tmp_time.year,tmp_time.month,tmp_time.day)buy_sell_order+=str(tmp_day).replace('-',',')+','+s_sym+',Sell,'+str(100)+','order_list=list(buy_sell_order.split(','))del order_list[-1]order_array=np.array(order_list)order_array.resize((order_array.size/6,6))np.savetxt("myorder.csv",order_array,delimiter=',',fmt='%s')return df_eventsif __name__ == '__main__':dt_start = dt.datetime(2008, 1, 1)dt_end = dt.datetime(2009, 12, 31)ldt_timestamps = du.getNYSEdays(dt_start, dt_end, dt.timedelta(hours=16))dataobj = da.DataAccess('Yahoo')ls_symbols = dataobj.get_symbols_from_list('sp5002012')ls_symbols.append('SPY')ls_keys = ['open', 'high', 'low', 'close', 'volume', 'actual_close']ldf_data = dataobj.get_data(ldt_timestamps, ls_symbols, ls_keys)d_data = dict(zip(ls_keys, ldf_data))for s_key in ls_keys:d_data[s_key] = d_data[s_key].fillna(method='ffill')d_data[s_key] = d_data[s_key].fillna(method='bfill')d_data[s_key] = d_data[s_key].fillna(1.0)df_events = find_events(ls_symbols, d_data)print "Creating Study"ep.eventprofiler(df_events, d_data, i_lookback=20, i_lookforward=20,s_filename='eventstudy.pdf', b_market_neutral=True, b_errorbars=True,s_market_sym='SPY')

股值计算

下单指令上一个模块已经生成,据此计算资产价值:

#how to work? evalate the command below in order
#execfile('hw4_event.py')
#execfile('hw4_order.py')
#execfile('hw4_anylize.py')#change currentCash,dt_start,dt_endimport pandas as pd
import numpy as np
import math
import copy
import QSTK.qstkutil.qsdateutil as du
import datetime as dt
import QSTK.qstkutil.DataAccess as da
import QSTK.qstkutil.tsutil as tsu
import QSTK.qstkstudy.EventProfiler as ep#get order
#sys.argv to get comman parameter
na_data = np.loadtxt('myorder.csv',dtype=np.str,delimiter=',')
#dtype={'names':('year','month','day','equity','buorsell','count'),    'formats':('i4','i4','i4','S5','S5','i4')},
na_dates=np.int_(na_data[:,0:3])
order=na_data[:,3:6]
ls_symbols=set(order[:,0])#get equity price
dt_start = dt.datetime(2008, 1, 1)
dt_end = dt.datetime(2009, 12, 31)
ldt_timestamps = du.getNYSEdays(dt_start, dt_end, dt.timedelta(hours=16))dataobj = da.DataAccess('Yahoo')#why close?
#close for Adjusted Close ;actual_close for actual close
ls_keys = 'close'#['open', 'high', 'low', 'close', 'volume', 'actual_close']
ldf_data = dataobj.get_data(ldt_timestamps, ls_symbols, ls_keys)#calc portfolio
currentCash=50000
currentEquity=dict()
byOrSellDict={'Buy':1,'Sell':-1}#dateInd=0
#currentDate=dt.datetime(na_dates[dateInd,0],na_dates[dateInd,1],na_dates[dateInd,2])+dt.timedelta(hours=16)
#orders=[dt.datetime(na_dates[dateInd,0],na_dates[dateInd,1],na_dates[dateInd,2])+dt.timedelta(hours=16),
#    [order[dateInd,0],order[dateInd,1],int(order[dateInd,2])] for dateInd in range(na_data.shape[0])]
orders={}
for dateInd in range(na_data.shape[0]):tmpDate=dt.datetime(na_dates[dateInd,0],na_dates[dateInd,1],na_dates[dateInd,2])+dt.timedelta(hours=16)if tmpDate in orders.keys():orders[tmpDate].append([order[dateInd,0],order[dateInd,1],int(order[dateInd,2])])else:orders[tmpDate]=[[order[dateInd,0],order[dateInd,1],int(order[dateInd,2])]]#calc first and last day of order
order_date_list=list(orders.keys())
order_date_list.sort()
first_day=order_date_list[0]
last_day=order_date_list[-1]values=''
for i in ldt_timestamps:if i<first_day or i>last_day:continueif i in orders.keys():for singleOrder in orders[i]:equity=singleOrder[0]byOrSell=singleOrder[1]count=singleOrder[2]if equity in currentEquity.keys():currentEquity[equity]+=count*byOrSellDict[byOrSell]else:currentEquity[equity]=count*byOrSellDict[byOrSell]currentCash+=-ldf_data[equity][i]*count*byOrSellDict[byOrSell]print '----------------------',i,equity,byOrSell,countprint currentEquity#dateInd+=1#currentDate=dt.datetime(na_dates[dateInd,0],na_dates[dateInd,1],na_dates[dateInd,2])+dt.timedelta(hours=16)#calc portfolia valueportfValue=currentCashfor tmpEqui in currentEquity.keys():portfValue+=ldf_data[tmpEqui][i]*currentEquity[tmpEqui]print i,portfValuevalues+=str(dt.date(i.year,i.month,i.day)).replace('-',',')+','+str(portfValue)+','values_list=list(values.split(','))
del values_list[-1]
values_array=np.array(values_list)
values_array.resize((values_array.size/4,4))
np.savetxt("hw4values.csv",values_array,delimiter=',',fmt='%s')

策略评估

根据上一模块生成了日期--价值文件计算策略的各种指标:

#how to work? evalate the command below in order
#execfile('hw4_event.py')
#execfile('hw4_order.py')
#execfile('hw4_anylize.py')from math import sqrtdate_values = np.loadtxt('hw4values.csv',dtype=np.str,delimiter=',')
values=np.float_(date_values[:,3])total_return=values[-1]/values[0]#dayly_return=values[1:]/values[:-1]-1
dayly_return=tsu.returnize0(values)std=np.std(dayly_return)ave_dayly_ret=np.mean(dayly_return)sharp_ratio=ave_dayly_ret/std*sqrt(252)print 'Total Return of Fund: ',total_return
print 'Standard Deviation of Fund: ',std
print 'Average Daily Return of Fund: ',ave_dayly_ret
print 'Sharpe Ratio of Fund: ',sharp_ratio

平台整合

顺序执行上述三个文件即可得到策略的各种指标,完成策略的回测:
execfile('hw4_event.py')
execfile('hw4_order.py')
execfile('hw4_anylize.py')

佐治亚理工学院 计算投资公开课第六周作业 投资策略分析平台相关推荐

  1. 佐治亚理工学院 计算投资公开课第五周作业 市场仿真器

    Computational Investing, Part I  by Dr. Tucker Balch 这门课的讲授者给出了一个开源的python包QuantSoftware ToolKit,方便教 ...

  2. Martin Odersky Scala编程公开课 第三周作业

    Functional Programming Principles in Scala  by Martin Odersky 这次的作业叫做Object-Oriented Sets.要完成一个完整的类, ...

  3. 佐治亚理工学院计算科学与工程系博士生招生!

    仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:机器之心 佐治亚理工学院计算科学与工程系助理教授 吴安琪 导师简介 吴安琪博士本科毕业于哈尔滨工业大学电子信息工程专业(师从于达仁教授),随后在 ...

  4. 肖臻公开课(六)——比特币中的网络

    本笔记对应北京大学肖臻老师<区块链技术与应用>公开课第六课. 0.前言 在本节课中,肖老师主要讲了比特币的底层网络实现.以计算机网络传统架构来说,比特币网络工作在应用层,底下的网络层是一个 ...

  5. 2019春第六周作业

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 2019春第六周作业 我在这个课程的目标是 掌握指针变量的基本运算:理解指针作为函数参数的作用:掌握如何使用指针实现函数调用返回多个值. ...

  6. 20189221 2018-2019-2 《密码与安全新技术专题》第六周作业

    20189221 2018-2019-2 <密码与安全新技术专题>第六周作业 课程:<密码与安全新技术专题> 班级: 201892 姓名: 郭开世 学号:20189221 上课 ...

  7. Python第六周作业

    Python第六周作业 1. 正则表达式的点星匹配 2. 计算函数曲线与x轴包围的面积 3. 哥德巴赫猜想 4. 鸡兔同笼B 5. 与7无关的数 6. 完美立方数 7. 高次方程求根 8. 在终端输出 ...

  8. 2018-2019-2 20189206 《网络攻防实践》 第六周作业

    2018-2019-2 20189206 <网络攻防实践> 第六周作业 课本学习 TCP/IP网络协议栈攻击 网络安全属性与攻击模式 机密性 保护网络中的信息安全,通常使用加密算法 完整性 ...

  9. 2017-2018-2 20179205 《网络攻防技术与实践》第六周作业

    <网络攻防技术与实践>第六周作业 视频学习总结 一.kali密码攻击之在线工具攻击 密码攻击是安全测试中必不可少的一环,而在线攻击多为对一个服务远程连接并使用用户名与密码破解. 1.cew ...

最新文章

  1. NGOSS的一点简单概念
  2. dac0832控制电机驱动流程图_智能电机驱动器让你的机器人控制更简单
  3. AI让交通管理省时、省心、省力
  4. 函数ZwQuerySystemInformation小结
  5. undo系统参数详解
  6. 【MATLAB教程案例2】GPS信号捕获算法的案例分析
  7. 逆向工程核心原理学习笔记(十三):分析abex' crackme #1 的延伸:将参数压入栈
  8. 二叉树---树的深度递归理解
  9. 福玛特机器人怎么开机_福玛特扫地机器人常见问题故障汇总
  10. 【搞事情】从零开始做一个微信小程序
  11. wordpress php 链接,简介WordPress中用于获取首页和站点链接的PHP函数_PHP
  12. 5月第3周安全回顾 思科路由器Rootkit现身 企业需漏洞管理
  13. 周鸿祎的“流氓”可否借鉴?
  14. 华为USG6000V防火墙的初始密码及修改密码的操作
  15. Python文本特征及分类
  16. 油猴插件的介绍和安装详解脚本的介绍和添加举例
  17. date_sub函数用法-----随笔记
  18. 微信小程序收藏功能实现思路
  19. android10手机运行内存怎么查看,安卓手机怎么查看手机内存
  20. 小白学习MySQL - 不同版本创建用户的些许区别

热门文章

  1. Java中遭遇NaN
  2. C语言实现1~100的和(三种循环)
  3. jsp怎么调用servlet_Servlet简述
  4. 【2020-06-16】CentOS8下yum安装nginx,systemctl start nginx报错undefined symbol: FT_Done_MM_Var
  5. 系统协调服务器,协调网络系统 Collaboration network system
  6. 3d模型多怎么优化_3D打印人像模型是怎么制作出来的呢?
  7. php怎么去除内容,php怎么把html标签去除?
  8. gfs mysql_linux搭建gfs系统--iscsi+GFS实现网络存储
  9. mysql binlog 多少_今天才知道,MySQL 的 binlog 编号可以这么大!
  10. oracle 进入gdsctl,oracle的分析函数over 及开窗函数[转]