量化投资 — 简单动量策略(Momentum Strategy)

本文探讨了量化投资中的动量策略,详细介绍了从数据准备到策略开发、可视化,再到策略优化的全过程。重点讨论了参数优化方法,如使用离散Return计算,并探索了如何利用高频数据提升动量策略的效果。
摘要由CSDN通过智能技术生成

动量策略 - Momentum Strategy

0. 引库
import numpy as np
import pandas as pd
import tushare as ts
import matplotlib.pyplot as plt
import seaborn
plt.style.use('seaborn')      
import matplotlib as mpl
%matplotlib inline
mpl.rcParams['font.family'] = 'serif'
import warnings; warnings.simplefilter('ignore')     # 忽略警告信息
1. 数据准备 & 回测准备
# tushare 获取沪深300股票数据
data = ts.get_k_data('hs300', start = '2010-01-01', end='2017-06-30')[['date','close']]
data.rename(columns={'close': 'price'}, inplace=True)
data.set_index('date', inplace = True)
data.head()
price
date
2010-01-043535.229
2010-01-053564.038
2010-01-063541.727
2010-01-073471.456
2010-01-083480.130
2. 策略开发思路
# 计算连续收益率
data['returns'] = np.log(data['price'] / data['price'].shift(1))
data.head()
pricereturns
date
2010-01-043535.229NaN
2010-01-053564.0380.008116
2010-01-063541.727-0.006280
2010-01-073471.456-0.020040
2010-01-083480.1300.002496
# np.sign()符号函数支持向量化
data['position'] = np.sign(data['returns'])     
data.head()
pricereturnsposition
date
2010-01-043535.229NaNNaN
2010-01-053564.0380.0081161.0
2010-01-063541.727-0.006280-1.0
2010-01-073471.456-0.020040-1.0
2010-01-083480.1300.0024961.0
# 计算Momentum策略收益(注意未来函数问题)
data['strategy'] = data['position'].shift(1) * data['returns']  
data.head(10)
pricereturnspositionstrategy
date
2010-01-043535.229NaNNaNNaN
2010-01-053564.0380.0081161.0NaN
2010-01-063541.727-0.006280-1.0-0.006280
2010-01-073471.456-0.020040-1.00.020040
2010-01-083480.1300.0024961.0-0.002496
2010-01-113482.0520.0005521.00.000552
2010-01-123534.9160.0150681.00.015068
2010-01-133421.144-0.032715-1.0-0.032715
2010-01-143469.0510.0139061.0-0.013906
2010-01-153482.7380.0039381.00.003938
3. 策略可视化
# 计算策略最终累计收益
data[['returns', 'strategy']].cumsum().apply(np.exp).plot(figsize=(10, 6))

策略累计收益

4. 策略优化之思路——参数优化和穷举
# 计算5日内平均信号
data['position_5'] = np.sign(data['returns'].rolling(5).mean())
data['strategy_5'] = data['position_5'].shift(1) * data['returns']
data[['returns', 'strategy_5']].dropna().cumsum().apply(np.exp).plot(figsize=(10, 6))

5日内平均信号

参数寻优——使用离散Return计算方法
data['returns_dis'] = data['price'] / data['price'].shift(1) - 1
# 也可这样计算离散收益率:data['returns_dis'] = data['price'].pct_change()
data['returns_dis_cum'] = (data['returns_dis'] + 1).cumprod()
data.head()
pricereturnspositionstrategyposition_5strategy_5returns_disreturns_dis_cum
date
2010-01-043535.229NaNNaNNaNNaNNaNNaNNaN
2010-01-053564.0380.0081161.0NaNNaNNaN0.0081491.008149
2010-01-063541.727-0.006280-1.0-0.006280NaNNaN-0.0062601.001838
2010-01-073471.456-0.020040-1.00.020040NaNNaN-0.0198410.981961
2010-01-083480.1300.0024961.0-0.002496NaNNaN0.0024990.984414
# 建立一个绘制图形的 list
price_plot = ['returns_dis_cum']    
type(price_plot)
list
# 参数寻优(入门方法)
for days in [10,20,30,60]:
    price_plot.append('sty_cumr_%dd' % days)
    data['position_%dd' % days] = np.where(data['returns'].rolling(days).mean()>0, 1, -1)
    data['strategy_%dd' % days] = data['position_%dd' % days].shift(1) * data['returns']
    data['sty_cumr_%dd' % days] = (data['strategy_%dd' % days] + 1).cumprod()
data.head()
pricereturnspositionstrategyposition_5strategy_5returns_disreturns_dis_cumposition_10dstrategy_10dsty_cumr_10dposition_20dstrategy_20dsty_cumr_20dposition_30dstrategy_30dsty_cumr_30dposition_60dstrategy_60dsty_cumr_60d
date
2010-01-043535.229NaNNaNNaNNaNNaNNaNNaN-1NaNNaN-1NaNNaN-1NaNNaN-1NaNNaN
2010-01-053564.0380.0081161.0NaNNaNNaN0.0081491.008149-1-0.0081160.991884-1-0.0081160.991884-1-0.0081160.991884-1-0.0081160.991884
2010-01-063541.727-0.006280-1.0-0.006280NaNNaN-0.0062601.001838-10.0062800.998113-10.0062800.998113-10.0062800.998113-10.0062800.998113
2010-01-073471.456-0.020040-1.00.020040NaNNaN-0.0198410.981961-10.0200401.018115-10.0200401.018115-10.0200401.018115-10.0200401.018115
2010-01-083480.1300.0024961.0-0.002496NaNNaN0.0024990.984414-1-0.0024961.015574-1-0.0024961.015574-1-0.0024961.015574-1-0.0024961.015574
# 查看绘制图形的 list
price_plot
['returns_dis_cum',
 'sty_cumr_10d',
 'sty_cumr_20d',
 'sty_cumr_30d',
 'sty_cumr_60d']
data[price_plot].dropna().plot(
    title='HS300 Multi Parameters Momuntum Strategy',
    figsize=(10, 6), style=['--', '--', '--', '--','--'])

参数寻优绘图

5. 策略优化思路之—— High Frequency Data用于Momentum策略
hs300_hf = ts.get_k_data('hs300', ktype='5')
hs300_hf.head(10)
dateopenclosehighlowvolumeamountturnoverratiocode
02019-03-28 14:553724.823725.073725.683724.423806742.0{}0.0000hs300
12019-03-28 15:003725.073728.403728.403724.902450800.0{}0.0000hs300
22019-03-29 09:353739.773754.433754.513739.7710164739.0{}0.0000hs300
32019-03-29 09:403754.443763.633763.943748.906341654.0{}0.0000hs300
42019-03-29 09:453764.663763.263764.843759.355622416.0{}0.0000hs300
52019-03-29 09:503763.443762.663763.893754.125955572.0{}0.0000hs300
62019-03-29 09:553762.873766.843769.463762.874600542.0{}0.0000hs300
72019-03-29 10:003766.663758.503766.663757.005533989.0{}0.0000hs300
82019-03-29 10:053758.203765.393765.393758.203587029.0{}0.0000hs300
92019-03-29 10:103766.193775.063775.153766.193993704.0{}0.0000hs300
hs300_hf.set_index('date',inplace = True)
hs300_hf.index = hs300_hf.index.to_datetime()
hs300_hf.info()          
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 482 entries, 2019-03-28 14:55:00 to 2019-04-12 15:00:00
Data columns (total 8 columns):
open             482 non-null float64
close            482 non-null float64
high             482 non-null float64
low              482 non-null float64
volume           482 non-null float64
amount           482 non-null object
turnoverratio    482 non-null object
code             482 non-null object
dtypes: float64(5), object(3)
memory usage: 33.9+ KB
# 如果自己实现,请注意具体日期范围,否则可能没有数据
hs300_hf['2019-04-01':'2019-04-02'].head()
openclosehighlowvolumeamountturnoverratiocode
2019-04-01 09:35:003901.173923.723929.063901.1725618175.0{}0.0000hs300
2019-04-01 09:40:003923.723952.363952.743921.9614481548.0{}0.0000hs300
2019-04-01 09:45:003952.363952.943955.063951.2713020862.0{}0.0000hs300
2019-04-01 09:50:003952.943965.553967.123952.9411968217.0{}0.0000hs300
2019-04-01 09:55:003965.553953.473965.553951.809892385.0{}0.0000hs300
hs300_hf['returns'] = np.log(hs300_hf['close'] / hs300_hf['close'].shift(1))
hs300_hf['position'] = np.sign(hs300_hf['returns'].rolling(10).mean()) 
hs300_hf['strategy'] = hs300_hf['position'].shift(1) * hs300_hf['returns']
# 画图
hs300_hf[['returns', 'strategy']].dropna().cumsum().apply(np.exp).plot(figsize=(10, 6), style=['--', '--'])

绘图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值