MQL5 クックブック:典型的なチャートイベントの処理
はじめに
本稿では MQL5 の開発者によって事前に定義されている典型的(標準的)なイベントについて OnChartEvent() を用いた機能と実践練習について記述したいと思います。MQL5 の数々の記事および コードベース ですでにこのハンドラの使用例は取り上げられています。
ですが、私の目的は「イベント駆動プログラミング(EOP)」の考え方でこの手段を分析することです。このハンドラを完全に自動化されたトレーディングシステムと半自動トレーディングシステムで問題なく使用することができると考えています。
1. "ChartEvent" イベント
それでは最初にこのイベントタイプがどんなものであるか見ていきます。
ドキュメンテーションによると ChartEvent イベントはチャート作業時に出現するようです。特に以下の場合です。
- チャートウィンドウに着目し、キーボード上でキーを押すとき。
- グラフィックオブジェクトを作成するとき
- グラフィックオブジェクトを削除するとき
- グラフィックオブジェクト上でクリックするとき
- マウスでグラフィックオブジェクトをドラッグするとき
- LabelEdit graphical オブジェクトのテキストフィールドでテキスト編集を終了するとき
よってこのイベントは双方向性をもたらしチャートとの交流を可能にします。その上、そのような相互作用はなんらかのアルゴリズム処理(自動トレーディング)同様マニュアルトレーディングの結果でありえます。
MQL5 開発者は ChartEvent イベントを ENUM_CHART_EVENT リストで指定されたタイプに分類しています。
このリストにはユーザー定義イベントが含まれ、それはプログラマーに役立つ隠れた蓄えのようなものであることに注意することが重要です。MQL5 開発者はカスタムイベントに 65,535個の IDを提供しています。
カスタムイベントと連携するにはプログラマーのニーズに応じて特殊な作成関数 EventChartCustom() が利用できます。ただし、本稿ではカスタムイベントは考察しません。
2. ChartEvent ハンドラとジェネレータ
ChartEvent イベントの処理はすべて特殊なハンドラ関数 OnChartEvent()によって行われます。これは MQL5 言語コンセプトと一致しており、それはたとえばトレードイベントは OnTrade() 関数で処理され、Init イベントは OnInit() 関数で処理される、などです。
OnChartEvent() 関数は以下のシグネチャーを持ちます。
void OnChartEvent(const int id, // event identifier const long& lparam, // parameter of the event of type long const double& dparam, // parameter of the event of type double const string& sparam // parameter of the event of type string )
入力パラメータはすべて定数で、ハンドラが呼ばれる時有用な情報を伝達します。
そのため id パラメータの値はどの特定のイベントがハンドラを呼んだか明らかにすることができます。その他ロング、ダブル、文字列タイプの値を持ちます。この方法でイベントに関する別の情報を取得することができます。
その後、進行中のことがらを分析するために使われる指定のパラメータ値の例を作成します。
ChartEvent イベントのカスタム部分は実装するプログラマー次第ですが、EventChartCustom() 関数に連携されます。まさにこの関数がイベントを生成します。以下がその関数のシグネチャーです。
bool EventChartCustom(long chart_id, // receiving chart identifier ushort custom_event_id, // event identifier long lparam, // the long parameter double dparam, // the double parameter string sparam // the string parameter )
実際、ジェネレータ関数がイベントを作成し、入力パラメータを持つ現在チャートを含む任意のチャートにそのイベントを送信します。後者は ushort、ロング、ダブル、文字列タイプです。
関数 OnChartEvent() および EventChartCustom() はともに「イベント駆動プログラミング」の恩恵の好例である力強いツールを作成します。
3. 標準イベント処理テンプレート
チャートイベントタイプを考察し、それぞれの例を示してこうと思います。各イベントは独自のバージョンの EventProcessor.mq5 を持ち、そのコードはチャートイベントを処理します。MQL5には典型的なイベントが10種類あります。
そのうちの3個(マウスイベント、グラフィックオブジェクト作成イベント、グラフィックオブジェクト消去イベント)に対してチャートを準備する必要があります。ChartSetInteger() 関数を使用することでそれを行います。それによりチャートは指定のイベントに応答することができます。
以下がチャートイベント処理の典型的なブロックの記述です。
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { string comment="Last event: "; //--- select event on chart switch(id) { //--- 1 case CHARTEVENT_KEYDOWN: { comment+="1) keystroke"; break; } //--- 2 case CHARTEVENT_MOUSE_MOVE: { comment+="2) mouse"; break; } //--- 3 case CHARTEVENT_OBJECT_CREATE: { comment+="3) create graphical object"; break; } //--- 4 case CHARTEVENT_OBJECT_CHANGE: { comment+="4) change object properties via properties dialog"; break; } //--- 5 case CHARTEVENT_OBJECT_DELETE: { comment+="5) delete graphical object"; break; } //--- 6 case CHARTEVENT_CLICK: { comment+="6) mouse click on chart"; break; } //--- 7 case CHARTEVENT_OBJECT_CLICK: { comment+="7) mouse click on graphical object"; break; } //--- 8 case CHARTEVENT_OBJECT_DRAG: { comment+="8) move graphical object with mouse"; break; } //--- 9 case CHARTEVENT_OBJECT_ENDEDIT: { comment+="9) finish editing text"; break; } //--- 10 case CHARTEVENT_CHART_CHANGE: { comment+="10) modify chart"; break; } } //--- Comment(comment); }
それぞれのケースで私は選択されたイベントを記述する文字列を追加しました。結果、コメント行でチャート上に起こった最後のイベントを確認することができます。テンプレートを実行し、チャートでさまざまな操作を行うと、コメント行が異なるレコードを持つことがわかります。
あきらかにイベントタイプを判断するだけの Expert Advisor はほとんど利用されません。その機能を拡張する必要があります。
4. 標準イベント処理例
4.1. キーストロークイベント
最初のケースを取りあげ、キーボードのボタンと連携します。それでわれわれの EA はキーストロークに応答するようになります。『上向き矢印』を押すと買い、『下向き矢印』を押すと売りとします。この場合の記述は以下のようなものになります。
//--- 1 case CHARTEVENT_KEYDOWN: { //--- "up" arrow if(lparam==38) TryToBuy(); //--- "down" arrow else if(lparam==40) TryToSell(); comment+="1) keystroke"; //--- break; }
TryToBuy() および TryToSell() の実装詳細については添付の EA ソースコードを参照ください。トレードパラメータ(ロットサイズ、ストップロス、テイクプロフィット等)は入力変数(InpLot、 InpStopLoss、InpTakeProfit等)として指定します。またパラメータ lparam は押されたキーのコードを取得することも述べる必要があります。
EA の更新バージョンは EventProcessor1.mq5と呼ばれます。
4.2. マウスイベント
このイベントタイプはプロパティ CHART_EVENT_MOUSE_MOVE がチャートに対して指定されたときのみ処理されます。このため EA の初期化ブロックには以下のような文字列が入ります。
//--- mouse move bool is_mouse=false; if(InpIsEventMouseMove) is_mouse=true; ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,is_mouse);
マウスを使用するなら当然マウスイベントも頻繁に起こることを覚えておく必要があります。よってこのイベントの処理を無効にするチャンスは有用です。ハンドラのパラメータ lparam およびdparam はそれぞれ X 軸と Y 軸の座標を知らせています。
作成された例についてお話します。右の境界からゼロバーの移動があるとします。シフトから右に画面上にカーソルを置くと、買いまたは売りを提案するウィンドウが表示されます。
そのためまずシフトを決定する必要があります。右境界からパーセント(InpChartShiftSize)でゼロバーシフトのサイズを決める入力変数を取り込みます。
図1 トレード処理ウィンドウ
シフトとサイズを有効にする関数、ChartShiftSet()および ChartShiftSizeSet()を使います。それからカーソルの X 座標が前に境界の左にあり右に移動したか特定します。そのとおりであれば、買いまたは売りを提案するウィンドウが表示されます(図1)。
以下が対象設定を実装するコードの記述です。
//--- 2 case CHARTEVENT_MOUSE_MOVE: { comment+="2) mouse"; //--- if a mouse event is processed if(InpIsEventMouseMove) { long static last_mouse_x; //--- enable shift if(ChartShiftSet(true)) //--- set shift size if(ChartShiftSizeSet(InpChartShiftSize)) { //--- chart width int chart_width=ChartWidthInPixels(); //--- calculate X coordinate of shift border int chart_shift_x=(int)(chart_width-chart_width*InpChartShiftSize/100.); //--- border crossing condition if(lparam>chart_shift_x && last_mouse_x<chart_shift_x) { int res=MessageBox("Yes: buy / No: sell","Trade operation",MB_YESNO); //--- buy if(res==IDYES) TryToBuy(); //--- sell else if(res==IDNO) TryToSell(); } //--- store mouse X coordinate last_mouse_x=lparam; } } //--- break; }
以前に作成されたトレード関数によって売りと買いが行われます。EA の更新バージョンを EventProcessor2.mq5と名づけます。
4.3. グラフィックオブジェクト作成イベント
このイベントタイプはチャート上にオブジェクトが作成されるとき生成されます。マウスイベント同様、このタイプはプロパティ CHART_EVENT_OBJECT_CREATEによって処理に対する許可を受け取る必要があります。新規グラフィックオブジェクトに応答しようとする場合、それをブロック内で一度のみ指定する必要があります。
//--- object create bool is_obj_create=false; if(InpIsEventObjectCreate) is_obj_create=true; ChartSetInteger(0,CHART_EVENT_OBJECT_CREATE,is_obj_create);
情報を持つハンドラのパラメータは1個だけです。それは作成されるグラフィックオブジェクト名を保持する文字列パラメータ sparam です。そのオブジェクトは名前で検索することができます。それを処理したら次に何をするか決めます。
シンプルな例があります。チャートに水平線を引き、ロボットにそれをチャートに反映されるすべてのバーの最大値に置かせ別に2本の線を引きます。下側の線は安値の位置に、三番目の線は先の2本の線それぞれから等間隔にその2本の間に引きます。
以下はこのタスクの実装コードです。
//--- 3 case CHARTEVENT_OBJECT_CREATE: { comment+="3) create graphical object"; //--- if graphical object creation event is processed if(InpIsEventObjectCreate) { //--- capture creation of horizontal line int all_hor_lines=ObjectsTotal(0,0,OBJ_HLINE); //--- if this is the only line if(all_hor_lines==1) { string hor_line_name1=sparam; //--- calculate levels int visible_bars_num=ChartVisibleBars(); //--- arrays for high and low prices double highs[],lows[]; //--- int copied=CopyHigh(_Symbol,_Period,0,visible_bars_num-1,highs); if(copied!=visible_bars_num-1) { Print("Failed to copy highs!"); return; } copied=CopyLow(_Symbol,_Period,0,visible_bars_num-1,lows); if(copied!=visible_bars_num-1) { Print("Failed to copy lows!"); return; } //--- high and low prices double ch_high_pr,ch_low_pr,ch_mid_pr; //--- ch_high_pr=NormalizeDouble(highs[ArrayMaximum(highs)],_Digits); ch_low_pr=NormalizeDouble(lows[ArrayMinimum(lows)],_Digits); ch_mid_pr=NormalizeDouble((ch_high_pr+ch_low_pr)/2.,_Digits); //--- place created line on high if(ObjectFind(0,hor_line_name1)>-1) if(!ObjectMove(0,hor_line_name1,0,0,ch_high_pr)) { Print("Failed to move!"); return; } //--- create line on low string hor_line_name2="Hor_line_min"; //--- if(!ObjectCreate(0,hor_line_name2,OBJ_HLINE,0,0,ch_low_pr)) { Print("Failed to create the 2nd horizontal line!"); return; } //--- create line between high and low string hor_line_name3="Hor_line_mid"; //--- if(!ObjectCreate(0,hor_line_name3,OBJ_HLINE,0,0,ch_mid_pr)) { Print("Failed to create the 3rd horizontal line!"); return; } } } break; }
EA の更新バージョンの名前は EventProcessor3.mq5です。
図2 グラフィックオブジェクト作成イベント処理結果
その手順が完了すると以下の描画を受け取りました(図2)。統合関数が EA にグラフィックオブジェクト作成に対して反応する機能を持たせ、その後それに従って処理を行います。
4.4. プロパティダイアログによるグラフィックオブジェクトのプロパティ変更イベント
このイベントタイプは部分的に前のタイプに似ています。これはグラフィックオブジェクトのプロパティの一つがプロパティダイアログによって変更されたときに起こります。Iこのツールはたとえば同じタイプのオブジェクトのグラフィックプロパティの同期などに有用です。
チャート上のいくつかのオブジェクト番号をイメージします。トレーダーは通常チャート上に数多くの様々な線を持ちます。こういった線は削除せず非表示にすることが必要となる場合があります。このタスクを行う方法を見つけていきます。変更された線の色を変え、他のグラフィックオブジェクトにも同じようにします。以下がそのときのコード例です。
//--- 4 case CHARTEVENT_OBJECT_CHANGE: { comment+="4) change object properties via properties dialog"; //--- string curr_obj_name=sparam; //--- find the changed object if(ObjectFind(0,curr_obj_name)>-1) { //--- get object color color curr_obj_color=(color)ObjectGetInteger(0,curr_obj_name,OBJPROP_COLOR); //--- total number of objects on chart int all_other_objects=ObjectsTotal(0); //--- find other objects for(int obj_idx=0;obj_idx<all_other_objects;obj_idx++) { string other_obj_name=ObjectName(0,obj_idx); if(StringCompare(curr_obj_name,other_obj_name)!=0) if(!ObjectSetInteger(0,other_obj_name,OBJPROP_COLOR,curr_obj_color)) { Print("Failed to change the object color!"); return; } } //--- redraw chart ChartRedraw(); } //--- break;
チャート上に一組の線があるとします(図3)。
図3 Multi-colored 変動ライン
任意の線の色を変えようとするか、もっと正確に言えばプロパティダイアログ内でその色を変える(図4)場合、チャートには法事されている線はなくなります。同時にグラフィックオブジェクトはまだそこに表示されています。
図4 線色の変更
EA の更新バージョンはEventProcessor4.mq5と名づけられます。
4.5. グラフィックオブジェクト削除イベント
このイベント名から判るように、チャートからオブジェクトを削除するときに出現するイベントです。グループの最終イベントで、処理に対する直接の事前承認が必要となります。プロパティ CHART_EVENT_OBJECT_DELETEによって行われます。
//--- object delete bool is_obj_delete=false; if(InpIsEventObjectDelete) is_obj_delete=true; ChartSetInteger(0,CHART_EVENT_OBJECT_DELETE,is_obj_delete);
別の仮定としての例です。EA がアタッチされているチャート上に異なるタイプのグラフィックオブジェクトがあります。特定タイプのオブジェクトを1個だけ削除する必要があるとします。たとえば縦線です(図5)。
図5 5本の縦線とその他ライン
われわれは縦線1本だけ消去し、後は「エキスパート」が消去します(図6)。
図6 残りの線
『エキスパート』の登録で次の入力が表示されます。
NS 0 10:31:17.937 EventProcessor5 (EURUSD.e,W1) Vertical lines before removing: 4 MD 0 10:31:17.937 EventProcessor5 (EURUSD.e,W1) Vertical lines removed from the chart: 4 QJ 0 10:31:18.078 EventProcessor5 (EURUSD.e,W1) Vertical lines after removing: 0
重要な側面についてお話する必要があるでしょう。オブジェクトが消去されると、そのプロパティにアクセスすることはできません。まえもってオブジェクトの必要なデータを取り戻さなければ 、消去後そのデータにアクセスできなくなる、ということです。消去されるオブジェクトタイプを見つける必要があれば、オブジェクト自体が消去される前にそれを格納しなければなりません。私は MQL5 開発者にターミナルで利用可能なチャートの履歴を作成いただくことを提案したいと思います。それで消去されるオブジェクトのプロパティを参照することができるようになります。
「エキスパート」の最終バージョンに EventProcessor5.mq5と名づけます。
4.6. チャート上のマウスクリックイベント
このイベントはチャートが左マウスボタンでクリックされると発生します。チャート上での右クリックはコンテキストメニューを開き、中央ボタンのクリックは crosshair.をもたらします。ハンドラのパラメータ lparam およびdparam はそれぞれ X 軸と Y 軸の座標を知らせています。
続くシンプルなタスクは例の役割をします。マウスのクリックが行われる場所に「買い」の矢印が描画されるように手配します。オブジェクト「矢印」にはアンカーポイントが1つしかありません。結果、アンカーポイントの時間と価格値に対する X 軸と Y 軸の変換が1件だけ必要となります。
以下は上記例のコードです。
//--- 6 case CHARTEVENT_CLICK: { comment+="6) mouse click on chart"; //--- object counter static uint sign_obj_cnt; string buy_sign_name="buy_sign_"+IntegerToString(sign_obj_cnt+1); //--- coordinates int mouse_x=(int)lparam; int mouse_y=(int)dparam; //--- time and price datetime obj_time; double obj_price; int sub_window; //--- convert the X and Y coordinates to the time and price values if(ChartXYToTimePrice(0,mouse_x,mouse_y,sub_window,obj_time,obj_price)) { //--- create object if(!ObjectCreate(0,buy_sign_name,OBJ_ARROW_BUY,0,obj_time,obj_price)) { Print("Failed to create buy sign!"); return; } //--- redraw chart ChartRedraw(); //--- increase object counter sign_obj_cnt++; } //--- break; }
EA の現在バージョンを EventProcessor6.mq5と名づけます。
4.7. グラフィックオブジェクト上でのマウスクリックイベント
チャートイベントのこのタイプが前出のイベントと異なるのはマウスのクリックがグラフィックオブジェクト上で起こる点のみです。文字列パラメータ sparam はクリックがその上で行われるオブジェクト名を持ちます。前出の例では「買い」矢印を作成しました。このタイプのオブジェクト上でのクリックが「売り」矢印に変えるようにしましょう。
以下はハンドラのこのブロックのコード記述です。
//--- 7 case CHARTEVENT_OBJECT_CLICK: { comment+="7) mouse click on graphical object"; //--- string sign_name=sparam; //--- delete buy arrow if(ObjectDelete(0,sign_name)) { //--- redraw chart ChartRedraw(); //--- static uint sign_obj_cnt; string sell_sign_name="sell_sign_"+IntegerToString(sign_obj_cnt+1); //--- coordinates int mouse_x=(int)lparam; int mouse_y=(int)dparam; //--- time and price datetime obj_time; double obj_price; int sub_window; //--- convert the X and Y coordinates to the time and price values if(ChartXYToTimePrice(0,mouse_x,mouse_y,sub_window,obj_time,obj_price)) { //--- create object if(!ObjectCreate(0,sell_sign_name,OBJ_ARROW_SELL,0,obj_time,obj_price)) { Print("Failed to create sell sign!"); return; } //--- redraw chart ChartRedraw(); //--- increase object counter sign_obj_cnt++; } } //--- break; }
この例のためにマウスクリック処理に触れずにおいたのです。EAを起動し、マウスの左クリックを3度行い3本の買い矢印を取得しました(図7)。その場所を黄色で強調しました。
図7 「買い」矢印
ここで各「買い」矢印をクリックすると、次の描画を受け取ります(図8)。
図8 「買い」矢印と「売り」矢印
「売り」矢印が予定どおり表示されましたが、「買い」矢印は表示されるよう予定されませんでした。「買い」矢印の名前を黄色で強調した箇所のチャート上にオブジェクトリストを持ってきているのには理由があります。
EA が4番目、5番目、6番目の「買い」矢印を作成したのはすぐに判ります。それはなぜ起こったのでしょうか?それはオブジェクト上の最初のクリックが2件のイベントを発生させたためです。1番目は実際のオブジェクト上のクリック、2番目はチャート上のクリックです。最後のイベントが「買い」矢印の作成を行います。2番目のイベント、チャート上のクリックを妨げるメカニズムを追加することが必要です。私にはそれは時間上の制御がそのようなメカニズムに思えます。
グローバル変数 gLastTimeを追加します。それは「買い」矢印作成時間の制御を促します。「売り」矢印作成後250秒以内にシンプルなクリックハンドラが呼ばれると、この呼び出しは渡されます。
チャートが再描写される前に下記の文字列がオブジェクト上のクリック処理のブロックに追加されます。
//--- store the moment of creation gLastTime=GetTickCount();
チャート上のクリック処理のブロックに時間の検証を追加する必要があります。
uint lastTime=GetTickCount(); if((lastTime-gLastTime)>250) { //--- click handling }
再び「買い」タイプのチャート上に3本の矢印を作成します(図9)。
図9 「買い」矢印
サイズが小さいですが、矢印の上でクリックしてみます。クリックしたら矢印は『売り』タイプに変わりました(図10)。
図10 「売り」矢印
前のものと同様、新しいバージョンをEventProcessor7.mq5.と名づけます。
4.8. マウスでグラフィックオブジェクトを移動するイベント
このイベントはオブジェクトがチャート領域内で移動されると発生します。ハンドラが移動したオブジェクト名を文字列パラメータ sparamの形式で受け取ります。
ここに別の例があります。Intra-day デイトレーダーはよく特定の時間間隔でトレードします。縦ラインはい時間間隔の限度です。図はおおよそ図11のようになります。関心のある間隔は強調表示されています。
図11 時間間隔の限度
時間間隔はマニュアルで変更可能です。われわれの半自動はそのような変更に対応の必要があります。
2本の縦ライン名を記載している変数をグローバルレベルで作成します。:gTimeLimit1_name と gTimeLimit2_nameです。また長方形の名前に対して数個の変数を作成する必要があります。それはチャート上のトレードのない時間の色を暗くします。アンカーポイント用のグローバル変数もまた作成する必要があります。長方形が2個あるので、アンカーポイントは4個になります。
以下はCHARTEVENT_OBJECT_DRAG ハンドラの場合のコードです。
//--- 8 case CHARTEVENT_OBJECT_DRAG: { comment+="8) move graphical object with mouse"; string curr_obj_name=sparam; //--- if one of the vertical lines is moved if(!StringCompare(curr_obj_name,gTimeLimit1_name) || !StringCompare(curr_obj_name,gTimeLimit2_name)) { //--- the time coordinate of vertical lines datetime time_limit1=0; datetime time_limit2=0; //--- find the first vertical line if(ObjectFind(0,gTimeLimit1_name)>-1) time_limit1=(datetime)ObjectGetInteger(0,gTimeLimit1_name,OBJPROP_TIME); //--- find the second vertical line if(ObjectFind(0,gTimeLimit2_name)>-1) time_limit2=(datetime)ObjectGetInteger(0,gTimeLimit2_name,OBJPROP_TIME); //--- if vertical lines are found if(time_limit1>0 && time_limit2>0) if(time_limit1<time_limit2) { //--- update properties of rectangles datetime start_time=time_limit1; datetime finish_time=time_limit2; //--- if(RefreshRecPoints(start_time,finish_time)) { //--- if(!ObjectMove(0,gRectLimit1_name,0,gRec1_time1,gRec1_pr1)) { Print("Failed to move the 1st point!"); return; } if(!ObjectMove(0,gRectLimit1_name,1,gRec1_time2,gRec1_pr2)) { Print("Failed to move the 2nd point!"); return; } //--- if(!ObjectMove(0,gRectLimit2_name,0,gRec2_time1,gRec2_pr1)) { Print("Failed to move the 1st point!"); return; } if(!ObjectMove(0,gRectLimit2_name,1,gRec2_time2,gRec2_pr2)) { Print("Failed to move the 2nd point!"); return; } } } } //--- break; }
このコードにはカスタム関数 RefreshRecPoints()が含まれています。それは2個の長方形のアンカーポイントの値を更新します。EA 初期化のブロックはグラフィックオブジェクト作成に関する情報をもたらします。更新バージョンは EventProcessor8.mq5と名づけます。
4.9. テキストフィールド内のテキスト編集終了 イベント
このイベントタイプは高度に特殊化された性質があり、データ入力フィールドのテキストが編集されるときに発生します。パラメータ sparam いんは作業対象のオブジェクト名が含まれます。
ここに考察する例があります。データ入力フィールドでは実行しようとしているトレード処理を入力します。処理を2件だけ:売りと買いとします。入力フィールドに「買い」と入れると EA は資産を買い入れ、「売り」と入れると売却します。このフィールドが大文字小文字の区別をしないように手配しようと思います。「売り」と「買い」とタイプできるようにするのです。テキストと入力フィールドは売却で赤色にし、購入で青色にします(図12)。
図12 テキストフィールドでの買い
以下はケース CHARTEVENT_OBJECT_ENDEDITのコードです。
//--- 9 case CHARTEVENT_OBJECT_ENDEDIT: { comment+="9) end of editing a text in the data entry field"; //--- string curr_obj_name=sparam; //--- if specified text field is being edited if(!StringCompare(curr_obj_name,gEdit_name)) { //--- get object description string obj_text=NULL; if(ObjectGetString(0,curr_obj_name,OBJPROP_TEXT,0,obj_text)) { //--- check value if(!StringCompare(obj_text,"Buy",false)) { if(TryToBuy()) //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrBlue); } else if(!StringCompare(obj_text,"Sell",false)) { if(TryToSell()) //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrRed); } else { //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrGray); } //--- redraw chart ChartRedraw(); } } //--- break; }
EA の更新バージョンは EventProcessor9.mq5と名づけます。ソースファイルでテキストフィールド作成ブロックを確認することができます。
4.10. チャート変更イベント
本稿で考察する最後のイベントはチャート設定変更に関連するものです。これは特殊なイベントです。というのもここではチャート上のオブジェクトではなくチャートそのものを対象とするからです。開発者によるとこのイベントはチャートサイズ変更時、または新規設定が行われるときに発生する、ということです。
ここに別の例があります。いくつかのチャート設定変更には禁止事項があるとします。そうすると制約下での設定変更をしようとしても無視されます。実際、EA は単に前回値を返すだけです。チャートの次のパラメータを固定します。
- 表示グリッド
- チャート表示タイプ
- 背景色
以下は上記に該当するコードです。
//--- 10 case CHARTEVENT_CHART_CHANGE: { //--- current height and width of the chart int curr_ch_height=ChartHeightInPixelsGet(); int curr_ch_width=ChartWidthInPixels(); //--- if chart height and width have not changed if(gChartHeight==curr_ch_height && gChartWidth==curr_ch_width) { //--- fix the properties: //--- display grid if(!ChartShowGridSet(InpToShowGrid)) { Print("Failed to show grid!"); return; } //--- type of chart display if(!ChartModeSet(InpMode)) { Print("Failed to set mode!"); return; } //--- background color if(!ChartBackColorSet(InpBackColor)) { Print("Failed to set background сolor!"); return; } } //--- store window dimensions else { gChartHeight=curr_ch_height; gChartWidth=curr_ch_width; } //--- comment+="10) modify chart"; //--- break; }
最終バージョンは EventProcessor10.mq5と名づけます。
おわりに
本稿では MetaTrader 5における典型的なチャートイベントの多様性の説明を試みました。ここで述べたイベント処理例が MQL5でコーディングを始めるプログラマーの方々の役に立つことを願っています。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/689
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索