📅 财经日历 📊 实时波动 📈 大盘云图 📶 行情走势 🆚 投机情绪 🚀 今日热点

    请老师修改截图中颜色编号,感激不尽!祝老师操作全胜! 

    2026-06-17 · 314 阅读
    截图中有两种颜色,一个红色一个绿色,两种颜色都分粗细,并且各有颜色编号。请老师帮忙把红色粗细颜色合并成同一个红色编号,比如编号0,绿色粗细柱子合并成同一个绿色编号,比如编号1.   其他逻辑框架一切不变,只合并颜色编号。再次表示感谢!


    //------------------------------------------------------------------
    #property copyright "外汇EA之家 修复版-保留跨周期 无致命重绘"
    #property link      "https://www.eazhijia.com"
    #property version   "2.00"
    //------------------------------------------------------------------

    enum enMacdType
    {
       macd_onReg,    // Regular macd
       macd_onZlag,   // Macd based on zero lag ma(已去除回溯重绘)
       macd_onRsi,    // Macd based on Rsi
       macd_onMom,    // Macd based on Momentum
       macd_onCci,    // Macd based on Cci
       macd_onSto     // Macd based on Stochastic
    };

    #property indicator_separate_window
    #property indicator_buffers  7
    #property indicator_color1   clrGreen
    #property indicator_color2   clrGreen
    #property indicator_color3   clrRed
    #property indicator_color4   clrRed
    #property indicator_color5   clrGray
    #property indicator_color6   clrGold
    #property indicator_color7   clrDimGray
    #property indicator_width1   1
    #property indicator_width2   2
    #property indicator_width3   1
    #property indicator_width4   2
    #property indicator_width5   2
    #property indicator_width6   1

    input string             inp_Macd_Set              = "MACD settings";
    input int                FastEMA        = 12;
    input int                SlowEMA        = 26;
    input int                SignalEMA      = 9;
    input ENUM_APPLIED_PRICE PriceType      = PRICE_CLOSE;
    input bool               ShowHisto      = true;
    input bool               ShowOSMA       = false;
    input int                OsmaMultiplier = 2;
    input bool               ShowLines      = true;
    input enMacdType         MACDType       = macd_onReg;
    input int                RSIPeriod      = 14;
    input int                MOMPeriod      = 14;
    input int                CCIPeriod      = 10;
    input int                StoK_period    = 14;
    input int                StoD_period    = 3;
    input int                StoSl_period   = 3;
    input int                StoPriceField  = 0;
    input int                StoMain_MaMode = 0;
    input int                StoSig_MaMode  = 0;
    input int                baseMaPeriod   = 1;
    input int                baseMaMode     = 0;

    input string TimeFrame         = "Current time frame";
    input string  inp_Alert_Set               = "alerts";
    input bool    alertsOn         = true;
    input bool    MACDalerts       = true;
    input bool    OsMAalerts       = true;
    input bool    alertsMessage    = true;
    input bool    alertsSound      = true;
    input bool    alertsEmail      = false;
    input string  soundfile        = "news.wav";

    input string  inp_Arrow_Set              = "arrows";
    input bool     arrowsVisible    = false;
    input bool     arrowsOnNewest   = false;
    input string   arrowsIdentifier = "macd Arrows1";
    input double   arrowsUpperGap   = 0.5;
    input double   arrowsLowerGap   = 0.5;
    input color    arrowsUpColor    = clrBlue;
    input color    arrowsDnColor    = clrCrimson;
    input int      arrowsUpCode     = 233;
    input int      arrowsDnCode     = 234;
    input int      arrowsUpSize     = 2;
    input int      arrowsDnSize     = 2;

    input string  note_MACD_Types_ = "0 regularMACD 1ZeroLag(无回溯) 2MACDofRSI  3MACDofMomentum 4MACDofCCI 5MACDofStochastic";
    input string  Sto_PriceField_  = "0Low/High  1Close/Close";

    double buffer1[];
    double buffer2[];
    double buffer3[];
    double buffer4[];
    double buffer5[];
    double buffer6[];
    double buffer7[];
    double buffer8[],slope[];
    string IndicatorName;
    int    targetTF;

    string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
    int    iTfTable[]  = {1,5,15,30,60,240,1440,10080,43200};

    //+------------------------------------------------------------------+
    int OnInit()
    {
       int i; // 全局函数内仅声明一次循环变量i
       IndicatorBuffers(9);
       SetIndexBuffer(0,buffer1,INDICATOR_DATA);
       SetIndexBuffer(1,buffer2,INDICATOR_DATA);
       SetIndexBuffer(2,buffer3,INDICATOR_DATA);
       SetIndexBuffer(3,buffer4,INDICATOR_DATA);
       SetIndexBuffer(4,buffer5,INDICATOR_DATA);
       SetIndexBuffer(5,buffer6,INDICATOR_DATA);
       SetIndexBuffer(6,buffer7,INDICATOR_DATA);
       SetIndexBuffer(7,buffer8,INDICATOR_DATA);
       SetIndexBuffer(8,slope,INDICATOR_DATA);
       
       bool local_ShowHisto = ShowHisto;
       if(ShowOSMA) local_ShowHisto = true;
       SetIndexStyle(6,DRAW_LINE);
       
       if(local_ShowHisto)
       {
          SetIndexStyle(0,DRAW_HISTOGRAM);
          SetIndexStyle(1,DRAW_HISTOGRAM);
          SetIndexStyle(2,DRAW_HISTOGRAM);
          SetIndexStyle(3,DRAW_HISTOGRAM);
       }
       else
       {
          SetIndexStyle(0,DRAW_NONE);
          SetIndexStyle(1,DRAW_NONE);
          SetIndexStyle(2,DRAW_NONE);
          SetIndexStyle(3,DRAW_NONE);
       }
       
       if(ShowLines)
       {
          SetIndexStyle(4,DRAW_LINE);
          SetIndexStyle(5,DRAW_LINE);
       }
       else
       {
          SetIndexStyle(4,DRAW_NONE);
          SetIndexStyle(5,DRAW_NONE);
       }
       
       targetTF = StringToTimeFrame(TimeFrame);
       string tfName = TimeFrameToString(targetTF);
       IndicatorShortName(tfName+" MACD CrossTF Fixed");
       IndicatorName = WindowExpertName();
       return INIT_SUCCEEDED;
    }
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
       int i;
       string filter = arrowsIdentifier+":";
       int len = StringLen(filter);
       for(i=ObjectsTotal()-1; i>=0; i--)
       {
          string n = ObjectName(i);
          if(StringSubstr(n,0,len)==filter) ObjectDelete(0,n);
       }
    }
    //+------------------------------------------------------------------+
    int OnCalculate(const int rates_total,
                    const int prev_calculated,
                    const datetime &time[],
                    const double &open[],
                    const double &high[],
                    const double &low[],
                    const double &close[],
                    const long &tick_volume[],
                    const long &volume[],
                    const int &spread[])
    {
       int i; // 本函数仅此处声明一次i,所有循环复用
       double alpha = 2.0/(1.0+SignalEMA);
       int start = prev_calculated>0 ? prev_calculated-1 : 0;
       int limit = rates_total-1;

       double tf_base[];
       ArraySetAsSeries(tf_base,true);
       ArrayResize(tf_base,limit+1);
       
       for(i=limit; i>=start; i--)
       {
          datetime barTime = time[i];
          int shiftTF = iBarShift(_Symbol,targetTF,barTime,false);
          if(shiftTF<0) { buffer8[i]=0; continue; }
          
          switch(MACDType)
          {
             case macd_onRsi:
                buffer8[i] = iRSI(_Symbol,targetTF,RSIPeriod,PriceType,shiftTF); break;
             case macd_onMom:
                buffer8[i] = iMomentum(_Symbol,targetTF,MOMPeriod,PriceType,shiftTF); break;
             case macd_onCci:
                buffer8[i] = iCCI(_Symbol,targetTF,CCIPeriod,PriceType,shiftTF); break;
             case macd_onSto:
                buffer8[i] = iStochastic(_Symbol,targetTF,StoK_period,StoD_period,StoSl_period,StoMain_MaMode,StoPriceField,0,shiftTF); break;
             default:
                buffer8[i] = iMA(_Symbol,targetTF,baseMaPeriod,0,baseMaMode,PriceType,shiftTF);
          }
       }

       for(i=limit; i>=start; i--)
       {
          buffer1[i]=EMPTY_VALUE; buffer2[i]=EMPTY_VALUE;
          buffer3[i]=EMPTY_VALUE; buffer4[i]=EMPTY_VALUE;
          slope[i] = (i==limit) ? 0 : slope[i+1];
          double val_prev = 0.0;
          if(i < limit) val_prev = ShowOSMA ? (buffer5[i+1]-buffer6[i+1])*OsmaMultiplier : buffer5[i+1];
          
          if(MACDType == macd_onZlag)
          {
             double mf = iMAOnArray(buffer8,0,FastEMA,0,MODE_EMA,i);
             double ms = iMAOnArray(buffer8,0,SlowEMA,0,MODE_EMA,i);
             double mf_next = mf,ms_next=ms;
             if(i < limit)
             {
                 mf_next = iMAOnArray(buffer8,0,FastEMA,0,MODE_EMA,i+1);
                 ms_next = iMAOnArray(buffer8,0,SlowEMA,0,MODE_EMA,i+1);
             }
             buffer5[i] = (mf*2 - mf_next) - (ms*2 - ms_next);
          }
          else
          {
             buffer5[i] = iMAOnArray(buffer8,0,FastEMA,0,MODE_EMA,i) - iMAOnArray(buffer8,0,SlowEMA,0,MODE_EMA,i);
             buffer6[i] = buffer6[i+1] + alpha*(buffer5[i] - buffer6[i+1]);
          }
          
          double val = ShowOSMA ? (buffer5[i]-buffer6[i])*OsmaMultiplier : buffer5[i];
          if(val>0)
          {
             if(val>val_prev) buffer2[i]=val;
             else buffer1[i]=val;
          }
          else
          {
             if(val<val_prev) buffer4[i]=val;
             else buffer3[i]=val;
          }
          
          if(val>val_prev) slope[i]=1;
          if(val<val_prev) slope[i]=-1;
          
          if(i>=2 && arrowsVisible) ManageArrow(i,time[i]);
          
          if(ShowOSMA) buffer7[i] = val;
       }

       if(alertsOn && start>=2)
       {
          int c1=1,c2=2,c3=3;
          if(MACDalerts)
          {
             if(buffer5[c1]>0 && buffer5[c2]<0) DoAlert("MACD线上穿0轴 多头");
             if(buffer5[c1]<0 && buffer5[c2]>0) DoAlert("MACD线下穿0轴 空头");
          }
          if(MACDalerts || OsMAalerts)
          {
             if(buffer6[c1]<buffer5[c1] && buffer6[c2]>buffer5[c2]) DoAlert("MACD金叉");
             if(buffer6[c1]>buffer5[c1] && buffer6[c2]<buffer5[c2]) DoAlert("MACD死叉");
          }
          if(OsMAalerts)
          {
             if(buffer7[c1]>buffer7[c2] && buffer7[c3]>buffer7[c2]) DoAlert("OSMA柱拐头向上");
             if(buffer7[c1]<buffer7[c2] && buffer7[c3]<buffer7[c2]) DoAlert("OSMA柱拐头向下");
          }
       }
       return rates_total;
    }
    //+------------------------------------------------------------------+
    void ManageArrow(int i,datetime t)
    {
       string objName = arrowsIdentifier+":"+(string)t;
       ObjectDelete(0,objName);
       if(slope[i]==slope[i+1]) return;
       
       double atrVal = iATR(_Symbol,_Period,20,i);
       datetime drawT = t;
       if(arrowsOnNewest) drawT += _Period*60-1;
       
       ObjectCreate(0,objName,OBJ_ARROW,0,drawT,0);
       ObjectSetInteger(0,objName,OBJPROP_WIDTH,slope[i]==1 ? arrowsUpSize : arrowsDnSize);
       ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,slope[i]==1 ? arrowsUpCode : arrowsDnCode);
       ObjectSetInteger(0,objName,OBJPROP_COLOR,slope[i]==1 ? arrowsUpColor : arrowsDnColor);
       
       if(slope[i]==1)
          ObjectSetDouble(0,objName,OBJPROP_PRICE1,Low[i] - arrowsLowerGap*atrVal);
       else
          ObjectSetDouble(0,objName,OBJPROP_PRICE1,High[i] + arrowsUpperGap*atrVal);
    }
    //+------------------------------------------------------------------+
    void DoAlert(string text)
    {
       static string lastMsg="";
       static datetime lastT=0;
       string msg = StringFormat("%s | %s",_Symbol,text);
       datetime now = TimeCurrent();
       if(lastMsg==msg && lastT==now) return;
       lastMsg=msg; lastT=now;
       
       if(alertsMessage) Alert(msg);
       if(alertsSound) PlaySound(soundfile);
       if(alertsEmail) SendMail("MACD交叉信号",msg);
    }
    //+------------------------------------------------------------------+
    int StringToTimeFrame(string tfStr)
    {
       int i;
       string s = StringUpperCase(tfStr);
       for(i=0; i<ArraySize(iTfTable); i++)
       {
          if(s==sTfTable[i] || s==(string)iTfTable[i])
             return iTfTable[i];
       }
       return _Period;
    }
    //+------------------------------------------------------------------+
    string TimeFrameToString(int tf)
    {
       int i;
       for(i=0; i<ArraySize(iTfTable); i++)
          if(iTfTable[i]==tf) return sTfTable[i];
       return "";
    }
    //+------------------------------------------------------------------+
    string StringUpperCase(string str)
    {
       int i;
       string res=str;
       int len=StringLen(str);
       for(i=0; i<len; i++)
       {
          int c = StringGetChar(res,i);
          if(c>96 && c<123) StringSetChar(res,i,c-32);
       }
       return res;
    }

    指标截图.jpg
    ""
    还没有人打赏,支持一下
    回复

    举报

     

    回答|共 11 个

    yang5277229 LV10

    发表于 2026-6-17 17:07:30 | 显示全部楼层

    888.png
    666.png

    以用ai帮你修复了,并把参数栏部分用中文表示
    1414.mq4 售价: 1 枚金币 (一共需要3金币)

    641386452 LV6

    发表于 2026-6-17 18:27:20 | 显示全部楼层

    yang5277229 发表于 2026-6-17 17:07
    以用ai帮你修复了,并把参数栏部分用中文表示

    谢谢老师,祝多多发财!

    641386452 LV6

    发表于 2026-6-17 18:50:56 | 显示全部楼层

    yang5277229 发表于 2026-6-17 17:07
    以用ai帮你修复了,并把参数栏部分用中文表示

    老师,你用的是什么名字的AI?,我用豆包和deepseek好多次都没成功。

    yang5277229 LV10

    发表于 2026-6-17 19:35:48 | 显示全部楼层

    要爬墙的

    ych711 LV2

    发表于 2026-6-17 20:04:12 | 显示全部楼层

    AI好像就能实现

    641386452 LV6

    发表于 2026-6-17 20:25:08 | 显示全部楼层


    爬墙的是什么意思,就是名字吗

    love4604 LV3

    发表于 2026-6-17 20:42:23 | 显示全部楼层

    641386452 发表于 2026-6-17 20:25
    爬墙的是什么意思,就是名字吗

    国外的ChatGPT和Claude都是国内不能访问的。

    641386452 LV6

    发表于 2026-6-17 22:25:23 | 显示全部楼层

    yang5277229 发表于 2026-6-17 17:07
    以用ai帮你修复了,并把参数栏部分用中文表示

    老师,非常感谢你给我修改的代码,但现在有个问题,不刷新或切换窗口,指标就不更新,麻烦再帮我看看。
    //------------------------------------------------------------------
    #property copyright "外汇EA之家 修复版-保留跨周期 无致命重绘"
    #property link      "https://www.eazhijia.com"
    #property version   "2.00"
    //------------------------------------------------------------------

    enum enMacdType
    {
       macd_onReg,    // 常规MACD
       macd_onZlag,   // 零滞后MACD(已去除回溯重绘)
       macd_onRsi,    // 基于RSI的MACD
       macd_onMom,    // 基于动量的MACD
       macd_onCci,    // 基于CCI的MACD
       macd_onSto     // 基于随机指标的MACD
    };

    #property indicator_separate_window
    #property indicator_buffers  5
    #property indicator_color1   clrGreen      // 0轴上方直方图
    #property indicator_color2   clrRed        // 0轴下方直方图
    #property indicator_color3   clrGray       // MACD主线
    #property indicator_color4   clrGold       // 信号线
    #property indicator_color5   clrDimGray    // OSMA线
    #property indicator_width1   2
    #property indicator_width2   2
    #property indicator_width3   2
    #property indicator_width4   1

    //-----------------------------MACD参数--------------------------------
    input string             inp_Macd_Set              = "MACD设置";
    input int                FastEMA        = 12;       // 快线EMA周期
    input int                SlowEMA        = 26;       // 慢线EMA周期
    input int                SignalEMA      = 9;        // 信号线周期
    input ENUM_APPLIED_PRICE PriceType      = PRICE_CLOSE; // 应用价格
    input bool               ShowHisto      = true;     // 显示直方图
    input bool               ShowOSMA       = false;    // 显示OSMA
    input int                OsmaMultiplier = 2;        // OSMA乘数
    input bool               ShowLines      = true;     // 显示信号线
    input enMacdType         MACDType       = macd_onReg; // MACD类型
    input int                RSIPeriod      = 14;       // RSI周期
    input int                MOMPeriod      = 14;       // 动量周期
    input int                CCIPeriod      = 10;       // CCI周期
    input int                StoK_period    = 14;       // Stochastic K周期
    input int                StoD_period    = 3;        // Stochastic D周期
    input int                StoSl_period   = 3;        // Stochastic 平滑周期
    input int                StoPriceField  = 0;        // Sto价格类型(0=Low/High, 1=Close/Close)
    input int                StoMain_MaMode = 0;        // Sto主线模式
    input int                StoSig_MaMode  = 0;        // Sto信号线模式
    input int                baseMaPeriod   = 1;        // 基础MA周期(常规模式)
    input int                baseMaMode     = 0;        // 基础MA模式

    input string TimeFrame         = "Current time frame"; // 目标时间框架

    //-----------------------------警报参数--------------------------------
    input string  inp_Alert_Set               = "警报设置";
    input bool    alertsOn         = true;     // 开启警报
    input bool    MACDalerts       = true;     // MACD交叉警报
    input bool    OsMAalerts       = true;     // OSMA转折警报
    input bool    alertsMessage    = true;     // 弹出消息
    input bool    alertsSound      = true;     // 声音提示
    input bool    alertsEmail      = false;    // 发送邮件
    input string  soundfile        = "news.wav"; // 声音文件

    //-----------------------------箭头参数--------------------------------
    input string  inp_Arrow_Set              = "箭头设置";
    input bool     arrowsVisible    = false;   // 显示箭头
    input bool     arrowsOnNewest   = false;   // 箭头画在K线末端
    input string   arrowsIdentifier = "macd Arrows1"; // 箭头标识
    input double   arrowsUpperGap   = 0.5;     // 上方距离(ATR倍数)
    input double   arrowsLowerGap   = 0.5;     // 下方距离(ATR倍数)
    input color    arrowsUpColor    = clrBlue; // 上涨箭头颜色
    input color    arrowsDnColor    = clrCrimson; // 下跌箭头颜色
    input int      arrowsUpCode     = 233;     // 上涨箭头代码
    input int      arrowsDnCode     = 234;     // 下跌箭头代码
    input int      arrowsUpSize     = 2;       // 上涨箭头大小
    input int      arrowsDnSize     = 2;       // 下跌箭头大小

    input string  note_MACD_Types_ = "0=常规,1=零滞后(无回溯),2=基于RSI,3=基于动量,4=基于CCI,5=基于随机";
    input string  Sto_PriceField_  = "0=Low/High, 1=Close/Close";

    //---- 缓冲区声明(共9个)----
    double buffer1[];   // 0轴上方绿色直方图
    double buffer2[];   // 原上升减弱辅助(现已废弃,内部用)
    double buffer3[];   // 0轴下方红色直方图
    double buffer4[];   // 原下跌减弱辅助(现已废弃,内部用)
    double buffer5[];   // MACD主线
    double buffer6[];   // 信号线
    double buffer7[];   // OSMA线
    double buffer8[];   // 基础数据跨周期存储
    double slope[];     // 方向记录(箭头用)

    string IndicatorName;
    int    targetTF;

    string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
    int    iTfTable[]  = {1,5,15,30,60,240,1440,10080,43200};

    //+------------------------------------------------------------------+
    int OnInit()
    {
       IndicatorBuffers(9);
       
       // 索引 0-4:绘图缓冲区(会出现在数据窗口)
       SetIndexBuffer(0, buffer1, INDICATOR_DATA);   // 绿色柱
       SetIndexBuffer(1, buffer3, INDICATOR_DATA);   // 红色柱
       SetIndexBuffer(2, buffer5, INDICATOR_DATA);   // MACD线
       SetIndexBuffer(3, buffer6, INDICATOR_DATA);   // 信号线
       SetIndexBuffer(4, buffer7, INDICATOR_DATA);   // OSMA线
       
       // 索引 5-8:计算辅助缓冲区(不会出现在数据窗口)
       SetIndexBuffer(5, buffer2, INDICATOR_CALCULATIONS);
       SetIndexBuffer(6, buffer4, INDICATOR_CALCULATIONS);
       SetIndexBuffer(7, buffer8, INDICATOR_CALCULATIONS);
       SetIndexBuffer(8, slope,  INDICATOR_CALCULATIONS);
       
       bool local_ShowHisto = ShowHisto;
       if(ShowOSMA) local_ShowHisto = true;
       
       // 直方图显示控制
       if(local_ShowHisto)
       {
          SetIndexStyle(0, DRAW_HISTOGRAM);   // 绿色柱
          SetIndexStyle(1, DRAW_HISTOGRAM);   // 红色柱
       }
       else
       {
          SetIndexStyle(0, DRAW_NONE);
          SetIndexStyle(1, DRAW_NONE);
       }
       
       // 信号线显示控制
       if(ShowLines)
       {
          SetIndexStyle(2, DRAW_LINE);        // MACD线
          SetIndexStyle(3, DRAW_LINE);        // 信号线
       }
       else
       {
          SetIndexStyle(2, DRAW_NONE);
          SetIndexStyle(3, DRAW_NONE);
       }
       
       // OSMA线显示控制
       if(ShowOSMA)
          SetIndexStyle(4, DRAW_LINE);
       else
          SetIndexStyle(4, DRAW_NONE);
       
       targetTF = StringToTimeFrame(TimeFrame);
       string tfName = TimeFrameToString(targetTF);
       IndicatorShortName(tfName + " 跨周期MACD 修复版");
       IndicatorName = WindowExpertName();
       return INIT_SUCCEEDED;
    }
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
       for(int i = ObjectsTotal() - 1; i >= 0; i--)
       {
          string n = ObjectName(i);
          if(StringSubstr(n, 0, StringLen(arrowsIdentifier + ":")) == arrowsIdentifier + ":")
             ObjectDelete(0, n);
       }
    }
    //+------------------------------------------------------------------+
    int OnCalculate(const int rates_total,
                    const int prev_calculated,
                    const datetime &time[],
                    const double &open[],
                    const double &high[],
                    const double &low[],
                    const double &close[],
                    const long &tick_volume[],
                    const long &volume[],
                    const int &spread[])
    {
       int i;
       double alpha = 2.0 / (1.0 + SignalEMA);
       int start = prev_calculated > 0 ? prev_calculated - 1 : 0;
       int limit = rates_total - 1;
       if(limit < 0) return 0;

       double tf_base[];
       ArraySetAsSeries(tf_base, true);
       ArrayResize(tf_base, limit + 1);
       
       // 第一阶段:获取目标周期基础数据
       for(i = limit; i >= start; i--)
       {
          datetime barTime = time;
          int shiftTF = iBarShift(_Symbol, targetTF, barTime, false);
          if(shiftTF < 0) { buffer8 = EMPTY_VALUE; continue; }
          
          switch(MACDType)
          {
             case macd_onRsi:
                buffer8 = iRSI(_Symbol, targetTF, RSIPeriod, PriceType, shiftTF); break;
             case macd_onMom:
                buffer8 = iMomentum(_Symbol, targetTF, MOMPeriod, PriceType, shiftTF); break;
             case macd_onCci:
                buffer8 = iCCI(_Symbol, targetTF, CCIPeriod, PriceType, shiftTF); break;
             case macd_onSto:
                buffer8 = iStochastic(_Symbol, targetTF, StoK_period, StoD_period, StoSl_period, StoMain_MaMode, StoPriceField, 0, shiftTF); break;
             default:
                buffer8 = iMA(_Symbol, targetTF, baseMaPeriod, 0, baseMaMode, PriceType, shiftTF);
          }
       }

       // 第二阶段:计算MACD及信号线
       for(i = limit; i >= start; i--)
       {
          buffer1 = EMPTY_VALUE;
          buffer2 = EMPTY_VALUE;
          buffer3 = EMPTY_VALUE;
          buffer4 = EMPTY_VALUE;
          
          // 计算MACD主线
          if(MACDType == macd_onZlag)
          {
             double mf = iMAOnArray(buffer8, 0, FastEMA, 0, MODE_EMA, i);
             double ms = iMAOnArray(buffer8, 0, SlowEMA, 0, MODE_EMA, i);
             double mf_next = mf, ms_next = ms;
             if(i < limit)
             {
                mf_next = iMAOnArray(buffer8, 0, FastEMA, 0, MODE_EMA, i + 1);
                ms_next = iMAOnArray(buffer8, 0, SlowEMA, 0, MODE_EMA, i + 1);
             }
             buffer5 = (mf * 2 - mf_next) - (ms * 2 - ms_next);
          }
          else
          {
             buffer5 = iMAOnArray(buffer8, 0, FastEMA, 0, MODE_EMA, i)
                        - iMAOnArray(buffer8, 0, SlowEMA, 0, MODE_EMA, i);
          }
          
          // 信号线计算
          if(i == limit)
             buffer6 = buffer5;
          else
             buffer6 = buffer6[i + 1] + alpha * (buffer5 - buffer6[i + 1]);
          
          double val_prev = (i < limit) ? (ShowOSMA ? (buffer5[i + 1] - buffer6[i + 1]) * OsmaMultiplier : buffer5[i + 1]) : 0.0;
          double val = ShowOSMA ? (buffer5 - buffer6) * OsmaMultiplier : buffer5;
          
          // 0轴上方绿色,下方红色
          if(val > 0)
             buffer1 = val;
          else if(val < 0)
             buffer3 = val;
          
          slope = 0;
          if(i < limit)
          {
             if(val > val_prev) slope = 1;
             else if(val < val_prev) slope = -1;
             else slope = slope[i + 1];
          }
          
          if(i >= 2 && arrowsVisible) ManageArrow(i, time);
          
          if(ShowOSMA) buffer7 = val;
          else buffer7 = EMPTY_VALUE;
       }

       // 警报(最新K线)
       if(alertsOn && limit >= 2)
       {
          int last  = limit;
          int prev  = limit - 1;
          int prev2 = limit - 2;
          if(prev2 < 0) return rates_total;
          
          if(MACDalerts)
          {
             if(buffer5[last] > 0 && buffer5[prev] < 0) DoAlert("MACD线上穿0轴 多头");
             if(buffer5[last] < 0 && buffer5[prev] > 0) DoAlert("MACD线下穿0轴 空头");
          }
          if(MACDalerts || OsMAalerts)
          {
             if(buffer6[last] < buffer5[last] && buffer6[prev] > buffer5[prev]) DoAlert("MACD金叉");
             if(buffer6[last] > buffer5[last] && buffer6[prev] < buffer5[prev]) DoAlert("MACD死叉");
          }
          if(OsMAalerts)
          {
             if(buffer7[last] > buffer7[prev] && buffer7[prev2] > buffer7[prev]) DoAlert("OSMA柱拐头向上");
             if(buffer7[last] < buffer7[prev] && buffer7[prev2] < buffer7[prev]) DoAlert("OSMA柱拐头向下");
          }
       }
       return rates_total;
    }
    //+------------------------------------------------------------------+
    void ManageArrow(int i, datetime t)
    {
       if(i >= Bars - 1) return;
       if(slope == slope[i + 1]) return;
       
       string objName = arrowsIdentifier + ":" + (string)t;
       if(ObjectFind(0, objName) < 0)
       {
          ObjectCreate(0, objName, OBJ_ARROW, 0, t, 0);
          ObjectSetInteger(0, objName, OBJPROP_WIDTH, slope == 1 ? arrowsUpSize : arrowsDnSize);
          ObjectSetInteger(0, objName, OBJPROP_ARROWCODE, slope == 1 ? arrowsUpCode : arrowsDnCode);
          ObjectSetInteger(0, objName, OBJPROP_COLOR, slope == 1 ? arrowsUpColor : arrowsDnColor);
       }
       else
       {
          ObjectSetInteger(0, objName, OBJPROP_WIDTH, slope == 1 ? arrowsUpSize : arrowsDnSize);
          ObjectSetInteger(0, objName, OBJPROP_ARROWCODE, slope == 1 ? arrowsUpCode : arrowsDnCode);
          ObjectSetInteger(0, objName, OBJPROP_COLOR, slope == 1 ? arrowsUpColor : arrowsDnColor);
       }
       
       double atrVal = iATR(_Symbol, _Period, 20, i);
       datetime drawT = t;
       if(arrowsOnNewest) drawT += _Period * 60 - 1;
       ObjectSetInteger(0, objName, OBJPROP_TIME, drawT);
       
       if(slope == 1)
          ObjectSetDouble(0, objName, OBJPROP_PRICE1, Low - arrowsLowerGap * atrVal);
       else
          ObjectSetDouble(0, objName, OBJPROP_PRICE1, High + arrowsUpperGap * atrVal);
    }
    //+------------------------------------------------------------------+
    void DoAlert(string text)
    {
       static string lastMsg = "";
       static datetime lastT = 0;
       string msg = StringFormat("%s | %s", _Symbol, text);
       datetime now = TimeCurrent();
       if(lastMsg == msg && lastT == now) return;
       lastMsg = msg; lastT = now;
       
       if(alertsMessage) Alert(msg);
       if(alertsSound) PlaySound(soundfile);
       if(alertsEmail) SendMail("MACD交叉信号", msg);
    }
    //+------------------------------------------------------------------+
    int StringToTimeFrame(string tfStr)
    {
       string s = StringUpperCase(tfStr);
       for(int i = 0; i < ArraySize(iTfTable); i++)
       {
          if(s == sTfTable || s == (string)iTfTable)
             return iTfTable;
       }
       return _Period;
    }
    //+------------------------------------------------------------------+
    string TimeFrameToString(int tf)
    {
       for(int i = 0; i < ArraySize(iTfTable); i++)
          if(iTfTable == tf) return sTfTable;
       return "";
    }
    //+------------------------------------------------------------------+
    string StringUpperCase(string str)
    {
       string res = str;
       int len = StringLen(str);
       for(int i = 0; i < len; i++)
       {
          int c = StringGetChar(res, i);
          if(c > 96 && c < 123) StringSetChar(res, i, c - 32);
       }
       return res;
    }
    //+------------------------------------------------------------------+

    yang5277229 LV10

    发表于 2026-6-18 00:08:07 | 显示全部楼层

    641386452 发表于 2026-6-17 22:25
    老师,非常感谢你给我修改的代码,但现在有个问题,不刷新或切换窗口,指标就不更新,麻烦再帮我看看。
    / ...


    22GIF.gif


    你给的原始代码就不更新,你也没说,
    下面是最终修复版本,这次要收取2金币了,哈哈哈
    1414.mq4 售价: 2 枚金币 (一共需要4金币)
    12下一页
    您需要登录后才可以回帖 登录 | 注册

    提醒: 禁止引战、谩骂、灌水内容

    微信二维码

    有问题联系客服