├── .gitignore ├── .vscode └── settings.json ├── MyTT.py ├── MyTT_plus.py ├── MyTT_python2.py ├── README.md ├── example1.py ├── hb_hq_api.py └── img ├── boll.png └── taq.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "MicroPython.executeButton": [ 3 | { 4 | "text": "▶", 5 | "tooltip": "运行", 6 | "alignment": "left", 7 | "command": "extension.executeFile", 8 | "priority": 3.5 9 | } 10 | ], 11 | "MicroPython.syncButton": [ 12 | { 13 | "text": "$(sync)", 14 | "tooltip": "同步", 15 | "alignment": "left", 16 | "command": "extension.execute", 17 | "priority": 4 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /MyTT.py: -------------------------------------------------------------------------------- 1 | # MyTT 麦语言-通达信-同花顺指标实现 https://github.com/mpquant/MyTT 2 | # MyTT高级函数验证版本: https://github.com/mpquant/MyTT/blob/main/MyTT_plus.py 3 | # Python2老版本pandas特别的MyTT: https://github.com/mpquant/MyTT/blob/main/MyTT_python2.py 4 | # V2.1 2021-6-6 新增 BARSLAST函数 SLOPE,FORCAST线性回归预测函数 5 | # V2.3 2021-6-13 新增 TRIX,DPO,BRAR,DMA,MTM,MASS,ROC,VR,ASI等指标 6 | # V2.4 2021-6-27 新增 EXPMA,OBV,MFI指标, 改进SMA核心函数(核心函数彻底无循环) 7 | # V2.7 2021-11-21 修正 SLOPE,BARSLAST,函数,新加FILTER,LONGCROSS, 感谢qzhjiang对SLOPE,SMA等函数的指正 8 | # V2.8 2021-11-23 修正 FORCAST,WMA函数,欢迎qzhjiang,stanene,bcq加入社群,一起来完善myTT库 9 | # V2.9 2021-11-29 新增 HHVBARS,LLVBARS,CONST, VALUEWHEN功能函数 10 | # V2.92 2021-11-30 新增 BARSSINCEN函数,现在可以 pip install MyTT 完成安装 11 | # V3.0 2021-12-04 改进 DMA函数支持序列,新增XS2 薛斯通道II指标 12 | # V3.1 2021-12-19 新增 TOPRANGE,LOWRANGE一级函数 13 | # V3.2 2023-04-04 新增 CR指标 14 | # V3.3 2023-11-09 新增 SIN,COS,TAN序列处理的三角函数 15 | 16 | #以下所有函数如无特别说明,输入参数S均为numpy序列或者列表list,N为整型int 17 | #应用层1级函数完美兼容通达信或同花顺,具体使用方法请参考通达信 18 | 19 | import numpy as np; import pandas as pd 20 | 21 | #------------------ 0级:核心工具函数 -------------------------------------------- 22 | def RD(N,D=3): return np.round(N,D) #四舍五入取3位小数 23 | def RET(S,N=1): return np.array(S)[-N] #返回序列倒数第N个值,默认返回最后一个 24 | def ABS(S): return np.abs(S) #返回N的绝对值 25 | def LN(S): return np.log(S) #求底是e的自然对数, 26 | def POW(S,N): return np.power(S,N) #求S的N次方 27 | def SQRT(S): return np.sqrt(S) #求S的平方根 28 | def SIN(S): return np.sin(S) #求S的正弦值(弧度) 29 | def COS(S): return np.cos(S) #求S的余弦值(弧度) 30 | def TAN(S): return np.tan(S) #求S的正切值(弧度) 31 | def MAX(S1,S2): return np.maximum(S1,S2) #序列max 32 | def MIN(S1,S2): return np.minimum(S1,S2) #序列min 33 | def IF(S,A,B): return np.where(S,A,B) #序列布尔判断 return=A if S==True else B 34 | 35 | 36 | def REF(S, N=1): #对序列整体下移动N,返回序列(shift后会产生NAN) 37 | return pd.Series(S).shift(N).values 38 | 39 | def DIFF(S, N=1): #前一个值减后一个值,前面会产生nan 40 | return pd.Series(S).diff(N).values #np.diff(S)直接删除nan,会少一行 41 | 42 | def STD(S,N): #求序列的N日标准差,返回序列 43 | return pd.Series(S).rolling(N).std(ddof=0).values 44 | 45 | def SUM(S, N): #对序列求N天累计和,返回序列 N=0对序列所有依次求和 46 | return pd.Series(S).rolling(N).sum().values if N>0 else pd.Series(S).cumsum().values 47 | 48 | def CONST(S): #返回序列S最后的值组成常量序列 49 | return np.full(len(S),S[-1]) 50 | 51 | def HHV(S,N): #HHV(C, 5) 最近5天收盘最高价 52 | return pd.Series(S).rolling(N).max().values 53 | 54 | def LLV(S,N): #LLV(C, 5) 最近5天收盘最低价 55 | return pd.Series(S).rolling(N).min().values 56 | 57 | def HHVBARS(S,N): #求N周期内S最高值到当前周期数, 返回序列 58 | return pd.Series(S).rolling(N).apply(lambda x: np.argmax(x[::-1]),raw=True).values 59 | 60 | def LLVBARS(S,N): #求N周期内S最低值到当前周期数, 返回序列 61 | return pd.Series(S).rolling(N).apply(lambda x: np.argmin(x[::-1]),raw=True).values 62 | 63 | def MA(S,N): #求序列的N日简单移动平均值,返回序列 64 | return pd.Series(S).rolling(N).mean().values 65 | 66 | def EMA(S,N): #指数移动平均,为了精度 S>4*N EMA至少需要120周期 alpha=2/(span+1) 67 | return pd.Series(S).ewm(span=N, adjust=False).mean().values 68 | 69 | def SMA(S, N, M=1): #中国式的SMA,至少需要120周期才精确 (雪球180周期) alpha=1/(1+com) 70 | return pd.Series(S).ewm(alpha=M/N,adjust=False).mean().values #com=N-M/M 71 | 72 | def WMA(S, N): #通达信S序列的N日加权移动平均 Yn = (1*X1+2*X2+3*X3+...+n*Xn)/(1+2+3+...+Xn) 73 | return pd.Series(S).rolling(N).apply(lambda x:x[::-1].cumsum().sum()*2/N/(N+1),raw=True).values 74 | 75 | def DMA(S, A): #求S的动态移动平均,A作平滑因子,必须 0B & A>0 & B>=0 91 | return np.array(pd.Series(S).rolling(A+1).apply(lambda x:np.all(x[::-1][B:]),raw=True),dtype=bool) 92 | 93 | #------------------ 1级:应用层函数(通过0级核心函数实现)使用方法请参考通达信-------------------------------- 94 | def COUNT(S, N): # COUNT(CLOSE>O, N): 最近N天满足S_BOO的天数 True的天数 95 | return SUM(S,N) 96 | 97 | def EVERY(S, N): # EVERY(CLOSE>O, 5) 最近N天是否都是True 98 | return IF(SUM(S,N)==N,True,False) 99 | 100 | def EXIST(S, N): # EXIST(CLOSE>3010, N=5) n日内是否存在一天大于3000点 101 | return IF(SUM(S,N)>0,True,False) 102 | 103 | def FILTER(S, N): # FILTER函数,S满足条件后,将其后N周期内的数据置为0, FILTER(C==H,5) 104 | for i in range(len(S)): S[i+1:i+1+N]=0 if S[i] else S[i+1:i+1+N] 105 | return S # 例:FILTER(C==H,5) 涨停后,后5天不再发出信号 106 | 107 | def BARSLAST(S): #上一次条件成立到当前的周期, BARSLAST(C/REF(C,1)>=1.1) 上一次涨停到今天的天数 108 | M=np.concatenate(([0],np.where(S,1,0))) 109 | for i in range(1, len(M)): M[i]=0 if M[i] else M[i-1]+1 110 | return M[1:] 111 | 112 | def BARSLASTCOUNT(S): # 统计连续满足S条件的周期数 by jqz1226 113 | rt = np.zeros(len(S)+1) # BARSLASTCOUNT(CLOSE>OPEN)表示统计连续收阳的周期数 114 | for i in range(len(S)): rt[i+1]=rt[i]+1 if S[i] else rt[i+1] 115 | return rt[1:] 116 | 117 | def BARSSINCEN(S, N): # N周期内第一次S条件成立到现在的周期数,N为常量 by jqz1226 118 | return pd.Series(S).rolling(N).apply(lambda x:N-1-np.argmax(x) if np.argmax(x) or x[0] else 0,raw=True).fillna(0).values.astype(int) 119 | 120 | def CROSS(S1, S2): # 判断向上金叉穿越 CROSS(MA(C,5),MA(C,10)) 判断向下死叉穿越 CROSS(MA(C,10),MA(C,5)) 121 | return np.concatenate(([False], np.logical_not((S1>S2)[:-1]) & (S1>S2)[1:])) # 不使用0级函数,移植方便 by jqz1226 122 | 123 | def LONGCROSS(S1,S2,N): # 两条线维持一定周期后交叉,S1在N周期内都小于S2,本周期从S1下方向上穿过S2时返回1,否则返回0 124 | return np.array(np.logical_and(LAST(S1S2)),dtype=bool) # N=1时等同于CROSS(S1, S2) 125 | 126 | def VALUEWHEN(S, X): # 当S条件成立时,取X的当前值,否则取VALUEWHEN的上个成立时的X值 by jqz1226 127 | return pd.Series(np.where(S,X,np.nan)).ffill().values 128 | 129 | def BETWEEN(S, A, B): # S处于A和B之间时为真。 包括 AS>B 130 | return ((AS) & (S>B)) 131 | 132 | def TOPRANGE(S): # TOPRANGE(HIGH)表示当前最高价是近多少周期内最高价的最大值 by jqz1226 133 | rt = np.zeros(len(S)) 134 | for i in range(1,len(S)): rt[i] = np.argmin(np.flipud(S[:i]S[i])) 140 | return rt.astype('int') 141 | 142 | 143 | #------------------ 2级:技术指标函数(全部通过0级,1级函数实现) ------------------------------ 144 | def MACD(CLOSE,SHORT=12,LONG=26,M=9): # EMA的关系,S取120日,和雪球小数点2位相同 145 | DIF = EMA(CLOSE,SHORT)-EMA(CLOSE,LONG); 146 | DEA = EMA(DIF,M); MACD=(DIF-DEA)*2 147 | return RD(DIF),RD(DEA),RD(MACD) 148 | 149 | def KDJ(CLOSE,HIGH,LOW, N=9,M1=3,M2=3): # KDJ指标 150 | RSV = (CLOSE - LLV(LOW, N)) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 151 | K = EMA(RSV, (M1*2-1)); D = EMA(K,(M2*2-1)); J=K*3-D*2 152 | return K, D, J 153 | 154 | def RSI(CLOSE, N=24): # RSI指标,和通达信小数点2位相同 155 | DIF = CLOSE-REF(CLOSE,1) 156 | return RD(SMA(MAX(DIF,0), N) / SMA(ABS(DIF), N) * 100) 157 | 158 | def WR(CLOSE, HIGH, LOW, N=10, N1=6): #W&R 威廉指标 159 | WR = (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 160 | WR1 = (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) * 100 161 | return RD(WR), RD(WR1) 162 | 163 | def BIAS(CLOSE,L1=6, L2=12, L3=24): # BIAS乖离率 164 | BIAS1 = (CLOSE - MA(CLOSE, L1)) / MA(CLOSE, L1) * 100 165 | BIAS2 = (CLOSE - MA(CLOSE, L2)) / MA(CLOSE, L2) * 100 166 | BIAS3 = (CLOSE - MA(CLOSE, L3)) / MA(CLOSE, L3) * 100 167 | return RD(BIAS1), RD(BIAS2), RD(BIAS3) 168 | 169 | def BOLL(CLOSE,N=20, P=2): #BOLL指标,布林带 170 | MID = MA(CLOSE, N); 171 | UPPER = MID + STD(CLOSE, N) * P 172 | LOWER = MID - STD(CLOSE, N) * P 173 | return RD(UPPER), RD(MID), RD(LOWER) 174 | 175 | def PSY(CLOSE,N=12, M=6): 176 | PSY=COUNT(CLOSE>REF(CLOSE,1),N)/N*100 177 | PSYMA=MA(PSY,M) 178 | return RD(PSY),RD(PSYMA) 179 | 180 | def CCI(CLOSE,HIGH,LOW,N=14): 181 | TP=(HIGH+LOW+CLOSE)/3 182 | return (TP-MA(TP,N))/(0.015*AVEDEV(TP,N)) 183 | 184 | def ATR(CLOSE,HIGH,LOW, N=20): #真实波动N日平均值 185 | TR = MAX(MAX((HIGH - LOW), ABS(REF(CLOSE, 1) - HIGH)), ABS(REF(CLOSE, 1) - LOW)) 186 | return MA(TR, N) 187 | 188 | def BBI(CLOSE,M1=3,M2=6,M3=12,M4=20): #BBI多空指标 189 | return (MA(CLOSE,M1)+MA(CLOSE,M2)+MA(CLOSE,M3)+MA(CLOSE,M4))/4 190 | 191 | def DMI(CLOSE,HIGH,LOW,M1=14,M2=6): #动向指标:结果和同花顺,通达信完全一致 192 | TR = SUM(MAX(MAX(HIGH - LOW, ABS(HIGH - REF(CLOSE, 1))), ABS(LOW - REF(CLOSE, 1))), M1) 193 | HD = HIGH - REF(HIGH, 1); LD = REF(LOW, 1) - LOW 194 | DMP = SUM(IF((HD > 0) & (HD > LD), HD, 0), M1) 195 | DMM = SUM(IF((LD > 0) & (LD > HD), LD, 0), M1) 196 | PDI = DMP * 100 / TR; MDI = DMM * 100 / TR 197 | ADX = MA(ABS(MDI - PDI) / (PDI + MDI) * 100, M2) 198 | ADXR = (ADX + REF(ADX, M2)) / 2 199 | return PDI, MDI, ADX, ADXR 200 | 201 | def TAQ(HIGH,LOW,N): #唐安奇通道(海龟)交易指标,大道至简,能穿越牛熊 202 | UP=HHV(HIGH,N); DOWN=LLV(LOW,N); MID=(UP+DOWN)/2 203 | return UP,MID,DOWN 204 | 205 | def KTN(CLOSE,HIGH,LOW,N=20,M=10): #肯特纳交易通道, N选20日,ATR选10日 206 | MID=EMA((HIGH+LOW+CLOSE)/3,N) 207 | ATRN=ATR(CLOSE,HIGH,LOW,M) 208 | UPPER=MID+2*ATRN; LOWER=MID-2*ATRN 209 | return UPPER,MID,LOWER 210 | 211 | def TRIX(CLOSE,M1=12, M2=20): #三重指数平滑平均线 212 | TR = EMA(EMA(EMA(CLOSE, M1), M1), M1) 213 | TRIX = (TR - REF(TR, 1)) / REF(TR, 1) * 100 214 | TRMA = MA(TRIX, M2) 215 | return TRIX, TRMA 216 | 217 | def VR(CLOSE,VOL,M1=26): #VR容量比率 218 | LC = REF(CLOSE, 1) 219 | return SUM(IF(CLOSE > LC, VOL, 0), M1) / SUM(IF(CLOSE <= LC, VOL, 0), M1) * 100 220 | 221 | def CR(CLOSE,HIGH,LOW,N=20): #CR价格动量指标 222 | MID=REF(HIGH+LOW+CLOSE,1)/3; 223 | return SUM(MAX(0,HIGH-MID),N)/SUM(MAX(0,MID-LOW),N)*100 224 | 225 | def EMV(HIGH,LOW,VOL,N=14,M=9): #简易波动指标 226 | VOLUME=MA(VOL,N)/VOL; MID=100*(HIGH+LOW-REF(HIGH+LOW,1))/(HIGH+LOW) 227 | EMV=MA(MID*VOLUME*(HIGH-LOW)/MA(HIGH-LOW,N),N); MAEMV=MA(EMV,M) 228 | return EMV,MAEMV 229 | 230 | 231 | def DPO(CLOSE,M1=20, M2=10, M3=6): #区间震荡线 232 | DPO = CLOSE - REF(MA(CLOSE, M1), M2); MADPO = MA(DPO, M3) 233 | return DPO, MADPO 234 | 235 | def BRAR(OPEN,CLOSE,HIGH,LOW,M1=26): #BRAR-ARBR 情绪指标 236 | AR = SUM(HIGH - OPEN, M1) / SUM(OPEN - LOW, M1) * 100 237 | BR = SUM(MAX(0, HIGH - REF(CLOSE, 1)), M1) / SUM(MAX(0, REF(CLOSE, 1) - LOW), M1) * 100 238 | return AR, BR 239 | 240 | def DFMA(CLOSE,N1=10,N2=50,M=10): #平行线差指标 241 | DIF=MA(CLOSE,N1)-MA(CLOSE,N2); DIFMA=MA(DIF,M) #通达信指标叫DMA 同花顺叫新DMA 242 | return DIF,DIFMA 243 | 244 | def MTM(CLOSE,N=12,M=6): #动量指标 245 | MTM=CLOSE-REF(CLOSE,N); MTMMA=MA(MTM,M) 246 | return MTM,MTMMA 247 | 248 | def MASS(HIGH,LOW,N1=9,N2=25,M=6): #梅斯线 249 | MASS=SUM(MA(HIGH-LOW,N1)/MA(MA(HIGH-LOW,N1),N1),N2) 250 | MA_MASS=MA(MASS,M) 251 | return MASS,MA_MASS 252 | 253 | def ROC(CLOSE,N=12,M=6): #变动率指标 254 | ROC=100*(CLOSE-REF(CLOSE,N))/REF(CLOSE,N); MAROC=MA(ROC,M) 255 | return ROC,MAROC 256 | 257 | def EXPMA(CLOSE,N1=12,N2=50): #EMA指数平均数指标 258 | return EMA(CLOSE,N1),EMA(CLOSE,N2); 259 | 260 | def OBV(CLOSE,VOL): #能量潮指标 261 | return SUM(IF(CLOSE>REF(CLOSE,1),VOL,IF(CLOSEREF(TYP,1),TYP*VOL,0),N)/SUM(IF(TYPBB) & (AA>CC),AA+BB/2+DD/4,IF( (BB>CC) & (BB>AA),BB+AA/2+DD/4,CC+DD/4)); 272 | X=(CLOSE-LC+(CLOSE-OPEN)/2+LC-REF(OPEN,1)); 273 | SI=16*X/R*MAX(AA,BB); ASI=SUM(SI,M1); ASIT=MA(ASI,M2); 274 | return ASI,ASIT 275 | 276 | def XSII(CLOSE, HIGH, LOW, N=102, M=7): #薛斯通道II 277 | AA = MA((2*CLOSE + HIGH + LOW)/4, 5) #最新版DMA才支持 2021-12-4 278 | TD1 = AA*N/100; TD2 = AA*(200-N) / 100 279 | CC = ABS((2*CLOSE + HIGH + LOW)/4 - MA(CLOSE,20))/MA(CLOSE,20) 280 | DD = DMA(CLOSE,CC); TD3=(1+M/100)*DD; TD4=(1-M/100)*DD 281 | return TD1, TD2, TD3, TD4 282 | 283 | 284 | #望大家能提交更多指标和函数 https://github.com/mpquant/MyTT 285 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /MyTT_plus.py: -------------------------------------------------------------------------------- 1 | # MyTT 麦语言-通达信-同花顺指标实现 https://github.com/mpquant/MyTT 2 | # 高级函数版本,本文件函数计算结果经过验证完全正确,可以正常使用,但代码比较复杂,做为进阶使用。 3 | # MyTT团队对每个函数精益求精,力争效率速度,代码优雅的完美统一,如果您有更好的实现方案,请不吝赐教! 4 | # 感谢以下团队成员的努力和贡献: 火焰,jqz1226, stanene, bcq 5 | 6 | #------------------------工具函数--------------------------------------------- 7 | 8 | def HHV(S, N): #HHV,支持N为序列版本 9 | # type: (np.ndarray, Optional[int,float, np.ndarray]) -> np.ndarray 10 | """ 11 | HHV(C, 5) # 最近5天收盘最高价 12 | """ 13 | if isinstance(N, (int, float)): 14 | return pd.Series(S).rolling(N).max().values 15 | else: 16 | res = np.repeat(np.nan, len(S)) 17 | for i in range(len(S)): 18 | if (not np.isnan(N[i])) and N[i] <= i + 1: 19 | res[i] = S[i + 1 - N[i]:i + 1].max() 20 | return res 21 | 22 | 23 | def LLV(S, N): #LLV,支持N为序列版本 24 | # type: (np.ndarray, Optional[int,float, np.ndarray]) -> np.ndarray 25 | """ 26 | LLV(C, 5) # 最近5天收盘最低价 27 | """ 28 | if isinstance(N, (int, float)): 29 | return pd.Series(S).rolling(N).min().values 30 | else: 31 | res = np.repeat(np.nan, len(S)) 32 | for i in range(len(S)): 33 | if (not np.isnan(N[i])) and N[i] <= i + 1: 34 | res[i] = S[i + 1 - N[i]:i + 1].min() 35 | return res 36 | 37 | 38 | def DSMA(X, N): # 偏差自适应移动平均线 type: (np.ndarray, int) -> np.ndarray 39 | """ 40 | Deviation Scaled Moving Average (DSMA) Python by: jqz1226, 2021-12-27 41 | Referred function from myTT: SUM, DMA 42 | """ 43 | a1 = math.exp(- 1.414 * math.pi * 2 / N) 44 | b1 = 2 * a1 * math.cos(1.414 * math.pi * 2 / N) 45 | c2 = b1 46 | c3 = -a1 * a1 47 | c1 = 1 - c2 - c3 48 | Zeros = np.pad(X[2:] - X[:-2],(2,0),'constant') 49 | Filt = np.zeros(len(X)) 50 | for i in range(len(X)): 51 | Filt[i] = c1 * (Zeros[i] + Zeros[i-1]) / 2 + c2 * Filt[i-1] + c3 * Filt[i-2] 52 | 53 | RMS = np.sqrt(SUM(np.square(Filt), N) / N) 54 | ScaledFilt = Filt / RMS 55 | alpha1 = np.abs(ScaledFilt) * 5 / N 56 | return DMA(X, alpha1) 57 | 58 | 59 | 60 | def SUMBARSFAST(X, A): 61 | # type: (np.ndarray, Optional[np.ndarray, float, int]) -> np.ndarray 62 | """ 63 | 通达信SumBars函数的Python实现 by jqz1226 64 | SumBars函数将X向前累加,直到大于等于A, 返回这个区间的周期数。例如SUMBARS(VOL, CAPITAL),求完全换手的周期数。 65 | :param X: 数组。被累计的源数据。 源数组中不能有小于0的元素。 66 | :param A: 数组(一组)或者浮点数(一个)或者整数(一个),累加截止的界限数 67 | :return: 数组。各K线分别对应的周期数 68 | """ 69 | if any(X<=0): raise ValueError('数组X的每个元素都必须大于0!') 70 | 71 | X = np.flipud(X) # 倒转 72 | length = len(X) 73 | 74 | if isinstance(A * 1.0, float): A = np.repeat(A, length) # 是单值则转化为数组 75 | A = np.flipud(A) # 倒转 76 | sumbars = np.zeros(length) # 初始化sumbars为0 77 | Sigma = np.insert(np.cumsum(X), 0, 0.0) # 在累加值前面插入一个0.0(元素变多1个,便于引用) 78 | 79 | for i in range(length): 80 | k = np.searchsorted(Sigma[i + 1:], A[i] + Sigma[i]) 81 | if k < length - i: # 找到 82 | sumbars[length - i - 1] = k + 1 83 | return sumbars.astype(int) 84 | 85 | 86 | 87 | 88 | #------------------------指标函数--------------------------------------------- 89 | 90 | def SAR(HIGH, LOW, N=10, S=2, M=20): 91 | """ 92 | 求抛物转向。 例如SAR(10,2,20)表示计算10日抛物转向,步长为2%,步长极限为20% 93 | Created by: jqz1226, 2021-11-24首次发表于聚宽(www.joinquant.com) 94 | 95 | :param HIGH: high序列 96 | :param LOW: low序列 97 | :param N: 计算周期 98 | :param S: 步长 99 | :param M: 步长极限 100 | :return: 抛物转向 101 | """ 102 | f_step = S / 100; f_max = M / 100; af = 0.0 103 | is_long = HIGH[N - 1] > HIGH[N - 2] 104 | b_first = True 105 | length = len(HIGH) 106 | 107 | s_hhv = REF(HHV(HIGH, N), 1) # type: np.ndarray 108 | s_llv = REF(LLV(LOW, N), 1) # type: np.ndarray 109 | sar_x = np.repeat(np.nan, length) # type: np.ndarray 110 | for i in range(N, length): 111 | if b_first: # 第一步 112 | af = f_step 113 | sar_x[i] = s_llv[i] if is_long else s_hhv[i] 114 | b_first = False 115 | else: # 继续多 或者 空 116 | ep = s_hhv[i] if is_long else s_llv[i] # 极值 117 | if (is_long and HIGH[i] > ep) or ((not is_long) and LOW[i] < ep): # 顺势:多创新高 或者 空创新低 118 | af = min(af + f_step, f_max) 119 | # 120 | sar_x[i] = sar_x[i - 1] + af * (ep - sar_x[i - 1]) 121 | 122 | if (is_long and LOW[i] < sar_x[i]) or ((not is_long) and HIGH[i] > sar_x[i]): # 反空 或者 反多 123 | is_long = not is_long 124 | b_first = True 125 | return sar_x 126 | 127 | 128 | def TDX_SAR(High, Low, iAFStep=2, iAFLimit=20): # type: (np.ndarray, np.ndarray, int, int) -> np.ndarray 129 | """ 通达信SAR算法,和通达信SAR对比完全一致 by: jqz1226, 2021-12-18 130 | :param High: 最高价序列 131 | :param Low: 最低价序列 132 | :param iAFStep: AF步长 133 | :param iAFLimit: AF极限值 134 | :return: SAR序列 135 | """ 136 | af_step = iAFStep / 100; af_limit = iAFLimit / 100 137 | SarX = np.zeros(len(High)) # 初始化返回数组 138 | 139 | # 第一个bar 140 | bull = True 141 | af = af_step 142 | ep = High[0] 143 | SarX[0] = Low[0] 144 | # 第2个bar及其以后 145 | for i in range(1, len(High)): 146 | # 1.更新:hv, lv, af, ep 147 | if bull: # 多 148 | if High[i] > ep: # 创新高 149 | ep = High[i] 150 | af = min(af + af_step, af_limit) 151 | else: # 空 152 | if Low[i] < ep: # 创新低 153 | ep = Low[i] 154 | af = min(af + af_step, af_limit) 155 | # 2.计算SarX 156 | SarX[i] = SarX[i - 1] + af * (ep - SarX[i - 1]) 157 | 158 | # 3.修正SarX 159 | if bull: 160 | SarX[i] = max(SarX[i - 1], min(SarX[i], Low[i], Low[i - 1])) 161 | else: 162 | SarX[i] = min(SarX[i - 1], max(SarX[i], High[i], High[i - 1])) 163 | 164 | # 4. 判断是否:向下跌破,向上突破 165 | if bull: # 多 166 | if Low[i] < SarX[i]: # 向下跌破,转空 167 | bull = False 168 | tmp_SarX = ep # 上阶段的最高点 169 | ep = Low[i] 170 | af = af_step 171 | if High[i - 1] == tmp_SarX: # 紧邻即最高点 172 | SarX[i] = tmp_SarX 173 | else: 174 | SarX[i] = tmp_SarX + af * (ep - tmp_SarX) 175 | else: # 空 176 | if High[i] > SarX[i]: # 向上突破, 转多 177 | bull = True 178 | ep = High[i] 179 | af = af_step 180 | SarX[i] = min(Low[i], Low[i - 1]) 181 | # end for 182 | return SarX 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /MyTT_python2.py: -------------------------------------------------------------------------------- 1 | # MyTT 麦语言-通达信-同花顺指标实现(python2版本) https://github.com/mpquant/MyTT 2 | # 此版本针对python2的老版本pandas使用 2021-10-22日更新 3 | 4 | 5 | 6 | import numpy as np; import pandas as pd 7 | 8 | #------------------ 0级:核心工具函数 python2 -------------------------------------------- 9 | def RD(N,D=3): return np.round(N,D) #四舍五入取3位小数 10 | def RET(S,N=1): return np.array(S)[-N] #返回序列倒数第N个值,默认返回最后一个 11 | def ABS(S): return np.abs(S) #返回N的绝对值 12 | def MAX(S1,S2): return np.maximum(S1,S2) #序列max 13 | def MIN(S1,S2): return np.minimum(S1,S2) #序列min 14 | 15 | def MA(S,N): #求序列的N日平均值,返回序列 16 | return pd.rolling_mean(S,N) 17 | 18 | def REF(S, N=1): #对序列整体下移动N,返回序列(shift后会产生NAN) 19 | return pd.Series(S).shift(N).values 20 | 21 | def DIFF(S, N=1): #前一个值减后一个值,前面会产生nan 22 | return pd.Series(S).diff(N).values #np.diff(S)直接删除nan,会少一行 23 | 24 | def STD(S,N): #求序列的N日标准差,返回序列 25 | return pd.rolling_std(S,N,ddof=0) 26 | 27 | def IF(S_BOOL,S_TRUE,S_FALSE): #序列布尔判断 res=S_TRUE if S_BOOL==True else S_FALSE 28 | return np.where(S_BOOL, S_TRUE, S_FALSE) 29 | 30 | def SUM(S, N): #对序列求N天累计和,返回序列 N=0对序列所有依次求和 31 | return pd.rolling_sum(S,N) if N>0 else pd.Series(S).cumsum() 32 | 33 | def HHV(S,N): # HHV(C, 5) # 最近5天收盘最高价 34 | return pd.rolling_max(S,N) 35 | 36 | def LLV(S,N): # LLV(C, 5) # 最近5天收盘最低价 37 | return pd.rolling_min(S,N) 38 | 39 | def EMA(S,N): #指数移动平均,为了精度 S>4*N EMA至少需要120周期 alpha=2/(span+1) 40 | return pd.ewma(S,span=N,adjust=False) 41 | 42 | def SMA(S, N, M=1): #中国式的SMA,至少需要120周期才精确 (雪球180周期) alpha=1/(1+com) 43 | return pd.ewma(S,com=((N-M)*1.0)/M,adjust=True) 44 | 45 | def DMA(S, A): #求S的动态移动平均,A作平滑因子 (此为核心函数,非指标) 46 | return pd.ewma(S,com=1.0/A-1,adjust=False) 47 | 48 | def AVEDEV(S,N): #平均绝对偏差 (序列与其平均值的绝对差的平均值) 49 | return pd.rolling_apply(S,N,lambda x: (np.abs(x - x.mean())).mean()) 50 | 51 | def SLOPE(S,N,RS=False): #返S序列N周期回线性回归斜率 (默认只返回斜率,不返回整个直线序列) 52 | M=pd.Series(S[-N:]); poly = np.polyfit(M.index, M.values,deg=1); Y=np.polyval(poly, M.index); 53 | if RS: return Y[1]-Y[0],Y 54 | return Y[1]-Y[0] 55 | 56 | 57 | #------------------ 1级:应用层函数(通过0级核心函数实现) ---------------------------------- 58 | def COUNT(S_BOOL, N): # COUNT(CLOSE>O, N): 最近N天满足S_BOO的天数 True的天数 59 | return SUM(S_BOOL,N) 60 | 61 | def EVERY(S_BOOL, N): # EVERY(CLOSE>O, 5) 最近N天是否都是True 62 | R=SUM(S_BOOL, N) 63 | return IF(R==N, True, False) 64 | 65 | def LAST(S_BOOL, A, B): #从前A日到前B日一直满足S_BOOL条件 66 | if AB 例:LAST(CLOSE>OPEN,5,3) 5天前到3天前是否都收阳线 67 | return S_BOOL[-A:-B].sum()==(A-B) #返回单个布尔值 68 | 69 | def EXIST(S_BOOL, N=5): # EXIST(CLOSE>3010, N=5) n日内是否存在一天大于3000点 70 | R=SUM(S_BOOL,N) 71 | return IF(R>0, True ,False) 72 | 73 | 74 | def FORCAST(S,N): #返S序列N周期回线性回归后的预测值 75 | K,Y=SLOPE(S,N,RS=True) 76 | return Y[-1]+K 77 | 78 | def CROSS(S1,S2): #判断向上金叉穿越 CROSS(MA(C,5),MA(C,10)) 判断向下死叉穿越 CROSS(MA(C,10),MA(C,5)) 79 | CROSS_BOOL=IF(S1>S2, True ,False) 80 | return (COUNT(CROSS_BOOL>0,2)==1)*CROSS_BOOL #上穿:昨天0 今天1 下穿:昨天1 今天0 81 | 82 | 83 | 84 | #------------------ 2级:技术指标函数(全部通过0级,1级函数实现) ------------------------------ 85 | def MACD(CLOSE,SHORT=12,LONG=26,M=9): # EMA的关系,S取120日,和雪球小数点2位相同 86 | DIF = EMA(CLOSE,SHORT)-EMA(CLOSE,LONG); 87 | DEA = EMA(DIF,M); MACD=(DIF-DEA)*2 88 | return RD(DIF),RD(DEA),RD(MACD) 89 | 90 | def KDJ(CLOSE,HIGH,LOW, N=9,M1=3,M2=3): # KDJ指标 91 | RSV = (CLOSE - LLV(LOW, N)) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 92 | K = EMA(RSV, (M1*2-1)); D = EMA(K,(M2*2-1)); J=K*3-D*2 93 | return K, D, J 94 | 95 | def RSI(CLOSE, N=24): 96 | DIF = CLOSE-REF(CLOSE,1) 97 | return RD(SMA(MAX(DIF,0), N) / SMA(ABS(DIF), N) * 100) 98 | 99 | def WR(CLOSE, HIGH, LOW, N=10, N1=6): #W&R 威廉指标 100 | WR = (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 101 | WR1 = (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) * 100 102 | return RD(WR), RD(WR1) 103 | 104 | def BIAS(CLOSE,L1=6, L2=12, L3=24): # BIAS乖离率 105 | BIAS1 = (CLOSE - MA(CLOSE, L1)) / MA(CLOSE, L1) * 100 106 | BIAS2 = (CLOSE - MA(CLOSE, L2)) / MA(CLOSE, L2) * 100 107 | BIAS3 = (CLOSE - MA(CLOSE, L3)) / MA(CLOSE, L3) * 100 108 | return RD(BIAS1), RD(BIAS2), RD(BIAS3) 109 | 110 | def BOLL(CLOSE,N=20, P=2): #BOLL指标,布林带 111 | MID = MA(CLOSE, N); 112 | UPPER = MID + STD(CLOSE, N) * P 113 | LOWER = MID - STD(CLOSE, N) * P 114 | return RD(UPPER), RD(MID), RD(LOWER) 115 | 116 | def PSY(CLOSE,N=12, M=6): 117 | PSY=COUNT(CLOSE>REF(CLOSE,1),N)/N*100 118 | PSYMA=MA(PSY,M) 119 | return RD(PSY),RD(PSYMA) 120 | 121 | def CCI(CLOSE,HIGH,LOW,N=14): 122 | TP=(HIGH+LOW+CLOSE)/3 123 | return (TP-MA(TP,N))/(0.015*AVEDEV(TP,N)) 124 | 125 | def ATR(CLOSE,HIGH,LOW, N=20): #真实波动N日平均值 126 | TR = MAX(MAX((HIGH - LOW), ABS(REF(CLOSE, 1) - HIGH)), ABS(REF(CLOSE, 1) - LOW)) 127 | return MA(TR, N) 128 | 129 | def BBI(CLOSE,M1=3,M2=6,M3=12,M4=20): #BBI多空指标 130 | return (MA(CLOSE,M1)+MA(CLOSE,M2)+MA(CLOSE,M3)+MA(CLOSE,M4))/4 131 | 132 | def DMI(CLOSE,HIGH,LOW,M1=14,M2=6): #动向指标:结果和同花顺,通达信完全一致 133 | TR = SUM(MAX(MAX(HIGH - LOW, ABS(HIGH - REF(CLOSE, 1))), ABS(LOW - REF(CLOSE, 1))), M1) 134 | HD = HIGH - REF(HIGH, 1); LD = REF(LOW, 1) - LOW 135 | DMP = SUM(IF((HD > 0) & (HD > LD), HD, 0), M1) 136 | DMM = SUM(IF((LD > 0) & (LD > HD), LD, 0), M1) 137 | PDI = DMP * 100 / TR; MDI = DMM * 100 / TR 138 | ADX = MA(ABS(MDI - PDI) / (PDI + MDI) * 100, M2) 139 | ADXR = (ADX + REF(ADX, M2)) / 2 140 | return PDI, MDI, ADX, ADXR 141 | 142 | def TAQ(HIGH,LOW,N): #唐安奇通道(海龟)交易指标,大道至简,能穿越牛熊 143 | UP=HHV(HIGH,N); DOWN=LLV(LOW,N); MID=(UP+DOWN)/2 144 | return UP,MID,DOWN 145 | 146 | def KTN(CLOSE,HIGH,LOW,N=20,M=10): #肯特纳交易通道, N选20日,ATR选10日 147 | MID=EMA((HIGH+LOW+CLOSE)/3,N) 148 | ATRN=ATR(CLOSE,HIGH,LOW,M) 149 | UPPER=MID+2*ATRN; LOWER=MID-2*ATRN 150 | return UPPER,MID,LOWER 151 | 152 | def TRIX(CLOSE,M1=12, M2=20): #三重指数平滑平均线 153 | TR = EMA(EMA(EMA(CLOSE, M1), M1), M1) 154 | TRIX = (TR - REF(TR, 1)) / REF(TR, 1) * 100 155 | TRMA = MA(TRIX, M2) 156 | return TRIX, TRMA 157 | 158 | def VR(CLOSE,VOL,M1=26): #VR容量比率 159 | LC = REF(CLOSE, 1) 160 | return SUM(IF(CLOSE > LC, VOL, 0), M1) / SUM(IF(CLOSE <= LC, VOL, 0), M1) * 100 161 | 162 | def EMV(HIGH,LOW,VOL,N=14,M=9): #简易波动指标 163 | VOLUME=MA(VOL,N)/VOL; MID=100*(HIGH+LOW-REF(HIGH+LOW,1))/(HIGH+LOW) 164 | EMV=MA(MID*VOLUME*(HIGH-LOW)/MA(HIGH-LOW,N),N); MAEMV=MA(EMV,M) 165 | return EMV,MAEMV 166 | 167 | 168 | def DPO(CLOSE,M1=20, M2=10, M3=6): #区间震荡线 169 | DPO = CLOSE - REF(MA(CLOSE, M1), M2); MADPO = MA(DPO, M3) 170 | return DPO, MADPO 171 | 172 | def BRAR(OPEN,CLOSE,HIGH,LOW,M1=26): #BRAR-ARBR 情绪指标 173 | AR = SUM(HIGH - OPEN, M1) / SUM(OPEN - LOW, M1) * 100 174 | BR = SUM(MAX(0, HIGH - REF(CLOSE, 1)), M1) / SUM(MAX(0, REF(CLOSE, 1) - LOW), M1) * 100 175 | return AR, BR 176 | 177 | def DFMA(CLOSE,N1=10,N2=50,M=10): #平行线差指标 178 | DIF=MA(CLOSE,N1)-MA(CLOSE,N2); DIFMA=MA(DIF,M) #通达信指标叫DMA 同花顺叫新DMA 179 | return DIF,DIFMA 180 | 181 | def MTM(CLOSE,N=12,M=6): #动量指标 182 | MTM=CLOSE-REF(CLOSE,N); MTMMA=MA(MTM,M) 183 | return MTM,MTMMA 184 | 185 | def MASS(HIGH,LOW,N1=9,N2=25,M=6): # 梅斯线 186 | MASS=SUM(MA(HIGH-LOW,N1)/MA(MA(HIGH-LOW,N1),N1),N2) 187 | MA_MASS=MA(MASS,M) 188 | return MASS,MA_MASS 189 | 190 | def ROC(CLOSE,N=12,M=6): #变动率指标 191 | ROC=100*(CLOSE-REF(CLOSE,N))/REF(CLOSE,N); MAROC=MA(ROC,M) 192 | return ROC,MAROC 193 | 194 | def EXPMA(CLOSE,N1=12,N2=50): #EMA指数平均数指标 195 | return EMA(CLOSE,N1),EMA(CLOSE,N2); 196 | 197 | def OBV(CLOSE,VOL): #能量潮指标 198 | return SUM(IF(CLOSE>REF(CLOSE,1),VOL,IF(CLOSEREF(TYP,1),TYP*VOL,0),N)/SUM(IF(TYPBB) & (AA>CC),AA+BB/2+DD/4,IF( (BB>CC) & (BB>AA),BB+AA/2+DD/4,CC+DD/4)); 209 | X=(CLOSE-LC+(CLOSE-OPEN)/2+LC-REF(OPEN,1)); 210 | SI=16*X/R*MAX(AA,BB); ASI=SUM(SI,M1); ASIT=MA(ASI,M2); 211 | return ASI,ASIT 212 | 213 | 214 | #望大家能提交更多指标和函数 https://github.com/mpquant/MyTT 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MyTT (My麦语言 T通达信 T同花顺) 2 | MyTT是您量化工具箱里的瑞士军刀,精炼而高效,它将通达信,同花顺,文华麦语言等指标公式indicators,最简移植到Python中,核心库单个文件,仅百行代码,实现和转换同花顺通达信所有常见指标MACD,RSI,BOLL,ATR,KDJ,CCI,PSY等,全部基于numpy和pandas的函数封装,简洁且高性能,能非常方便的应用在各自股票股市技术分析,股票自动程序化交易,数字货币BTC等量化等领域.Mini Python library with most stock market indicators. 3 | 4 | [![license](https://img.shields.io/:license-gpl-blue.svg)](https://badges.gpl-license.org/) 5 | 6 | # 功能特点 7 | * 核心库轻量化: 项目库就一个文件 [MyTT.py](https://github.com/mpquant/MyTT/blob/main/MyTT.py),不用安装设置,可自由裁剪,随用随走 `from MyTT import *` 即可 8 | 9 | * 代码人类化:) 没有什么炫耀的编程花样,初学者也能看懂,自己就能自行增加指标,马上就能用在项目中。 10 | 11 | * 不需要安装ta-lib库,是纯python代码实现的的核心逻辑,很多人都有安装ta-lib库的痛苦经历 12 | 13 | * 和通达信,同花顺的指标写法完全兼容,一个新的指标基本不用做修改,直接拿来即可使用 14 | 15 | * 超高性能,基本不用循环,全是靠numpy,pandas的内置函数实现各种指标 16 | 17 | * 和Talib库一样是多天参数进,多天指标出(序列进,序列出),便于画图和观察趋势 18 | 19 | * MyTT实现的各种指标和通达信,同花顺,雪球等软件的技术指标一致到小数点后2位 20 | 21 | * MyTT高级进阶版本,收录了高级复杂用法的函数和实验验证函数 [MyTT_plus](https://github.com/mpquant/MyTT/blob/main/MyTT_plus.py) 22 | 23 | * MyTT也能在python2的老版本pandas中使用,请用此python2版本 [MyTT_python2](https://github.com/mpquant/MyTT/blob/main/MyTT_python2.py) 24 | 25 | 26 | ### 先看一个最简单的例子 27 | 28 | ```python 29 | 30 | #数字货币行情获取和指标计算演示 31 | from hb_hq_api import * #数字货币行情库 32 | from MyTT import * #myTT麦语言工具函数指标库 33 | 34 | #获取btc.usdt交易对120日的数据 35 | df=get_price('btc.usdt',count=120,frequency='1d'); #'1d'是1天, '4h'是4小时 36 | 37 | #-----------df结果如下表(股市也基本一样)------------------------------------------- 38 | ``` 39 | 40 | | |open| close| high |low| vol| 41 | |--|--|--|--|--|--| 42 | |2021-05-16 |48983.62| 47738.24| 49800.00| 46500.0 |1.333333e+09 | 43 | |2021-05-17 |47738.24| 43342.50| 48098.66| 42118.0 |3.353662e+09 | 44 | |2021-05-18 |43342.50| 44093.24| 45781.52| 42106.0 |1.793267e+09 | 45 | 46 | 47 | ```python 48 | 49 | #-------有数据了,下面开始正题 ------------- 50 | CLOSE=df.close.values; OPEN=df.open.values #基础数据定义,只要传入的是序列都可以 51 | HIGH=df.high.values; LOW=df.low.values #例如 CLOSE=list(df.close) 都是一样 52 | 53 | MA5=MA(CLOSE,5) #获取5日均线序列 54 | MA10=MA(CLOSE,10) #获取10日均线序列 55 | 56 | print('BTC5日均线', MA5[-1] ) # 只取最后一个数 57 | print('BTC10日均线',RET(MA10)) # RET(MA10) == MA10[-1] 58 | print('今天5日线是否上穿10日线',RET(CROSS(MA5,MA10))) 59 | print('最近5天收盘价全都大于10日线吗?',EVERY(CLOSE>MA10,5) ) 60 | 61 | ``` 62 | ### 安装方法 63 | * 直接拷贝 MyTT.py到你的项目下 `from MyTT import *` 即可调用文件中的所有函数 64 | 65 | * 传统标准库安装 `pip install MyTT` 66 | 67 | ```python 68 | from MyTT import * #声明调用MyTT, 请注意大小写 69 | S=np.random.randint(1,99,[10]) #生成1-99内的10个数序列 70 | EMA(S,6) #对这个序列S进行6周期EMA指数平均计算 71 | ``` 72 | 73 | ### 教程和案例应用 74 | * [通达信公式转Python神器——MyTT库](https://www.joinquant.com/view/community/detail/a6cc7d1fb73a57dbac4b77044a33b15d) 75 | 76 | * [利用MyTT库整合通达信指标公式](https://www.joinquant.com/view/community/detail/4237ebaa5db39a5a9a2195338e8be588) 77 | 78 | * [MyTT库应用示例及计算精度验证](https://www.joinquant.com/view/community/detail/bd26874654a6f9f1958f23043ca06149) 79 | 80 | * [如何在聚宽研究环境中建立myTT.py库文件](https://www.joinquant.com/view/community/detail/2abf0cc457352b59ef2e873ad7c4e430) 81 | 82 | * [基于MyTT来编写Python版通达信指标](https://www.joinquant.com/view/community/detail/7a0297fb7bd717cfb2be40b4c8062eeb) 83 | 84 | * [MyTT基础函数EMA指数平均的公式推导](https://www.joinquant.com/view/community/detail/ab76489c8fdfd1f201b6df47f11a5360) 85 | 86 | 87 | ### MyTT库中的部分工具函数 88 | * n天前的数据:`REF` 89 | ```python 90 | REF(CLOSE, 1) # 截止到昨天收盘价 序列 91 | ``` 92 | 93 | * 移动平均线计算:MA 94 | ```python 95 | MA(CLOSE, 5) # 取得收盘价5日平均线 96 | ``` 97 | 98 | * 加权移动平均计算:EMA 99 | ```python 100 | EMA(CLOSE, 5) # 为了精度 , EMA至少需要120周期 101 | ``` 102 | 103 | * 中国式的SMA计算:SMA 104 | ```python 105 | SMA(CLOSE, 5) # 为了精度 , SMA至少需要120周期 106 | ``` 107 | 108 | * 返回序列标准差:STD 109 | ```python 110 | STD(CLOSE, 5) # 返回收盘价5日内标准差 111 | ``` 112 | 113 | * 平均绝对偏差:`AVEDEV` 114 | ```python 115 | AVEDEV(CLOSE, 5) # 序列与其平均值的绝对差的平均值 116 | ``` 117 | 118 | * 金叉判断:CROSS 119 | ```python 120 | CROSS(MA(CLOSE, 5), MA(CLOSE, 10)) #5日均线上穿10日均线 121 | ``` 122 | 123 | * 两个序列取最大值,最小值:`MAX` `MIN` 124 | ```python 125 | MAX(OPEN, CLOSE ) #K线实体的最高价 126 | ``` 127 | 128 | * n天内满足条件的天数:COUNT 129 | ```python 130 | COUNT(CLOSE > OPEN, 10) #最近10天收阳线的天数 131 | ``` 132 | 133 | * n天内全部满足条件的天数:EVERY 134 | ```python 135 | EVERY(CLOSE >OPEN, 5) #最近5天都是收阳线 136 | ``` 137 | 138 | * 从前A日到前B日一直满足条件 :LAST 139 | ```python 140 | LAST(CLOSE>OPEN,5,3) #5天前到3天前是否都收阳线 141 | ``` 142 | 143 | * n天内是否至少满足条件一次:EXIST 144 | ```python 145 | EXIST(CLOSE>OPEN, 5) #最近5天是否有一天收阳线 146 | ``` 147 | 148 | * 上一次条件成立到当前的周期:BARSLAST 149 | ```python 150 | BARSLAST(CLOSE/REF(CLOSE)>=1.1) #上一次涨停到今天的天数 151 | ``` 152 | 153 | * 返回序列的线性回归斜率:`SLOPE` 154 | ```python 155 | SLOPE(MA(CLOSE,10),5) #得到10日平均线最近5天的斜率(其实就是MA均线的方向) 156 | ``` 157 | 158 | * 取回线性回归后的预测值:`FORCAST` 159 | ```python 160 | FORCAST(CLOSE,20) #根据最近20日的走势预测明天的收盘价 161 | ``` 162 | 163 | * n天内最大值:`HHV` 164 | ```python 165 | HHV(MAX(OPEN, CLOSE), 20) #最近20天K线实体的最高价 166 | ``` 167 | 168 | * n天内最小值:`LLV` 169 | ```python 170 | LLV(MIN(OPEN, CLOSE), 60) #最近60天K线实体的最低价 171 | ``` 172 | 173 | * 条件 `IF` 174 | ```python 175 | IF(OPEN > CLOSE, OPEN, CLOSE) #如果 开盘>收盘 返回OPEN ,否则返回CLOSE 176 | ``` 177 | 178 | ### 具体指标的实现,全部基于MyTT库中的工具函数 (更多指标可以自行添加) 179 | 180 | ```python 181 | def MACD(CLOSE,SHORT=12,LONG=26,M=9): # EMA的关系,CLOSE取120日,结果能精确到雪球小数点2位 182 | DIF = EMA(CLOSE,SHORT)-EMA(CLOSE,LONG); 183 | DEA = EMA(DIF,M); MACD=(DIF-DEA)*2 184 | return RD(DIF),RD(DEA),RD(MACD) 185 | ``` 186 | 187 | ```python 188 | def KDJ(CLOSE,HIGH,LOW, N=9,M1=3,M2=3): 189 | RSV = (CLOSE - LLV(LOW, N)) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 190 | K = EMA(RSV, (M1*2-1)); D = EMA(K,(M2*2-1)); J=K*3-D*2 191 | return K, D, J 192 | ``` 193 | 194 | ```python 195 | def RSI(CLOSE, N=24): #RSI指标 196 | DIF = CLOSE-REF(CLOSE,1) 197 | return RD(SMA(MAX(DIF,0), N) / SMA(ABS(DIF), N) * 100) 198 | ``` 199 | 200 | ```python 201 | def WR(CLOSE, HIGH, LOW, N=10, N1=6): #W&R 威廉指标 202 | WR = (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) * 100 203 | WR1 = (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) * 100 204 | return RD(WR), RD(WR1) 205 | ``` 206 | 207 | ```python 208 | def BIAS(CLOSE,L1=6, L2=12, L3=24): #BIAS乖离率 209 | BIAS1 = (CLOSE - MA(CLOSE, L1)) / MA(CLOSE, L1) * 100 210 | BIAS2 = (CLOSE - MA(CLOSE, L2)) / MA(CLOSE, L2) * 100 211 | BIAS3 = (CLOSE - MA(CLOSE, L3)) / MA(CLOSE, L3) * 100 212 | return RD(BIAS1), RD(BIAS2), RD(BIAS3) 213 | ``` 214 | 215 | ```python 216 | def BOLL(CLOSE,N=20, P=2): #BOLL布林带 217 | MID = MA(CLOSE, N); 218 | UPPER = MID + STD(CLOSE, N) * P 219 | LOWER = MID - STD(CLOSE, N) * P 220 | return RD(UPPER), RD(MID), RD(LOWER) 221 | ``` 222 | 223 | ```python 224 | def PSY(CLOSE,N=12, M=6): #PSY心理线指标 225 | PSY=COUNT(CLOSE>REF(CLOSE,1),N)/N*100 226 | PSYMA=MA(PSY,M) 227 | return RD(PSY),RD(PSYMA) 228 | ``` 229 | 230 | ```python 231 | def CCI(CLOSE,HIGH,LOW,N=14): #CCI顺势指标 232 | TP=(HIGH+LOW+CLOSE)/3 233 | return (TP-MA(TP,N))/(0.015*AVEDEV(TP,N)) 234 | ``` 235 | 236 | ```python 237 | def ATR(CLOSE,HIGH,LOW, N=20): #真实波动N日平均值 238 | TR = MAX(MAX((HIGH - LOW), ABS(REF(CLOSE, 1) - HIGH)), ABS(REF(CLOSE, 1) - LOW)) 239 | return MA(TR, N) 240 | ``` 241 | 242 | ```python 243 | def BBI(CLOSE,M1=3,M2=6,M3=12,M4=20): #BBI多空指标 244 | return (MA(CLOSE,M1)+MA(CLOSE,M2)+MA(CLOSE,M3)+MA(CLOSE,M4))/4 245 | ``` 246 | 247 | 248 | ```python 249 | def TAQ(HIGH,LOW,N): #唐安奇通道(海龟)交易指标,大道至简,能穿越牛熊 250 | UP=HHV(HIGH,N); DOWN=LLV(LOW,N); MID=(UP+DOWN)/2 251 | return UP,MID,DOWN 252 | ``` 253 | 254 | ```python 255 | def KTN(CLOSE,HIGH,LOW,N=20,M=10): #肯特纳交易通道, N选20日,ATR选10日 256 | MID=EMA((HIGH+LOW+CLOSE)/3,N) 257 | ATRN=ATR(CLOSE,HIGH,LOW,M) 258 | UPPER=MID+2*ATRN; LOWER=MID-2*ATRN 259 | return UPPER,MID,LOWER 260 | ``` 261 | 262 | ```python 263 | def TRIX(CLOSE,M1=12, M2=20): #三重指数平滑平均线 264 | TR = EMA(EMA(EMA(CLOSE, M1), M1), M1) 265 | TRIX = (TR - REF(TR, 1)) / REF(TR, 1) * 100 266 | TRMA = MA(TRIX, M2) 267 | return TRIX, TRMA 268 | ``` 269 | 270 | ```python 271 | def BRAR(OPEN,CLOSE,HIGH,LOW,M1=26): #BRAR-ARBR 情绪指标 272 | AR = SUM(HIGH - OPEN, M1) / SUM(OPEN - LOW, M1) * 100 273 | BR = SUM(MAX(0, HIGH - REF(CLOSE, 1)), M1) / SUM(MAX(0, REF(CLOSE, 1) - LOW), M1) * 100 274 | return AR, BR 275 | ``` 276 | 277 | ```python 278 | def MTM(CLOSE,N=12,M=6): #动量指标 279 | MTM=CLOSE-REF(CLOSE,N); MTMMA=MA(MTM,M) 280 | return MTM,MTMMA 281 | ``` 282 | ```python 283 | def ROC(CLOSE,N=12,M=6): #变动率指标 284 | ROC=100*(CLOSE-REF(CLOSE,N))/REF(CLOSE,N); MAROC=MA(ROC,M) 285 | return ROC,MAROC 286 | ``` 287 | ```python 288 | def EXPMA(CLOSE,N1=12,N2=50): #EMA指数平均数指标 289 | return EMA(CLOSE,N1),EMA(CLOSE,N2); 290 | ``` 291 | ```python 292 | def OBV(CLOSE,VOL): #能量潮指标 293 | return SUM(IF(CLOSE>REF(CLOSE,1),VOL,IF(CLOSEREF(TYP,1),TYP*VOL,0),N)/SUM(IF(TYPREF(C,1) AND C>REF(C,2)); 311 | python写法: VAR1=( (CLOSE>REF(CLOSE,1)) & (CLOSE>REF(CLOSE,2)) ); 312 | 313 | # 收盘价在10日均线上 且10日均线在20日均线上 314 | python写法: (C > MA(C, 10)) & (MA(C, 10) > MA(C, 20)) 315 | 316 | # 收阳线 或 收盘价大于昨收 317 | python写法: (CLOSE > O) | (CLOSE > REF(CLOSE, 1)) 318 | 319 | ``` 320 | 321 | 322 | ### BOLL带指标数据获取和做图演示 (上证综指) 323 | 324 | ```python 325 | up,mid,lower=BOLL(CLOSE) #获取布林带数据 326 | 327 | plt.figure(figsize=(15,8)) 328 | plt.plot(CLOSE,label='上证'); plt.plot(up,label='up'); #画图显示 329 | plt.plot(mid,label='mid'); plt.plot(lower,label='lower'); 330 | 331 | ``` 332 |
Boll线
333 | 334 | 335 | ### 唐安奇交易通道指标计算和做图演示 (沪深300指数) 336 | 337 | ```python 338 | up,mid,down=TAQ(HIGH,LOW,20) #获取唐安奇交易通道数据,大道至简,能穿越牛熊 339 | plt.figure(figsize=(15,8)) 340 | plt.plot(CLOSE,label='沪深300指数') 341 | plt.plot(up,label='唐安奇-上轨'); plt.plot(mid,label='唐安奇-中轨'); plt.plot(down,label='唐安奇-下轨') 342 | ``` 343 |
taq
344 | 345 | 346 | ### 需安装第三方库(无需ta-lib库,所有指标实现仅需要安装pandas既可) 347 | * pandas 348 | 349 | 350 | ### 代码贡献者Contributors 351 | 火焰,jqz1226, stanene, bcq 352 | 353 | 354 | ---------------------------------------------------- 355 | ### 团队其他开源项目 - 如果本项目能帮助到您,请右上角帮我们点亮 ★star 以示鼓励! 356 | * [MyTT 通达信,同花顺公式指标,文华麦语言的python实现](https://github.com/mpquant/MyTT) 357 | 358 | * [Ashare最简股票行情数据接口API,A股行情完全开源免费](https://github.com/mpquant/Ashare) 359 | 360 | 361 | 362 | ---------------------------------------------------- 363 | 364 | ![加入群聊](https://github.com/mpquant/Ashare/blob/main/img/qrcode.png) 365 | 366 | > #### 股市程序化交易大群,数字货币量化交易探讨, 圈内大咖量化策略分享 367 | > #### 全是干货,无闲聊 ,物以类聚,人以群分,一起感受思维碰撞的力量! 368 | 369 | 370 | 371 | ---------------------------------------------------- 372 | ## Star 历史 373 | [![Star History Chart](https://api.star-history.com/svg?repos=mpquant/MyTT&type=Date)](https://star-history.com/#mpquant/MyTT&Date) 374 | -------------------------------------------------------------------------------- /example1.py: -------------------------------------------------------------------------------- 1 | #数字货币行情获取和指标计算演示 2 | from hb_hq_api import * 3 | from MyTT import * 4 | 5 | 6 | df=get_price('btc.usdt',count=120,frequency='1d'); #日线数据获取 1d:1天 4h:4小时 60m: 60分钟 15m:15分钟 7 | CLOSE=df.close.values; OPEN=df.open.values; HIGH=df.high.values; LOW=df.low.values #基础数据定义 8 | 9 | MA5=MA(CLOSE,5) 10 | MA10=MA(CLOSE,10) 11 | CROSS_TODAY=RET(CROSS(MA5,MA10)) 12 | 13 | print(f'BTC5日均线{ MA5[-1]} BTC10日均线 {MA10[-1]}' ) 14 | print('今天5日线是否上穿10日线',CROSS_TODAY) 15 | print('最近5天收盘价全都大于5日线吗?',EVERY(CLOSE>MA10,5) ) 16 | 17 | DIF,DEA,MACD=MACD(CLOSE) 18 | print('MACD值',DIF,DEA,MACD) -------------------------------------------------------------------------------- /hb_hq_api.py: -------------------------------------------------------------------------------- 1 | #火币行情功能函数 2 | import json,requests,urllib3,datetime; import pandas as pd; import numpy as np ; urllib3.disable_warnings() 3 | 4 | huobi_domain='api.huobi.de.com' #API地址 'api.huobi.pro' api.huobi.be没有被墙 api.huobi.de.com 5 | 6 | class Context: #根类 7 | def __init__(self): 8 | self.current_dt=datetime.datetime.now() 9 | 10 | # #1d:1天 4h:4小时 60m: 60分钟 15m:15分钟 11 | def get_price(code, end_date=None, count=1,frequency='1d', fields=['close']): 12 | code=code.replace('.','') 13 | frequency=frequency.replace('d','day').replace('m','min').replace('h','hour') 14 | url = f'https://{huobi_domain}/market/history/kline?period={frequency}&size={count}&symbol={code}' 15 | res = requests.get(url,verify=False).text 16 | df=pd.DataFrame(json.loads(res)['data']); df=df.iloc[::-1] #排序翻转 17 | df["time"] = pd.to_datetime(df["id"]+8*3600, unit='s') #时间戳转时间,北京时间+8小时 18 | df=df[['time','open','close','high','low','vol']] #更正排序 19 | df.set_index(["time"], inplace=True); df.index.name='' #处理索引 20 | return df 21 | 22 | def get_last_price(code): #获取某只股票最新价格函数04-25 23 | return get_price(code,count=1,frequency='1m', fields=['close']).close[0] 24 | 25 | def attribute_history(security, count, unit='1d', fields=['open', 'close', 'high', 'low', 'volume', 'money']): #获取历史行情 26 | return get_price(security = security, end_date = context.current_dt, frequency=unit, fields=fields, fq = fq, count = count)[:-1] 27 | 28 | 29 | -------------------------------------------------------------------------------- /img/boll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpquant/MyTT/880f7fd1abb3135106fb702b1734bcb753d894fd/img/boll.png -------------------------------------------------------------------------------- /img/taq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpquant/MyTT/880f7fd1abb3135106fb702b1734bcb753d894fd/img/taq.jpg --------------------------------------------------------------------------------