2016年8月4日木曜日

[MT4プログラム]定型チャート対策、オブジェクトを生成するインジケータは要注意!

たまにはプログラムネタを書かないと!

MT4には定型チャートという、オブジェクトやインジケータ設定を復元する機能があります。

■定型チャート

チャートの右クリックなどから呼び出せます。

便利な機能なのですが、インジケータ開発者には少し注意が必要です。
この機能、オブジェクトも復元してしまうため、チャート上にオブジェクトを生成するようなインジケータでは、想定していない古いオブジェクトが残った状態になります。

インジケータ内で作成したオブジェクトを管理しているようなものだと、オブジェクトと管理情報が結びつかず正しく動作しないという現象が発生します。

特にCButtonなど、Controlsのクラス群を使用する場合は要注意です。

販売中のハーモニックパターン検出インジケータでは、チャート上のボタンをしても反応しないという症状が発生しました。

この対策として、OnInit時にインジケータで作成すると思われるオブジェクトをいったん削除するコードを入れます。
たとえば、CButtonを使用する場合は、次の形になります。

CButton btnTest;
int OnInit()
{
   ObjectDelete(0, "CTL_BTN_TEST");
   btnTest.FontSize(8);
   btnTest.Text("Test");
   btnTest.Create(ChartID(), "CTL_BTN_TEST", 0, 10, 20, 50, 50);
   
   return(INIT_SUCCEEDED);
}

ただ、これだと、仮にCButtonの中で複数オブジェクトを生成する場合などは、正しく動作しません。MQLのコントロールクラスは、指定された名前+付加文字列というルールでオブジェクトを作成します。

あらかじめインジケータで使用するオブジェクト名の頭の部分を決めて置き、一致するものをすべて削除するという対応を行います。こんな感じです。

#define OBJECT_NAME "OBJ_TEST_"

// テストボタン
CButton btnTest;

//------------------------------------------------------------------
//初期化
int OnInit()
{
   //チャートに残っているかもしれない古いオブジェクトを全削除する
   ClearObjects();
   
   btnTest.FontSize(8);
   btnTest.Text("Test");
   btnTest.Create(ChartID(), OBJECT_NAME + "BTN_TEST", 0, 10, 20, 50, 50);
   
   return(INIT_SUCCEEDED);
}
  
//------------------------------------------------------------------
//オブジェクト全削除
void ClearObjects()
{
   int total = ObjectsTotal();
   //生成したオブジェクトを削除する。
   //0から削除するとインデックス位置がずれて
   //正しく削除できないため、後ろから削除するようにする。
   for( int i = total - 1; i >= 0 ; i--)
   {
      string name = ObjectName( i );
      
      // 先頭文字列が一致する場合、削除する。
      if ( StringFind( name, OBJECT_NAME ) == 0 )
      {
         ObjectDelete( name );
      }
   }   
}


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。