概述
均线最早由美国投资专家 Joseph E.Granville (格兰威尔) 于 20 世纪中期提出. 现在仍然广泛为人们使用, 成为判断买卖信号的一大重要指标. 从统计角度来说, 均线就是历史价格的平均值, 可以代表过去 N 日股价的平均走势.
1 术语
- 多头:短期均线在长期均线上方
- 空头:短期均线在长期均线下方
- 金叉:短期均线向上穿越长期均线
- 死叉:短期均线向下穿越长期均线
- 买出信号:金叉 + 一定的条件
- 卖出出信号:死叉 + 一定的条件
- 双均线:一句话来讲就是金叉买死叉卖。
- 布林带:突破压力线(上轨)清仓,跌破支撑线(下轨)持仓。
- PEG:根据PE/G调整仓位。
- 均值回归:跌下去的要涨,涨上来的要跌(废话。
- 羊驼:随机选股,定期调仓(意外地能赚?)
策略收益(Total Returns)
最容易理解的一个概念,策略收益也就是策略开始到结束,总资产的变化率。
基准收益(Benchmark Returns)
如果一个策略一年赚了50%,而这一年来上证指数上涨了100%,所以要评判一个策略的好坏,
不过是要看它的收益率,还需要一个基准来衡量它的优劣性,这个准基就是准基收益率。
对于股票的策略如果高于上证指数,那么就跑赢了基准收益率,也就是跑赢了大盘;
低于上证指数,那么就是跑输了基准收益率。所以说一个好的策略至少要高于基准收益。
2 计算均线
- 去除缺失值
- 计算短期与长期均线
- 标记短期与长期均线位置关系
# 查看是否有缺失值
print("缺失值个数;", data["close"].isna().sum()) # 缺失值个数为0, 无需去除空值
print(data.head())
# 定义短期平均和长期时间窗口
SMA_1 = 7
SMA_2 = 14
# 计算均线
data['7_day_moving_average'] = data["close"].rolling(SMA_1).mean() # 7 天均线
data['14_day_moving_average'] = data["close"].rolling(SMA_2).mean() # 14 天平均
print(data.tail())
print(data.index)
# 画图
data.plot(figsize=(16, 12))
# 标记黄金交叉和死亡交叉位置
data["Position"] = np.where(data["7_day_moving_average"] > data["14_day_moving_average"], 1, -1)
print(data.head())
# 画图
data.plot(secondary_y='Position',figsize=(16, 12))
# 二 获取pd数据处理
df_ma5 = df['close'].rolling(5).mean() #计算收盘价5日短期移动平均
df_ma60 = df['close'].rolling(60).mean() #计算收盘价60日长期移动平均
df_ma5o = df_ma5['2020-03':'2020-04'] #取2020年3月和2020年4月的数据
df_ma60o = df_ma60['2020-03':'2020-04']
df_org = df['close']['2020-03':'2020-04']
plt.figure(figsize=(15, 8)) #调整图片大小
plt.plot(df_ma5o.index, df_ma5o, label='5 days moving average')
plt.plot(df_ma60o.index, df_ma60o, label='60 days moving average')
plt.plot(df_org.index, df_org, label='price')
plt.xticks(df_ma60o.index[::10], rotation=45)
plt.gcf().subplots_adjust(bottom=0.20)
plt.legend(loc='upper left') #左上加上图例
plt.show()
3 策略实施
- 计算无策略收益
- 计算均线策略收益
# 计算连续增长率
data["Return"] = np.log(data["close"] / data["close"].shift(1))
# 计算策策略增长率
data['Strategy'] = data['Position'].shift(1) * data['Return']
# 去除头部的na值
data = data.iloc[143:] # 统一舍去 6 个月
# 调试输出
print(data.head())
print()
# 计算收益率
original = np.exp(data['Return'].sum()) # 无策略收益率
strategy = np.exp(data['Strategy'].sum()) # 均线策略收益率
print("无策略回报", original)
print("均线策略回报", strategy)
# 画图
data[["Return","Strategy"]].cumsum().apply(np.exp).plot(figsize=(16, 12))
4 均线天数选择
- 遍历不同短期与长期数值
- 选出最好的结果
- 可视化展示
from itertools import product
# 获取数据
data = get_price("002304.XSHE", start_date=start_date, end_date=end_date, fields="close")
data = pd.DataFrame(data, index=data.index)
# 定义长短期
sma_1 = range(3,31,1)
sma_2 = range(10,61,1)
results = pd.DataFrame()
# 笛卡尔积元组
for SMA1,SMA2 in product(sma_1,sma_2):
data2 = data.copy()
# 计算连续增长
data2['Returns'] = np.log(data2["close"] / data2["close"].shift(1))
data2['SMA1'] = data2['close'].rolling(SMA1).mean()
data2['SMA2'] = data2['close'].rolling(SMA2).mean()
# 计算策略值
data2['Position'] = np.where(data2['SMA1'] > data2['SMA2'], 1, -1)
data2['Strategy'] = data2['Position'].shift(1) * data2['Returns']
# 去除头部的na值
data2 = data2.iloc[143:] # 统一舍去前6个月
origional = np.exp(data2['Returns'].sum())
strategy = np.exp(data2['Strategy'].sum())
# 得到结果
results = results.append(pd.DataFrame({'SMA1':SMA1,'SMA2':SMA2,'Returns': origional,'Strategy': strategy,
'Out': strategy - origional},
index=[0]),ignore_index=True)
# 输出结果
print(results.head(15))
# 输出最优结果
SMA1 = 7
SMA2 = 19
row = results["Out"].idxmax() # 最佳值所在行
print(results.iloc[row, :]) # 最佳短期7, 长期19
# 画图
# 计算连续增长
data2['Returns'] = np.log(data2["close"] / data2["close"].shift(1))
data2['SMA1'] = data2['close'].rolling(SMA1).mean()
data2['SMA2'] = data2['close'].rolling(SMA2).mean()
# 计算策略值
data2['Position'] = np.where(data2['SMA1'] > data2['SMA2'], 1, -1)
data2['Strategy'] = data2['Position'].shift(1) * data2['Returns']
# 去除头部的na值
data2 = data2.iloc[143:] # 统一舍去前6个月
origional = np.exp(data2['Returns'].sum())
strategy = np.exp(data2['Strategy'].sum())
# 画图
data2[["Returns","Strategy"]].cumsum().apply(np.exp).plot(figsize=(16, 12))