|
| 1 | +# MyTT 麦语言-通达信-同花顺指标实现 https://github.com/mpquant/MyTT |
| 2 | +# V2.1 2021-6-6 新增 BARSLAST函数 |
| 3 | +# V2.2 2021-6-8 新增 SLOPE,FORCAST线性回归,和回归预测函数 |
| 4 | + |
| 5 | +import numpy as np; import pandas as pd |
| 6 | + |
| 7 | +#------------------ 0级:核心工具函数 -------------------------------------------- |
| 8 | +def RD(N,D=3): return np.round(N,D) #四舍五入取3位小数 |
| 9 | +def RET(S,N=1): return np.array(S)[-N] #返回序列倒数第N个值,默认返回最后一个 |
| 10 | +def ABS(S): return np.abs(S) #返回N的绝对值 |
| 11 | +def MAX(S1,S2): return np.maximum(S1,S2) #序列max |
| 12 | +def MIN(S1,S2): return np.minimum(S1,S2) #序列min |
| 13 | + |
| 14 | +def MA(S,N): #求序列的N日平均值,返回序列 |
| 15 | + return pd.Series(S).rolling(N).mean().values |
| 16 | + |
| 17 | +def REF(S, N=1): #对序列整体下移动N,返回序列(shift后会产生NAN) |
| 18 | + return pd.Series(S).shift(N).values |
| 19 | + |
| 20 | +def DIFF(S, N=1): #前一个值减后一个值,前面会产生nan |
| 21 | + return pd.Series(S).diff(N) #np.diff(S)直接删除nan,会少一行 |
| 22 | + |
| 23 | +def STD(S,N): #求序列的N日标准差,返回序列 |
| 24 | + return pd.Series(S).rolling(N).std(ddof=0).values |
| 25 | + |
| 26 | +def IF(S_BOOL,S_TRUE,S_FALSE): #序列布尔判断 res=S_TRUE if S_BOOL==True else S_FALSE |
| 27 | + return np.where(S_BOOL, S_TRUE, S_FALSE) |
| 28 | + |
| 29 | +def SUM(S, N): #对序列求N天累计和,返回序列 |
| 30 | + return pd.Series(S).rolling(N).sum().values |
| 31 | + |
| 32 | +def HHV(S,N): # HHV(C, 5) # 最近5天收盘最高价 |
| 33 | + return pd.Series(S).rolling(N).max().values |
| 34 | + |
| 35 | +def LLV(S,N): # LLV(C, 5) # 最近5天收盘最低价 |
| 36 | + return pd.Series(S).rolling(N).min().values |
| 37 | + |
| 38 | +def EMA(S,N): #指数移动平均,为了精度 S>4*N EMA至少需要120周期 |
| 39 | + return pd.Series(S).ewm(span=N, adjust=False).mean().values |
| 40 | + |
| 41 | +def SMA(S, N, M=1): #中国式的SMA,至少需要120周期才精确 |
| 42 | + K = pd.Series(S).rolling(N).mean() #先求出平均值 (下面如果有不用循环的办法,能提高性能,望告知) |
| 43 | + for i in range(N+1, len(S)): K[i] = (M * S[i] + (N -M) * K[i-1]) / N # 因为要取K[i-1],所以 range(N+1, len(S)) |
| 44 | + return K |
| 45 | + |
| 46 | +def AVEDEV(S,N): #平均绝对偏差 (序列与其平均值的绝对差的平均值) |
| 47 | + avedev=pd.Series(S).rolling(N).apply(lambda x: (np.abs(x - x.mean())).mean()) |
| 48 | + return avedev.values |
| 49 | + |
| 50 | +def SLOPE(S,N,RS=False): #返S序列N周期回线性回归斜率 (默认只返回斜率,不返回整个直线序列) |
| 51 | + M=pd.Series(S[-N:]); poly = np.polyfit(M.index, M.values,deg=1); Y=np.polyval(poly, M.index); |
| 52 | + if RS: return Y[1]-Y[0],Y |
| 53 | + return Y[1]-Y[0] |
| 54 | + |
| 55 | + |
| 56 | +#------------------ 1级:应用层函数(通过0级核心函数实现) ---------------------------------- |
| 57 | +def COUNT(S_BOOL, N): # COUNT(CLOSE>O, N): 最近N天满足S_BOO的天数 True的天数 |
| 58 | + return SUM(S_BOOL,N) |
| 59 | + |
| 60 | +def EVERY(S_BOOL, N): # EVERY(CLOSE>O, 5) 最近N天是否都是True |
| 61 | + R=SUM(S_BOOL, N) |
| 62 | + return IF(R==N, True, False) |
| 63 | + |
| 64 | +def LAST(S_BOOL, A, B): #从前A日到前B日一直满足S_BOOL条件 |
| 65 | + if A<B: A=B #要求A>B 例:LAST(CLOSE>OPEN,5,3) 5天前到3天前是否都收阳线 |
| 66 | + return S_BOOL[-A:-B].sum()==(A-B) #返回单个布尔值 |
| 67 | + |
| 68 | +def EXIST(S_BOOL, N=5): # EXIST(CLOSE>3010, N=5) n日内是否存在一天大于3000点 |
| 69 | + R=SUM(S_BOOL,N) |
| 70 | + return IF(R>0, True ,False) |
| 71 | + |
| 72 | +def BARSLAST(S_BOOL): #上一次条件成立到当前的周期 |
| 73 | + M=np.argwhere(S_BOOL); # BARSLAST(CLOSE/REF(CLOSE)>=1.1) 上一次涨停到今天的天数 |
| 74 | + return len(S_BOOL)-int(M[-1])-1 if M.size>0 else -1 |
| 75 | + |
| 76 | +def FORCAST(S,N): #返S序列N周期回线性回归后的预测值 |
| 77 | + K,Y=SLOPE(S,N,RS=True) |
| 78 | + return Y[-1]+K |
| 79 | + |
| 80 | +def CROSS(S1,S2): #判断穿越 CROSS(MA(C,5),MA(C,10)) |
| 81 | + CROSS_BOOL=IF(S1>S2, True ,False) |
| 82 | + return COUNT(CROSS_BOOL>0,2)==1 #上穿:昨天0 今天1 下穿:昨天1 今天0 |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | +#------------------ 2级:技术指标函数(全部通过0级,1级函数实现) ------------------------------ |
| 87 | +def MACD(CLOSE,SHORT=12,LONG=26,M=9): # EMA的关系,S取120日,和雪球小数点2位相同 |
| 88 | + DIF = EMA(CLOSE,SHORT)-EMA(CLOSE,LONG); |
| 89 | + DEA = EMA(DIF,M); MACD=(DIF-DEA)*2 |
| 90 | + return RD(DIF),RD(DEA),RD(MACD) |
| 91 | + |
| 92 | +def KDJ(CLOSE,HIGH,LOW, N=9,M1=3,M2=3): # KDJ指标 |
| 93 | + RSV = (CLOSE - LLV(LOW, N)) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 |
| 94 | + K = EMA(RSV, (M1*2-1)); D = EMA(K,(M2*2-1)); J=K*3-D*2 |
| 95 | + return K, D, J |
| 96 | + |
| 97 | +def RSI(CLOSE, N=24): |
| 98 | + DIF = CLOSE-REF(CLOSE,1) |
| 99 | + return RD(SMA(MAX(DIF,0), N) / SMA(ABS(DIF), N) * 100) |
| 100 | + |
| 101 | +def WR(CLOSE, HIGH, LOW, N=10, N1=6): #W&R 威廉指标 |
| 102 | + WR = (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 |
| 103 | + WR1 = (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) * 100 |
| 104 | + return RD(WR), RD(WR1) |
| 105 | + |
| 106 | +def BIAS(CLOSE,L1=6, L2=12, L3=24): # BIAS乖离率 |
| 107 | + BIAS1 = (CLOSE - MA(CLOSE, L1)) / MA(CLOSE, L1) * 100 |
| 108 | + BIAS2 = (CLOSE - MA(CLOSE, L2)) / MA(CLOSE, L2) * 100 |
| 109 | + BIAS3 = (CLOSE - MA(CLOSE, L3)) / MA(CLOSE, L3) * 100 |
| 110 | + return RD(BIAS1), RD(BIAS2), RD(BIAS3) |
| 111 | + |
| 112 | +def BOLL(CLOSE,N=20, P=2): #BOLL指标,布林带 |
| 113 | + MID = MA(CLOSE, N); |
| 114 | + UPPER = MID + STD(CLOSE, N) * P |
| 115 | + LOWER = MID - STD(CLOSE, N) * P |
| 116 | + return RD(UPPER), RD(MID), RD(LOWER) |
| 117 | + |
| 118 | +def PSY(CLOSE,N=12, M=6): |
| 119 | + PSY=COUNT(CLOSE>REF(CLOSE,1),N)/N*100 |
| 120 | + PSYMA=MA(PSY,M) |
| 121 | + return RD(PSY),RD(PSYMA) |
| 122 | + |
| 123 | +def CCI(CLOSE,HIGH,LOW,N=14): |
| 124 | + TP=(HIGH+LOW+CLOSE)/3 |
| 125 | + return (TP-MA(TP,N))/(0.015*AVEDEV(TP,N)) |
| 126 | + |
| 127 | +def ATR(CLOSE,HIGH,LOW, N=20): #真实波动N日平均值 |
| 128 | + TR = MAX(MAX((HIGH - LOW), ABS(REF(CLOSE, 1) - HIGH)), ABS(REF(CLOSE, 1) - LOW)) |
| 129 | + return MA(TR, N) |
| 130 | + |
| 131 | +def BBI(CLOSE,M1=3,M2=6,M3=12,M4=20): #BBI多空指标 |
| 132 | + return (MA(CLOSE,M1)+MA(CLOSE,M2)+MA(CLOSE,M3)+MA(CLOSE,M4))/4 |
| 133 | + |
| 134 | +def DMI(CLOSE,HIGH,LOW,M1=14,M2=6): #动向指标:结果和同花顺,通达信完全一致 |
| 135 | + TR = SUM(MAX(MAX(HIGH - LOW, ABS(HIGH - REF(CLOSE, 1))), ABS(LOW - REF(CLOSE, 1))), M1) |
| 136 | + HD = HIGH - REF(HIGH, 1); LD = REF(LOW, 1) - LOW |
| 137 | + DMP = SUM(IF((HD > 0) & (HD > LD), HD, 0), M1) |
| 138 | + DMM = SUM(IF((LD > 0) & (LD > HD), LD, 0), M1) |
| 139 | + PDI = DMP * 100 / TR; MDI = DMM * 100 / TR |
| 140 | + ADX = MA(ABS(MDI - PDI) / (PDI + MDI) * 100, M2) |
| 141 | + ADXR = (ADX + REF(ADX, M2)) / 2 |
| 142 | + return PDI, MDI, ADX, ADXR |
| 143 | + |
| 144 | +def TAQ(HIGH,LOW,N): #唐安奇通道交易指标,大道至简,能穿越牛熊 |
| 145 | + UP=HHV(HIGH,N); DOWN=LLV(LOW,N); MID=(UP+DOWN)/2 |
| 146 | + return UP,MID,DOWN |
| 147 | + |
| 148 | +def TRIX(CLOSE,M1=12, M2=20): #三重指数平滑平均线 |
| 149 | + TR = EMA(EMA(EMA(CLOSE, M1), M1), M1) |
| 150 | + TRIX = (TR - REF(TR, 1)) / REF(TR, 1) * 100 |
| 151 | + TRMA = MA(TRIX, M2) |
| 152 | + return TRIX, TRMA |
| 153 | + |
| 154 | +def VR(CLOSE,VOL,M1=26): #VR容量比率 |
| 155 | + LC = REF(CLOSE, 1) |
| 156 | + return SUM(IF(CLOSE > LC, VOL, 0), M1) / SUM(IF(CLOSE <= LC, VOL, 0), M1) * 100 |
| 157 | + |
| 158 | +def EMV(HIGH,LOW,VOL,N=14,M=9): #简易波动指标 |
| 159 | + VOLUME=MA(VOL,N)/VOL; MID=100*(HIGH+LOW-REF(HIGH+LOW,1))/(HIGH+LOW) |
| 160 | + EMV=MA(MID*VOLUME*(HIGH-LOW)/MA(HIGH-LOW,N),N); MAEMV=MA(EMV,M) |
| 161 | + return EMV,MAEMV |
| 162 | + |
| 163 | + |
| 164 | +def DPO(CLOSE,M1=20, M2=10, M3=6): #区间震荡线 |
| 165 | + DPO = CLOSE - REF(MA(CLOSE, M1), M2); MADPO = MA(DPO, M3) |
| 166 | + return DPO, MADPO |
| 167 | + |
| 168 | +def BRAR(OPEN,CLOSE,HIGH,LOW,M1=26): #BRAR-ARBR 情绪指标 |
| 169 | + AR = SUM(HIGH - OPEN, M1) / SUM(OPEN - LOW, M1) * 100 |
| 170 | + BR = SUM(MAX(0, HIGH - REF(CLOSE, 1)), M1) / SUM(MAX(0, REF(CLOSE, 1) - LOW), M1) * 100 |
| 171 | + return AR, BR |
| 172 | + |
| 173 | +def DMA(CLOSE,N1=10,N2=50,M=10): #平行线差指标 |
| 174 | + DIF=MA(CLOSE,N1)-MA(CLOSE,N2); DIFMA=MA(DIF,M) |
| 175 | + return DIF,DIFMA |
| 176 | + |
| 177 | +def MTM(CLOSE,N=12,M=6): #动量指标 |
| 178 | + MTM=CLOSE-REF(CLOSE,N); MTMMA=MA(MTM,M) |
| 179 | + return MTM,MTMMA |
| 180 | + |
| 181 | +def ROC(CLOSE,N=12,M=6): #变动率指标 |
| 182 | + ROC=100*(CLOSE-REF(CLOSE,N))/REF(CLOSE,N); MAROC=MA(ROC,M) |
| 183 | + return ROC,MAROC |
| 184 | + |
| 185 | + #望大家能提交更多指标和函数 https://github.com/mpquant/MyTT |
0 commit comments