イベントの流れ イベントの制御やアイドリングストップはどのように行うのですか?(+解決済み)

 

1つ問題があって、ある関数を更新する必要があるのですが、タイマーのMQLよりも速く、1秒未満で更新する必要があります。
解決方法:OnChartEventで EventChartCustomを 作成し、自分自身にイベントを送信する。

すべての動作が非常に速い。しかし、2つ目の問題は、メッセージキューがクリーンアップされる時間がないことです。

例えば、オブジェクトをクリックすると、イベントCHARTEVENT_OBJECT_CLICK が一度に発生するのではなく、以前のイベントがすべてキューから削除された後に発生します。
そして、ご理解の通り、イベントキューはEventChartCustomで詰まって います。

基本的には、ある関数の更新をきっちりと 実現する必要がありますが、同時に

- while (true)のような無限ループはなかった。
- が、OnChartEventが チャートイベントが起きるとすぐに応答することも。

こんなときはどうしたらいい?EventChartCustomの 送信コントロールで他のオプションがあるかも

言い換えれば、MQLがある関数を1秒以上、キューなしで呼び出すにはどうしたらいいかということです。

----------

最も簡単な解決策(ただし開発者の関与が必要)は、イベントキューから次のイベントを受信できるようにすることですが、OnChartEvent 関数を終了させないようにすることです。

つまり、私のEventChartCustomからすべての空のイベントを一度にクリーンアップしたいのです。また、左のイベントでキューをロードすることを許可しない。

 

OnChartEventを 処理するときにイベントを送信するだけなら、論理的にキューがオーバーフローすることはないはずです。このイベントはどこでもやっているわけではないんですよね?

また、イベントルーティングで送信することも可能です。すなわち、あるイベントに対する応答イベントを送信者に送ることだけが必要なインジケータや他のExpert Advisorがある。

 
TheXpert:

OnChartEventが 処理されたときだけイベントを送信すれば、論理的にキューがオーバーフローすることはないはずです。

いや、自分でオーバーフローしているだけです。OnChartEventで EventChartCustomが 呼び出されます。そして、そこには濃密な流れがある。一方では必要なものですが、他方ではチャートイベントに長い時間がかかります。

また、イベントパッドから送信することもできます。すなわち、あるイベントに対する応答イベントを送信者に送るためだけに必要なインデュック、あるいは他のExpert Advisorが存在する。

このように考えてはみたものの、何も思いつきません。交換方式を説明してください。
 
sergeev:
考えてはみたものの、なかなか思いつきません。交換方式について教えてください。

インジケータがあります(スレッドが違うので、そちらの方が良いかもしれません)。イベント1をキャッチしています。その際、必要な情報をすべて渡して送り返すことが望ましい。

トルコはイベント1の送信者にイベント2を送信する。

EAはイベント2をキャッチして再度イベント1を送信するが、イベント1に対してEAは全く反応しない。

そして、偽のExpert Advisorを使えば、眠れるようになるのです。

 

考え方は明快だが、それではうまくいかない。

でも、こんな簡単なアルゴリズムをテストしてみただけです。

int rest=0;
int all=0;
bool click=false;
//------------------------------------------------------------------    OnInit
int OnInit() { EventChartCustom(0, 0, 0, 0, ""); return(0); }
//------------------------------------------------------------------    OnChartEvent
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
        if (id==CHARTEVENT_OBJECT_CLICK) click=!click;
        if (!click) { EventChartCustom(0, 0, 0, 0, ""); all++; }
        else rest++;
        
        string txt="all="+string(all)+"  rest="+string(rest);
        SetButton(0, "btn", 0, txt, clrWhite, clrDarkBlue, 150, 150, 200, 50, 0, 9, "Tahoma", click);
        ChartRedraw(0);
}
//------------------------------------------------------------------ SetButton
void SetButton(long achart, string name, int wnd, string text, color txtclr, color bgclr, int x, int y, int dx, int dy, int corn=0, int fontsize=8, string font="Tahoma", bool state=false)
{
        ObjectCreate(achart, name, OBJ_BUTTON, wnd, 0, 0); ObjectSetInteger(achart, name, OBJPROP_CORNER, corn); 
        ObjectSetString(achart, name, OBJPROP_TEXT, text); ObjectSetInteger(achart, name, OBJPROP_STATE, state);
        ObjectSetInteger(achart, name, OBJPROP_COLOR, txtclr); ObjectSetInteger(achart, name, OBJPROP_BGCOLOR, bgclr); ObjectSetInteger(achart, name, OBJPROP_BORDER_COLOR, clrNONE);
        ObjectSetInteger(achart, name, OBJPROP_FONTSIZE, fontsize); ObjectSetString(achart, name, OBJPROP_FONT, font);
        ObjectSetInteger(achart, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(achart, name, OBJPROP_YDISTANCE, y);
        ObjectSetInteger(achart, name, OBJPROP_XSIZE, dx); ObjectSetInteger(achart, name, OBJPROP_YSIZE, dy);
        ObjectSetInteger(achart, name, OBJPROP_SELECTABLE, false);
        ObjectSetInteger(achart, name, OBJPROP_BORDER_TYPE, 0);
        ObjectSetString(achart, name, OBJPROP_TOOLTIP, text);
}

すべてのイベントが正常に動作します。ラグがない。

しかし、2つ(またはそれ以上)のEventChartCustomを 1行に並べると

if (!click) { EventChartCustom(0, 0, 0, 0, ""); EventChartCustom(0, 0, 0, 0, ""); all++; }

は2倍のラグが発生します。

したがって、私はすべてがあるべきように動作し、それは私のコードであるダブルEventChartCustom コール 、このイベントが蓄積されていることを結論づけます。

コードを見てみます。とりあえず、この話題は終了してよい。

 
sergeev:

しかし、それではうまくいきません。

いいえ、はい、イベント1と2でチャートが違うという意味です

(1)スレッドによって動作がかなり遅くなるのでは?

(2) アドバイザーがいれば眠れる。

まあと2倍は(少なくとも)遅い。

 
свой OnCustomTimer в миллисекундах


#define MSECTIMER 100
#define TIMEREVENT 111
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(60);
   EventSetCustomTimer(MSECTIMER);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EventSetCustomTimer(int msec) 
  {
   EventChartCustom(0,TIMEREVENT,msec,NULL,NULL);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   static uint lasttick=0;
   if(id==CHARTEVENT_CLICK) 
     {
      Print("Click");
     }

   if(id==CHARTEVENT_CUSTOM+TIMEREVENT) 
     {
      uint current=GetTickCount();
      if(lasttick+lparam<=current) 
        {
         lasttick=current;
         OnCustomTimer();
        }
     }
   EventSetCustomTimer(MSECTIMER);
  }
//+------------------------------------------------------------------+


void OnCustomTimer() 
  {
//
  }
//+------------------------------------------------------------------+

OnChartEvent は、ピギーバックを使用することができます。
EventSetCustomTimer
 
TheXpert:

いいえ、はい、イベント1と2でチャートが違うという意味です

(1)スレッドが異なると動作がかなり遅くなる疑いがある。

(2)EAなら寝られる。

まあと2倍は(少なくとも)遅い。


朝になると賢くなる、というのは本当です。:) 問題解決しました。とてもエレガントに仕上がったとさえ言えます。

- 送信済みメッセージのカウンターを導入しよう event_idle

- イベント送信時、このカウンターをLPARAMEventChartCustom(chart, VM_IDLE, event_idle, 0, "") に送ります。

- そして、OnChartEvent ハンドラで、受信する LPARAM パラメータが現在の event_idle と等しくなるまで、すべての VM_IDLE メッセージをかき集める。

このように

ulong event_idle=0; bool bidle;
void OnChartEvent(int iview, int id, long lparam, double dparam, string sparam)
{
    if (id==CHARTEVENT_CUSTOM+VM_IDLE)
    {
        if (event_idle>(ulong)lparam || bidle) { bidle=event_idle>(ulong)lparam; if (bidle) return; event_idle=0; } // если последнее посланное больше чем пришедшее, то сразу выходим
        event_idle++;
        ChartRedraw(m_chart); // обновили чарт
        EventChartCustom(m_chart, VM_IDLE, (long)event_idle, 0, ""); // отправили событие с указанием последнего счетчика
        return; 
    }
    EventChartCustom(m_chart, VM_IDLE, (long)event_idle, 0, ""); // отправили событие  с указанием последнего счетчика

    /*
        обработка остальных событий
    */
}

こうすれば、すべてかき集められるので、このイベントでオーバーシュートが発生することはないでしょう。

現在では、event_idle queue enumeration なしでも問題ない速度です :)

 
sergeev:

...しかし、メッセージ・キューがクリアされないという2つ目の問題が浮上した。

イベントキューのオーバーフローはRAMサイズにどのような影響を与えるのか、という質問に対する答えが見当たりません。イベントキューがオーバーフローしていることが判明した場合、オーバーフローしたイベントはどこに行くのでしょうか?たまたま「歴史から外れた」出来事のために確保された記憶の一部が解放されているのだろうか。

私の質問は、用語的には正しくないかもしれませんが、問題の本質を捉えていると思います(期待)。

 
Yedelkin:

イベントキューのオーバーフローがRAMサイズにどのような影響を与えるのか、という質問に対する答えが見つからないのですが。イベントキューが溢れているように見える場合、キューを溢れさせたイベントはどこに行くのでしょうか?

それが、「しない」「溜める」です。
 
sergeev:
というのは、どこにも行かないということです。

つまり、イベントキューが満杯になると、キューをオーバーフローしたイベントがRAMを「食い尽くして」しまい、消費されるRAMのサイズが徐々に大きくなっていくのでは?しかし、これは間違っている。キューを吹っ飛ばした」イベントが、ようやくそのために確保されたメモリを解放することになるようです。

...1年経っても、イベントキューの大きさについての質問には、まだまとまった答えが得られていないんだ。したがって、端末イベントのキューをオーバーフローさせないために、どの程度の頻度でユーザーイベントを 発信すべきかは、まだ明確ではありません......。

Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы графиков / Типы событий графика - Документация по MQL5