基础概念金叉和死叉是股票分析中十分常见的技术名词。
金叉是指短期线上穿长期线,且这两根线方向均朝上,则此线组合为『金叉』,反之为『死叉』。
股票交易中,金叉通常为买进信号:短期线带节奏拽着长期线往上,说明短期强势,可以考虑买进。那『金叉买进』之后到底涨的概率为多少呢?涨幅又如何?不妨通过 Python 来算算看。
寻找金叉我们取出过去两年的所有数据,用来计算 MA 的值。然后再取出 2015 年的数据,用于寻找金叉:
%matplotlib inline import tushare as ts import pandas as pd import matplotlib.dates as dates import matplotlib.finance as f import matplotlib.pyplot as plt import datetime all_df = ts.get_h_data('601233',start='2014-01-01',end='2016-03-01') all_df = all_df.sort_index(ascending=True) params = [5, 10, 20, 60] for p in params: all_df['ma'+str(p)] = pd.rolling_mean(all_df['close'], window=p) df = all_df[all_df.index.year == 2015]
|
预处理后的数据大概是这样的:
open |
high |
close |
low |
volume |
amount |
ma5 |
ma10 |
ma20 |
ma60 |
date |
2015-01-05 |
10.64 |
11.10 |
10.98 |
10.34 |
19559160 |
210219728 |
10.916 |
10.405 |
9.3165 |
8.095000 |
2015-01-06 |
10.97 |
11.59 |
10.67 |
10.49 |
39208700 |
431741216 |
10.942 |
10.570 |
9.4515 |
8.153833 |
2015-01-07 |
10.58 |
10.71 |
10.42 |
10.26 |
17181430 |
179871040 |
10.708 |
10.636 |
9.5755 |
8.211667 |
… |
… |
… |
… |
… |
… |
… |
… |
… |
… |
… |
2015-12-30 |
13.37 |
13.54 |
13.42 |
13.31 |
8711024 |
116829360 |
13.816 |
13.699 |
13.8625 |
13.012667 |
2015-12-31 |
13.42 |
13.47 |
13.15 |
13.04 |
16588625 |
218821303 |
13.588 |
13.640 |
13.7710 |
13.066167 |
我们先用 MA5(5日滑动平均) 和 MA10(10日滑动平均) 来寻找金叉。
金叉需要满足一下两个条件:
- 昨日的 MA5 小于昨天的 MA10
- 今天的 MA5 大于今日的 MA10
- 今天的 MA5 大于昨天的 MA5
- 今天的 MA10 大于昨日的 MA10
我们用 pre 临时存储昨日的数据,用 golden_cross 存储金叉的具体数据,方便后面标记,则寻找金叉的代码如下:
pre = None golden_cross = pd.DataFrame() for index, row in df.iterrows(): if not pre is None: if pre['ma5'] < pre['ma10'] and row['ma5'] > row['ma10'] \ and pre['ma5'] < row['ma5'] and pre['ma10'] < row['ma10']: golden_cross = golden_cross.append(row) print index print '昨日MA5 = %s ,昨日MA10 = %s' % (pre['ma5'], pre['ma10'],) print '今日MA5 = %s ,今日MA10 = %s' % (row['ma5'], row['ma10']) print '----------' pre = row
|
运行结果:
2015-01-28 00:00:00 昨日MA5 = 10.258 ,昨日MA10 = 10.264 今日MA5 = 10.386 ,今日MA10 = 10.316 ---------- 2015-02-17 00:00:00 昨日MA5 = 11.564 ,昨日MA10 = 11.671 今日MA5 = 11.692 ,今日MA10 = 11.677 ---------- ... ---------- 2015-11-25 00:00:00 昨日MA5 = 12.97 ,昨日MA10 = 12.999 今日MA5 = 13.434 ,今日MA10 = 13.206 ----------
|
如果希望更直观的表现出金叉,可以用 Pandas 的绘图工具绘制均线,并且将找到的金叉标记出来:
%matplotlib inline fig = plt.figure() ax = fig.add_axes([0, 0, 1, 1]) param_colors = ['y', 'b'] params = [5, 10] for (i,p) in enumerate(params): ax.plot(df.index, df[['ma'+str(p)]], param_colors[i]) ax.plot(golden_cross.index, golden_cross[['ma5']], 'rD') fig.autofmt_xdate()
|
绘图结果如下:
乍一看似乎确实是几个不错的买入时机。我们不妨试一下,如果都在金叉后的一天以开盘价买入,然后在第二天按照开盘价卖出,看看收益如何。
模拟交易『在金叉后的一天以开盘价买入然后在第二天按照开盘价卖出』其实已经是一种量化交易了,我们可以借助一些已有的平台更轻松的完成这个任务。这里我选择的是 RiceQuant ,国内同类型的还有 UQER 和 JoinQuant 可供选择。
现在我们将量化策略设定为:『金叉买入,第二天卖出』。是不是简单粗暴!来看看如果我们按照这个策略在股市中摸爬滚打数年到底是亏了还是赚了。编写代码如下:
import talib import numpy as np import math import pandas # 初始化数据,将初始化变量存储在 context 中 def init(context): context.s1 = "601233.XSHG" context.SHORT_PERIOD = 5 context.LONG_PERIOD = 10 context.fired = False # 该函数每天调用一次 def handle_bar(context, bar_dict): # 获取关注股票的历史价格 prices = history(context.LONG_PERIOD+1,'1d','close')[context.s1].values # 计算短期均线和长期均线 short_ma = talib.SMA(prices,context.SHORT_PERIOD) long_ma = talib.SMA(prices,context.LONG_PERIOD) # 绘制均线 plot("short ma",short_ma[-1]) plot("long ma",long_ma[-1]) # 如果已经买入,则全部卖出 if context.fired == True: logger.info('卖出!') order_target_percent(context.s1, 0) context.fired = False # 金叉则满仓买入 if short_ma[-1]>long_ma[-1] and short_ma[-2]<long_ma[-2] \ and short_ma[-1]>short_ma[-2] and long_ma[-1]>long_ma[-2]: logger.info('买入!') order_percent(context.s1,1) context.fired = True
|
预测一下应该是赚得爽翻天了啊!这可是金叉啊!来看下回测的结果:
回测结果并不是很乐观,总体来看如果按照『金叉买入,第二天卖出』的策略来交易的话,回测收益为 -12.533% 左右。问题出在哪里?看下交易详细:
可以看到,最近的四个回合交易里,两次的卖出价比买入价低,而且就算赚了的,也没赚到多少钱。仔细想一下可能是时间太短,上涨的趋势还没能完全表现出来就卖了。于是调整下策略,在出现金叉后的第10天再卖。代码稍作修改就可以了,看下结果:
从数据上来看要好看很多,对比一下基准收益(沪深300),主要是躲过了六七月的那一波大跌。
基准收益是一个非常有价值的参考信息,因为如果你是在股市全局大涨的情况下,就算是闭着眼睛买进卖出也是赚得,这并不能说明你的量化策略是优秀的。
一个优秀的量化策略有以下几个基本特征:
- 市场中性,与市场关联度低
- 稳定性,高 sharpe 低回撤
- 交易频率应该保持稳定,不长期空仓也不频繁交易
为了更方便观察,可以将交易记录绘制在均线图里,红色标记买入,绿色标记卖出:
从图中可以看到,除了四五月份那次不走运之外,其他几次基本都是赚的。尤其是赶上了五六月份的大涨赚了不少,金叉是一个可以参考的买进信号。
小结我在量化分析方面还是个新手,前面的内容如果有理解错误的地方欢迎指出。今天小试了一下量化分析平台,感觉效果还可以。
当然,优秀的量化策略远比这金叉银叉复杂得多,我也还在慢慢学习中。多多指教。
|