KD报警求助!!!

楼主  收藏   举报   帖子创建时间:  2019-05-05 05:13 回复:0 关注量:376
网上看到一个思路很好的报警指标, 但是有一个问题,报不了警, 请高手帮忙看一看, 非常感谢!
  
  
  
  以下内容为转载:
  
  
  
  
  
  KDJ提醒器 0.5
  我自己写的KDJ提醒器。
  它可以设置两个时间框架(Timeframe)及KDJ指标(实际上使用的不是KDJ指标而是MT4自带的Stochastic指标)的相关参数,当KDJ在两个时间框架上同时出现低位金叉或高位死叉时,将会向你发现提示信息。在选择入场点时,KDJ出现低位金叉或高位死叉是一个非常不错的判断方法。
  
  相关参数说明:
  p_RefTimeframe1:参考时间框架1,默认值:PERIOD_M5 (即5分钟图)
  p_RefTimeframe2:参数时间框架2,默认值:PERIOD_M15(即15分钟图)
  p_CareCrossType:所关心的交叉点类型(1-关注金叉,-1-关注死叉,0-不关注任何交叉,相当于暂停处理),默认值:1
  
  p_TopLimit:死叉时,KD的值必须高于这个值(即需要高位死叉)
  p_BottomLimit:金叉时,KD的值必须底于这个值(即需要低位金叉)
  
  p_Kperiod:KDJ指标的%K周期,默认值:8
  p_Dperiod:KDJ指标的%D周期,默认值:5
  p_Slowing:慢线周期,默认值:3
  
  p_MessageboxAlarm:出现条件时,是否弹出消息提示对象框,默认值:true
  p_SendMailAlarm:是否发邮件提示消息,默认值:false
  
  
  我在中国移动可以申请一个手机邮箱,并开通了邮件到达通知功能,这样我把p_SendMailAlarm参数设置成true,于是这个“邮件提示”就变成了“短信提示”,非常好用。
  
  
  源代码如下:
  //+------------------------------------------------------------------+
  //|                                              KDJ交叉信号告警.mq4 |
  //|                                                        Jesse Loo |
  //|                                                                  |
  //+------------------------------------------------------------------+
  //** KDJ交叉信号告警 **
  //当KDJ出现指定的金叉或死叉时发出告警
  //Version: 0.50
  //Date: 2007.01.25
  //修改记录:
  #property copyright "Jesse Loo"
  #property link      ""
  string    EA_FLAG = "EA_KDJ_0.50";       //自动交易程序的标志
  
  
  
  // **** 外部参数 ****
  extern int  p_RefTimeframe1    = PERIOD_M5;  //参考时间框架1
  extern int  p_RefTimeframe2    = PERIOD_M15; //参考时间框架2
  
  extern int  p_CareCrossType    = 1;          //所关心的交叉点类型(1-关注金叉,-1-关注死叉,
                                               //0-不关注任何交叉,相当于暂停处理)
  
  extern int  p_TopLimit         = 20;         //死叉时,KDJ的值必须高于这个值
  extern int  p_BottomLimit      = 80;         //金叉时,KDJ的值必须底于这个值
  
  extern int  p_Kperiod          = 8;          //%K周期
  extern int  p_Dperiod          = 5;          //%D周期
  extern int  p_Slowing          = 3;          //慢线周期
  
  extern bool p_MessageboxAlarm  = true;       //弹出消息提示
  extern bool p_SendMailAlarm    = false;      //发送邮件提示信息
  
  
  
  // **** 全局变量 ****
  datetime    g_dtLastCrossTime   = 0;         //前一次告警的最后一个交叉点的出现时间
  
  
  
  
  //+------------------------------------------------------------------+
  //| expert initialization function                                   |
  //+------------------------------------------------------------------+
  int init()
  {
     if (GlobalVariableCheck("KDJCross_ForceSendMailAlarm") &&
         MathAbs(GlobalVariableGet("KDJCross_ForceSendMailAlarm")) > 0.9999)
     {
        Print("KDJCross_ForceSendMailAlarm = true");
     }
     else
     {
        Print("KDJCross_ForceSendMailAlarm = false");
     }
  
     return(0);
  }
  
  
  
  //+------------------------------------------------------------------+
  //| expert deinitialization function                                 |
  //+------------------------------------------------------------------+
  int deinit()
  {
  
     return(0);
  }
  
  
  //+------------------------------------------------------------------+
  //| expert start function                                            |
  //+------------------------------------------------------------------+
  int start()
  {  
     int      nRef1CrossType = 0;
     datetime dtRef1CrossTime = 0;
     
     int      nRef2CrossType = 0;
     datetime dtRef2CrossTime = 0;
     
     datetime dtLastCrossTime = 0;
     
     if (p_RefTimeframe1 > 0)
     {
        //在参考时间框架1寻找第一个交叉点
        nRef1CrossType = FindKDJCross(dtRef1CrossTime, p_RefTimeframe1, p_Kperiod, p_Dperiod, p_Slowing);      
  
        if (nRef1CrossType != -999 && dtRef1CrossTime >dtLastCrossTime)
        {
           dtLastCrossTime = dtRef1CrossTime;
        }
     }
     
     if (p_RefTimeframe2 > 0)
     {
        //在参考时间框架2寻找第一个交叉点
        nRef2CrossType = FindKDJCross(dtRef2CrossTime, p_RefTimeframe2, p_Kperiod, p_Dperiod, p_Slowing);
  
        if (nRef1CrossType != -999 && dtRef2CrossTime >dtLastCrossTime)
        {
           dtLastCrossTime = dtRef2CrossTime;
        }
     }
     
     if ((nRef1CrossType == p_CareCrossType && nRef2CrossType == 0) ||
         (nRef1CrossType == p_CareCrossType && nRef2CrossType == p_CareCrossType))
     {
        if (dtLastCrossTime > g_dtLastCrossTime)
        {
           //告警条件达到,发出告警
           string strAlarmMsg = Symbol() + ",KDJ cross " + nRef1CrossType + " be detected!";
           
           Print("KDJ Cross Alarm: ", strAlarmMsg);
           
           bool bGlobalSendMailAlarm = false;
           if (GlobalVariableCheck("KDJCross_ForceSendMailAlarm") &&
               MathAbs(GlobalVariableGet("KDJCross_ForceSendMailAlarm")) > 0.9999)
           {
              bGlobalSendMailAlarm = true;
           }
        
           if (p_SendMailAlarm || bGlobalSendMailAlarm)
           {
              SendMail("Alarm: " + strAlarmMsg, "Alarm happened: " + strAlarmMsg);
           }
           
           if (p_MessageboxAlarm)
           {
              MessageBox(strAlarmMsg, "Alarm");
           }
           
           
           g_dtLastCrossTime = dtLastCrossTime;
        }
     }
     
     return(0);
  }
  
  //功能:寻找KDJ指示最近的一个交叉点类型
  //参数:
  //  dtCross - [out]返回交叉点的时间
  //返回:
  //  若是金叉则返回1,若是死叉则返回-1,没有找到时(如数据不足)则返回-999
  int FindKDJCross(datetime &dtCross, int nTimeframe, int nKperiod, int nDperiod, int nSlowing)
  {
     int nResult = -999;
     int nCrossValue = -1;
     
     int i;
     int nBarsCount = iBars(NULL, nTimeframe) - 30;
     
     for (i = 0; i < nBarsCount; i++)
     {
        int nMain1 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_MAIN, i);
        int nMain2 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_MAIN, i + 1);
        
        int nSignal1 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_SIGNAL, i);
        int nSignal2 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_SIGNAL, i + 1);
        
        if (nMain2 = nSignal1)
        {
           //金叉
           nResult = 1;
           nCrossValue = nMain1;
           break;
        }
        else if (nMain2 >= nSignal2 && nMain1  p_BottomLimit)
     {
        //金叉位置太高,需要忽略之
        nResult = -999;     
     }
     if (nResult == -1 && nCrossValue < p_TopLimit)
     {
        //死叉位置太低,需要忽略之
        nResult = -999;
     }
     
     if (nResult != -999)
     {
        dtCross = iTime(NULL, nTimeframe, i);
        
        //Print("In timeframe ", nTimeframe, " Cross ", nResult, " happened at ", TimeToStr(dtCross, TIME_DATE|TIME_MINUTES|TIME_SECONDS));
     }
        
     //没有找到交叉点
     return (nResult);
  }
  
  //+------------------------------------------------------------------+
打赏