一个典型的双均线策略
定义
双均线策略,通过建立m天移动平均线,n天移动平均线,则这两条均线必有交点。若m>n,n天平均线“上穿越”m天均线则为买入点,反之为卖点。该策略基于不同天数均线的交叉点,抓住股票的强势和弱势时刻,进行交易。
对于每一个交易日,都可以计算出前N天的移动平均值,然后把这些移动平均值连起来,成为一条线,就叫做N日移动平均线。一般由5日均线(MA5),10日均线(MA10)
比如前5个交易日的收盘价分别为10,9,9,10,11元,那么,5日的移动平均股价为9.8元。同理,如果下一个交易日的收盘价为12,那么在下一次计算移动平均值的时候,需要计算9,9,10,11,12元的平均值,也就是10.2元。将这平均值连起来,就是均线。
如下图,收盘价是蓝线,橙色的线表示5日的移动平均线。
可以看到股票价格的波动比5天均线的波动要大,这是因为5天均线取的是前5个交易日的均值,相当于做了一个平滑
双均线
股名思义,就是两条天数不同的移动平均线,比如,一天是5日的移动平均线,另一条是10日的移动平均线。如图,蓝色是5天均线,黄色为10日均线
金叉和死叉
由时间短的均线(如上图蓝色的线)在下方向上穿越时间长一点的均线(如上图黄色的线),为金叉,反之为死叉
双均线策略
构建一个简单的策略:认为双均线金叉的时候,表示股票很强势,反之很弱势,那么我们就在强势的时候买入,弱势的时候卖出即可
使用聚宽平台进行代码的编写与回测
# 导入函数库 from jqdata import * # 初始化函数,设定基准等等 def initialize(context): # 设定沪深300作为基准 set_benchmark('000300.XSHG') # 开启动态复权模式(真实价格) set_option('use_real_price', True) # 输出内容到日志 log.info() log.info('初始函数开始运行且全局只运行一次') # 过滤掉order系列API产生的比error级别低的log # log.set_level('order', 'error') ### 股票相关设定 ### # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱 set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock') ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的) # 开盘前运行 run_daily(before_market_open, time='before_open', reference_security='000300.XSHG') # 开盘时运行 run_daily(market_open, time='open', reference_security='000300.XSHG') # 收盘后运行 run_daily(after_market_close, time='after_close', reference_security='000300.XSHG') ## 开盘前运行函数 def before_market_open(context): # 输出运行时间 log.info('函数运行时间(before_market_open):'+str(context.current_dt.time())) # 给微信发送消息(添加模拟交易,并绑定微信生效) # send_message('美好的一天~') # 要操作的股票:万科A股(g.为全局变量) g.security = '000002.XSHE' ## 开盘时运行函数 def market_open(context): log.info('函数运行时间(market_open):'+str(context.current_dt.time())) security = g.security #设置均线窗口长度 n1 = 5 n2 = 10 # 获取股票的收盘价 close_date = attribute_history(security,n2+2,'1d',['close'],df = False) #获取过去ma_n1天的平均价格 ma_n1=close_date['close'][-n1:].mean() #获取过去ma_n2 天的平均价格 ma_n2=close_date['close'][-n2:].mean() #取得当前现金 cash = context.portfolio.available_cash #如果当前有余额,并且n1日均线大于n2日均线 if ma_n1 > ma_n2: #用掉所有cash买入股票 order_value(security,cash) #记录此次买入 log.info("Buying %s" %(security)) #如果n1 日均线小于n2 日均线,并且目前有头寸 elif ma_n1 < ma_n2 and context.portfolio.positions[security].closeable_amount > 0: #全部卖出 order_target(security,0) #记录此次卖出 log.info("Selling %s" %(security)) #绘制n1日均线价格 record(ma_n1 = ma_n1) #绘制n2日均线价格 record(ma_n2 = ma_n2) ## 收盘后运行函数 def after_market_close(context): log.info(str('函数运行时间(after_market_close):'+str(context.current_dt.time()))) #得到当天所有成交记录 trades = get_trades() for _trade in trades.values(): log.info('成交记录:'+str(_trade)) log.info('一天结束') log.info('##############################################################')
可以看出该策略从2016/4/25到2018/4/27收益率27.19,策略年化利率13.14%,最大回撤25.64%