|
在国内一般不支持Long Short Strategy,所以只写了Long Strategy。
收益与风险
源码:
- g.roc_window = 15
- g.n_count = 50
- def initialize(context):
- context.sid1 = "000001.XSHE"
- context.securities = [context.sid1]
- 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[context.sid1].mavg(g.n_count)
-
- cash = context.portfolio.cash
- position = context.portfolio.positions[context.sid1].amount
-
- if roc > 0 and data[context.sid1].price > upper_band and cash > 0 and position < 1:
- print "Long >>>>>>>>>>>>>>>"
- order_target_value(context.sid1, cash)
- elif roc < 0 and data[context.sid1].price < lower_band and cash > 0 and position < 1:
- print "Short >>>>>>>>>>>>>> not supported by Chinese Market"
-
-
- if n_count_mavg > upper_band and data[context.sid1].price <= n_count_mavg and position > 0:
- print "liquidate Long >>>>>>>>>>>>>>>"
- order_target(context.sid1, 0)
- elif n_count_mavg < lower_band and data[context.sid1].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[context.sid1].mavg(20)
- std_dev =data[context.sid1].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[context.sid1][0]
- l_close = h[context.sid1][-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([0]*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[stk]) or account.referencePrice[stk] == 0: # 停牌或是还没有上市等原因不能交易
- continue
- # 计算股票的BOLL线上下轨
- ## 计算MA
- MA = np.mean(hist[stk][-N:])
- ## 计算标准差MD
- MD = np.sqrt((sum(hist[stk][-N:] - MA)**2) / N)
- ## 计算MB、UP、DN线
- MB =np.mean(hist[stk][-(N-1):])
- UP = MB + k * MD
- DN = MB - k * MD
- # 计算股票的ROC
- ROC = float(hist[stk][-1] - hist[stk][-M])/float(hist[stk][-M])
- # 开仓条件
- if (hist[stk][-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[stk]['duration'] = 1
- # 对于持有的股票,若股票不符合平仓条件,则将持仓时间加1,否则卖出,并删除该持仓时间记录
- for stk in account.valid_secpos:
- T = max(E - account.duration.loc[stk]['duration'],10)
- if hist[stk][-1] > np.mean(hist[stk][-T:]):
- account.duration.loc[stk]['duration'] = account.duration.loc[stk]['duration'] + 1
- else:
- order_to(stk,0)
- account.duration.loc[stk]['duration'] = 0
- return
复制代码
|
|