トップ  >  自作してみる >  MQL4未経験者向け(インジケータ作成の基本)  >  O6.オブジェクト系インジケータ作成(シグナルアロー【矢印】)
O6.オブジェクト系インジケータ作成(シグナルアロー【矢印】)


今回はシグナルアロー【矢印】のオブジェクトについて説明します。
具体的には以前作成したM6.トレンド系インジケータ作成(トレンド転換シグナルアロー【矢印】) を、
OBJ_ARROWを使って作成します。


それでは以前作成したトレンド系インジケータ作成(トレンド転換シグナルアロー【矢印】) のソースコードTestArrowFractal.mq4をコピペして、
ファイル名をTestObjArrowFractal.mq4に変更しましょう。

不要なソースコードを削除

インジケータプロパティは不要なので全て削除します。
今回はOBJ_ARROWを使ってインジケータ作成をする事がメインテーマなので、
ソースコード量を減らすためにオブジェクトのPixel単位オフセットも削除します。


ソースコード:
//+------------------------------------------------------------------+
//|                                          TestObjArrowFractal.mq4 |
//|                                                             yuki |
//|                                      https://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "yuki"
#property link      "https://yukifx.web.fc2.com/"
#property version   "1.00"
#property strict // strictは絶対に削除しない事
#property indicator_chart_window // カスタムインジケータをチャートウインドウに表示する

// マクロ定義
#define    IND_MIN_INDEX         3               // 最小バー数

//+------------------------------------------------------------------+
//| OnInit(初期化)イベント
//+------------------------------------------------------------------+
int OnInit()
{

   return( INIT_SUCCEEDED );      // 戻り値:初期化成功
}

//+------------------------------------------------------------------+
//| OnCalculate(tick受信)イベント
//| カスタムインジケータ専用のイベント関数
//+------------------------------------------------------------------+
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[],   // Tick出来高
                const long     &volume[],        // Real出来高
                const int      &spread[])        // スプレッド
{
    int end_index = Bars - prev_calculated;  // バー数取得(未計算分)
    if ( end_index <= IND_MIN_INDEX ) {    // 直近数本は常時更新
        end_index = IND_MIN_INDEX;
    }

    if ( Bars <= IND_MIN_INDEX ) {         // ヒストリカルデータ不足時
        return 0;                            // 全て再計算が必要なので、計算済みバー数を0にして終了する
    }

    for( int icount = 0 ; icount < end_index ; icount++ ) {
        double get_lower = iFractals(                // フラクタル算出
                                       Symbol(),      // 通貨ペア
                                       Period(),      // 時間軸
                                       MODE_LOWER,   // ラインインデックス
                                       icount          // シフト
                                      );

        double get_upper = iFractals(                // フラクタル算出
                                       Symbol(),      // 通貨ペア
                                       Period(),      // 時間軸
                                       MODE_UPPER,   // ラインインデックス
                                       icount          // シフト
                                     );
    

/*
        if ( get_lower > 0 ) {
            get_lower = GetOffsetRate(get_lower, 10); // 価格をピクセル単位でオフセット
            _IndBuffer1[icount]    = get_lower;       // インジケータ1にフラクタル下を設定
        }
        if ( get_upper > 0 ) {
            get_upper = GetOffsetRate(get_upper, -10);  // 価格をピクセル単位でオフセット
            _IndBuffer2[icount]    = get_upper;         // インジケータ2にフラクタル上を設定
        }
*/
    }

   return( rates_total ); // 戻り値設定:次回OnCalculate関数が呼ばれた時のprev_calculatedの値に渡される
}


まずはこの状態でコンパイルエラーにならない事を確認して下さい。

オブジェクト描画に必要ないつものアレを追加

オブジェクト描画の解説で何度も説明している内容なので、もう説明がかなり雑になってしまいますが、
今までと同様にオブジェクト描画に必要ないつものアレを追加します。

ソースコード:
#define    OBJ_HEAD              ( __FILE__ + "_" )  // オブジェクトヘッダ名

//+------------------------------------------------------------------+
//| OnDeinit(アンロード)イベント
//+------------------------------------------------------------------+
void OnDeinit( const int reason ) {

    ObjectsDeleteAll(              // 追加したオブジェクトを全削除
                        0,           // チャートID
                        OBJ_HEAD    // オブジェクト名の接頭辞
                       );

}



オブジェクトアロー描画する関数を追加する

今までと同様にオブジェクト描画する関数を追加します。
やる事は今までやって来た内容と大差はありません。


ソースコード:
//+------------------------------------------------------------------+
//| オブジェクト描画
//+------------------------------------------------------------------+
void DispObj( int    in_index,       // 1番目のインデックス
               double in_rate,       // 表示価格
               bool    in_upper_bool  // 上矢印表示フラグ
) {

    // インデックスが範囲外の場合は描画しない
    if ( in_index < 0 ) {
        return;
    }

    if ( in_index >= Bars ) {
        return;
    }

    int    arrow_code;         // アローコード
    int    arrow_anchor;       // オブジェクトアンカー
    string obj_name;          // オブジェクト名
    obj_name = StringFormat( "%sFractalArrow%s" , OBJ_HEAD, TimeToStr( Time[in_index] ));


    if ( in_upper_bool == true) {
        arrow_code = 217;                // 上アロー
        arrow_anchor = ANCHOR_BOTTOM;  // オブジェクトアンカー:下
    } else {
        arrow_code = 218;               // 下アロー
        arrow_anchor = ANCHOR_TOP;    // オブジェクトアンカー:上
    }

    ObjectDelete( obj_name );        // 指定したオブジェクトを常に削除する

    if ( in_rate > 0 ) {
        ObjectCreate(                                  // オブジェクト生成
                        obj_name,                        // オブジェクト名
                        OBJ_ARROW,                      // オブジェクトタイプ
                        0,                               // ウインドウインデックス
                        Time[in_index] ,                // 1番目の時間のアンカーポイント
                        in_rate                         // 1番目の価格のアンカーポイント
                        );


        // オブジェクトプロパティ設定
        ObjectSetInteger( 0, obj_name, OBJPROP_COLOR, clrWhite);     // ラインの色設定
        ObjectSetInteger( 0 ,obj_name, OBJPROP_BACK, false);         // オブジェクトの背景表示設定
        ObjectSetInteger( 0 ,obj_name, OBJPROP_SELECTABLE, false);   // オブジェクトの選択可否設定
        ObjectSetInteger( 0 ,obj_name, OBJPROP_SELECTED, false);     // オブジェクトの選択状態
        ObjectSetInteger( 0 ,obj_name, OBJPROP_HIDDEN, true);        // オブジェクトリスト表示設定

        ObjectSetInteger(0,obj_name,OBJPROP_WIDTH,2);                   // 幅設定
        ObjectSetInteger(0,obj_name,OBJPROP_ANCHOR,arrow_anchor);       // アンカータイプ
        ObjectSetInteger(0,obj_name,OBJPROP_ARROWCODE,arrow_code);      // アローコード
    }
}



オブジェクトアローを描画

OnCalculate()イベント関数内でiFractals()関数でフラクタル算出した後に、オブジェクトアロー描画する処理を追加します。

ソースコード:
      double set_rate = MathMax( get_lower , get_upper ); // 最大値取得
      bool   upper_bool = false;                          // 上表示判定
      if ( get_upper > 0 ) {                              // アッパー取得出来ている場合
          upper_bool = true;
      }

      DispObj( icount , set_rate , upper_bool  );         // オブジェクト描画


MathMax()関数は2つの値を比較して、大きい方の返します。
iFractals()関数は上か下のどちらか一方しか取得しないので、片方は必ずゼロを返します。
その為、0以上の値を返した側のオブジェクトを描画させます。

インジケータOBJ_ARROW


常に連続して表示させる必要の無いインジケータは、
このようにOBJ_ARROWオブジェクト を使って作る事が出来ます。


基本的に今まで解説してきた内容の復習でしかないので、細かい解説は割愛します。
今までの解説を全て見て来た人ならソースコードのコメントを見れば分かるレベルになっている筈です。


オブジェクトの隙間について

バーとオブジェクトがピッタリ合わず隙間が空いてしまうというお問い合わせがありましたので説明追記します。

オブジェクトを選択状態にすると分かり易いのですが、

ソースコード:
        ObjectSetInteger( 0 ,obj_name, OBJPROP_SELECTED, true);     // オブジェクトの選択状態

インジケータOBJ_ARROW

オブジェクトのシンボル自体にマージンがある為、このように隙間が空いているように見えます。
もしピッタリ合わせたいのであれば以前説明したシンボル表示位置をピクセル単位で調整するを参考にして位置調整して下さい。

完成したサンプルソースコード


最後に出来上がったソースコードをまとめると、

ソースコード:
//+------------------------------------------------------------------+
//|                                          TestObjArrowFractal.mq4 |
//|                                                             yuki |
//|                                      https://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "yuki"
#property link      "https://yukifx.web.fc2.com/"
#property version   "1.00"
#property strict // strictは絶対に削除しない事
#property indicator_chart_window // カスタムインジケータをチャートウインドウに表示する

// マクロ定義
#define    IND_MIN_INDEX         3               // 最小バー数
#define    OBJ_HEAD              ( __FILE__ + "_" )  // オブジェクトヘッダ名

//+------------------------------------------------------------------+
//| OnInit(初期化)イベント
//+------------------------------------------------------------------+
int OnInit()
{

   return( INIT_SUCCEEDED );      // 戻り値:初期化成功
}


//+------------------------------------------------------------------+
//| OnDeinit(アンロード)イベント
//+------------------------------------------------------------------+
void OnDeinit( const int reason ) {

    ObjectsDeleteAll(              // 追加したオブジェクトを全削除
                        0,           // チャートID
                        OBJ_HEAD    // オブジェクト名の接頭辞
                       );

}

//+------------------------------------------------------------------+
//| OnCalculate(tick受信)イベント
//| カスタムインジケータ専用のイベント関数
//+------------------------------------------------------------------+
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[],   // Tick出来高
                const long     &volume[],        // Real出来高
                const int      &spread[])        // スプレッド
{
    int end_index = Bars - prev_calculated;  // バー数取得(未計算分)
    if ( end_index <= IND_MIN_INDEX ) {    // 直近数本は常時更新
        end_index = IND_MIN_INDEX;
    }

    if ( Bars <= IND_MIN_INDEX ) {         // ヒストリカルデータ不足時
        return 0;                            // 全て再計算が必要なので、計算済みバー数を0にして終了する
    }

    for( int icount = 0 ; icount < end_index ; icount++ ) {
        double get_lower = iFractals(                // フラクタル算出
                                       Symbol(),      // 通貨ペア
                                       Period(),      // 時間軸
                                       MODE_LOWER,   // ラインインデックス
                                       icount          // シフト
                                      );

        double get_upper = iFractals(                // フラクタル算出
                                       Symbol(),      // 通貨ペア
                                       Period(),      // 時間軸
                                       MODE_UPPER,   // ラインインデックス
                                       icount          // シフト
                                     );
    
        double set_rate = MathMax( get_lower , get_upper ); // 最大値取得
        bool   upper_bool = false;                          // 上表示判定
        if ( get_upper > 0 ) {                              // アッパー取得出来ている場合
            upper_bool = true;
        }

        DispObj( icount , set_rate , upper_bool  );         // オブジェクト描画

    }

   return( rates_total ); // 戻り値設定:次回OnCalculate関数が呼ばれた時のprev_calculatedの値に渡される
}

//+------------------------------------------------------------------+
//| オブジェクト描画
//+------------------------------------------------------------------+
void DispObj( int    in_index,       // 1番目のインデックス
               double in_rate,       // 表示価格
               bool    in_upper_bool  // 上矢印表示フラグ
) {

    // インデックスが範囲外の場合は描画しない
    if ( in_index < 0 ) {
        return;
    }

    if ( in_index >= Bars ) {
        return;
    }

    int    arrow_code;         // アローコード
    int    arrow_anchor;       // オブジェクトアンカー
    string obj_name;          // オブジェクト名
    obj_name = StringFormat( "%sFractalArrow%s" , OBJ_HEAD, TimeToStr( Time[in_index] ));


    if ( in_upper_bool == true) {
        arrow_code = 217;                // 上アロー
        arrow_anchor = ANCHOR_BOTTOM;  // オブジェクトアンカー:下
    } else {
        arrow_code = 218;               // 下アロー
        arrow_anchor = ANCHOR_TOP;    // オブジェクトアンカー:上
    }

    ObjectDelete( obj_name );        // 指定したオブジェクトを常に削除する

    if ( in_rate > 0 ) {
        ObjectCreate(                                  // オブジェクト生成
                        obj_name,                        // オブジェクト名
                        OBJ_ARROW,                      // オブジェクトタイプ
                        0,                               // ウインドウインデックス
                        Time[in_index] ,                // 1番目の時間のアンカーポイント
                        in_rate                         // 1番目の価格のアンカーポイント
                        );


        // オブジェクトプロパティ設定
        ObjectSetInteger( 0, obj_name, OBJPROP_COLOR, clrWhite);     // ラインの色設定
        ObjectSetInteger( 0 ,obj_name, OBJPROP_BACK, false);         // オブジェクトの背景表示設定
        ObjectSetInteger( 0 ,obj_name, OBJPROP_SELECTABLE, false);   // オブジェクトの選択可否設定
        ObjectSetInteger( 0 ,obj_name, OBJPROP_SELECTED, false);     // オブジェクトの選択状態
        ObjectSetInteger( 0 ,obj_name, OBJPROP_HIDDEN, true);        // オブジェクトリスト表示設定

        ObjectSetInteger(0,obj_name,OBJPROP_WIDTH,2);                   // 幅設定
        ObjectSetInteger(0,obj_name,OBJPROP_ANCHOR,arrow_anchor);       // アンカータイプ
        ObjectSetInteger(0,obj_name,OBJPROP_ARROWCODE,arrow_code);      // アローコード
    }
}



スポンサーリンク
検索

↑の検索エンジンが表示されない人は、
↓の古い検索エンジンを使用して下さい。
カスタム検索
MQL4リファレンスツリー
スポンサーリンク


Copyright ©2015 MT4でEA自作しちゃお~ All Rights Reserved.


Top

inserted by FC2 system