失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 量化投资 — 移动平均及双均线策略

量化投资 — 移动平均及双均线策略

时间:2018-07-03 15:08:41

相关推荐

量化投资 — 移动平均及双均线策略

SMA — 移动平均及双均线模型

0. 引库

%matplotlib inlineimport matplotlib.pyplot as pltimport seabornplt.style.use('seaborn') import matplotlib as mplmpl.rcParams['font.family'] = 'serif'# 解决一些字体显示乱码问题import warnings; warnings.simplefilter('ignore') # 忽略警告信息

import numpy as npimport pandas as pdimport tushare as ts

1. 前导知识备习

# 采用 Tushare API 获取中信证券 600030 数据data = ts.get_k_data('600030', start = '-01-01', end='-06-30')

data.head() #DataFrame数据结构

data.set_index('date', inplace = True) #设置索引;替换,真实覆盖;

data.head()

data['SMA_20'] = data['close'].rolling(20).mean()data['SMA_60'] = data['close'].rolling(60).mean()

data.tail()

# 可视化data[['close','SMA_20','SMA_60']].plot(figsize = (10,6))

#计算股票连续收益率 returnsdata['returns'] = np.log(data['close'] / data['close'].shift(1))# 算股票离散收益率方法1data['returns_dis'] = data['close']/data['close'].shift(1) - 1# 算股票连续收益率方法2data['return_dis2'] = data['close'].pct_change()

data.head()

# 核心判断语句(用于依策略确定决策符号)data['position'] = np.where(data['SMA_20'] > data['SMA_60'], 1, -1)# 可视化计算的累计收益率data['returns'].cumsum().apply(np.exp).plot(figsize=(10, 6));

SMA策略

1. 数据准备 & 回测准备

import numpy as npimport pandas as pdimport tushare as ts

# 推荐改用 Tushare新的数据获取接口,不然数据获取有bug;data = ts.get_k_data('hs300', start = '-01-01', end='-06-30')# 把 data转换成为 DataFrame格式data = pd.DataFrame(data)

data.head()

# 用字典对列改名data.rename(columns={'close': 'price'}, inplace=True)data.info()

<class 'pandas.core.frame.DataFrame'>Int64Index: 1819 entries, 0 to 1818Data columns (total 7 columns):date1819 non-null objectopen1819 non-null float64price1819 non-null float64high1819 non-null float64low 1819 non-null float64volume 1819 non-null float64code1819 non-null objectdtypes: float64(5), object(2)memory usage: 113.7+ KB

data.head()

# 设置date项为列,inplace=True进行覆盖操作data.set_index('date', inplace = True)

data.head()

data['SMA_10'] = data['price'].rolling(10).mean()data['SMA_60'] = data['price'].rolling(60).mean()

data.tail()

# 选择多列进行绘制data[['price','SMA_10','SMA_60']].plot(title='HS300 stock price | 10 & 60 days SMAs', figsize=(10, 6));

2. 策略开发思路

data['position'] = np.where(data['SMA_10'] > data['SMA_60'], 1, -1)

data.head()

# 去掉空值,NaNdata.dropna(inplace=True)data['position'].plot(ylim=[-1.1, 1.1], title='Market Positioning');

3. 计算策略年化收益并可视化

data['returns'] = np.log(data['price'] / data['price'].shift(1))

data.head()

# data['returns_dis'] = data['price']/data['price'].shift(1)-1 #离散计算return方法1# data['return_dis2'] = data['price'].pct_change()#离散计算return方法2

# 绘制收益率的直方图data['returns'].hist(bins=35);

# 注意进行 shift(1),用错一般会使得回测收益高估data['strategy'] = data['position'].shift(1) * data['returns']data.head()

# 算总的收益率data[['returns', 'strategy']].sum()

returns0.073386strategy 0.727122dtype: float64

# 测试data[['returns','strategy']].tail()

# 测试data[['returns', 'strategy']].head()

# 对收益率进行累积求和data[['returns', 'strategy']].cumsum().tail()

data[['returns', 'strategy']].sum()

returns0.073386strategy 0.727122dtype: float64

# 计算累积收益率data[['returns', 'strategy']].cumsum().apply(np.exp).tail()

# 可视化data[['returns', 'strategy']].cumsum().apply(np.exp).plot(figsize=(10, 6));

4. 策略收益风险评估

# 计算年化收益率data[['returns', 'strategy']].mean() * 252

returns0.010513strategy 0.104170dtype: float64

# 计算年化风险data[['returns', 'strategy']].std() * 252 ** 0.5

returns0.245468strategy 0.245382dtype: float64

# 计算策略累积收益率data['cumret'] = data['strategy'].cumsum().apply(np.exp)data['cumret'].tail()

date-06-26 2.069846-06-27 2.073587-06-28 2.057477-06-29 2.070263-06-30 2.069118Name: cumret, dtype: float64

# 计算策略累积最大值data['cummax'] = data['cumret'].cummax()data['cummax'].head(6)

date-04-02 NaN-04-06 0.999354-04-07 0.999354-04-08 0.999354-04-09 0.999354-04-12 0.999354Name: cummax, dtype: float64

data.tail()

# 绘制累积收益率和累积最大值data[['cumret', 'cummax']].plot(figsize=(10, 6));

# 算回撤序列drawdown = (data['cummax'] - data['cumret'])

# 算最大回撤drawdown.max()

0.7744165301748813

# 算所有drawdown==0项temp = drawdown[drawdown == 0]temp.head()

date-04-06 0.0-05-06 0.0-05-07 0.0-05-11 0.0-05-17 0.0dtype: float64

temp.index[1:]

Index(['-05-06', '-05-07', '-05-11', '-05-17', '-06-07','-06-29', '-06-30', '-07-01', '-07-05', '-10-15','-10-19', '-10-20', '-10-25', '-11-05', '-11-08','-12-04', '-12-05', '-12-08', '-12-16', '-12-17','-12-19', '-12-22', '-12-26', '-12-29', '-12-30','-12-31', '-01-05', '-01-07', '-03-16', '-03-17','-03-18', '-03-20', '-03-23', '-03-24', '-03-30','-04-01', '-04-02', '-04-03', '-04-07', '-04-08','-04-10', '-04-13', '-04-14', '-04-16', '-04-17','-04-21', '-04-22', '-04-23', '-04-27', '-05-21','-05-22', '-05-25', '-05-26', '-06-05', '-06-08','-07-08', '-08-21', '-08-24', '-08-25', '-08-26'],dtype='object', name='date')

temp.index[:-1]

Index(['-04-06', '-05-06', '-05-07', '-05-11', '-05-17','-06-07', '-06-29', '-06-30', '-07-01', '-07-05','-10-15', '-10-19', '-10-20', '-10-25', '-11-05','-11-08', '-12-04', '-12-05', '-12-08', '-12-16','-12-17', '-12-19', '-12-22', '-12-26', '-12-29','-12-30', '-12-31', '-01-05', '-01-07', '-03-16','-03-17', '-03-18', '-03-20', '-03-23', '-03-24','-03-30', '-04-01', '-04-02', '-04-03', '-04-07','-04-08', '-04-10', '-04-13', '-04-14', '-04-16','-04-17', '-04-21', '-04-22', '-04-23', '-04-27','-05-21', '-05-22', '-05-25', '-05-26', '-06-05','-06-08', '-07-08', '-08-21', '-08-24', '-08-25'],dtype='object', name='date')

temp.index[1:].to_datetime() - temp.index[:-1].to_datetime()

TimedeltaIndex([ '30 days', '1 days', '4 days', '6 days','21 days', '22 days', '1 days', '1 days','4 days', '102 days', '4 days', '1 days','5 days', '11 days', '3 days', '1487 days','1 days', '3 days', '8 days', '1 days','2 days', '3 days', '4 days', '3 days','1 days', '1 days', '5 days', '2 days','68 days', '1 days', '1 days', '2 days','3 days', '1 days', '6 days', '2 days','1 days', '1 days', '4 days', '1 days','2 days', '3 days', '1 days', '2 days','1 days', '4 days', '1 days', '1 days','4 days', '24 days', '1 days', '3 days','1 days', '10 days', '3 days', '30 days','44 days', '3 days', '1 days', '1 days'],dtype='timedelta64[ns]', freq=None)

periods = temp.index[1:].to_datetime() - temp.index[:-1].to_datetime()periods

TimedeltaIndex([ '30 days', '1 days', '4 days', '6 days','21 days', '22 days', '1 days', '1 days','4 days', '102 days', '4 days', '1 days','5 days', '11 days', '3 days', '1487 days','1 days', '3 days', '8 days', '1 days','2 days', '3 days', '4 days', '3 days','1 days', '1 days', '5 days', '2 days','68 days', '1 days', '1 days', '2 days','3 days', '1 days', '6 days', '2 days','1 days', '1 days', '4 days', '1 days','2 days', '3 days', '1 days', '2 days','1 days', '4 days', '1 days', '1 days','4 days', '24 days', '1 days', '3 days','1 days', '10 days', '3 days', '30 days','44 days', '3 days', '1 days', '1 days'],dtype='timedelta64[ns]', freq=None)

# 算持续最长时间periods.max()

Timedelta('1487 days 00:00:00')

5. 策略优化的一种思路

hs300 = ts.get_k_data('hs300','-01-01', '-06-30')[['date','close']]hs300 = pd.DataFrame(hs300) # 一般不用hs300.rename(columns={'close': 'price'}, inplace=True) hs300.set_index('date',inplace = True)hs300.head()

hs300['SMA_10'] = hs300['price'].rolling(10).mean()hs300['SMA_60'] = hs300['price'].rolling(60).mean()hs300[['price', 'SMA_10', 'SMA_60']].tail()

# 绘图hs300[['price', 'SMA_10', 'SMA_60']].plot(grid=True, figsize = (8,6));

# 算10日SMA和60日SMA差值hs300['10-60'] = hs300['SMA_10'] - hs300['SMA_60']hs300['10-60'].tail()

date-06-2698.140500-06-27 103.970333-06-28 112.041000-06-29 122.177167-06-30 133.468667Name: 10-60, dtype: float64

SD = 20 # 设置阈值 hs300['regime'] = np.where(hs300['10-60'] > SD, 1,0)hs300['regime'] = np.where(hs300['10-60'] < -SD, -1,hs300['regime']) # 重要hs300['regime'].value_counts()

1 792-1 7510 276Name: regime, dtype: int64

hs300.tail(20)

hs300['Market'] = np.log(hs300['price']/hs300['price'].shift(1))hs300['Strategy'] = hs300['regime'].shift(1) * hs300['Market']hs300[['Market','Strategy']].cumsum().apply(np.exp).plot(grid=True, figsize = (8,6));

hs300.head()

# 算总收益hs300[['Market', 'Strategy']].sum()

Market0.036541Strategy 0.896131dtype: float64

# 算优化策略年化收益hs300[['Market', 'Strategy']].mean() * 252

Market0.005065Strategy 0.124216dtype: float64

# 算优化策略年化风险hs300[['Market', 'Strategy']].std() * 252 ** 0.5

Market0.244318Strategy 0.235367dtype: float64

如果觉得《量化投资 — 移动平均及双均线策略》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。