指标名称:RT动量[color=rgba(0, 0, 0, 0.9)]
版本:MT4-MT5 ver. 1.16
RT动量指标。它在独立窗口中显示,范围为 -50 至 +50,通过动态柱状图颜色变化、趋势线交叉及水平位突破,帮助交易者识别超买超卖区域及潜在趋势反转信号。
信号解读 1. 柱状图颜色 绿色柱状图:RSI值大于0,表示潜在多头趋势。 亮绿色:斜率向上(当前值 > 前值)。 暗绿色:斜率向下(当前值 < 前值)。 粉红色柱状图:RSI值小于0,表示潜在空头趋势。 亮粉色:斜率向上。 暗粉色:斜率向下。 灰色中线:零轴(0值),用于判断多空分界。 2. 趋势与斜率 趋势(Trend): RSI值 > 0:多头趋势(柱状图位于零轴上方)。 RSI值 < 0:空头趋势(柱状图位于零轴下方)。 斜率(Slope): 当前RSI值 > 前值:斜率向上(柱状图颜色更亮)。 当前RSI值 < 前值:斜率向下(柱状图颜色更暗)。 3. 关键信号 超买/超卖:RSI突破 +30 或跌破 -30,可能预示反转。 零轴交叉:柱状图从负转正(上穿零轴)为买入信号,反之为卖出信号。 斜率变化:柱状图颜色亮度切换时,表明动量方向可能改变。 警报系统 警报触发条件 斜率变化: 零轴交叉:
参数:
部分代码展示:
- //+------------------------------------------------------------------+//| RT动量.mq4 |//| Copyright © 2009-2024, www.QChaos.com |//| https://www.qchaos.com/ |//+------------------------------------------------------------------+#property copyright "Copyright © 量化混沌, www.qchaos.com"#property link "https://www.qchaos.com"#property version "2.01"#property strict#property indicator_separate_window#property indicator_buffers 5#property indicator_color1 clrLimeGreen#property indicator_color2 clrLimeGreen#property indicator_color3 clrPaleVioletRed#property indicator_color4 clrPaleVioletRed#property indicator_color5 clrDarkGray#property indicator_width1 2#property indicator_width3 2#property indicator_width5 2#property indicator_minimum -50#property indicator_maximum +50#property indicator_levelcolor clrDarkGray#property strict
- // 输入参数配置extern double RsiPeriod = 25; // RSI周期(计算RSI的窗口长度)extern ENUM_APPLIED_PRICE RsiPrice = PRICE_CLOSE; // RSI计算价格类型(默认收盘价)extern double Hot = 0.7; // T3平滑热度系数(灵敏度调节)extern bool OriginalT3 = false; // 是否使用原始T3算法?extern double LevelUp = 30; // 超买水平阈值(上方警戒线)extern double LevelDown = -30; // 超卖水平阈值(下方警戒线)
- // 警报系统配置extern bool alertsOn = true; // 是否启用警报?extern bool alertsOnSlope = true; // 是否在斜率变化时触发警报?extern bool alertsOnZeroCross = true; // 是否在零轴交叉时触发警报?extern bool alertsOnCurrent = false; // 是否在当前未闭合K线触发警报?extern bool alertsMessage = true; // 是否显示弹窗警报?extern bool alertsPushNotif = false; // 是否发送推送通知?extern bool alertsSound = false; // 是否播放声音警报?extern bool alertsEmail = false; // 是否发送邮件警报?extern string soundFile = "alert2.wav"; // 警报声音文件(默认alert2.wav)
- // 箭头标记配置extern bool arrowsVisible = false; // 是否显示箭头?extern string arrowsIdentifier = "RT arrows1"; // 箭头对象唯一标识符extern double arrowsUpperGap = 0.5; // 上方箭头与K线的间距(ATR倍数)extern double arrowsLowerGap = 0.5; // 下方箭头与K线的间距(ATR倍数)
- // 零轴交叉箭头设置extern bool arrowsOnZeroCross = true; // 是否显示零轴交叉箭头?extern color arrowsOnZeroCrossUpColor = clrLimeGreen; // 零轴上交叉箭头颜色(亮绿色)extern color arrowsOnZeroCrossDnColor = clrRed; // 零轴下交叉箭头颜色(红色)extern int arrowsOnZeroCrossUpCode = 241; // 零轴上交叉箭头符号代码(MT4内置编码)extern int arrowsOnZeroCrossDnCode = 242; // 零轴下交叉箭头符号代码extern int arrowsOnZeroCrossUpSize = 2; // 零轴上交叉箭头尺寸extern int arrowsOnZeroCrossDnSize = 2; // 零轴下交叉箭头尺寸
- // 斜率变化箭头设置extern bool arrowsOnSlope = false; // 是否显示斜率变化箭头?extern color arrowsOnSlopeUpColor = clrLimeGreen; // 斜率向上箭头颜色(亮绿色)extern color arrowsOnSlopeDnColor = clrRed; // 斜率向下箭头颜色(红色)extern int arrowsOnSlopeUpCode = 159; // 斜率向上箭头符号代码(▲)extern int arrowsOnSlopeDnCode = 159; // 斜率向下箭头符号代码(▼)extern int arrowsOnSlopeUpSize = 2; // 斜率向上箭头尺寸extern int arrowsOnSlopeDnSize = 2; // 斜率向下箭头尺寸double rsi[],rsihuu[],rsihud[],rsihdu[],rsihdd[],slope[],trend[];
- //+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int init() { IndicatorBuffers(7); SetIndexBuffer(0,rsihuu); SetIndexStyle(0, DRAW_HISTOGRAM); SetIndexBuffer(1,rsihud); SetIndexStyle(1, DRAW_HISTOGRAM); SetIndexBuffer(2,rsihdd); SetIndexStyle(2, DRAW_HISTOGRAM); SetIndexBuffer(3,rsihdu); SetIndexStyle(3, DRAW_HISTOGRAM); SetIndexBuffer(4,rsi); SetIndexBuffer(5,slope); SetIndexBuffer(6,trend); SetLevelValue(0,0); SetLevelValue(1,LevelUp); SetLevelValue(2,LevelDown); IndicatorShortName("RT动量("+DoubleToStr(RsiPeriod,1)+","+DoubleToStr(Hot,2)+")"); return(0); }//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int deinit() { string lookFor = arrowsIdentifier+":"; int lookForLength = StringLen(lookFor); for(int i=ObjectsTotal()-1; i>=0; i--) { string objectName = ObjectName(i); if(StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName); } return(0); }
- //+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int start() { int counted_bars=IndicatorCounted(); if(counted_bars < 0) return(-1); if(counted_bars>0) counted_bars--; int limit = fmin(Bars-counted_bars,Bars-1); for(int i = limit; i >= 0; i--) { if(i<Bars-1) { rsi = iRsi(iMA(NULL,0,1,0,MODE_SMA,RsiPrice,i),RsiPeriod,Hot,OriginalT3,i); rsihuu = EMPTY_VALUE; rsihud = EMPTY_VALUE; rsihdd = EMPTY_VALUE; rsihdu = EMPTY_VALUE; slope = (i<Bars-1) ? (rsi>rsi[i+1]) ? 1 : (rsi<rsi[i+1]) ? -1 : slope[i+1] : 0; trend = (i<Bars-1) ? (rsi>0) ? 1 : (rsi<0) ? -1 : trend[i+1] : 0;
- if(rsi>0) if(slope==1) rsihuu = rsi; else rsihud = rsi; if(rsi<0) if(slope==1) rsihdu = rsi; else rsihdd = rsi;
- if(arrowsVisible) { ObjectDelete(arrowsIdentifier+":1:"+(string)Time); ObjectDelete(arrowsIdentifier+":2:"+(string)Time); string lookFor = arrowsIdentifier+":"+(string)Time; ObjectDelete(lookFor); if(i<(Bars-1) && arrowsOnZeroCross && trend != trend[i+1]) { if(trend == 1) drawArrow("1",0.5,i,arrowsOnZeroCrossUpColor,arrowsOnZeroCrossUpCode,arrowsOnZeroCrossUpSize,false); if(trend ==-1) drawArrow("1",0.5,i,arrowsOnZeroCrossDnColor,arrowsOnZeroCrossDnCode,arrowsOnZeroCrossDnSize,true); } if(i<(Bars-1) && arrowsOnSlope && slope != slope[i+1]) { if(slope == 1) drawArrow("2",1,i,arrowsOnSlopeUpColor,arrowsOnSlopeUpCode,arrowsOnSlopeUpSize,false); if(slope ==-1) drawArrow("2",1,i,arrowsOnSlopeDnColor,arrowsOnSlopeDnCode,arrowsOnSlopeDnSize,true); } } } } if(alertsOn) { int whichBar = 1; if(alertsOnCurrent) whichBar = 0; static datetime time1 = 0; static string mess1 = ""; if(alertsOnSlope && slope[whichBar] != slope[whichBar+1]) { if(slope[whichBar] == 1) doAlert(time1,mess1,whichBar,"sloping up"); if(slope[whichBar] ==-1) doAlert(time1,mess1,whichBar,"sloping down"); } static datetime time2 = 0; static string mess2 = ""; if(alertsOnZeroCross && trend[whichBar] != trend[whichBar+1]) { if(trend[whichBar] == 1) doAlert(time2,mess2,whichBar,"crossing zero up"); if(trend[whichBar] == -1) doAlert(time2,mess2,whichBar,"crossing zero down"); } } return(0); }
- double workRsi[][1];#define _price 0
- //+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+double iRsi(double price, double period, double hot, bool original, int i) { if(ArrayRange(workRsi,0)!=Bars) ArrayResize(workRsi,Bars); workRsi[Bars-i-1][_price] = price;
-
-
- double chng = workRsi[Bars-i-1][_price]-workRsi[Bars-i-2][_price]; double change = iT3(chng,period,hot,original,i,0); double changa = iT3(fabs(chng),period,hot,original,i,1); if(changa != 0) return(fmin(fmax(50.0*(change/fmax(changa,0.0000001)),-50),50)); else return(0); }
-
- #define t3Instances 2double workT3[][t3Instances*6];double workT3Coeffs[][6];#define _tperiod 0#define _c1 1#define _c2 2#define _c3 3#define _c4 4#define _alpha 5
- //+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+double iT3(double price, double period, double hot, bool original, int i, int tinstanceNo=0) { if(ArrayRange(workT3,0) != Bars) ArrayResize(workT3,Bars); if(ArrayRange(workT3Coeffs,0) < (tinstanceNo+1)) ArrayResize(workT3Coeffs,tinstanceNo+1);
- if(workT3Coeffs[tinstanceNo][_tperiod] != period) { workT3Coeffs[tinstanceNo][_tperiod] = period; double a = hot; workT3Coeffs[tinstanceNo][_c1] = -a*a*a; workT3Coeffs[tinstanceNo][_c2] = 3*a*a+3*a*a*a; workT3Coeffs[tinstanceNo][_c3] = -6*a*a-3*a-3*a*a*a; workT3Coeffs[tinstanceNo][_c4] = 1+3*a+a*a*a+3*a*a; if(original) workT3Coeffs[tinstanceNo][_alpha] = 2.0/(1.0 + period); else workT3Coeffs[tinstanceNo][_alpha] = 2.0/(2.0 + (period-1.0)/2.0); }
- int instanceNo = tinstanceNo*6; int r = Bars-i-1; if(r == 0) { workT3[r][0+instanceNo] = price; workT3[r][1+instanceNo] = price; workT3[r][2+instanceNo] = price; workT3[r][3+instanceNo] = price; workT3[r][4+instanceNo] = price; workT3[r][5+instanceNo] = price; } else { workT3[r][0+instanceNo] = workT3[r-1][0+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(price -workT3[r-1][0+instanceNo]); workT3[r][1+instanceNo] = workT3[r-1][1+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][0+instanceNo]-workT3[r-1][1+instanceNo]); workT3[r][2+instanceNo] = workT3[r-1][2+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][1+instanceNo]-workT3[r-1][2+instanceNo]); workT3[r][3+instanceNo] = workT3[r-1][3+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][2+instanceNo]-workT3[r-1][3+instanceNo]); workT3[r][4+instanceNo] = workT3[r-1][4+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][3+instanceNo]-workT3[r-1][4+instanceNo]); workT3[r][5+instanceNo] = workT3[r-1][5+instanceNo]+workT3Coeffs[tinstanceNo][_alpha]*(workT3[r][4+instanceNo]-workT3[r-1][5+instanceNo]); }
- return(workT3Coeffs[tinstanceNo][_c1]*workT3[r][5+instanceNo] + workT3Coeffs[tinstanceNo][_c2]*workT3[r][4+instanceNo] + workT3Coeffs[tinstanceNo][_c3]*workT3[r][3+instanceNo] + workT3Coeffs[tinstanceNo][_c4]*workT3[r][2+instanceNo]); }
- //+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+void doAlert(datetime& previousTime, string& previousAlert, int forBar, string doWhat) { string message;
- if(previousAlert != doWhat || previousTime != Time[forBar]) { previousAlert = doWhat; previousTime = Time[forBar]; message = StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS),"RT动量",doWhat); if(alertsMessage) Alert(message); if(alertsPushNotif) SendNotification(message); if(alertsEmail) SendMail(_Symbol+" RT动量 ",message); if(alertsSound) PlaySound(soundFile); } }
-
复制代码
|