MQL5 简介(第 11 部分):MQL5 中使用内置指标的初学者指南(二)·进阶篇
📘

MQL5 简介(第 11 部分):MQL5 中使用内置指标的初学者指南(二)·进阶篇

第 2/3 篇

◍ 用 RSI 拐点配均线抓隐藏背离

识别最近的 RSI 高/低点是把指标行为和价格行为对齐的第一步。隐藏看涨背离出现在价格抬出更高的低点、而 RSI 却压出更低的低点时,市场后续延续上行的概率偏大;反过来的隐藏看跌背离则是价格更低的高点配 RSI 更高的高点,下行倾向更明显。外汇与贵金属杠杆高,这类信号只是概率优势,不是确定性结论。 判定 RSI 低点不能随便取谷底。原文逻辑要求:低点前至少有一次看跌运动,随后连续三次看涨运动(即 RSI 从 i+4 到 i+3 下滑,再 i+3→i+2→i+1→i 连续抬升),扫描范围限定最后 30 根柱。命中的点要记下 RSI 值、对应收盘价、同位置 MA 值及时间戳,再用 corresponding_low_value > corresponding_low_ma 与 close[0] > ma_buffer[0] 双重校验,价格仍站在均线上才认作有效。 找完首个显著低点,还要向后搜一个更新的更低 RSI 低点:只需一根看跌回落接一根看涨回升,且新低点 RSI 低于前低、价格却高于前低(更高低点)。满足后图上会拉出趋势线并标 L / LL(RSI 侧)与 L / HL(价格侧)。若 close[0] 跌破 ma_buffer[0] 或期间最低收盘价跌破 corresponding_low_value,ObjectDelete() 会清掉这些标记,避免过期图形干扰。 看跌一侧镜像处理:RSI 高点需一次看涨运动后接三次看跌运动,新高点 RSI 更高而价格形成更低高点(LH),标记 H / HH 与 H / LH。同样在价格收上 MA 或价格突破前高时删对象。下面这段声明是后续全部计算的地基,先吃透变量分工再谈信号。

MQL5 / C++
class=class="str">"cmt">//DECLEAR INDICATOR HANDLES
class="type">int ma_handle;
class="type">int rsi_handle;
class="type">int stoch_handle;
class=class="str">"cmt">//DECLEAR DOUBLE VARIABLES THAT STORES INDICATORS DATA
class="type">class="kw">double ma_buffer[];
class="type">class="kw">double rsi_buffer[];
class="type">class="kw">double stoch_buffer_k[], stoch_buffer_d[];
class=class="str">"cmt">//DECLEAR VARIABLES TO STORE CANDLE DATA
class="type">class="kw">double open[];
class="type">class="kw">double close[];
class="type">class="kw">double high[];
class="type">class="kw">double low[];
class="type">class="kw">datetime time[];
class=class="str">"cmt">//DECLEAR VARIBLE ROR RSI LOW AND CORESPONDING  CANDLE
class="type">class="kw">double  rsi_low_value;           class=class="str">"cmt">// Stores the RSI value at the identified low point.
class="type">class="kw">double  corresponding_low_value; class=class="str">"cmt">// Stores the price(closing value) corresponding to the RSI low.

三指标句柄与缓冲区怎么挂

这段初始化逻辑把 EMA200、RSI(14) 与 Stochastic(5,3,3) 三个句柄在 OnInit 里一次性建好,周期都取 PERIOD_CURRENT,也就是跟随当前图表周期跑,不写死。EMA 用 PRICE_CLOSE、RSI 同样收线价, stochastic 则按 STO_LOWHIGH 取高低价区间,参数直接对应 MT5 插入指标时的默认面板。 所有数组都调了 ArraySetAsSeries(...,true),含义是把索引 0 指向最新一根蜡烛,回看历史时顺着下标增大往过去数。若漏掉这步,后面用 ma_buffer[1] 取到的会是 30 根前的旧值,信号整体错位。 OnTick 里 CopyBuffer 的起始位是 1、长度是 30,即从第二根蜡烛往前拉 30 根(不含当前未收线根),覆盖 ma / stoch_k / stoch_d / rsi 四个缓冲区。CopyOpen 同样从 1 拉 30,保证 K 线与指标数组下标对齐,避免用错位价格做背离判定。外汇与贵金属杠杆高,这类 EA 逻辑仅作信号辅助,实盘前请在策略测试器用历史数据验证缓冲区对齐效果。

MQL5 / C++
class="type">class="kw">double   corresponding_low_ma;     class=class="str">"cmt">// Stores the Moving Average value at the same point.
class="type">class="kw">datetime rsi_low_time;              class=class="str">"cmt">// Stores the timestamp of the RSI low.
class=class="str">"cmt">//DECLEAR VARIABLE FOR THE MINIMUM CORRESPONDING PRICE VALUE
class="type">int   minimum_value_low;
class=class="str">"cmt">//DECLEAR VARIBLE ROR NEW RSI LOW AND CORESPONDING  CANDLE
class="type">class="kw">double new_rsi_low_value;
class="type">class="kw">datetime new_rsi_low_time;
class="type">class="kw">double new_corresponding_low_value;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Expert initialization function                                     |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
class=class="str">"cmt">//INDICATOR PROPERTIES
   ma_handle = iMA(_Symbol,PERIOD_CURRENT,class="num">200,class="num">0,MODE_EMA,PRICE_CLOSE);
   rsi_handle = iRSI(_Symbol,PERIOD_CURRENT,class="num">14,PRICE_CLOSE);
   stoch_handle = iStochastic(_Symbol,PERIOD_CURRENT,class="num">5,class="num">3,class="num">3,MODE_SMA,STO_LOWHIGH);
class=class="str">"cmt">//START FROM THE LATEST CANDLE ON THE CHART
   ArraySetAsSeries(ma_buffer,true);
   ArraySetAsSeries(rsi_buffer,true);
   ArraySetAsSeries(stoch_buffer_k,true);
   ArraySetAsSeries(stoch_buffer_d,true);
class=class="str">"cmt">//START FROM THE LATEST CANDLE ON THE CHART
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(time,true);
   class="kw">return(INIT_SUCCEEDED);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Expert deinitialization function                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnDeinit(const class="type">int reason)
  {
class=class="str">"cmt">//---
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Expert tick function                                             |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTick()
  {
class=class="str">"cmt">//COPY INDICATOR&class="macro">#x27;S DATA FROM THE SECOND BAR ON THE CHART TO THE LAST 31st BAR ON THE CHART
   CopyBuffer(ma_handle,class="num">0,class="num">1,class="num">30,ma_buffer);
   CopyBuffer(stoch_handle,class="num">0,class="num">1,class="num">30,stoch_buffer_k);
   CopyBuffer(stoch_handle,class="num">1,class="num">1,class="num">30,stoch_buffer_d);
   CopyBuffer(rsi_handle,class="num">0,class="num">1,class="num">30,rsi_buffer);
class=class="str">"cmt">//COPY CANDLE&class="macro">#x27;S DATA FROM THE SECOND BAR ON THE CHART TO THE LAST 31st BAR ON THE CHART
   CopyOpen(_Symbol,PERIOD_CURRENT,class="num">1,class="num">30,open);

「定位最近一次 RSI 低点并画线」

在 MT5 的 EA 或指标里,先通过 CopyClose、CopyHigh、CopyLow、CopyTime 把当前图表最近 30 根 K 线的收盘价、最高价、最低价和时间拉进数组,避免后续循环里反复访问历史缓冲区。 随后用 for 循环扫这 30 根 K 线,并加一组边界判断(i+4 仍小于 30)防止数组越界。逻辑上找的是 RSI 缓冲区里的一段“谷”:rsi_buffer[i+4] > rsi_buffer[i+3] 且后续三根依次抬升,即 i+3 位置为局部 RSI 低点。 一旦命中,就把该低点的 RSI 值、对应收盘价、对应 MA 值以及时间存下来并 break,相当于只取图表上“最新的”那一个 RSI 低点。 用 Bars() 算出从该 RSI 低点到当前 K 线共跨了多少根,再用 ArrayMinimum(close,0,total_bars_2) 找这段区间内的最低收盘价下标。若对应 candle 低点在 MA 上方、现价也在 MA 上方、且区间最低收盘价不低于当时低点,就倾向认为结构未被破坏。 最后用 ObjectCreate 画两条 OBJ_TREND 水平线,分别标 RSI 低值和对应当根收盘价,并染成黑色,方便肉眼核对背离区。外汇与贵金属波动剧烈,这类结构识别只提供概率参考,实盘前请在策略测试器里用不同品种验证。

MQL5 / C++
CopyClose(_Symbol,PERIOD_CURRENT,class="num">1,class="num">30,close);
CopyHigh(_Symbol,PERIOD_CURRENT,class="num">1,class="num">30,high);
CopyLow(_Symbol,PERIOD_CURRENT,class="num">1,class="num">30,low);
CopyTime(_Symbol,PERIOD_CURRENT,class="num">1,class="num">30,time);
class=class="str">"cmt">//LOOP THROUGH THE LAST class="num">30 BARS ON THE CHART
for(class="type">int i = class="num">0; i < class="num">30; i++)
  {
  class=class="str">"cmt">//PREVENT ARRAY OUT OF RANGE ERROR
  if((i+class="num">1 < class="num">30) && (i+class="num">2 < class="num">30) && (i < class="num">30) && (i+class="num">3 < class="num">30) && (i+class="num">4 < class="num">30))
    {
    class=class="str">"cmt">//LOGIC TO IDENTIFY THE LATEST RSI LOW
    if(rsi_buffer[i+class="num">4] > rsi_buffer[i+class="num">3] && rsi_buffer[i+class="num">2] > rsi_buffer[i+class="num">3] && rsi_buffer[i+class="num">1] > rsi_buffer[i+class="num">2] && rsi_buffer[i] > rsi_buffer[i+class="num">1])
      {
      class=class="str">"cmt">//GETTING LATEST RSI LOW, CORRESPONDING CANDLE LOW, CORRESPONDING MA VALUE, and RSI TIME
      rsi_low_value = rsi_buffer[i+class="num">3];
      corresponding_low_value = close[i+class="num">3];
      corresponding_low_ma = ma_buffer[i+class="num">3];
      rsi_low_time = time[i+class="num">3];
      break;
      }
    }
  }
class=class="str">"cmt">//TOTAL NUMBERS OF BARS FROM THE LAST SIGNIFICANT RSI LOW
class="type">int total_bars_2 = class="num">0;
total_bars_2 = Bars(_Symbol,PERIOD_CURRENT,rsi_low_time, time[class="num">0]);
class=class="str">"cmt">//MINIMUM CLOSE PRICE FROM THE LAST SIGNIFICANT RSI LOW
minimum_value_low = ArrayMinimum(close,class="num">0,total_bars_2);
if(corresponding_low_value > corresponding_low_ma && close[class="num">0] > ma_buffer[class="num">0] && close[minimum_value_low] >= corresponding_low_value)
  {
  class=class="str">"cmt">//CREATE LINES TO MARK RSI AND CORRESPONDING CANDLE LOW
  ObjectCreate(ChartID(),"RSI LOW VALUE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,TimeCurrent(),rsi_low_value);
  ObjectCreate(ChartID(),"C-CANDLE",OBJ_TREND,class="num">0,rsi_low_time,corresponding_low_value,TimeCurrent(),corresponding_low_value);
  class=class="str">"cmt">//SETTING OBJECTS COLOUR
  ObjectSetInteger(ChartID(),"RSI LOW VALUE",OBJPROP_COLOR,clrBlack);
  ObjectSetInteger(ChartID(),"C-CANDLE",OBJPROP_COLOR,clrBlack);
  class=class="str">"cmt">//CREATE TWO LINES TO CONNECT RSI LOW AND THE CORRESPONDING PRICE ON THE CHART

◍ 在图上画出隐藏牛背离的锚点

把 RSI 低点对应的价格和指标值同时画到主图与副图,是识别隐藏牛背离的第一步。下面这段代码在主图 0 上画一条从 rsi_low_time 出发、纵坐标为 corresponding_low_value 的 OBJ_TREND,并在副图 1 画一条纵坐标为 rsi_low_value、上下边界 0~100 的参考线,两条线都设为 clrBlack。

MQL5 / C++
ObjectCreate(ChartID(),"C-CANDLE LINE",OBJ_TREND,class="num">0,rsi_low_time,corresponding_low_value,rsi_low_time,class="num">0);
ObjectCreate(ChartID(),"RSI LOW LINE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,rsi_low_time,class="num">100);
class=class="str">"cmt">//SETTING OBJECTS COLOUR
ObjectSetInteger(ChartID(),"C-CANDLE LINE",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"RSI LOW LINE",OBJPROP_COLOR,clrBlack);
class=class="str">"cmt">//CREATE TEXTS TO MART RSI LOW AND CORRESPONDING PRICE(C-PRICE)
ObjectCreate(ChartID(),"C-CANDLE TEXT",OBJ_TEXT,class="num">0,TimeCurrent(),corresponding_low_value);
ObjectSetString(ChartID(),"C-CANDLE TEXT",OBJPROP_TEXT,"C-PRICE");
ObjectCreate(ChartID(),"RSI LOW TEXT",OBJ_TEXT,class="num">1,TimeCurrent(),rsi_low_value);
ObjectSetString(ChartID(),"RSI LOW TEXT",OBJPROP_TEXT,"RSI LOW");
class=class="str">"cmt">//SETTING TEXT COLOUR
ObjectSetInteger(ChartID(),"C-CANDLE TEXT",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"RSI LOW TEXT",OBJPROP_COLOR,clrBlack);
逐行拆解:前两行 ObjectCreate 分别在主图、副图建立趋势线对象;中间四行 ObjectSetInteger 统一把线色刷成黑;随后四个 ObjectCreate+ObjectSetString 在主图副图当前时间处打上“C-PRICE”“RSI LOW”文字标签,最后两行给文字也上黑色。 新的 RSI 低点判定靠三根 K 线:rsi_buffer[0] > rsi_buffer[1] 且 rsi_buffer[1] < rsi_buffer[2],同时 rsi_buffer[1] 低于已有 rsi_low_value、close[1] 高于 corresponding_low_value,才把 1 号柱记为新低点。
MQL5 / C++
class=class="str">"cmt">//class="num">19 LOGIC TO GET THE NEW RSI LOW
if(rsi_buffer[class="num">0] > rsi_buffer[class="num">1] && rsi_buffer[class="num">1] < rsi_buffer[class="num">2] && rsi_buffer[class="num">1] < rsi_low_value && close[class="num">1] > corresponding_low_value)
  {
   new_rsi_low_value = rsi_buffer[class="num">1];
   new_rsi_low_time = time[class="num">1];
   new_corresponding_low_value = close[class="num">1];
  }
class=class="str">"cmt">//CONDITION FOR HIDDEN BULLISH DIVERGENCE
if(rsi_low_value > new_rsi_low_value && corresponding_low_value < new_corresponding_low_value)
  {
   ObjectCreate(ChartID(),"RSI LOW TREND LINE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,new_rsi_low_time,new_rsi_low_value);
   ObjectCreate(ChartID(),"L",OBJ_TEXT,class="num">1,rsi_low_time,rsi_low_value);
   ObjectSetString(ChartID(),"L",OBJPROP_TEXT,"L");
   ObjectSetInteger(ChartID(),"L",OBJPROP_FONTSIZE,class="num">15);
   ObjectSetInteger(ChartID(),"RSI LOW TREND LINE",OBJPROP_COLOR,clrBlack);
   ObjectSetInteger(ChartID(),"L",OBJPROP_COLOR,clrBlack);
当旧 RSI 低点高于新 RSI 低点、但旧价格低点低于新价格低点,隐藏牛背离成立。代码在副图连一条 RSI 低点趋势线并标“L”(字号 15),外汇与贵金属品种在此信号下反弹概率偏大,但杠杆市场高风险,仍须结合止损。

MQL5 / C++
ObjectCreate(ChartID(),"C-CANDLE LINE",OBJ_TREND,class="num">0,rsi_low_time,corresponding_low_value,rsi_low_time,class="num">0);
ObjectCreate(ChartID(),"RSI LOW LINE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,rsi_low_time,class="num">100);
class=class="str">"cmt">//SETTING OBJECTS COLOUR
ObjectSetInteger(ChartID(),"C-CANDLE LINE",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"RSI LOW LINE",OBJPROP_COLOR,clrBlack);
class=class="str">"cmt">//CREATE TEXTS TO MART RSI LOW AND CORRESPONDING PRICE(C-PRICE)
ObjectCreate(ChartID(),"C-CANDLE TEXT",OBJ_TEXT,class="num">0,TimeCurrent(),corresponding_low_value);
ObjectSetString(ChartID(),"C-CANDLE TEXT",OBJPROP_TEXT,"C-PRICE");
ObjectCreate(ChartID(),"RSI LOW TEXT",OBJ_TEXT,class="num">1,TimeCurrent(),rsi_low_value);
ObjectSetString(ChartID(),"RSI LOW TEXT",OBJPROP_TEXT,"RSI LOW");
class=class="str">"cmt">//SETTING TEXT COLOUR
ObjectSetInteger(ChartID(),"C-CANDLE TEXT",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"RSI LOW TEXT",OBJPROP_COLOR,clrBlack);
class=class="str">"cmt">//class="num">19 LOGIC TO GET THE NEW RSI LOW
if(rsi_buffer[class="num">0] > rsi_buffer[class="num">1] && rsi_buffer[class="num">1] < rsi_buffer[class="num">2] && rsi_buffer[class="num">1] < rsi_low_value && close[class="num">1] > corresponding_low_value)
  {
   new_rsi_low_value = rsi_buffer[class="num">1];
   new_rsi_low_time = time[class="num">1];
   new_corresponding_low_value = close[class="num">1];
  }
class=class="str">"cmt">//CONDITION FOR HIDDEN BULLISH DIVERGENCE
if(rsi_low_value > new_rsi_low_value && corresponding_low_value < new_corresponding_low_value)
  {
   ObjectCreate(ChartID(),"RSI LOW TREND LINE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,new_rsi_low_time,new_rsi_low_value);
   ObjectCreate(ChartID(),"L",OBJ_TEXT,class="num">1,rsi_low_time,rsi_low_value);
   ObjectSetString(ChartID(),"L",OBJPROP_TEXT,"L");
   ObjectSetInteger(ChartID(),"L",OBJPROP_FONTSIZE,class="num">15);
   ObjectSetInteger(ChartID(),"RSI LOW TREND LINE",OBJPROP_COLOR,clrBlack);
   ObjectSetInteger(ChartID(),"L",OBJPROP_COLOR,clrBlack);

在图上标出隐藏背离并自动撤掉失效信号

这段逻辑干两件事:当 RSI 出现更低的低点但价格对应低点抬高时,在副图打 "LL" 标签、在主图画连接两根蜡烛低点的趋势线并标 "L" 与 "HL";一旦价格收盘跌破均线或刺穿前低,就批量删除这些对象。 标 RSI 低点的代码直接用 ObjectCreate 在 subwindow 1 建文本 "LL",坐标取 new_rsi_low_time 与 new_rsi_low_value,字号 15、黑色。主图趋势线 "C-CANDLE TREND LINE" 用 OBJ_TREND,两端锚在 rsi_low_time/corresponding_low_value 与 new_rsi_low_time/new_corresponding_low_value,同样黑色绘制。 失效判定写在 else 分支:close[0] < ma_buffer[0] 或 close[minimum_value_low] < corresponding_low_value 任一成立,便 ObjectDelete 清掉包括 "RSI LOW VALUE" "C-CANDLE" "L" "LL" 在内的 10 个对象名。外汇与贵金属波动大,这类标记仅作结构参考,信号失效速度可能快于预期,请先在 MT5 策略测试器跑一遍验证。

MQL5 / C++
ObjectCreate(ChartID(),"LL",OBJ_TEXT,class="num">1,new_rsi_low_time,new_rsi_low_value);
ObjectSetString(ChartID(),"LL",OBJPROP_TEXT,"LL");
ObjectSetInteger(ChartID(),"LL",OBJPROP_FONTSIZE,class="num">15);
ObjectSetInteger(ChartID(),"LL",OBJPROP_COLOR,clrBlack);
class=class="str">"cmt">//for candle
ObjectCreate(ChartID(),"C-CANDLE TREND LINE",OBJ_TREND,class="num">0,rsi_low_time,corresponding_low_value,new_rsi_low_time,new_corresponding_low_value);
ObjectCreate(ChartID(),"CL",OBJ_TEXT,class="num">0,rsi_low_time,corresponding_low_value);
ObjectSetString(ChartID(),"CL",OBJPROP_TEXT,"L");
ObjectSetInteger(ChartID(),"CL",OBJPROP_FONTSIZE,class="num">15);
ObjectSetInteger(ChartID(),"C-CANDLE TREND LINE",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"CL",OBJPROP_COLOR,clrBlack);
ObjectCreate(ChartID(),"CLL",OBJ_TEXT,class="num">0,new_rsi_low_time,new_corresponding_low_value);
ObjectSetString(ChartID(),"CLL",OBJPROP_TEXT,"HL");
ObjectSetInteger(ChartID(),"CLL",OBJPROP_FONTSIZE,class="num">15);
ObjectSetInteger(ChartID(),"CLL",OBJPROP_COLOR,clrBlack);
}
}
class=class="str">"cmt">//LOGIC TO DELETE THE OBJECTS WHEN ITS NO LONGER RELEVEANT
else
if((close[class="num">0] < ma_buffer[class="num">0]) || (close[minimum_value_low] < corresponding_low_value))
{
ObjectDelete(ChartID(),"RSI LOW VALUE");
ObjectDelete(ChartID(),"C-CANDLE");
ObjectDelete(ChartID(),"C-CANDLE LINE");
ObjectDelete(ChartID(),"RSI LOW LINE");
ObjectDelete(ChartID(),"C-CANDLE TEXT");
ObjectDelete(ChartID(),"RSI LOW TEXT");
ObjectDelete(ChartID(),"RSI LOW TREND LINE");
ObjectDelete(ChartID(),"L");
ObjectDelete(ChartID(),"LL");

「背离信号的可视化落点」

当价格低点抬升而 RSI 低点继续下移,这段逻辑就在图上把背离关系画出来。先清掉旧对象再建新线,避免 MT5 图表上堆叠重复图形导致刷新卡顿。 触发条件写得很具体:corresponding_low_value 大于对应均线值、close[0] 站上 ma_buffer[0]、且最低 K 线收盘价不低于对应低值,才允许画线。RSI 子图用 OBJ_TREND 绑 rsi_low_time 与 rsi_low_value,主图用另一条 OBJ_TREND 绑同源时间的对应价格,两条水平线颜色全设 clrBlack。 文本标签 C-PRICE 与 RSI LOW 用 OBJ_TEXT 挂在 TimeCurrent() 位置,方便你一眼对出“指标低”和“价格低”的错位。若 rsi_buffer[1] 是局部凹点且收盘价已破前低对应价,new_rsi_low_value 被刷新为 buffer[1],后续再用 rsi_low_value > new_rsi_low_value 且价格更低来连出趋势线。 外汇与贵金属波动受杠杆放大,这类背离线只提示概率倾斜,实盘前请在策略测试器用历史数据验证重绘频率。

MQL5 / C++
ObjectDelete(ChartID(),"C-CANDLE TREND LINE");
ObjectDelete(ChartID(),"CL");
ObjectDelete(ChartID(),"RSI LOW TEXT");
ObjectDelete(ChartID(),"CLL");
}
if(corresponding_low_value > corresponding_low_ma && close[class="num">0] > ma_buffer[class="num">0] && close[minimum_value_low] >= corresponding_low_value)
class=class="str">"cmt">//CREATE LINES TO MARK RSI AND CORRESPONDING PRICE
ObjectCreate(ChartID(),"RSI LOW VALUE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,TimeCurrent(),rsi_low_value);
ObjectCreate(ChartID(),"C-CANDLE",OBJ_TREND,class="num">0,rsi_low_time,corresponding_low_value,TimeCurrent(),corresponding_low_value);
class=class="str">"cmt">//SETTING OBJECTS COLOUR
ObjectSetInteger(ChartID(),"RSI LOW VALUE",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"C-CANDLE",OBJPROP_COLOR,clrBlack);
class=class="str">"cmt">//CREATE TWO LINES TO CONNECT RSI LOW AND THE CORRESPONDING PRICE ON THE CHART
ObjectCreate(ChartID(),"C-CANDLE LINE",OBJ_TREND,class="num">0,rsi_low_time,corresponding_low_value,rsi_low_time,class="num">0);
ObjectCreate(ChartID(),"RSI LOW LINE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,rsi_low_time,class="num">100);
class=class="str">"cmt">//SETTING OBJECTS COLOUR
ObjectSetInteger(ChartID(),"C-CANDLE LINE",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"RSI LOW LINE",OBJPROP_COLOR,clrBlack);
class=class="str">"cmt">//CREATE TEXTS TO MART RSI LOW AND CORRESPONDING PRICE(C-PRICE)
ObjectCreate(ChartID(),"C-CANDLE TEXT",OBJ_TEXT,class="num">0,TimeCurrent(),corresponding_low_value);
ObjectSetString(ChartID(),"C-CANDLE TEXT",OBJPROP_TEXT,"C-PRICE");
ObjectCreate(ChartID(),"RSI LOW TEXT",OBJ_TEXT,class="num">1,TimeCurrent(),rsi_low_value);
ObjectSetString(ChartID(),"RSI LOW TEXT",OBJPROP_TEXT,"RSI LOW");
class=class="str">"cmt">//SETTING TEXT COLOUR
ObjectSetInteger(ChartID(),"C-CANDLE TEXT",OBJPROP_COLOR,clrBlack);
ObjectSetInteger(ChartID(),"RSI LOW TEXT",OBJPROP_COLOR,clrBlack);
if(rsi_buffer[class="num">0] > rsi_buffer[class="num">1] && rsi_buffer[class="num">1] < rsi_buffer[class="num">2] && rsi_buffer[class="num">1] < rsi_low_value && close[class="num">1] > corresponding_low_value)
  {
  new_rsi_low_value = rsi_buffer[class="num">1];
  new_rsi_low_time = time[class="num">1];
  new_corresponding_low_value = close[class="num">1];
  }
if(rsi_low_value > new_rsi_low_value && corresponding_low_value < new_corresponding_low_value)
class=class="str">"cmt">//FOR RSI
ObjectCreate(ChartID(),"RSI LOW TREND LINE",OBJ_TREND,class="num">1,rsi_low_time,rsi_low_value,new_rsi_low_time,new_rsi_low_value);

常见问题

先取 RSI 句柄和均线句柄,定位最近一次 RSI 低点,若价格更高但 RSI 更低即为隐藏牛背离,在对应 K 线画锚点即可。
用 iRSI、iMA 等函数创建句柄,CopyBuffer 把指标值拷进数组,再用 PlotIndexSetInteger 绑定到图表缓冲区。
可以,小布盯盘的 AIGC 已内置多指标背离诊断,打开对应品种页就能看到隐藏牛背离标记和失效撤单提示。
当价格跌破前低或 RSI 上破原拐点,原背离逻辑失效,代码里检测条件后删除箭头和线段即可。
循环从右往左比对本根与左右两根 RSI 值,确认严格小于邻值才记低点,再用时间与价格坐标打锚点,避免含未来函数。