OnChartEventを 処理するときにイベントを送信するだけなら、論理的にキューがオーバーフローすることはないはずです。このイベントはどこでもやっているわけではないんですよね?
また、イベントルーティングで送信することも可能です。すなわち、あるイベントに対する応答イベントを送信者に送ることだけが必要なインジケータや他のExpert Advisorがある。
OnChartEventが 処理されたときだけイベントを送信すれば、論理的にキューがオーバーフローすることはないはずです。
いや、自分でオーバーフローしているだけです。OnChartEventで EventChartCustomが 呼び出されます。そして、そこには濃密な流れがある。一方では必要なものですが、他方ではチャートイベントに長い時間がかかります。
また、イベントパッドから送信することもできます。すなわち、あるイベントに対する応答イベントを送信者に送るためだけに必要なインデュック、あるいは他のExpert Advisorが存在する。
考えてはみたものの、なかなか思いつきません。交換方式について教えてください。
インジケータがあります(スレッドが違うので、そちらの方が良いかもしれません)。イベント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 コール 、このイベントが蓄積されていることを結論づけます。
コードを見てみます。とりあえず、この話題は終了してよい。
しかし、それではうまくいきません。
いいえ、はい、イベント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
いいえ、はい、イベント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 なしでも問題ない速度です :)
...しかし、メッセージ・キューがクリアされないという2つ目の問題が浮上した。
イベントキューのオーバーフローはRAMサイズにどのような影響を与えるのか、という質問に対する答えが見当たりません。イベントキューがオーバーフローしていることが判明した場合、オーバーフローしたイベントはどこに行くのでしょうか?たまたま「歴史から外れた」出来事のために確保された記憶の一部が解放されているのだろうか。
私の質問は、用語的には正しくないかもしれませんが、問題の本質を捉えていると思います(期待)。
イベントキューのオーバーフローがRAMサイズにどのような影響を与えるのか、という質問に対する答えが見つからないのですが。イベントキューが溢れているように見える場合、キューを溢れさせたイベントはどこに行くのでしょうか?
というのは、どこにも行かないということです。
つまり、イベントキューが満杯になると、キューをオーバーフローしたイベントがRAMを「食い尽くして」しまい、消費されるRAMのサイズが徐々に大きくなっていくのでは?しかし、これは間違っている。キューを吹っ飛ばした」イベントが、ようやくそのために確保されたメモリを解放することになるようです。
...1年経っても、イベントキューの大きさについての質問には、まだまとまった答えが得られていないんだ。したがって、端末イベントのキューをオーバーフローさせないために、どの程度の頻度でユーザーイベントを 発信すべきかは、まだ明確ではありません......。
- www.mql5.com
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
1つ問題があって、ある関数を更新する必要があるのですが、タイマーのMQLよりも速く、1秒未満で更新する必要があります。
解決方法:OnChartEventで EventChartCustomを 作成し、自分自身にイベントを送信する。
すべての動作が非常に速い。しかし、2つ目の問題は、メッセージキューがクリーンアップされる時間がないことです。
例えば、オブジェクトをクリックすると、イベントCHARTEVENT_OBJECT_CLICK が一度に発生するのではなく、以前のイベントがすべてキューから削除された後に発生します。
基本的には、ある関数の更新をきっちりと 実現する必要がありますが、同時にそして、ご理解の通り、イベントキューはEventChartCustomで詰まって います。
- while (true)のような無限ループはなかった。
- が、OnChartEventが チャートイベントが起きるとすぐに応答することも。
こんなときはどうしたらいい?EventChartCustomの 送信コントロールで他のオプションがあるかも?
言い換えれば、MQLがある関数を1秒以上、キューなしで呼び出すにはどうしたらいいかということです。
----------
最も簡単な解決策(ただし開発者の関与が必要)は、イベントキューから次のイベントを受信できるようにすることですが、OnChartEvent 関数を終了させないようにすることです。
つまり、私のEventChartCustomからすべての空のイベントを一度にクリーンアップしたいのです。また、左のイベントでキューをロードすることを許可しない。