[解决]当从不同工作时间段的指标中调用/创建指标时,指标不能正确实例化。 - 页 3

 
Stanislav Korotky:
发表更具体的问题,并附上示例代码。它可能是错误的。这个方法对我有用。

下面是一个指标访问失败的代码例子。即使经过循环、刷新、等待(两种不同的等待方法)。

//+------------------------------------------------------------------+
//|                                                    THROWAWAY.mq5 |
//|                                                      nicholishen |
//|                                   www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "www.reddit.com/u/nicholishenFX"
#property version   "1.00"
#property indicator_chart_window

#include <Indicators\Trend.mqh>
#include <errordescription.mqh>

CiMA ima;
int m_bufferSize = -1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   static int iCnt = 0;
//--- indicator buffers mapping
      Print("-----------------------",TimeCurrent(),"--------------------------");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
   static int tickCnt = 0;
   tickCnt++;
//---
   if(rates_total != prev_calculated || m_bufferSize < 1 ){
      ResetLastError();
      datetime createTime = TimeCurrent();
      ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
      ima.Refresh(); //no wait time!
          
      CIndicatorBuffer *buff = ima.At(0);
      m_bufferSize = buff.Total();
      int call = 0;
      int sleep = 200;
      // try with Sleep function ...
      while(buff.Total() <= 0 && call < 10){
         Sleep(sleep);
         ima.Refresh(); // Refreshed 10x since create
         m_bufferSize = buff.Total();
         call++;
         Print(__LINE__," ",__FUNCTION__," ",buff.Name(),
               " Buffer size = ",m_bufferSize," | Call (",
               call,")"," Sleep(",sleep,")"
               );
         sleep+=100;
        
      }
      // try wait with looping  
      if(buff.Total() <=0){
         datetime waitTime = timeLoop(createTime);
         Print("Time Between Create and Refresh() = ",TimeToString(waitTime,TIME_SECONDS));
         ima.Refresh();
         m_bufferSize = buff.Total();
      }
      if(m_bufferSize < 1){
         Print(ErrorDescription(GetLastError()));
         return(rates_total);
      } else {
         for(int i=0;i<m_bufferSize;i++){
            if(i>2return(rates_total);
            else{
               Print(__LINE__," ",__FUNCTION__,buff.Name(),
                     " Buffer size = ",m_bufferSize,
                     " | ",ima.PeriodDescription()," iMA(",i,") value = ",
                     DoubleToString(ima.Main(i),_Digits),
                     " | Tick-count = ",tickCnt
                     );  
            }
         }
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason){

}

datetime timeLoop(datetime timeIn){
   int cnt = 0;
   while(TimeCurrent() - timeIn < 10 && !IsStopped()){
      Comment("Time looping i = ",cnt);
      cnt++;
   }
   return TimeCurrent() - timeIn;
}

而这里是输出结果。

-----------------------2017.01.31 23:48:03--------------------------


60 OnCalculate MAIN_LINE Buffer size = -1 | Call (1) Sleep(200)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(2) Sleep(300)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(3) Sleep(400)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(4) Sleep(500)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(5) Sleep(600)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(6) Sleep(700)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(7) Sleep(800)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(8) Sleep(900)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(9) Sleep(1000)

60 OnCalculate MAIN_LINE 缓冲区大小=-1 | 调用(10) Sleep(1100)

创建和刷新()之间的时间 = 00:00:11

没有找到所需的数据

81 OnCalculateMAIN_LINE 缓冲区大小 = 1024 | H1 iMA(0) 值 = 113.227 | Tick-count = 2

81 OnCalculateMAIN_LINE 缓冲区大小 = 1024 | H1 iMA(1) 值 = 113.269 | Tick-count = 2

81 OnCalculateMAIN_LINE 缓冲区大小 = 1024 | H1 iMA(2) 值 = 113.313 | Tick-count = 2

















 
nicholishen:

下面是一个指标 访问失败的代码例子。即使经过循环、刷新、等待(两种不同的等待方法)。

         Sleep(sleep);


睡眠在指标上是行不通的,你不能打断接口线程。

用OnTimer()代替试试。

 
honest_knave:

睡眠在指标上是行不通的,你不能打断接口线程。

试着用OnTimer()来代替吧。

这就是了!这就是解决方法这就是解决的办法!我真想亲你一下。

这让OnInit()返回到平台,而OnTimer()跳过它,为第二遍的调用。我把EventSetMillisecondTimer设置为1ms,只调用一次,现在就可以工作了。

//+------------------------------------------------------------------+
//|                                                    THROWAWAY.mq5 |
//|                                                      nicholishen |
//|                                   www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "www.reddit.com/u/nicholishenFX"
#property version   "1.00"
#property indicator_chart_window

#include <Indicators\Trend.mqh>
#include <errordescription.mqh>

CiMA ima;
int m_bufferSize = -1;
bool timedEvent = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
      int waitMS = 1;
      Print("-----------------------",TimeCurrent(),"--------------------------");
  
      ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
      EventSetMillisecondTimer(waitMS);
      Print("OnTimer set to ",waitMS," ms");
      
//---
   return(INIT_SUCCEEDED);
  }

void OnTimer()
  {
//---
   ima.Refresh();
   EventKillTimer();
   timedEvent = true;
  
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {

   static int tickCnt = 0;
   tickCnt++;
  
   if(!timedEvent)return rates_total;
//---
   if(rates_total != prev_calculated || m_bufferSize < 1 ){
      ResetLastError();
      CIndicatorBuffer *buff = ima.At(0);
      m_bufferSize = buff.Total();
      if(m_bufferSize <=0) ima.Refresh();
      // try wait with looping  
      
      if(m_bufferSize < 1){
         Print(ErrorDescription(GetLastError()));
        
      } else {
         for(int i=0;i<m_bufferSize;i++){
            if(i>2) break;
            else{
               Print(__LINE__," ",__FUNCTION__,buff.Name(),
                     " Buffer size = ",m_bufferSize,
                     " | ",ima.PeriodDescription()," iMA(",i,") value = ",
                     DoubleToString(ima.Main(i),_Digits),
                     " | Tick-count = ",tickCnt
                     );  
            }
         }
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+


输出。

-----------------------2017.02.01 01:31:01--------------------------

OnTimer设置为1毫秒

75 OnCalculateMAIN_LINE 缓冲区大小 = 1024 | H1 iMA(0) 值 = 113.142 | Tick-count = 2

75 OnCalculateMAIN_LINE 缓冲区大小 = 1024 | H1 iMA(1) 值 = 113.181 | Tick-count = 2

 
nicholishen:

这就是了!这就是变通的办法!我可以吻你的男人!

没问题,我接受银行转账和所有主要的信用卡......100美元不是吗?
 
nicholishen:

这就是了!这就是变通的办法!我可以吻你的男人!

酷!

我建议你使用一个计时器。你回答说它对你不起作用。我要求你提供一个例子,说明你都试过什么。但你说你不能发表更多的细节,因为你已经做了。

现在另一个人建议你使用计时器,而你似乎对它很满意。)

 
Stanislav Korotky:

很好!

我建议你使用定时器。你回答说它对你不起作用。我要求你提供一个例子,说明你已经尝试了什么。但你说你不能发表更多的细节,因为你已经做了。

现在另一个人建议你使用计时器,而你似乎对它很满意。)

嘿!不要再试图强加在我的150美元上了。
 
Stanislav Korotky:

很好!

我建议你使用定时器。你回答说它对你不起作用。我要求你提供一个例子,说明你已经尝试了什么。但你说你不能发表更多的细节,因为你已经做了。

现在另一个人建议你使用计时器,而你似乎对它很满意。)

我们现在有一个MT5的错误被修复了...
 
honest_knave:
没问题,我接受银行转账和所有主要的信用卡...100美元不是吗?

100美元? ...我以为我提供了更多...

关于交易、自动交易系统和测试交易策略的论坛

[MQL5 BUG] [SOLVED]当从不同工作时间段的指标中调用/创建指标时,指标不能正确实例化。

Stanislav Korotky, 2017.02.01 09:27

很好!

我建议你使用一个定时器。你回答说它对你不起作用。我要求你提供一个你所尝试的例子。但你说你不能发布比已经发布的更多细节。

现在另一个人建议你使用计时器,而你似乎对它很满意。)


对不起,我不明白你的意思,直到现在。我认为你是knave的合伙人,由于没有人公布工作模式,我将裁定赏金为50%--分两份。所以,这就是......嗯......携带两个......。我请你们俩喝啤酒怎么样?说真的,请给我一个BTC地址,我保证你们俩都能得到补偿 :)

我想特别感谢你的帮助......如果不是你的居高临下,我不知道我在哪里能找到继续努力的动力!/s

 
nicholishen:

说真的,请给我一个BTC地址,我保证你们都能得到补偿 :)

这是一个慷慨的提议,但没有必要。很高兴你能解决这个问题。
 
我正在与服务台结案,但如果MetaQuotes看到这篇文章,我仍然认为这是平台的一个重大缺陷。如果这是一个线程的问题,应该有一个更好的方法来处理这些类型的事件,而不是任意地把(一个猜测的数量)等待时间扔进代码。