Simple Bollinger Bands

来源;https://uqer.io/community/share/54b5c1b4f9f06c276f651a15

策略思路: 在一段时间内,股票价格可以认为是在一定水平上下波动。例如,可以简单认为股价在过去100天的平均值基础上,上下波动几个标准差。

策略实现: (1) 股价高于这个波动区间,说明股价虚高,故卖出 (2) 股价低于这个波动区间,说明股价虚低,故买入

PS:本策略适用于股市平稳波动时期,在大牛市或者大熊市不太适用

  1. import quartz
  2. import quartz.backtest as qb
  3. import quartz.performance as qp
  4. from quartz.api import *
  5. import pandas as pd
  6. import numpy as np
  7. from datetime import datetime
  8. from matplotlib import pylab
  9. import talib
  1. start = datetime(2011, 1, 1)
  2. end = datetime(2014, 10, 1)
  3. benchmark = 'HS300'
  4. universe = ['601398.XSHG', '600028.XSHG', '601988.XSHG', '600036.XSHG', '600030.XSHG',
  5. '601318.XSHG', '600000.XSHG', '600019.XSHG', '600519.XSHG', '601166.XSHG']
  6. capital_base = 1000000
  7. refresh_rate = 5
  8. window = 200
  9. def initialize(account):
  10. account.amount = 10000
  11. account.universe = universe
  12. add_history('hist', window)
  13. def handle_data(account):
  14. for stk in account.universe:
  15. prices = account.hist[stk]['closePrice']
  16. if prices is None:
  17. return
  18. mu = prices.mean()
  19. sd = prices.std()
  20. upper = mu + 2*sd
  21. middle = mu
  22. lower = mu - 2*sd
  23. cur_pos = account.position.stkpos.get(stk, 0)
  24. cur_prc = prices[-1]
  25. if cur_prc > upper and cur_pos >= 0:
  26. order_to(stk, 0)
  27. if cur_prc < lower and cur_pos <= 0:
  28. order(stk, account.amount)

Simple Bollinger Bands - 图1

  1. bt
tradeDatecashstock_positionportfolio_valuebenchmark_returnblotter
02011-11-011000000.00000{}1000000.000000.000000[]
12011-11-021000000.00000{}1000000.000000.016629[]
22011-11-031000000.00000{}1000000.000000.000697[]
32011-11-041000000.00000{}1000000.000000.007086[]
42011-11-071000000.00000{}1000000.00000-0.009950[]
52011-11-081000000.00000{}1000000.00000-0.003120[]
62011-11-091000000.00000{}1000000.000000.008778[]
72011-11-101000000.00000{}1000000.00000-0.018922[]
82011-11-111000000.00000{}1000000.00000-0.001699[]
92011-11-141000000.00000{}1000000.000000.020480[]
102011-11-151000000.00000{}1000000.00000-0.002005[]
112011-11-161000000.00000{}1000000.00000-0.027167[]
122011-11-171000000.00000{}1000000.00000-0.003033[]
132011-11-181000000.00000{}1000000.00000-0.020857[]
142011-11-211000000.00000{}1000000.000000.001225[]
152011-11-221000000.00000{}1000000.00000-0.000081[]
162011-11-231000000.00000{}1000000.00000-0.009758[]
172011-11-241000000.00000{}1000000.000000.001898[]
182011-11-251000000.00000{}1000000.00000-0.007317[]
192011-11-281000000.00000{}1000000.000000.001303[]
202011-11-291000000.00000{}1000000.000000.013697[]
212011-11-301000000.00000{}1000000.00000-0.033370[]
222011-12-011000000.00000{}1000000.000000.024625[]
232011-12-021000000.00000{}1000000.00000-0.010180[]
242011-12-051000000.00000{}1000000.00000-0.014048[]
252011-12-061000000.00000{}1000000.00000-0.002000[]
262011-12-071000000.00000{}1000000.000000.004724[]
272011-12-081000000.00000{}1000000.00000-0.001276[]
282011-12-091000000.00000{}1000000.00000-0.008531[]
292011-12-121000000.00000{}1000000.00000-0.010293[]
6792014-08-1996907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1149017.279890.000087[]
6802014-08-2096907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1168551.04989-0.003633[Order({'transact_price': 0.0, 'symbol': '6000…
6812014-08-2196907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1155719.88989-0.005028[]
6822014-08-2296907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1152026.339890.004723[]
6832014-08-2596907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1148250.45989-0.009513[]
6842014-08-2696907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1141866.53989-0.008012[]
6852014-08-2796907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1133729.609890.001507[]
6862014-08-2896907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1130309.43989-0.007010[]
6872014-08-2996907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1144849.979890.011686[]
6882014-09-0196907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1146127.249890.007283[]
6892014-09-0296907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1171994.819890.013222[]
6902014-09-0396907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1186363.069890.009377[Order({'transact_price': 0.0, 'symbol': '6000…
6912014-09-0496907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1188453.829890.007218[]
6922014-09-0596907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1203626.039890.009494[]
6932014-09-0996907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1182303.76989-0.001647[]
6942014-09-1096907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1180321.58989-0.005231[]
6952014-09-1196907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1168537.55989-0.003691[Order({'transact_price': 0.0, 'symbol': '6000…
6962014-09-1296907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1171787.869890.006150[]
6972014-09-1596907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1153269.96989-0.000479[]
6982014-09-1696907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1141194.90989-0.019869[]
6992014-09-1796907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1145778.589890.005258[]
7002014-09-1896907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1152235.309890.003056[]
7012014-09-1996907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1162000.359890.006870[]
7022014-09-2296907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1136441.48989-0.019087[]
7032014-09-2396907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1139988.079890.008635[]
7042014-09-2496907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1157613.469890.017671[]
7052014-09-2596907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1169367.30989-0.002006[]
7062014-09-2696907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1169791.299890.000094[]
7072014-09-2996907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1170503.499890.004349[]
7082014-09-3096907.47989{u'601166.XSHG': 3877.0, u'600036.XSHG': 0, u'…1168692.079890.001303[]
  1. 709 rows × 6 columns
  1. perf = qp.perf_parse(bt)
  2. out_keys = ['annualized_return', 'volatility', 'information',
  3. 'sharpe', 'max_drawdown', 'alpha', 'beta']
  4. for k in out_keys:
  5. print '%s: %s' % (k, perf[k])
  6. annualized_return: 0.0594823977045
  7. volatility: 0.214571802928
  8. information: 0.407163653335
  9. sharpe: 0.102806600884
  10. max_drawdown: 0.36585509048
  11. alpha: 0.052294592526
  12. beta: 0.434097117249
  1. perf['cumulative_return'].plot()
  2. perf['benchmark_cumulative_return'].plot()
  3. pylab.legend(['current_strategy','HS300'])
  4. <matplotlib.legend.Legend at 0x568fe90>

Simple Bollinger Bands - 图2