量化交易策略——布林强盗策略

0
回复
4749
查看
[复制链接]

196

主题

140

回帖

1444

积分

管理员

积分
1444
来源: 2019-7-18 06:37:53 显示全部楼层 |阅读模式
  在国内一般不支持Long Short Strategy,所以只写了Long Strategy。


收益与风险

190824011.jpg 190824012.jpg 190824013.jpg 190824014.jpg 190824015.jpg cl190824010.jpg


源码:

  1. g.roc_window = 15
  2. g.n_count = 50

  3. def initialize(context):
  4.     context.sid1 = "000001.XSHE"
  5.     context.securities = [context.sid1]
  6.     set_universe(context.securities)

  7. def handle_data(context, data):
  8.    
  9.     upper_band, mid_band, lower_band, mavg_20 = get_bollinger_band(context, data)
  10.     roc = get_roc(context, data, g.roc_window)
  11.     n_count_mavg = data[context.sid1].mavg(g.n_count)
  12.    
  13.     cash = context.portfolio.cash
  14.     position = context.portfolio.positions[context.sid1].amount
  15.    
  16.     if roc > 0 and data[context.sid1].price > upper_band and cash > 0 and position < 1:
  17.         print "Long >>>>>>>>>>>>>>>"
  18.         order_target_value(context.sid1, cash)
  19.     elif roc < 0 and data[context.sid1].price < lower_band and cash > 0 and position < 1:
  20.         print "Short >>>>>>>>>>>>>> not supported by Chinese Market"   
  21.    
  22.    
  23.     if n_count_mavg > upper_band and data[context.sid1].price <= n_count_mavg and position > 0:
  24.         print "liquidate Long >>>>>>>>>>>>>>>"
  25.         order_target(context.sid1, 0)
  26.     elif n_count_mavg < lower_band and data[context.sid1].price >= n_count_mavg and position < 0:
  27.         print "liquidate Short >>>>>>>>>>>>>> not supported by Chinese Market"
  28.         
  29.     if position > 1 and g.n_count >10:   
  30.         g.n_count = g.n_count - 1
  31.     elif position < 1:
  32.         g.n_count = 50
  33.    
  34. def get_bollinger_band(context, data):
  35.     mavg_20 = data[context.sid1].mavg(20)
  36.     std_dev =data[context.sid1].stddev(20, field='price')
  37.    
  38.     upper_band = mavg_20 + 2 * std_dev
  39.     mid_band = mavg_20
  40.     lower_band = mavg_20 - 2 * std_dev
  41.    
  42.     return upper_band, mid_band, lower_band, mavg_20

  43. def get_roc(context, data, period):
  44.     h = history(period, unit='1d', field='close')
  45.     period_ago_close = h[context.sid1][0]
  46.     l_close = h[context.sid1][-1]
  47.    
  48.     roc = (l_close - period_ago_close) / period_ago_close
  49.    
  50.     return roc

  51. def before_trading_start(context):
  52.     pass

  53. def after_trading_end(context):
  54.     pass


  55. 延伸研究

  56. 布林强盗策略(BollingerBandit)的实现

  57. 日内策略,要求都是对一组股票或基金进行测试,不重复买入,单只股票最高持仓不超过10%,不过,参数没怎么调。

  58. import numpy as np
  59. import pandas as pd

  60. start = '2015-01-01'                       # 回测起始时间
  61. end = '2015-11-26'                         # 回测结束时间
  62. benchmark = 'HS300'                        # 策略参考标准
  63. universe = set_universe('HS300')  # 证券池,支持股票和基金
  64. capital_base = 100000                      # 起始资金
  65. #commission = Commission(buycost=0.00025,sellcost=0.00025)  # 佣金
  66. freq = 'd'                                 # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
  67. refresh_rate = 1                           # 调仓频率

  68. # 全局参数
  69. ## Boll线参数
  70. N = 20
  71. k = 2
  72. ## ROC变动率参数
  73. M = 20
  74. ## 平仓参数
  75. E = 20

  76. def initialize(account):                   # 初始化虚拟账户状态
  77.     # 持股代码以及持股时间
  78.     account.duration = pd.DataFrame(np.array([0]*len(universe)), index=universe, columns=['duration'])
  79.     account.amount = 400

  80. def handle_data(account):                  # 每个交易日的买入卖出指令
  81.     hist = account.get_attribute_history('closePrice',50)
  82.     ticker_name = []                       # 符合买入要求股票代码
  83.     for stk in account.universe:           # 遍历股票池内所有股票,选出符合要求的股票   
  84.         if np.isnan(account.referencePrice[stk]) or account.referencePrice[stk] == 0:  # 停牌或是还没有上市等原因不能交易
  85.             continue      

  86.         # 计算股票的BOLL线上下轨
  87.         ## 计算MA
  88.         MA = np.mean(hist[stk][-N:])
  89.         ## 计算标准差MD
  90.         MD = np.sqrt((sum(hist[stk][-N:] - MA)**2) / N)
  91.         ## 计算MB、UP、DN线
  92.         MB =np.mean(hist[stk][-(N-1):])
  93.         UP = MB + k * MD
  94.         DN = MB - k * MD

  95.         # 计算股票的ROC
  96.         ROC = float(hist[stk][-1] - hist[stk][-M])/float(hist[stk][-M])

  97.         # 开仓条件
  98.         if (hist[stk][-1] > UP) and (ROC > 0):
  99.             ticker_name.append(stk)
  100.     # 若股票符合开仓条件且尚未持有,则买入
  101.     for stk in ticker_name:
  102.         if stk not in account.valid_secpos:
  103.             order(stk,account.amount)
  104.             account.duration.loc[stk]['duration'] = 1   
  105.     # 对于持有的股票,若股票不符合平仓条件,则将持仓时间加1,否则卖出,并删除该持仓时间记录
  106.     for stk in account.valid_secpos:
  107.         T = max(E - account.duration.loc[stk]['duration'],10)
  108.         if hist[stk][-1] > np.mean(hist[stk][-T:]):
  109.             account.duration.loc[stk]['duration'] = account.duration.loc[stk]['duration'] + 1
  110.         else:
  111.             order_to(stk,0)
  112.             account.duration.loc[stk]['duration'] = 0      
  113.     return
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 免费注册
关注微信