[解決済み] 異なる作業時間枠のインディケータから呼び出され作成された場合、インディケータが適切にインスタンス化されない。 - ページ 3

 
Stanislav Korotky:
もっと具体的な質問をサンプルコード付きで投稿してください。それはバグがあるかもしれません。このアプローチは私のために動作します。

インジケータアクセスに失敗したコード例です。ループ、リフレッシュ、待機(2種類の待機方法)の後でも、です。

//+------------------------------------------------------------------+
//|                                                    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 Buffer size = -1 | Call (2) Sleep(300)

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

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

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

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

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

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

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

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

作成からリフレッシュ()までの時間 = 00:00:11

要求されたデータが見つかりません

81 OnCalculateMAIN_LINE Buffer size = 1024 | H1 iMA(0) value = 113.227 | Tick-count = 2

81 OnCalculateMAIN_LINE Buffer size = 1024|H1 iMA(1) value = 113.269|Tick-count = 2|バッファサイズ = 1024|H1 iMA(1) value = 113.269|Tick-count = 2

81 OnCalculateMAIN_LINE バッファサイズ = 1024 | H1 iMA(2) value = 113.313 | Tick-count = 2

















 
nicholishen:

インジケータ アクセスに失敗したコード例です。ループ、リフレッシュ、待機(2つの異なる待機方法)の後でも。

         Sleep(sleep);


Sleepはインジケータには効きません。インターフェイススレッドに割り込むことはできません。

代わりにOnTimer()で試してみてください。

 
honest_knave:

Sleep はインジケータには使えません。インターフェイススレッドに割り込むことはできません。

代わりにOnTimer()で試してみてください。

そうです!これが回避策だ!キスしたいくらいだ!

これで、OnInit()がプラットフォームに戻り、OnTimer()がそれをスキップして2回目のパスを呼び出すことができます。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を1msに設定

75 OnCalculateMAIN_LINE バッファサイズ = 1024|H1 iMA(0) 値 = 113.142|Tick-count = 2

75 OnCalculateMAIN_LINE Buffer size = 1024|H1 iMA(1) value = 113.181|Tick-count = 2|この場合、H1 iMA(1) value = 113.181 になります。

 
nicholishen:

それだ!それは回避策だ!私はあなたにキスすることができます男!

大丈夫、銀行振り込みもできるし、主要なクレジットカードも使える...100ドルだったかな?
 
nicholishen:

それだ!それは回避策だ!私はあなたにキスすることができます男!

かっこいい!

タイマーを使ったらどうかと言ったけどうまくいかなかったと答えましたね。私は、あなたが試したことのある例を尋ねました。しかし、あなたはこれ以上の詳細を投稿することはできないと言いました。

今、別の人があなたにタイマーを提案し、あなたはそれに満足しているようです;;-)

 
Stanislav Korotky:

かっこいい!

タイマーを使ったらどうかと言ったのですがあなたは「うまくいかなかった」と答えました。私は、あなたが何を試したのか、その例を求めました。しかし、あなたはこれ以上の詳細を投稿することはできないと言いました。

今、別の人があなたにタイマーを提案し、あなたはそれに満足しているようです;;-)

おい!私の$ 150に筋肉をしようとするのを止めろ!。
 
Stanislav Korotky:

かっこいい!

タイマーを使ったらどうかと言ったのですがあなたは「うまくいかなかった」と答えました。私は、あなたが何を試したのか、その例を求めました。しかし、あなたはこれ以上の詳細を投稿することはできないと言いました。

今、別の人があなたにタイマーを提案し、あなたはそれに満足しているようです;;-)

そして、私たちは今、MT5のバグを修正しました...
 
honest_knave:
問題ありません、銀行振込と主要なクレジットカードを受け付けます...100ドルでしたっけ?

100ドルって! ...もっと提供したつもりなんだけど...。

取引、自動取引システム、取引戦略のテストに関するフォーラム

[MQL5 BUG] [SOLVED]異なるワーキングタイムフレームのIndicatorから呼び出された/作成された場合、Indicatorは適切にインスタンス化されない。

スタニスラフ・コロツキー 2017.02.01 09:27

かっこいいですねぇ。

私はタイマーを使うことを提案しました。あなたはそれがあなたのために動作しないことを答えました。私は、あなたが試したことの例を尋ねました。しかし、あなたはすでにした以上の詳細を投稿することはできませんと言いました。

今、別の人があなたにタイマーを提案し、あなたはそれに満足しているようです。)


申し訳ありませんが、私は今まで、あなたが何を意味するのか理解していませんでした。そして、誰も作業モデルを投稿していないので、私は賞金を50%-2つの方法で分割することにします。だから...その...2人で...二人にビールをおごろうか?真面目な話、BTCのアドレスをPMしてくれれば、二人とも補償されることを確認します :)

私は特にあなたの助けに感謝したい...もしあなたの慇懃さがなかったら、私はどこに努力する動機を見つけたかわかりません!/s

 
nicholishen:

マジでBTCのアドレスをPMしてくれれば、二人とも補償されるようにしますよ :)

寛大な申し出ですが、不要です。あなたがそれを解決したことを嬉しく思います。
 
私はサービスデスクとこの件を終わりにしていますが、MetaQuotesがこれを読んでいる場合に備えて、私はこれがプラットフォームの大きな 欠陥であるとまだ考えています。もしこれがスレッドの問題なら、コードに任意に(推測される量の)待ち時間を投げ込むよりも、この種のイベントを 処理するもっと良い方法があるはずです。
理由: