均线策略和新高策略【被diss版】

标签: 市场
320人阅读 评论(0) 收藏 举报
分类:

基本策略


目录

1 均线策略

1.1 C.J.Neely, P.A.Weller, Technical analysis in the foreign exchange market, Working Paper, Federal Reserve of St.Louis,2011.

1) 策略

2) 收益率回测

1.2 Valeriy Zakamulin, Market timing with moving averages,2017

1) 移动平均的几种类型

I 基本类

i. 简单移动平均 Simple Moving Average(SMA)

ii. 线性移动平均 Linear Moving Average(LMA)

iii. 指数移动平均 Exponential Moving Average(EMA)

II 进阶:平均中的平均 Moving Averages of Moving Averages

i. 三角移动平均 Triangular Moving Average

ii.双/三指数平滑 Double and Triple Exponential Smoothing

III 混合移动平均 Double Exponential Moving Average (DEMA), by Mulloy (1994a)

2) 均线策略

i. 动量法则 Momentum Rule

ii.均线策略 Moving Average Change of Direction Rule

iii. Price Minus Moving Average Rule

iv. 均线交叉 Moving Average Crossover Rule (MAC)

v.多均线策略

vi.均线收敛/发散规则 Moving Average Convergence/Divergence Rule

1.3 Valeriy Zakamulin, A Comprehensive Look at the Empirical Performance of Moving Average Trading Strategies, SSRN, Dec. 11,2015

说明:1.3和1.2基本一致,故略

1.4 F. Papailias, D.D. Thomakos, An improved moving average technical trading rule, Physica A 428(2015),458-469

属于对均线策略的优化,不知这个优化策略是否权威,所以暂时没有复制算法

2 新高策略

George, Hwang, The 52-Week High Momentum Investing, The Journal of Finance,Vol Lix No.5,Oct. 2004

1)指标构建

2)策略构建

3)收益率回测

此文提出的动量策略比较经典,以致后来的许多文献都以此为基础展开分析

  • Ming Liu and Qianqiu Liu (2009),The 52-Week High Momentum Strategy in International Stock Markets
  • Alsubaie and Najand (2008),Trading volume, Price Momentum,and the 52-Week High Momentum Strategy in the Saudi Stock Market

正文

说明:设我们获取到的数据集命名为为df。

1 均线策略

1.1 C.J.Neely, P.A.Weller, Technical analysis in the foreign exchange market, Working Paper, Federal Reserve of St.Louis,2011.

An MA rule compares a short and a long moving average of past prices and generates a buy (sell) signal if the short moving average intersects the long moving average from below (above). For example, one widely used rule, which we write as MA(5, 20), compares a 5-day and a 20-day moving average.

1) 策略

import pandas as pd
import numpy as np
import math


## 均线构建 (参数n为均线构建期间)
def MA(n):
    df['MA'+str(n)] = pd.rolling_mean(df['close'], n)
    print(df.head())

MA(5)  # 5日均线
MA(20) # 20日均线


## 多空信号
lst_signal=[]
df['signal']=df['MA5']-df['MA20']
for i in df['signal']:
    if i>0:
        lst_signal.append(1)   # 多头信号
    else:
        lst_signal.append(0)   # 空头信号

df['signal']=lst_signal

2)收益率回测

# 构建指标z
lst_z=[]
for j in df['signal']:
    if i=1:
        lst_z.append(1)   # 多头信号
    else:
        lst_z.append(-1)   # 空头信号

df['z']=lst_z

# 构建指标R
s_t1=pd.Series(df['close'].values).shift(1)
df['s_t1']=list(s_t1)   # 超前变量的设置,用shift函数
df['R_t1']=df['s_t1']/df['close']*df['i_']/df['i']
df['log_s_t1']=[math.log(i) for i in df['s_t1']]
df['log_s']=[math.log(j) for j in df['close']]
df['log_i_']=[math.log(i+1) for i in df['i_']]
df['log_i']=[math.log(j+1) for j in df['i']]
df['r_t1']=df['log_s_t1']-df['log_s']+df['log_i_']-df['log_i']
r=sum(df['z']*df['r+1'])+ math.log((1-c)/(1+c))    # r为交易期间使用策略获得的累计超额收益

1.2 Valeriy Zakamulin, Market timing with moving averages,2017

很详细的一本文献,详尽地介绍了关于均线的一切。

1) 移动平均的几种类型

I 基本类

i. 简单移动平均 Simple Moving Average(SMA)

# 简单移动平均 SMA
def SMA(n):
    df['SMA'+str(n)] = pd.rolling_mean(df['close'], n)
    print(df.head())

ii. 线性移动平均 Linear Moving Average(LMA)

# 线性移动平均 LMA
def LMA(n):
    LMA=0
    for i in range(5):
        p=pd.Series(df['close'].values).shift(i)
        LMA=(5-i)*p+LMA
        df['LMA'+str(5)]=list(LMA*2/(1+5)/5)

LMA(n)
df.head(10)

iii. 指数移动平均 Exponential Moving Average(EMA)

# 指数移动平均 EMA
def EMA(n):
    df['EMA'+str(n)] = pd.ewma(df['close'], n)
    print(df.head())

II 进阶:平均中的平均 Moving Averages of Moving Averages

i. 三角移动平均 Triangular Moving Average

# 三角移动平均
def TMA(n):
    df['TMA'+str(n)] = pd.rolling_mean(df['SMA'+str(n)], n)
    print(df.head())

ii.双/三指数平滑 Double and Triple Exponential Smoothing

双指数:EMA(EMA(n))

三指数:EMA(EMA(EMA(n)))

# 双指数平均dEMA
def dEMA(n):
    df['dEMA'+str(n)] = pd.ewma(df['EMA'+str(n)], n)
    print(df.head())

# 三指数平均tEMA
def tEMA(n):
    df['tEMA'+str(n)] = pd.ewma(df['dEMA'+str(n)], n)
    print(df.head())    

III 混合移动平均
Double Exponential Moving Average (DEMA), by Mulloy (1994a)

Triple Exponential Moving Average (TEMA), by Mulloy (1994b)

# DEMA
def DEMA(n):
    df['DEMA'+str(n)] = 2*df['EMA'+str(n)] - df['dEMA'+str(n)]
    print(df.head())

# TEMA
def TEMA(n):
    df['TEMA'+str(n)] = 3*df['EMA'+str(n)] - 3*df['dEMA'+str(n)]+df['tEMA'+str(n)] 
    print(df.head())

2) 均线策略

一般说来,策略的形成有两个步骤

step1:At the first step, the value of a technical trading indicator is computed using the past prices including the last closing price

step2:At the second step, the value of the technical indicator is translated into a trading signal.

i. 动量法则 Momentum Rule

信号:当出现连续下跌时,为卖出信号;反之为多头信号。

# 动量指标的构建
def MOM(n):
    close_lag=pd.Series(df['close'].values).shift(1-n) #滞后n-1期
    df['close_lag']=list(close_lag)  
    df['MOM'+str(n)] = df['close'] - df['close_lag']
    print(df.head())

ii.均线策略 Moving Average Change of Direction Rule

信号:连续上涨为多头信号。A Buy signal is generated when the value of a moving average has increased over the last period.

# MACD指标的构建
def MACD(n):
    MA_lag=pd.Series(df['SMA'+str(n)].values).shift(-1) #滞后1期
    df['MA_lag'+str(n)]=list(MA_lag)  
    df['MACD'+str(n)] = df['SMA'+str(n)]-df['MA_lag'+str(n)]
    print(df.head())

iii. Price Minus Moving Average Rule

信号:A Buy signal is generated when the last closing price is above the moving average. Otherwise, if the last closing price is below the moving average, a Sell signal is generated.

# PMA指标的构建 & 与交易信号
def PMA(n):
    df['PMA'+str(n)] = df['close']-df['SMA'+str(n)]
    signal_lst=[]
    for i in df['PMA'+str(n)]:
        if i>0:
            signal_lst.append(1) 
        else:
            signal_lst.append(0)
    df['signal_PMA']=signal_lst # signal变量为1则表示多头信号,signal为零则是空头信号
    print(df.head())

iv. 均线交叉 Moving Average Crossover Rule (MAC)

信号:
多头:when a shorter moving average crosses either above or below a longer moving average (“golden cross”)

# MAC指标的构建 & 与交易信号
def MAC(n,m): 
    df['MAC'+str(n)+'_'+str(m)] = df['MAC'+str(n)]-df['MAC'+str(m)]  # 参数n小于参数m
    signal_lst=[]
    for i in df['MAC'+str(n)+'_'+str(m)]:
        if i>0:
            signal_lst.append(1) 
        else:
            signal_lst.append(0)
    df['signal_MAC']=signal_lst # signal变量为1则表示多头信号,signal为零则是空头信号
    print(df.head())

v.多均线策略

注:文章中并未给出具体规则。

• When all moving averages are moving in the same direction (that is, parallel), the trend is said to be strong because all of them are largely in agreement.

• When moving averages in a ribbon start to converge or diverge, a trend change has already begun to occur.

• When all moving averages converge and fluctuate more than usual, the price moves sideways.

vi.均线收敛/发散规则 Moving Average Convergence/Divergence Rule

信号:
A Buy (Sell) signal is gernerated when MAC increases (decreases).

def delta_MAC(n,m): 
    MAC_lag=pd.Series(df['MAC'+str(n)+'_'+str(m)].values).shift(-1) #滞后1期
    df['MAC_lag'+str(n)+'_'+str(m)]=list(MAC_lag)  
    df['deltaMAC'+str(n)+'_'+str(m)] = df['MAC'+str(n)+'_'+str(m)]-  df['MAC_lag'+str(n)+'_'+str(m)] # 参数n小于参数m
    signal_lst=[]
    for i in df['deltaMAC'+str(n)+'_'+str(m)]:
        if i>0:
            signal_lst.append(1) 
        else:
            signal_lst.append(0)
    df['signal_deltaMAC']=signal_lst # signal变量为1则表示多头信号,signal为零则是空头信号
    print(df.head())

2 新高策略

George, Hwang, The 52-Week High Momentum Investing, The Journal of Finance,Vol Lix No.5,Oct. 2004

主要结论:

  • 基于52周新高的动量策略,比起传统的动量,能帮助投资者获得更大的收益
  • 新高之后并不一定出现长期反转,两者间相互独立

说明:此文提出的基于一年新高的动量策略比较经典,以致后来的许多文献都以此为基础展开分析
比如:

  • Ming Liu and Qianqiu Liu (2009),The 52-Week High Momentum Strategy in International Stock Markets
  • Alsubaie and Najand (2008),Trading volume, Price Momentum,and the 52-Week High Momentum Strategy in the Saudi Stock Market
#设:现在有一张DataFrame,索引是时间(年/月),列变量是A股所有股票的代码,
#行记录是回测期间的个股月收益率。
#(下面用随机数生成了每月股价,目的是方便写代码)


### 创建raw data(随机模拟了100只票,在2012.1.1至2017.1.1期间5年的月价格)

import pandas as pd
import random

# 创建列变量:股票代码
lst_col=[]
j=0
for i in range(100):
    j=j+1
    s=str(j)
    k=s.zfill(6) #仿照股票代码,向左填充0至6位
    lst_col.append(k)

# 创建行记录:个股月价格(利用随机数填充)
lst1=[]
lst2=[]
for i in range(61):   
    for j in range(100):
        lst1.append(random.randint(1, 100))
    lst2.append(lst1)
    lst1=[]

lst_record=lst2

# 生成日期索引(以月为间隔)
time=[]
for i in range(2012,2017):
    s=str(i)
    for m in range(1,13):
        m_=str(m).zfill(2)
        time.append(s+m_)
time.append('201701')     

# 生成raw data的DataFrame
df = pd.DataFrame(lst_record,index=time,columns=lst_col)
df.tail(2)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
000001 000002 000003 000004 000005 000006 000007 000008 000009 000010 000091 000092 000093 000094 000095 000096 000097 000098 000099 000100
201612 71 26 36 32 100 14 42 34 54 82 71 61 90 66 43 72 43 45 9 69
201701 64 7 11 40 4 36 84 8 37 31 72 54 63 64 19 73 28 46 82 42

2 rows × 100 columns

1) 指标构建

选股指标:现价/过去52周最高价 (是一个比率ratio)

P(i,t-1)/HIGH(i,t-1)

说明:令当前时间所在月份为t,ratio中分子处的现价是指第t-1个月末的股价,52周最高价是指从第t-1个月末回溯12个月的这个期间内出现的最高股价。

## 1)指标构建

# 生成前52周最大价格,新建保存在一张df中,命名为newdf
maxp=[] #这个列表储存过去52周(12个月)的最高价格
mp=[] #中转列表,无实际含义
for i in df3.columns[0:100]:
    for j in df3['id'][12:61]: #前12个月没有足够的历史
        l=j-13
        r=j-1
        mp.append(max(df3[str(i)][l:r].values))
    maxp.append(mp)
    mp=[]

newcol=[]    
for i in lst_col:
    newcol.append('max'+str(i))

t_maxp=list(map(list,zip(*maxp))) #将maxp矩阵转置,以适配df的生成
newdf=pd.DataFrame(t_maxp,index=time[12:61],columns=newcol)

# 横向合并表格
df_ind=df[12:61].join(newdf) # 把原始价格表df和含有指标的表newdf合并在一起,命名为df_ind
df_ind.head()

#生成指标
for i in lst_col:
    df_ind['ind_'+str(i)]=df_ind[str(i)]/df_ind['max'+str(i)] #S生成比率指标
df_ind.head()

df_ind=df_ind.iloc[:,200:300]  #删除不需要的中间变量
df_ind.head(2)

.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
ind_000001 ind_000002 ind_000003 ind_000004 ind_000005 ind_000006 ind_000007 ind_000008 ind_000009 ind_000010 ind_000091 ind_000092 ind_000093 ind_000094 ind_000095 ind_000096 ind_000097 ind_000098 ind_000099 ind_000100
201301 0.626506 0.894737 0.744186 1.044444 0.83 0.510204 0.868421 0.717172 0.369565 0.21 0.474747 0.600000 1.129870 0.257732 0.520833 1.034884 0.365591 0.784946 0.204301 0.302083
201302 0.458333 0.463158 0.043011 0.755556 0.48 0.908163 0.631579 0.646465 0.913043 0.53 0.858586 0.642105 0.545455 0.288660 0.406250 0.802326 0.763441 0.129032 0.763441 0.364583

2 rows × 100 columns

2) 策略构建:

  • winner和loser portfolio的识别:

Winner portfolio:ratio排名在top 30%

Loser portfolio:ratio排名在bottom 30%

  • 策略:买入winner组合里的股票,卖出loser组合里的股票,持有6个月
## 2)策略构建——构建winner和loser的股票池

# winner股票池(也即投资者按该策略每月应买入的股票组合)
winner=[]
for i in time[12:61]:
    winner.append(list(df_ind.T.sort_values(str(i)).T.columns)[0:30]) #按行观测值排序

l=[] #l列表是一个中转列表,没有什么实际意义
winner_port=[]
for i in winner:
    for j in i:
        l.append(str(j)[4:10]) #去掉前面的“ind_”字符
    winner_port.append(l) #将所有的top30收益的winner portfolios股票代码保存在winner_port的二维矩阵中
    l=[]



# loser股票池
loser=[]
for i in time[12:61]:
    loser.append(list(df_ind.T.sort_values(str(i),ascending=False).T.columns)[0:30]) #按行观测值排序

l=[] #l列表是一个中转列表,没有什么实际意义
loser_port=[]
for i in loser:
    for j in i:
        l.append(str(j)[4:10]) #去掉前面的“ind_”字符
    loser_port.append(l) #将所有bottom30收益的loser portfolios股票代码保存在loser_port的二维矩阵中
    l=[]
3) 收益回测: 回测期:38年半 1963年7月-2001年12月(在这里中我只用了5年的模拟数据) 每个月投资者都买入一个winner股票池,其收益率的计算是基于前6个月的回报水平,回报水平用简单算术平均来测算
## 3)收益回测

# 用随机数模拟每月收益变量,如:r_000001
lst3=[]
for i in lst_col:
    for j in range(49):
        lst3.append(random.randint(-100, 100)/100) #用随机数模拟收益率
    df_ind['r_'+str(i)]=lst3
    lst3=[]

# 创建持有期(6个月)的收益变量(向前移动平均)
re=[]
rr=[]
df_ind['id']=range(1,50) 
for i in lst_col:
    for j in df_ind['id'][0:43]: #最后6个月的收益无法计算
        l=j+5
        rr.append(sum(df_ind['r_'+str(i)][j:l].values)/6 )
    re.append(rr)
    rr=[]

newcol2=[]    
for i in lst_col:
    newcol2.append('avgr'+str(i))

t_re=list(map(list,zip(*re))) #将re矩阵转置,以适配df的生成
newdf2=pd.DataFrame(t_re,index=time[12:55],columns=newcol2)
newdf2.tail()

# 横向合并表格
dfr=df_ind[0:43].join(newdf2) # 把原始价格表df和含有指标的表newdf合并在一起,命名为df_ind
dfr.head()
df_ind=dfr

df_ind['id']=range(1,44) #生成一个id变量,方便下面写循环

mid=[] #中间列表,无实际用处
ret=[] #收益率列表
int_winner_code=[]  # 将winner组合的股票代码以整数形式保存在列表int_winner_code中

for i in winner_port: #将winner_port这个二维列表转化为一维(实际处理时,可考虑补全所有代码,再删除匹配不到的缺失值)
    for j in i:
        int_winner_code.append(int(j))


# 获得策略的收益结果,保存在list中
for k in df_ind['id']:
    lpara=(k-1)*30
    rpara=k*30 
    for m in int_winner_code[lpara:rpara]: #由于每次购买的组合数均为30个,故可以直接按数字索引,以实现list和dataframe的匹配
        u=k-1
        n=m-1
        mid.append(float(df_ind.iloc[u:k,n:m].values)) #每一次append一个数值,行坐标由id变量值决定,
                                                       #列坐标由代码值->列表中数值->数值又和df中的列向量匹配
    ret.append(mid)  # ret为一个二维列表,外层有49个元素,代表日期月份,内层有30个元素,代表股票数
    mid=[]


# 将结果整理到DataFrame中呈现出来
lst_col2=[]   
for i in range(30):
    lst_col2.append('stock'+str(i+1))

strategy_return = pd.DataFrame(ret,index=time[12:55],columns=lst_col2)
strategy_return.head()
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
stock1 stock2 stock3 stock4 stock5 stock6 stock7 stock8 stock9 stock10 stock21 stock22 stock23 stock24 stock25 stock26 stock27 stock28 stock29 stock30
201301 0.041667 0.047619 0.050000 0.080808 0.109890 0.111111 0.112245 0.120000 0.142857 0.150000 0.275510 0.276316 0.279570 0.302083 0.312500 0.322581 0.325581 0.325843 0.330000 0.340426
201302 0.040816 0.042553 0.043011 0.070588 0.080000 0.084211 0.100000 0.105263 0.129032 0.134021 0.238636 0.240000 0.242424 0.255814 0.257143 0.269663 0.270000 0.288660 0.290000 0.291667
201303 0.013158 0.021053 0.021277 0.030000 0.053763 0.072917 0.090000 0.091837 0.105263 0.106383 0.193878 0.200000 0.210526 0.220000 0.242105 0.247423 0.250000 0.252525 0.261364 0.266667
201304 0.032258 0.046512 0.051020 0.056818 0.058824 0.060000 0.080808 0.090000 0.120000 0.120000 0.242105 0.242424 0.268041 0.276596 0.285714 0.285714 0.297872 0.298969 0.300000 0.301075
201305 0.030612 0.040000 0.041237 0.051020 0.055556 0.070000 0.072917 0.082474 0.142857 0.155556 0.244898 0.256410 0.260000 0.279570 0.290000 0.292929 0.329787 0.340000 0.354167 0.360465

5 rows × 30 columns

查看评论

均线21EMA和55SMA

原文地址:均线21EMA和55SMA作者:心_再出发 此套系统只有均线和MACD,不需要添加其他指标。均线的核心是21EMA和55SMA,MACD参数不需要改变,先晒一张图,看看效果 第一步,...
  • sjpljr
  • sjpljr
  • 2017-04-14 10:11:36
  • 674

短线起爆点(移动均线15种战法)

移动均线是我们投资者最常用的一个指标,但是我们很多投资者经常把参数改来改去的,或者是给自己找支撑位和压力位。在日线上30天线跌破后,等待60日均线是否能支撑或者半年线等等。我在10来年的操作当中总结了...
  • eidolon8
  • eidolon8
  • 2015-11-04 16:39:20
  • 2577

二条均线打天下

将介绍如何使用IT技术,处理金融大数据。在互联网混迹多年,已经熟练掌握一些IT技术。单纯地在互联网做开发,总觉得使劲的方式不对。要想靠技术养活自己,就要把技术变现。通过“跨界”可以寻找新的机会,创造技...
  • robertsong2004
  • robertsong2004
  • 2014-09-11 11:11:50
  • 7667

基于excelVBA的均线策略数据回测工具

  • 2013年11月05日 16:06
  • 79KB
  • 下载

python-双均线预测能力检验2

# -*- coding: utf-8 -*- """ Created on Thu May 25 08:55:12 2017 @author: yunjinqi E-mail:...
  • qq_26948675
  • qq_26948675
  • 2017-06-08 10:23:46
  • 392

新三价线交易策略源码 中长线

新三价线的定义: 新三价线指标,英文全名为Three Line Break(TLB)。史蒂夫·尼森(Steven Nison)在其《非K线判市法》一书中,将新三值线的概念引入到美国。原理是任意三根...
  • eidolon8
  • eidolon8
  • 2015-10-27 23:08:39
  • 705

千投量化体验:采用均线加风控建模(一)

创建模型思路我比较倾向于均线趋势型的模型,因而一开始模型探索主要以均线类指标为主,其他指标辅助:我添加了3个均线突破的入市指标,添加了3个均线突破的出市指标,以及3个趋势型风控,每种类型的指标组合方式...
  • wlzzhcsdn
  • wlzzhcsdn
  • 2017-10-13 14:33:37
  • 415

量化交易 Alpha Algo 1. 简单的双均线策略

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def init(context):     context.st...
  • wzb19940510
  • wzb19940510
  • 2017-04-22 12:36:10
  • 974

python-双均线策略的预测能力研究

做量化,不仅要懂编程,有交易经验,而且要数学和统计学要好。恶补统计理论中,好后悔上统计课的时候做白日梦了。。。。。。。。。。。 下面试着尝试了分析双均线能否产生预测力,我们知道很多回测产生的盈利,有...
  • qq_26948675
  • qq_26948675
  • 2017-06-06 17:33:15
  • 1173

MQL语言 EA代码注解

原文地址:EA代码注解">MQL语言 EA代码注解作者:交易之外在MT4安装后,默认会给用户提供几个例子程序,这些程序对于新学习EA开发过程中有很大的帮助,下面我们就来对MACD Sample这个例子...
  • sjpljr
  • sjpljr
  • 2017-03-16 10:57:24
  • 1403
    个人资料
    持之以恒
    等级:
    访问量: 8591
    积分: 486
    排名: 10万+