# [量化策略］`Sharpe_Momentum` (夏普率动量策略)

## 2. Parameters

1）换仓频率

2）过去表现的周期设定（即设定之前的多少天作为衡量基准）

3）股票池的选取：全部A股？或是弹性更高的中证500？或是流动性最好的上证50？

4）按照过去表现排序后，选择其中哪些股票？（Top 20%？Top 10%？或是中间的一部分？）

## 3. Development

PS：关于夏普率如何计算，可参考笔者的”［量化基础］如何计算夏普率“一文

``````import numpy as np
import pandas as pd

start = '2012-01-01'
end   = '2015-06-01'
benchmark = 'HS300'
universe = set_universe('HS300')
capital_base = 10000000
refresh_rate = 10

def initialize(account):
pass

def handle_data(account):
window = 20  #回望表现周期
history = account.get_attribute_history('closePrice', window+1) #多取一天收盘价，为了计算window个收益率
history = pd.DataFrame(history)
sharpe = {'symbol':[], 'ratio':[]} #设置一个字典
for stk in account.universe:
sharpe['symbol'].append(stk)  #字典中的symbol段 储存股票代码
ret = history[stk].pct_change() #之前讲history转化成DataFrame结构，方便计算
ratio = ret.mean() / ret.std() #夏普率简化为平均收益／收益波动率，也不年化了，反正排序后效果是一致的
sharpe['ratio'].append(ratio)

# 按照过去window日收益率排序，并且选择前20%的股票作为买入候选
sharpe = pd.DataFrame(sharpe).sort(columns = 'ratio').reset_index()
sharpe = sharpe[len(sharpe)*4/5:len(sharpe)]
for stk in account.valid_secpos:
order_to(stk, 0)

# 等权重买入所选股票
portfolio_value = account.referencePortfolioValue

if not np.isnan(account.referencePrice[stk]):

if stk not in account.valid_secpos:
order_to(stk, int(portfolio_value / account.referencePrice[stk] / 100.0 / len(buylist))*100)
``````

## 4. Comparison

``````import numpy as np
import pandas as pd

start = '2012-01-01'
end   = '2015-06-01'
benchmark = 'HS300'
universe = set_universe('HS300')   # 股票池为沪深300
capital_base = 10000000
refresh_rate = 10

def initialize(account):
pass

def handle_data(account):
history = account.get_attribute_history('closePrice', 20)
momentum = {'symbol':[], 'c_ret':[]}
for stk in account.universe:
momentum['symbol'].append(stk)
momentum['c_ret'].append(history[stk][-1]/history[stk][0])

# 按照过去20日收益率排序，并且选择前20%的股票作为买入候选
momentum = pd.DataFrame(momentum).sort(columns='c_ret').reset_index()
momentum = momentum[len(momentum)*4/5:len(momentum)]   # 选择
for stk in account.valid_secpos:
order_to(stk, 0)

# 等权重买入所选股票
portfolio_value = account.referencePortfolioValue

if not np.isnan(account.referencePrice[stk]):

if stk not in account.valid_secpos:
order_to(stk, int(portfolio_value / account.referencePrice[stk] / 100.0 / len(buylist))*100)
``````