如何精确判断 均线相交的金叉和死叉

 

网上 找了 均线判断金叉和死叉的指标, 发现 有些金叉和死叉无法判断到. 这个该怎么优化呢 ? 

下面是MT5 的具体指标代码:

#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 5 //定义5个画线位置
#property indicator_plots   5 //画5条线

input ulong                m_magic                    = 382418976;      // magic number







input int    StartHour = 3; // 挂单的开始时间
input int    EndHour   = 18; // 挂单的结束时间
//---- plot long
#property indicator_label5  "long55" //这条线的名称
#property indicator_type5   DRAW_LINE //这条线的类型是线性
#property indicator_color5  clrAqua //这条线的颜色
#property indicator_style5  STYLE_SOLID //这条线是实线
#property indicator_width5  3 //这条线的宽度是1


//---- plot long
#property indicator_label1  "long" //这条线的名称
#property indicator_type1   DRAW_LINE //这条线的类型是线性
#property indicator_color1  Red //这条线的颜色
#property indicator_style1  STYLE_SOLID //这条线是实线
#property indicator_width1  2 //这条线的宽度是1
//---- plot small
#property indicator_label2  "small"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Yellow
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
//---- plot up
#property indicator_label3  "up"
#property indicator_type3   DRAW_ARROW //这里我们要画箭头
#property indicator_color3  White
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
//---- plot down
#property indicator_label4  "down"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  MediumBlue
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1
//--- input parameters
input int      long55 = 55;
input int      longma = 10; //长均线周期(也就是上面图中我们输入的)
input int      smallma = 5; //短均线周期(也就是上面图中我们输入的)
//--- indicator buffers
double         longBuffer[]; //(也就是上面图中我们输入的画线是long的时候,这里就会产生一个longBuffer[]数组)
double         smallBuffer[]; //同上
double         long55Buffer[]; //同上

double         upBuffer[]; //同上
double         downBuffer[]; //同上


int             longma_handle; //这里定义长周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             smallma_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             long55_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。


int OnInit() {

   SetIndexBuffer(0,longBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,smallBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,upBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,downBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,long55Buffer,INDICATOR_DATA);

   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_ARROW);
   PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_ARROW);
   PlotIndexSetInteger(2,PLOT_ARROW,1001); //箭头类型是1001号箭头
   PlotIndexSetInteger(3,PLOT_ARROW,1002); //箭头类型是1002号箭头

    longma_handle=iMA(Symbol(),0,longma,0,MODE_EMA,PRICE_CLOSE); //初始化长周期均线函数
    smallma_handle=iMA(Symbol(),0,smallma,0,MODE_EMA,PRICE_CLOSE); //初始化短周期均线函数
    long55_handle=iMA(Symbol(),0,long55,0,MODE_SMA,PRICE_CLOSE); //初始化短周期均线函数
    
    
   

   return(0);
}



int OnCalculate(const int rates_total, // 当前图表上的柱数量
                const int prev_calculated, //本根K线前一根K线的序号,通常来说prev_calculated=rates_total-1  指标已计算的柱数量
                const datetime& time[], //存储所有K线的时间数组
                const double& open[], //存储所有K线的开盘价数组
                const double& high[], //存储所有K线的最高价数组
                const double& low[], //存储所有K线的最低价数组
                const double& close[], //存储所有K线的收盘价数组
                const long& tick_volume[], // 跳动量
                const long& volume[], // 交易量
                const int& spread[] // 点差值
                ) {
   int malong=CopyBuffer(longma_handle,0,0,rates_total,longBuffer); //  10 日均线
   int masmall=CopyBuffer(smallma_handle,0,0,rates_total,smallBuffer); // 5 日均线
   int ma55long=CopyBuffer(long55_handle,0,0,rates_total,long55Buffer); // 55 日均线
   double bid = SymbolInfoDouble( Symbol() ,SYMBOL_BID);
   double ask = SymbolInfoDouble( Symbol() ,SYMBOL_ASK);
   MqlTick last_tick;
   MqlDateTime dt;
   TimeCurrent(dt);
  
      for(int i = 1; i<rates_total; i++) {
         double highP  = high[i];
         double lowP = low[i];
         double openP  = open[i];
         double closeP = close[i];
         MqlTick last_tick; // 账户
         SymbolInfoTick(Symbol(),last_tick);
         
         
          bool preLong55for5Result_ge =  long55Buffer[i-1] > smallBuffer[i-1];// 55 线日线小于 5 日线
          bool thisLong55for5Result_lt = long55Buffer[i] < smallBuffer[i];// 55 线日线小于 5 日线
          
          bool preLong55For10Result_ge =  long55Buffer[i-1] > longBuffer[i-1]; // 55 线日线大于 10 日线
          bool thisLong55For10Result_lt = long55Buffer[i] < longBuffer[i];// 55 线日线小于 10 日线

         if(
            (preLong55for5Result_ge && thisLong55for5Result_lt)||(preLong55For10Result_ge &&  thisLong55For10Result_lt)
         ){ 
                  if(i== prev_calculated){
                      string eS=StringFormat("Time: %s,品种: %s, 5日线,或者10日上穿55日均线,看多信号. 当前买价: %f ,收盘价格: %f ",
                                             TimeLocal(),Symbol(),last_tick.ask,close[i]);
                      sendNotice(eS);
                      
                  } 
          }
            
           bool preLong55for5Result_le = (long55Buffer[i-1] < smallBuffer[i-1] ); // 55 日均线 小于 5 日线
           bool thisLong55for5Result_mt = long55Buffer[i] > smallBuffer[i];// 55 日均线 大于 5 日线
            
           bool preLong55for10Result_le = long55Buffer[i-1] < longBuffer[i-1]; // 55 日均线 小于 10 日线
           bool thisLong55for5Result10_mt = long55Buffer[i] > long55Buffer[i]; // 55 日均线 大于 10 日线
           if( (preLong55for5Result_le && thisLong55for5Result_mt )||(preLong55for10Result_le && thisLong55for5Result10_mt ) ){
                     if(i== prev_calculated){
                          //  bool isF = false; // 1.2  - 0.5 
                            //       if((closeP - lowP)  > (openP - closeP)){
                              //       isF = true;
                               //    }
                                  string eS=StringFormat("Time: %s,品种: %s, 5日线,或者10日下穿55日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                                       TimeLocal(),Symbol(),last_tick.bid,close[i]);
                                  sendNotice(eS);
                                  
                     }
                   
                   
            }
            
      
      }
   

   return(rates_total);
}

int sendNotice(string tmpEs){
   printf(tmpEs);
   //Alert(tmpEs);
   //SendMail(tmpEs,"1");
   //SendNotification(tmpEs);
   return 1;
}

void getFloatSpread() 
  { 
//--- 从交易品种属性获得点差 
   bool spreadfloat=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD_FLOAT); 
   string comm=StringFormat("Spread %s = %I64d points\r\n", 
                            spreadfloat?"floating":"fixed", 
                            SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)); 
//--- 现在自己计算点差 
   double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); 
   double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID); 
   double spread=ask-bid; 
   int spread_points=(int)MathRound(spread / SymbolInfoDouble(Symbol(),SYMBOL_POINT)); 
   comm=comm+"Calculated spread = "+(string)spread_points+" points"; 
   Comment(comm); 
  }




 
附加的文件:
bbs_d9.png  333 kb
 
附近中的图片前面的2种开多,和开空信号都完整解决,  但是在 2019-11-29 16:30 的时候, 出现了金叉, 并没有判断到呢? 上面的图是30 分钟的k 线图
 
s32967326:

网上 找了 均线判断金叉和死叉的指标, 发现 有些金叉和死叉无法判断到. 这个该怎么优化呢 ? 

下面是MT5 的具体指标代码:


没理解你所说的 没有判断到什么意思  你得程序运行是这个样子 ,原有程序没有 up、down 箭头语句是吗? 加上两句就是上图这样,你是要这样吗?另你的绘图缓冲区定义的通道序列是胡乱的重新给你 对应通道后代码如下:

#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 5//定义5个画线位置
#property indicator_plots   5 //画5条线


//---- plot long55
#property indicator_label1  "long55" //这条线的名称
#property indicator_type1   DRAW_LINE //这条线的类型是线性
#property indicator_color1  clrAqua //这条线的颜色
#property indicator_style1  STYLE_SOLID //这条线是实线
#property indicator_width1  1 //这条线的宽度是1

//---- plot long
#property indicator_label2  "long" //这条线的名称
#property indicator_type2   DRAW_LINE //这条线的类型是线性
#property indicator_color2  clrRed //这条线的颜色
#property indicator_style2  STYLE_SOLID //这条线是实线
#property indicator_width2  1 //这条线的宽度是1
//---- plot small
#property indicator_label3  "small"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrYellow
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1


//---- plot up
#property indicator_label4  "up"
#property indicator_type4   DRAW_ARROW //这里我们要画箭头
#property indicator_color4  clrWhite
#property indicator_style4  STYLE_SOLID
#property indicator_width4  3
//---- plot down
#property indicator_label5  "down"
#property indicator_type5   DRAW_ARROW
#property indicator_color5  clrMagenta
#property indicator_style5  STYLE_SOLID
#property indicator_width5  3

//--- indicator buffers
double         long55Buffer[]; //(也就是上面图中我们输入的画线是long的时候,这里就会产生一个longBuffer[]数组)
double         longBuffer[]; //同上
double         smallBuffer[]; //同上

double         upBuffer[]; //同上
double         downBuffer[]; //同上


//--- input parameters
int             long55_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             longma_handle; //这里定义长周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             smallma_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。


input ulong                m_magic                    = 382418976;      // magic number
input int    StartHour = 3; // 挂单的开始时间
input int    EndHour   = 18; // 挂单的结束时间
input int      long55 = 55;
input int      longma = 10; //长均线周期(也就是上面图中我们输入的)
input int      smallma = 5; //短均线周期(也就是上面图中我们输入的)

int OnInit() 
{
//--- indicator buffers mapping
//--- 指标缓冲区映射关系
   SetIndexBuffer(0,long55Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,longBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,smallBuffer,INDICATOR_DATA);
   
   SetIndexBuffer(3,upBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,downBuffer,INDICATOR_DATA);
  

   //PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_ARROW);
   //PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_ARROW);
   PlotIndexSetInteger(3,PLOT_ARROW,1001); //箭头类型是1001号箭头
   PlotIndexSetInteger(4,PLOT_ARROW,1002); //箭头类型是1002号箭头
   
   
    long55_handle=iMA(Symbol(),0,long55,0,MODE_SMA,PRICE_CLOSE); //初始化短周期均线函数
    longma_handle=iMA(Symbol(),0,longma,0,MODE_EMA,PRICE_CLOSE); //初始化长周期均线函数
    smallma_handle=iMA(Symbol(),0,smallma,0,MODE_EMA,PRICE_CLOSE); //初始化短周期均线函数
    
    
    
   

   return(0);
}



int OnCalculate(const int rates_total, // 当前图表上的柱数量
                const int prev_calculated, //本根K线前一根K线的序号,通常来说prev_calculated=rates_total-1  指标已计算的柱数量
                const datetime& time[], //存储所有K线的时间数组
                const double& open[], //存储所有K线的开盘价数组
                const double& high[], //存储所有K线的最高价数组
                const double& low[], //存储所有K线的最低价数组
                const double& close[], //存储所有K线的收盘价数组
                const long& tick_volume[], // 跳动量
                const long& volume[], // 交易量
                const int& spread[] // 点差值
                ) 
{
   int ma55long=CopyBuffer(long55_handle,0,0,rates_total,long55Buffer); // 55 日均线
   int malong  =CopyBuffer(longma_handle,0,0,rates_total,longBuffer); //  10 日均线
   int masmall =CopyBuffer(smallma_handle,0,0,rates_total,smallBuffer); // 5 日均线
   
   
   
   
   
   double bid = SymbolInfoDouble( Symbol() ,SYMBOL_BID);
   double ask = SymbolInfoDouble( Symbol() ,SYMBOL_ASK);
   
   
   MqlTick last_tick;
   MqlDateTime dt;
   
   TimeCurrent(dt);
  
      for(int i = 1; i<rates_total; i++) {
         double highP  = high[i];
         double lowP = low[i];
         double openP  = open[i];
         double closeP = close[i];
         MqlTick last_tick; // 账户
         
         SymbolInfoTick(Symbol(),last_tick);
         
         
          bool preLong55for5Result_ge =  long55Buffer[i-1] > smallBuffer[i-1];// 55 线日线大于于 5 日线
          bool thisLong55for5Result_lt = long55Buffer[i] < smallBuffer[i];// 55 线日线小于 5 日线
          
          bool preLong55For10Result_ge =  long55Buffer[i-1] > longBuffer[i-1]; // 55 线日线大于 10 日线
          bool thisLong55For10Result_lt = long55Buffer[i] < longBuffer[i];// 55 线日线小于 10 日线

                  if((preLong55for5Result_ge && thisLong55for5Result_lt)||(preLong55For10Result_ge &&  thisLong55For10Result_lt) )
                  
                  { 
                           if(i== prev_calculated)
                           {
                               string eS=StringFormat("Time: %s,品种: %s, 5日线,或者10日上穿55日均线,看多信号. 当前买价: %f ,收盘价格: %f ",
                                                      TimeLocal(),Symbol(),last_tick.ask,close[i]);
                               sendNotice(eS);
                               
                           } 
                           
                           upBuffer[i]=long55Buffer[i];
                   }
            
           bool preLong55for5Result_le = (long55Buffer[i-1] < smallBuffer[i-1] ); // 55 日均线 小于 5 日线
           bool thisLong55for5Result_mt = long55Buffer[i] > smallBuffer[i];// 55 日均线 大于 5 日线
            
           bool preLong55for10Result_le = long55Buffer[i-1] < longBuffer[i-1]; // 55 日均线 小于 10 日线
           bool thisLong55for5Result10_mt = long55Buffer[i] > long55Buffer[i]; // 55 日均线 大于 10 日线
           if( (preLong55for5Result_le && thisLong55for5Result_mt )||(preLong55for10Result_le && thisLong55for5Result10_mt ) )
           {
                     if(i== prev_calculated)
                     {
                          //  bool isF = false; // 1.2  - 0.5 
                            //       if((closeP - lowP)  > (openP - closeP)){
                              //       isF = true;
                               //    }
                                  string eS=StringFormat("Time: %s,品种: %s, 5日线,或者10日下穿55日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                                       TimeLocal(),Symbol(),last_tick.bid,close[i]);
                                  sendNotice(eS);
                                  
                     }
                     downBuffer[i]=long55Buffer[i];
                   
                   
            }
            
      
      }
   
   
   

   return(rates_total);
}

int sendNotice(string tmpEs){
   printf(tmpEs);
   //Alert(tmpEs);
   //SendMail(tmpEs,"1");
   //SendNotification(tmpEs);
   return 1;
}

void getFloatSpread() 
  { 
//--- 从交易品种属性获得点差 
   bool spreadfloat=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD_FLOAT); 
   string comm=StringFormat("Spread %s = %I64d points\r\n", 
                            spreadfloat?"floating":"fixed", 
                            SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)); 
//--- 现在自己计算点差 
   double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); 
   double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID); 
   double spread=ask-bid; 
   int spread_points=(int)MathRound(spread / SymbolInfoDouble(Symbol(),SYMBOL_POINT)); 
   comm=comm+"Calculated spread = "+(string)spread_points+" points"; 
   Comment(comm); 
  }


 
s32967326:
附近中的图片前面的2种开多,和开空信号都完整解决,  但是在 2019-11-29 16:30 的时候, 出现了金叉, 并没有判断到呢? 上面的图是30 分钟的k 线图

新修正的代码 白银 在 2019-11-29 16:30 的时候, 出现了金叉可以判断的出来,你是说为什么没在16:30 而是在17:00才判断是吗?还是 说为什么没出现5、10周期均线双金叉的双箭头吗?

 
Mars Yuan:

新修正的代码 白银 在 2019-11-29 16:30 的时候, 出现了金叉可以判断的出来,你是说为什么没在16:30 而是在17:00才判断是吗?还是 说为什么没出现5、10周期均线双金叉的双箭头吗?

我给你一张图和 一份新的代码
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 5 //定义5个画线位置
#property indicator_plots   5 //画5条线

input ulong                m_magic                    = 382418976;      // magic number


// 移动平均线交叉 - MetaTrader 5EA https://www.mql5.com/zh/code/21515

#include <Trade\AccountInfo.mqh>
#include<Trade\SymbolInfo.mqh>

#include<Trade\Trade.mqh>
//--- 执行交易操作的对象
CTrade  trade;




input int    StartHour = 3; // 挂单的开始时间
input int    EndHour   = 18; // 挂单的结束时间
//---- plot long
#property indicator_label5  "long55" //这条线的名称
#property indicator_type5   DRAW_LINE //这条线的类型是线性
#property indicator_color5  clrAqua //这条线的颜色
#property indicator_style5  STYLE_SOLID //这条线是实线
#property indicator_width5  3 //这条线的宽度是1


//---- plot long
#property indicator_label1  "long" //这条线的名称
#property indicator_type1   DRAW_LINE //这条线的类型是线性
#property indicator_color1  Red //这条线的颜色
#property indicator_style1  STYLE_SOLID //这条线是实线
#property indicator_width1  2 //这条线的宽度是1
//---- plot small
#property indicator_label2  "small"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Yellow
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
//---- plot up
#property indicator_label3  "up"
#property indicator_type3   DRAW_ARROW //这里我们要画箭头
#property indicator_color3  White
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
//---- plot down
#property indicator_label4  "down"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  MediumBlue
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1
//--- input parameters
input int      long55 = 55;
input int      longma = 10; //长均线周期(也就是上面图中我们输入的)
input int      smallma = 5; //短均线周期(也就是上面图中我们输入的)
//--- indicator buffers
double         longBuffer[]; //(也就是上面图中我们输入的画线是long的时候,这里就会产生一个longBuffer[]数组)
double         smallBuffer[]; //同上
double         long55Buffer[]; //同上

double         upBuffer[]; //同上
double         downBuffer[]; //同上


int             longma_handle; //这里定义长周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             smallma_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             long55_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。


int OnInit() {

   SetIndexBuffer(0,longBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,smallBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,upBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,downBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,long55Buffer,INDICATOR_DATA);

   // PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_ARROW);
   //PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_ARROW);
   PlotIndexSetInteger(2,PLOT_ARROW,1001); //箭头类型是1001号箭头
   PlotIndexSetInteger(3,PLOT_ARROW,1002); //箭头类型是1002号箭头

    longma_handle=iMA(Symbol(),0,longma,0,MODE_EMA,PRICE_CLOSE); //初始化长周期均线函数
    smallma_handle=iMA(Symbol(),0,smallma,0,MODE_EMA,PRICE_CLOSE); //初始化短周期均线函数
    long55_handle=iMA(Symbol(),0,long55,0,MODE_SMA,PRICE_CLOSE); //初始化短周期均线函数
    
    
   

   return(0);
}



int OnCalculate(const int rates_total, // 当前图表上的柱数量
                const int prev_calculated, //本根K线前一根K线的序号,通常来说prev_calculated=rates_total-1  指标已计算的柱数量
                const datetime& time[], //存储所有K线的时间数组
                const double& open[], //存储所有K线的开盘价数组
                const double& high[], //存储所有K线的最高价数组
                const double& low[], //存储所有K线的最低价数组
                const double& close[], //存储所有K线的收盘价数组
                const long& tick_volume[], // 跳动量
                const long& volume[], // 交易量
                const int& spread[] // 点差值
                ) {
   int malong=CopyBuffer(longma_handle,0,0,rates_total,longBuffer); //  10 日均线
   int masmall=CopyBuffer(smallma_handle,0,0,rates_total,smallBuffer); // 5 日均线
   int ma55long=CopyBuffer(long55_handle,0,0,rates_total,long55Buffer); // 55 日均线
   double bid = SymbolInfoDouble( Symbol() ,SYMBOL_BID);
   double ask = SymbolInfoDouble( Symbol() ,SYMBOL_ASK);
   MqlTick last_tick;
   MqlDateTime dt;
   TimeCurrent(dt);
    if( (dt.hour >= StartHour && dt.hour < EndHour)){
      for(int i = 1; i<rates_total; i++) {
         double highP  = high[i];
         double lowP = low[i];
         double openP  = open[i];
         double closeP = close[i];
         MqlTick last_tick; // 账户
         SymbolInfoTick(Symbol(),last_tick);
         
         
          bool preLong55for5Result_ge =  long55Buffer[i-1] > smallBuffer[i-1];
          bool thisLong55for5Result_lt = long55Buffer[i] < smallBuffer[i];
          
          bool preLong55For10Result_ge =  long55Buffer[i-1] > longBuffer[i-1];
          bool thisLong55For10Result_lt = long55Buffer[i] < longBuffer[i];

         if(
            (preLong55for5Result_ge && thisLong55for5Result_lt)
         ){ // 5 日线大于 55 日线,那么5 日线必然大于 10 日均线
                  if(i== prev_calculated){
                      string eS=StringFormat("Time: %s,品种: %s, 5日线上穿55日均线,看多信号. 当前买价: %f ,收盘价格: %f ",
                                             TimeLocal(),Symbol(),last_tick.ask,close[i]);
                     sendNotice(eS,1,Symbol());
                      
                  } 
          }
          
          if((preLong55For10Result_ge &&  thisLong55For10Result_lt)){
             if(i== prev_calculated){
                      string eS=StringFormat("Time: %s,品种: %s, 10日线上穿55日均线,看多信号. 当前买价: %f ,收盘价格: %f ",
                                             TimeLocal(),Symbol(),last_tick.ask,close[i]);
                     sendNotice(eS,1,Symbol());
                      
                  } 
          }

           bool preLong55for5Result_le = (long55Buffer[i-1] < smallBuffer[i-1] );
           bool thisLong55for5Result_mt = long55Buffer[i] > smallBuffer[i];
            
           bool preLong55for10Result_le = long55Buffer[i-1] < longBuffer[i-1];
           bool thisLong55for5Result10_mt = long55Buffer[i] > long55Buffer[i];
           if( (preLong55for5Result_le && thisLong55for5Result_mt ) ){
                     if(i== prev_calculated){
                            bool isF = false; // 1.2  - 0.5 
                                   if((closeP - lowP)  > (openP - closeP)){
                                     isF = true;
                                   }
                                  string eS=StringFormat("Time: %s,品种: %s, 5日线下穿55日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                                       TimeLocal(),Symbol(),last_tick.bid,close[i]);
                                  sendNotice(eS,2,Symbol());
                     }
            }
            if(preLong55for10Result_le && thisLong55for5Result10_mt ){
                if(i== prev_calculated){
                            bool isF = false; // 1.2  - 0.5 
                                   if((closeP - lowP)  > (openP - closeP)){
                                     isF = true;
                                   }
                                  string eS=StringFormat("Time: %s,品种: %s, 10日线下穿55日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                                       TimeLocal(),Symbol(),last_tick.bid,close[i]);
                                  sendNotice(eS,2,Symbol());
                     }
            }
            
         if((longBuffer[i-1] > smallBuffer[i-1]) && (longBuffer[i] <= smallBuffer[i])) { 
               upBuffer[i]=longBuffer[i]; 
               if( i == prev_calculated ){
                  string eS=StringFormat("Time: %s,品种: %s, 5日线上穿10日均线,看多信号. 当前卖价: %f ,收盘价格: %f ",
                                      TimeLocal(),Symbol(),last_tick.ask,close[i]);
                  //sendNotice(eS);
                  if(smallBuffer[i] > long55Buffer[i]){ // close[i]
                     string tmpEs = StringFormat(eS+",%s","并且在收盘价格在55日均线上方");
                     sendNotice(tmpEs,1,Symbol());
                     upBuffer[i]=long55Buffer[i];//在金叉处画上白色箭头 
                  }
               }
         }
      if((longBuffer[i-1] < smallBuffer[i-1])&&(longBuffer[i] >= smallBuffer[i])) { //判断两均线产生了死叉
         if( i == prev_calculated ){
               string eS=StringFormat("Time: %s,品种: %s, 5日线下穿10日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                   TimeLocal(),Symbol(),last_tick.bid,close[i]);
               //sendNotice(eS);
               if(smallBuffer[i] < long55Buffer[i]){
                  string tmpEs = StringFormat(eS+",%s","并且在收盘价格在55日均线下方");
                  sendNotice(tmpEs,2,Symbol());
                  downBuffer[i]=long55Buffer[i];    
               }
            }
          downBuffer[i]=longBuffer[i];   
        }    
      }
   }
   

   return(rates_total);
}

int sendNotice(string tmpEs,int orderType,string symbol){
   printf(tmpEs);
   //Alert(tmpEs);
   //SendMail(tmpEs,"1");
   //SendNotification(tmpEs);
   

   return 1;
}

void getFloatSpread() 
  { 
//--- 从交易品种属性获得点差 
   bool spreadfloat=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD_FLOAT); 
   string comm=StringFormat("Spread %s = %I64d points\r\n", 
                            spreadfloat?"floating":"fixed", 
                            SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)); 
//--- 现在自己计算点差 
   double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); 
   double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID); 
   double spread=ask-bid; 
   int spread_points=(int)MathRound(spread / SymbolInfoDouble(Symbol(),SYMBOL_POINT)); 
   comm=comm+"Calculated spread = "+(string)spread_points+" points"; 
   Comment(comm); 
   
   
  }




 
 
 //--- 买入的例子  
//+------------------------------------------------------------------+
//|  在当前交易对象上买入指定大小的量                                |                                     
//+------------------------------------------------------------------+
void BuySample1()
  {
//--- 1. 在当前交易对象上进行买入的例子
   if(!trade.Buy(0.1))
     {
      //--- 报错信息
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     
}
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     
}
//---
  
}
图里面 , 当 黄金 2019-12-03 9:30 的时候 5 日和10日线金叉, 没有发出做多信号. 能帮我找找原因吗?
附加的文件:
bbs_ku.png  323 kb
 
s32967326:
我给你一张图和 一份新的代码 图里面 , 当 黄金 2019-12-03 9:30 的时候 5 日和10日线金叉, 没有发出做多信号. 能帮我找找原因吗?

天啊 你是一直在长时间编程,休息一下;我看你是在你最初代码打补丁,静下心 仔细对比每一行代码,你的绘图缓存变量和通道的次序混乱,你的金叉死叉内部判断逻辑和箭头标明的语句位置逻辑也乱.. 因此就出莫名其妙问题...稍加整理顺序 12月3日9:30的金叉很清晰啊!!!

#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 5 //定义5个画线位置
#property indicator_plots   5 //画5条线


// 移动平均线交叉 - MetaTrader 5EA https://www.mql5.com/zh/code/21515

#include <Trade\AccountInfo.mqh>
#include<Trade\SymbolInfo.mqh>

#include<Trade\Trade.mqh>
//--- 执行交易操作的对象
CTrade  trade;


//---- plot long55
#property indicator_label1  "long55" //这条线的名称
#property indicator_type1   DRAW_LINE //这条线的类型是线性
#property indicator_color1  clrAqua //这条线的颜色
#property indicator_style1  STYLE_SOLID //这条线是实线
#property indicator_width1  1 //这条线的宽度是1

//---- plot long
#property indicator_label2  "long" //这条线的名称
#property indicator_type2   DRAW_LINE //这条线的类型是线性
#property indicator_color2  clrRed //这条线的颜色
#property indicator_style2  STYLE_SOLID //这条线是实线
#property indicator_width2  1 //这条线的宽度是1
//---- plot small
#property indicator_label3  "small"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrYellow
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1


//---- plot up
#property indicator_label4  "up"
#property indicator_type4   DRAW_ARROW //这里我们要画箭头
#property indicator_color4  clrWhite
#property indicator_style4  STYLE_SOLID
#property indicator_width4  3
//---- plot down
#property indicator_label5  "down"
#property indicator_type5   DRAW_ARROW
#property indicator_color5  clrMagenta
#property indicator_style5  STYLE_SOLID
#property indicator_width5  3

//--- indicator buffers
double         long55Buffer[]; //(也就是上面图中我们输入的画线是long的时候,这里就会产生一个longBuffer[]数组)
double         longBuffer[]; //同上
double         smallBuffer[]; //同上

double         upBuffer[]; //同上
double         downBuffer[]; //同上


//--- input parameters
int             long55_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             longma_handle; //这里定义长周期均线的句柄,有了句柄,以后就可以做相关的操作。
int             smallma_handle; //这里定义短周期均线的句柄,有了句柄,以后就可以做相关的操作。


input ulong  m_magic   = 382418976;      // magic number
input int    StartHour = 3; // 挂单的开始时间
input int    EndHour   = 18; // 挂单的结束时间
input int      long55  = 55;
input int      longma  = 10; //长均线周期(也就是上面图中我们输入的)
input int      smallma = 5; //短均线周期(也就是上面图中我们输入的)



int OnInit() 
{

//--- indicator buffers mapping
//--- 指标缓冲区映射关系
   SetIndexBuffer(0,long55Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,longBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,smallBuffer,INDICATOR_DATA);
   
   SetIndexBuffer(3,upBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,downBuffer,INDICATOR_DATA);
  

   //PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_ARROW);
   //PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_ARROW);
   PlotIndexSetInteger(3,PLOT_ARROW,1001); //箭头类型是1001号箭头
   PlotIndexSetInteger(4,PLOT_ARROW,1002); //箭头类型是1002号箭头
   
   
    long55_handle=iMA(Symbol(),0,long55,0,MODE_SMA,PRICE_CLOSE); //初始化短周期均线函数
    longma_handle=iMA(Symbol(),0,longma,0,MODE_EMA,PRICE_CLOSE); //初始化长周期均线函数
    smallma_handle=iMA(Symbol(),0,smallma,0,MODE_EMA,PRICE_CLOSE); //初始化短周期均线函数

   return(0);
}



int OnCalculate(const int rates_total, // 当前图表上的柱数量
                const int prev_calculated, //本根K线前一根K线的序号,通常来说prev_calculated=rates_total-1  指标已计算的柱数量
                const datetime& time[], //存储所有K线的时间数组
                const double& open[], //存储所有K线的开盘价数组
                const double& high[], //存储所有K线的最高价数组
                const double& low[], //存储所有K线的最低价数组
                const double& close[], //存储所有K线的收盘价数组
                const long& tick_volume[], // 跳动量
                const long& volume[], // 交易量
                const int& spread[] // 点差值
                ) 
{
   int malong=CopyBuffer(longma_handle,0,0,rates_total,longBuffer); //  10 日均线
   int masmall=CopyBuffer(smallma_handle,0,0,rates_total,smallBuffer); // 5 日均线
   int ma55long=CopyBuffer(long55_handle,0,0,rates_total,long55Buffer); // 55 日均线
   
   double bid = SymbolInfoDouble( Symbol() ,SYMBOL_BID);
   double ask = SymbolInfoDouble( Symbol() ,SYMBOL_ASK);
   
   MqlTick last_tick;
   MqlDateTime dt;
   TimeCurrent(dt);
   
    if( (dt.hour >= StartHour && dt.hour < EndHour))
    {
      for(int i = 1; i<rates_total; i++) {
         double highP  = high[i];
         double lowP = low[i];
         double openP  = open[i];
         double closeP = close[i];
         MqlTick last_tick; // 账户
         SymbolInfoTick(Symbol(),last_tick);
         
         
          bool preLong55for5Result_ge =  long55Buffer[i-1] > smallBuffer[i-1];//------5周期对55周期金叉
          bool thisLong55for5Result_lt = long55Buffer[i] < smallBuffer[i];
          
          bool preLong55For10Result_ge =  long55Buffer[i-1] > longBuffer[i-1];//------10周期对55周期金叉
          bool thisLong55For10Result_lt = long55Buffer[i] < longBuffer[i];

         if((preLong55for5Result_ge && thisLong55for5Result_lt) ) //------5周期对55周期发生金叉
         
          { 
                  //upBuffer[i]=long55Buffer[i]; //在金叉处画白色上箭头 
                  if(i== prev_calculated)
                  {
                      string eS=StringFormat("Time: %s,品种: %s, 5日线上穿55日均线,看多信号. 当前买价: %f ,收盘价格: %f ",
                                             TimeLocal(),Symbol(),last_tick.ask,close[i]);
                     sendNotice(eS,1,Symbol());
                      
                  } 
          }
          
          
          
          if((preLong55For10Result_ge &&  thisLong55For10Result_lt))//------10周期对55周期发生金叉
          {       
                 // upBuffer[i]=long55Buffer[i]; //在金叉处画白色上箭头 
                  if(i== prev_calculated)
                  {
                      string eS=StringFormat("Time: %s,品种: %s, 10日线上穿55日均线,看多信号. 当前买价: %f ,收盘价格: %f ",
                                             TimeLocal(),Symbol(),last_tick.ask,close[i]);
                     sendNotice(eS,1,Symbol());
                      
                  } 
          }


           bool preLong55for5Result_le = (long55Buffer[i-1] < smallBuffer[i-1] );//------5周期对55周期死叉
           bool thisLong55for5Result_mt = long55Buffer[i] > smallBuffer[i];
            
           bool preLong55for10Result_le = long55Buffer[i-1] < longBuffer[i-1];//------10周期对55周期死叉
           bool thisLong55for5Result10_mt = long55Buffer[i] > long55Buffer[i];
           
           if( (preLong55for5Result_le && thisLong55for5Result_mt ) )//------5周期对55周期发生死叉
           {
                     //downBuffer[i]=long55Buffer[i];//在死叉处画上粉色下白色箭头
                     
                     if(i== prev_calculated)
                     {
                            bool isF = false; // 1.2  - 0.5 
                                   if((closeP - lowP)  > (openP - closeP)){
                                     isF = true;
                                   }
                                  string eS=StringFormat("Time: %s,品种: %s, 5日线下穿55日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                                       TimeLocal(),Symbol(),last_tick.bid,close[i]);
                                  sendNotice(eS,2,Symbol());
                     }
            }
            
            if(preLong55for10Result_le && thisLong55for5Result10_mt )//------10周期对55周期发生死叉
            {
            
                   //downBuffer[i]=long55Buffer[i];//在死叉处画上粉色下白色箭头
                   if(i== prev_calculated)
                   {
                            bool isF = false; // 1.2  - 0.5 
                                   if((closeP - lowP)  > (openP - closeP)){
                                     isF = true;
                                   }
                                  string eS=StringFormat("Time: %s,品种: %s, 10日线下穿55日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                                       TimeLocal(),Symbol(),last_tick.bid,close[i]);
                                  sendNotice(eS,2,Symbol());
                   }
            }
            
            
            
         if((longBuffer[i-1] > smallBuffer[i-1]) && (longBuffer[i] <= smallBuffer[i])) //------5周期对10周期发生金叉
         
         { 
               upBuffer[i]=longBuffer[i]; //在金叉处画白色上箭头 
               if( i == prev_calculated )
               {
                  string eS=StringFormat("Time: %s,品种: %s, 5日线上穿10日均线,看多信号. 当前卖价: %f ,收盘价格: %f ",
                                      TimeLocal(),Symbol(),last_tick.ask,close[i]);
                  //sendNotice(eS);
                  if(smallBuffer[i] > long55Buffer[i])
                  { // close[i]
                     string tmpEs = StringFormat(eS+",%s","并且在收盘价格在55日均线上方");
                     sendNotice(tmpEs,1,Symbol());
                     //upBuffer[i]=longBuffer[i];
                     
                  }
               }
         }
        if((longBuffer[i-1] < smallBuffer[i-1])&&(longBuffer[i] >= smallBuffer[i])) //------5周期对10周期发生死叉
      
         { 
            downBuffer[i]=longBuffer[i];   //在死叉处画上粉色下白色箭头
            
            if( i == prev_calculated )
            {
                  string eS=StringFormat("Time: %s,品种: %s, 5日线下穿10日均线,看空信号. 当前卖价: %f ,收盘价格: %f ",
                                      TimeLocal(),Symbol(),last_tick.bid,close[i]);
                  //sendNotice(eS);
                  if(smallBuffer[i] < long55Buffer[i])
                  {
                     string tmpEs = StringFormat(eS+",%s","并且在收盘价格在55日均线下方");
                     sendNotice(tmpEs,2,Symbol());
                     //downBuffer[i]=long55Buffer[i];    
                  }
               }
             
           }    
         }
   }
   

   return(rates_total);
}

int sendNotice(string tmpEs,int orderType,string symbol){
   printf(tmpEs);
   //Alert(tmpEs);
   //SendMail(tmpEs,"1");
   //SendNotification(tmpEs);
   

   return 1;
}

void getFloatSpread() 
  { 
//--- 从交易品种属性获得点差 
   bool spreadfloat=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD_FLOAT); 
   string comm=StringFormat("Spread %s = %I64d points\r\n", 
                            spreadfloat?"floating":"fixed", 
                            SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)); 
//--- 现在自己计算点差 
   double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); 
   double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID); 
   double spread=ask-bid; 
   int spread_points=(int)MathRound(spread / SymbolInfoDouble(Symbol(),SYMBOL_POINT)); 
   comm=comm+"Calculated spread = "+(string)spread_points+" points"; 
   Comment(comm); 
   
   
  }




 
 
 //--- 买入的例子  
//+------------------------------------------------------------------+
//|  在当前交易对象上买入指定大小的量                                |                                     
//+------------------------------------------------------------------+
void BuySample1()
  {
//--- 1. 在当前交易对象上进行买入的例子
   if(!trade.Buy(0.1))
     {
      //--- 报错信息
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     
}
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     
}
//---
  
}
 
Mars Yuan:

天啊 你是一直在长时间编程,休息一下;我看你是在你最初代码打补丁,静下心 仔细对比每一行代码,你的绘图缓存变量和通道的次序混乱,你的金叉死叉内部判断逻辑和箭头标明的语句位置逻辑也乱.. 因此就出莫名其妙问题...稍加整理顺序 12月3日9:30的金叉很清晰啊!!!

 我的意思是有金叉出现,为什么没有 i== prev_calculated 这个判断没有通过, 这个是奇怪的地方. 刚才debug 的时候, 发现  rates_total 有时候总是和prev_calculated, 相等,那么i 在for循环中小于rates_total, 那么 i == prev_calculated  就不成立, 不知道这中情况是MT5的数据问题, 还是其他的问题. 
 
s32967326:
 我的意思是有金叉出现,为什么没有 i== prev_calculated 这个判断没有通过, 这个是奇怪的地方. 刚才debug 的时候, 发现  rates_total 有时候总是和prev_calculated, 相等,那么i 就用户按小于rates_total, 那么 i == prev_calculated  就不成立, 不知道这中情况是MT5的数据问题, 还是其他的问题. 
   第一次产生新bar时,rates_total = prev_calculated +1; 其他时间rates_total = prev_calculated.
 
simons Luo:
   第一次产生新bar时,rates_total = prev_calculated +1; 其他时间rates_total = prev_calculated.
   我刚好也在研究这个均线策略。
 
simons Luo:
   第一次产生新bar时,rates_total = prev_calculated +1; 其他时间rates_total = prev_calculated.

啊.. 原来如此, 你有解决的方法没有? 

 
我还在研究中,到时我发消息到你的ID通知你