量化交易策略——布林强盗策略
在国内一般不支持Long Short Strategy,所以只写了Long Strategy。收益与风险
源码:
g.roc_window = 15
g.n_count = 50
def initialize(context):
context.sid1 = "000001.XSHE"
context.securities =
set_universe(context.securities)
def handle_data(context, data):
upper_band, mid_band, lower_band, mavg_20 = get_bollinger_band(context, data)
roc = get_roc(context, data, g.roc_window)
n_count_mavg = data.mavg(g.n_count)
cash = context.portfolio.cash
position = context.portfolio.positions.amount
if roc > 0 and data.price > upper_band and cash > 0 and position < 1:
print "Long >>>>>>>>>>>>>>>"
order_target_value(context.sid1, cash)
elif roc < 0 and data.price < lower_band and cash > 0 and position < 1:
print "Short >>>>>>>>>>>>>> not supported by Chinese Market"
if n_count_mavg > upper_band and data.price <= n_count_mavg and position > 0:
print "liquidate Long >>>>>>>>>>>>>>>"
order_target(context.sid1, 0)
elif n_count_mavg < lower_band and data.price >= n_count_mavg and position < 0:
print "liquidate Short >>>>>>>>>>>>>> not supported by Chinese Market"
if position > 1 and g.n_count >10:
g.n_count = g.n_count - 1
elif position < 1:
g.n_count = 50
def get_bollinger_band(context, data):
mavg_20 = data.mavg(20)
std_dev =data.stddev(20, field='price')
upper_band = mavg_20 + 2 * std_dev
mid_band = mavg_20
lower_band = mavg_20 - 2 * std_dev
return upper_band, mid_band, lower_band, mavg_20
def get_roc(context, data, period):
h = history(period, unit='1d', field='close')
period_ago_close = h
l_close = h[-1]
roc = (l_close - period_ago_close) / period_ago_close
return roc
def before_trading_start(context):
pass
def after_trading_end(context):
pass
延伸研究
布林强盗策略(BollingerBandit)的实现
日内策略,要求都是对一组股票或基金进行测试,不重复买入,单只股票最高持仓不超过10%,不过,参数没怎么调。
import numpy as np
import pandas as pd
start = '2015-01-01' # 回测起始时间
end = '2015-11-26' # 回测结束时间
benchmark = 'HS300' # 策略参考标准
universe = set_universe('HS300')# 证券池,支持股票和基金
capital_base = 100000 # 起始资金
#commission = Commission(buycost=0.00025,sellcost=0.00025)# 佣金
freq = 'd' # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 1 # 调仓频率
# 全局参数
## Boll线参数
N = 20
k = 2
## ROC变动率参数
M = 20
## 平仓参数
E = 20
def initialize(account): # 初始化虚拟账户状态
# 持股代码以及持股时间
account.duration = pd.DataFrame(np.array(*len(universe)), index=universe, columns=['duration'])
account.amount = 400
def handle_data(account): # 每个交易日的买入卖出指令
hist = account.get_attribute_history('closePrice',50)
ticker_name = [] # 符合买入要求股票代码
for stk in account.universe: # 遍历股票池内所有股票,选出符合要求的股票
if np.isnan(account.referencePrice) or account.referencePrice == 0:# 停牌或是还没有上市等原因不能交易
continue
# 计算股票的BOLL线上下轨
## 计算MA
MA = np.mean(hist[-N:])
## 计算标准差MD
MD = np.sqrt((sum(hist[-N:] - MA)**2) / N)
## 计算MB、UP、DN线
MB =np.mean(hist[-(N-1):])
UP = MB + k * MD
DN = MB - k * MD
# 计算股票的ROC
ROC = float(hist[-1] - hist[-M])/float(hist[-M])
# 开仓条件
if (hist[-1] > UP) and (ROC > 0):
ticker_name.append(stk)
# 若股票符合开仓条件且尚未持有,则买入
for stk in ticker_name:
if stk not in account.valid_secpos:
order(stk,account.amount)
account.duration.loc['duration'] = 1
# 对于持有的股票,若股票不符合平仓条件,则将持仓时间加1,否则卖出,并删除该持仓时间记录
for stk in account.valid_secpos:
T = max(E - account.duration.loc['duration'],10)
if hist[-1] > np.mean(hist[-T:]):
account.duration.loc['duration'] = account.duration.loc['duration'] + 1
else:
order_to(stk,0)
account.duration.loc['duration'] = 0
return
页:
[1]