トップ  >  自作してみる  >  EA作成方法  >  ボリンジャーバンド逆張りサンプルソースコード(リミット・ストップ設定)
スポンサーリンク
検索

↑の検索エンジンが表示されない人は、
↓の古い検索エンジンを使用して下さい。
カスタム検索
MQL4リファレンスツリー
ボリンジャーバンド逆張りサンプルソースコード(リミット・ストップ設定)











ボリンジャーバンドの2σで逆張りをし、ベースライン抜けで決済するサンプルプログラムです。
リミット・ストップの設定も行います。
前のサンプルコードよりも長いコードですが、実用的な処理が含まれています。
クラスを用いればもっとスマートになりますが、プログラミング慣れしていない人には理解し難いのでクラスは使用していません。
一応簡単なテストをして動作チェックは行っていますが、3時間くらいで作成・テストしたものなのでバグが含まれているかもしれません。

下記ソースコード上の関数をクリックすると、対象のリファレンスページが開かれます。
分かりやすいように日本語コメントをつけていますが、分からない事があれば問い合わせページで質問して下さい。


注意事項:

以下サンプルソースは、実際に売買を行う処理が含まれているので、絶対にライブ口座では実行しないで下さい。
念の為、デモ口座でしか処理しない対策処理を施しています。
これはあくまで勉強用のソースコードです。



サンプルソース:
緑色の部分はコメントです。
//+------------------------------------------------------------------+
//|                                            SampleBollingerEA.mq4 |
//|                                 Copyright 2019, Created by Yuki. |
//|                                       https://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "yuki"
#property link      "https://yukifx.web.fc2.com/"
#property version   "1.00"
#property strict

#define    MAGIC_NO        20191012                // EA識別用マジックナンバー(他EAと被らない任意の値を使用する)
#property description "ボリンジャーバンド2σタッチ(前回終値判定)で逆張りし、MAタッチで決済するサンプルEA。"
#property description "プログラミングの勉強用サンプルEAの為、勝てるEAではありません。"
#property description "絶対にライブ口座で稼働させないで下さい、絶対に負けます。"

#define EA_ORDER_TIMES_INTERVAL        5                        // エントリー試行回数
#define ORDER_SLIPRATE                50                        // スリップページ[分解能:0.1pips]

//―――― EAインプットパラメータ ――――――――――――――――――――
input    int       Input_MAPeriod      = 25;                    // 期間
input    double    Input_Limit         = 100;                   // リミット[pips] 0指定で無効
input    double    Input_Stop          = 100;                   // ストップ[pips] 0指定で無効
sinput   double    Input_EntryLot      = 0.01;                  // エントリーロット[10万通貨]
sinput   bool      Input_Debug         = true;                  // デバッグ情報出力

//――― 型宣言 ――――――――――――――――――――――――
struct struct_PositionInfo {                // ポジション情報構造体型
    int               ticket_no;                // チケットNo
    int               entry_dir;                // エントリーオーダータイプ
    double            entry_orderrate;          // エントリーオーダーレート
    double            entry_donerate;           // エントリー約定レート
    double            entry_lot;                // エントリーlot
    double            set_limit;                // リミットレート
    double            set_stop;                 // ストップレート
};


//――― 変数宣言 ――――――――――――――――――――――――
struct_PositionInfo _StPositionInfoData;    // ポジション情報構造体データ


//――― イベント処理 ――――――――――――――――――――――――

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

    if ( IsDemo() == false ) { // デモ口座かチェック
        // リアル口座の場合、エラーメッセージを出力し、処理終了
        MessageBox("実際に新規オーダーするので、デモ口座で動作させて下さい。","エラー",MB_ICONEXCLAMATION);
        return(INIT_FAILED);               // 処理終了
    }

    GetPosiInfo(_StPositionInfoData);          // ポジション情報をサーバーから取得

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


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

//+------------------------------------------------------------------+
//| OnTick(tick受信)イベント
//+------------------------------------------------------------------+
void OnTick() {

   TaskMain();                    // メイン処理を実行

}



//――― 内部処理 ―――――――――――――――――――――――――――


//+------------------------------------------------------------------+
//| メイン処理
//+------------------------------------------------------------------+
void TaskMain()  {

    static    datetime slasttime;                       // 最後に記録した時間軸時間
                                                        // staticはTaskMain()関数が終了してもデータは保持される

    datetime temptime    = iTime(Symbol(),Period(),0);  // 現在の時間軸の時間取得

    if ( temptime != slasttime ) {                      // 時間足が確定時にtrue
        slasttime = temptime;                           // 最後に記録した時間軸時間を保存

        GetPosiInfo(_StPositionInfoData);               // ポジション情報をサーバーから取得
        if ( CheckTicketPosition( _StPositionInfoData.ticket_no) == true ) { // 指定チケットが決済済みの場合
            ClearPosiInfo(_StPositionInfoData);
        }

        // 現在ポジションを保有しているか判定
        if ( GetKeepPosition(_StPositionInfoData) == false ) {
            // ノーポジの場合
            JudgeEntry(_StPositionInfoData);            // エントリー判定を行う
        }
    }

    // 現在ポジションを保有しているか判定
    if ( GetKeepPosition(_StPositionInfoData) == true ) {
        // ポジション保有している場合
        JudgeClose(_StPositionInfoData);                // クローズ判定を行う
    }


}

//+------------------------------------------------------------------+
//| ポジション情報構造体初期化
//+------------------------------------------------------------------+
void ClearPosiInfo( struct_PositionInfo &in_st ){
    // 変更判定に必要なメンバのみ初期化

    in_st.ticket_no       = 0;      // チケットNo
    in_st.entry_orderrate = 0;      // エントリーレート
    in_st.entry_donerate  = 0;      // エントリー約定レート
    in_st.set_limit       = 0;      // リミットレート
    in_st.set_stop        = 0;      // ストップレート
}

//+------------------------------------------------------------------+
//| ポジション保有判定
//+------------------------------------------------------------------+
bool GetKeepPosition( struct_PositionInfo &in_st ){
    bool ret = false;
    
    if ( in_st.ticket_no != 0 ) {                        // チケットNoが初期値以外ならポジション保有と判定
        ret = true;
    }
    
    return ret;
}

//+------------------------------------------------------------------+
//| ポジション情報を取得
//+------------------------------------------------------------------+
bool GetPosiInfo( struct_PositionInfo &in_st ){

    int     total_order;
    int     pos;
    bool    ret = false;

    total_order     = OrdersTotal();                                      // 保有ポジション数取得

    if ( IsConnected() == true ) {                                          // サーバー接続チェック
        for ( pos = 0 ; pos < total_order ; pos++ ) {                        // 保有ポジション数分ループ
            if ( OrderSelect( pos , SELECT_BY_POS ) == true ) {              // インデックス指定でポジションを選択

                if ( OrderMagicNumber() != MAGIC_NO ) {                     // マジックNoの異なるポジションはスルー
                    continue;                                               // 次のループ処理へ
                }

                if ( OrderSymbol() != Symbol() ) {                          // 通貨ペアの異なるポジションはスルー
                    continue;                                               // 次のループ処理へ
                }

                in_st.ticket_no      = OrderTicket();                       // チケット番号を取得
                in_st.entry_dir      = OrderType();                         // オーダータイプを取得
                in_st.entry_donerate = OrderOpenPrice();                    // エントリーレートを取得
                in_st.entry_lot      = OrderLots();                         // ロットを取得
                in_st.set_limit      = OrderTakeProfit();                   // リミットを取得
                in_st.set_stop       = OrderStopLoss();                     // ストップを取得

                CheckLimitStop(in_st);                                      // リミットストップ再設定

                ret = true;

                break;                                                      // ループ処理中断
            }
        }
    }

    return ret;
}

//+------------------------------------------------------------------+
//| リミットストップ再設定
//+------------------------------------------------------------------+
void CheckLimitStop( struct_PositionInfo &in_st ){
    
    double    temp_limit    = Input_Limit * Point() * 10;            // リミット値
    double    temp_stop     = Input_Stop  * Point() * 10;            // ストップ値
    double    set_limitrate = 0;
    double    set_stoprate  = 0;

    if ( in_st.entry_donerate > 0 ) {
        if ( in_st.entry_dir == OP_BUY ) {                                   // 買いエントリーの場合
            if ( temp_limit > 0 ) {                                          // リミット指定がある場合
                set_limitrate        = in_st.entry_donerate + temp_limit;    // 約定レートを基にリミットレートを算出
            }

            if ( temp_stop > 0) {                                            // ストップ指定がある場合
                set_stoprate        = in_st.entry_donerate - temp_stop;      // 約定レートを基にストップレートを算出
            }
        } else {                                                             // 売りエントリーの場合
            if ( temp_limit > 0 ) {                                          // リミット指定がある場合
                set_limitrate        = in_st.entry_donerate - temp_limit;    // 約定レートを基にリミットレートを算出
            }

            if ( temp_stop > 0) {                                            // ストップ指定がある場合
                set_stoprate        = in_st.entry_donerate + temp_stop;      // 約定レートを基にストップレートを算出
            }
        }

        set_limitrate  = NormalizeDouble( set_limitrate  , Digits );         // リミットレートを正規化
        set_stoprate   = NormalizeDouble( set_stoprate   , Digits );         // ストップレートを正規化

        // リミット・ストップに変化がある場合
        if ( set_limitrate != in_st.set_limit || set_stoprate != in_st.set_stop ) {
            EA_Modify_Order( in_st.ticket_no , set_limitrate , set_stoprate, __LINE__ );    // オーダー変更
        }
    }
    
}

//+------------------------------------------------------------------+
//| チケットチェック
//+------------------------------------------------------------------+
bool CheckTicketPosition( int in_ticket ){

    bool done_ret = false;

    if ( in_ticket > 0   ) {
        bool bool_order_sel = OrderSelect( in_ticket , SELECT_BY_TICKET) ;    // チケットNOを指定して注文を選択

        if ( bool_order_sel == false ) {                                        // 指定したチケットNOの注文が無い場合
            debug_print(__LINE__ , StringFormat("TicketSelectErr:%d" , GetLastError()));
        }

        if ( OrderCloseTime() > 0 ) { // 指定した注文が決済済み(リミット・ストップによる決済も含む)の場合
            done_ret = true;
        }
        
    }
    
    return done_ret;
}

//+------------------------------------------------------------------+
//| エントリー判定
//+------------------------------------------------------------------+
void JudgeEntry(struct_PositionInfo &in_stposi){

    bool    upper_bool      = true;        // 取得モード判定
    int     lineindexmode   = MODE_UPPER;  // 乖離ラインモード
    double  bband_diverrate = 0;           // ボリンジャーバンド乖離ライン
    double  bband_baserate  = 0;           // ボリンジャーバンド中央ライン
    bool    entry_bool      = false;       // エントリー判定

    // ボリンジャーバンド中央ライン取得
    bband_baserate = iBands(
         Symbol()            // 通貨ペア:現在表示中の通貨ペアを指定
        ,Period()            // 時間軸:現在表示中の時間軸を指定
        ,Input_MAPeriod      // 平均期間
        ,2                   // 標準偏差:2σを指定
        ,0                   // バンドシフト
        ,PRICE_CLOSE         // 適用価格:終値を指定
        ,MODE_MAIN           // ラインインデックス:中央ラインを指定
        ,0                   // シフト
    );

    if ( Close[0] > bband_baserate ) {
        lineindexmode = MODE_UPPER;       // 現在値が中央ラインより上なら上弦ラインを取得
        upper_bool = true;                // 上弦判定
    } else {
        lineindexmode = MODE_LOWER;       // 現在値が中央ラインより上なら下弦ラインを取得
        upper_bool = false;               // 下弦判定
    }
    
    // ボリンジャーバンド乖離ライン取得
    bband_diverrate = iBands(
         Symbol()            // 通貨ペア:現在表示中の通貨ペアを指定
        ,Period()            // 時間軸:現在表示中の時間軸を指定
        ,Input_MAPeriod      // 平均期間
        ,2                   // 標準偏差:2σを指定
        ,0                   // バンドシフト
        ,PRICE_CLOSE         // 適用価格:終値を指定
        ,lineindexmode       // ラインインデックス:乖離ラインを指定
        ,0                   // シフト
    );

    // 前回終値とボリンジャーバンド価格が取得出来ている場合
    if ( Close[1] > 0 && bband_baserate > 0 && bband_diverrate > 0) {
        if ( upper_bool == true ) {                                           // 上弦ライン判定
            if ( Close[1] > bband_diverrate && Bid > bband_diverrate) {       // 前回終値とBidが上弦ライン超え
                entry_bool = true;                                            // エントリー判定:許可
            }
        } else {
            if ( Close[1] < bband_diverrate && Ask < bband_diverrate) {       // 前回終値とAskが下弦ライン超え
                entry_bool = true;                                            // エントリー判定:許可
            }
        }

        if ( entry_bool == true ) {                        // エントリー判定:許可の場合
            EA_Entry_Order( upper_bool , in_stposi );      // 新規エントリーオーダー
        }
    }
    
}

//+------------------------------------------------------------------+
//| クローズ判定
//+------------------------------------------------------------------+
void JudgeClose(struct_PositionInfo &in_stposi){

    bool    close_bool     = false;    // 決済判定
    bool    close_ret      = false;    // 決済執行結果
    double  bband_baserate = 0;        // ボリンジャーバンド中央ライン

    if ( in_stposi.ticket_no > 0 ) {
        // ボリンジャーバンド中央ライン取得
        bband_baserate = iBands(
             Symbol()            // 通貨ペア:現在表示中の通貨ペアを指定
            ,Period()            // 時間軸:現在表示中の時間軸を指定
            ,Input_MAPeriod      // 平均期間
            ,2                   // 標準偏差:2σを指定
            ,0                   // バンドシフト
            ,PRICE_CLOSE         // 適用価格:終値を指定
            ,MODE_MAIN           // ラインインデックス:中央ラインを指定
            ,0                   // シフト
        );

        if ( in_stposi.entry_dir == OP_BUY) {                        // 買いポジションの場合
            if ( Bid > bband_baserate && bband_baserate > 0) {       // 売値がボリバンより上の場合
                close_bool = true;                                   // 決済判定:許可
            }
        } else {                                                     // 売りポジションの場合
            if ( Ask < bband_baserate && bband_baserate > 0) {       // 買値がボリバンより下の場合
                close_bool = true;                                   // 決済判定:許可
            }
        }
        

        if ( close_bool == true ) {                                  // 決済判定:許可の場合
            close_ret = EA_CloseOrder( in_stposi.ticket_no );        // クローズオーダー執行
            if ( close_ret == true ) {                               // クローズオーダー約定した場合
                ClearPosiInfo(in_stposi);                            // ポジション情報初期化
            }
        }
    }
    
}

//+------------------------------------------------------------------+
//| 新規エントリオーダー
//+------------------------------------------------------------------+
bool EA_Entry_Order( bool in_upper , struct_PositionInfo &in_stposi) {

    bool    entry_comp   = false;                        // エントリー完了判定
    double  temp_limit   = Input_Limit * Point() * 10;   // リミット値
    double  temp_stop    = Input_Stop  * Point() * 10;   // ストップ値

    ClearPosiInfo(in_stposi);                            // ポジション情報を初期化
    
    if ( in_upper == false ) {                           // 下弦タッチは逆張り買い
        in_stposi.entry_dir          = OP_BUY;           // エントリーオーダータイプ:買い設定
        in_stposi.entry_orderrate    = Ask;              // エントリーオーダーレート:Ask値設定

        if ( temp_limit > 0 ) {                          // リミット指定がある場合
            in_stposi.set_limit = in_stposi.entry_orderrate + temp_limit; // オーダーレートを基にリミットレートを算出
        }

        if ( temp_stop > 0) {                             // ストップ指定がある場合
            in_stposi.set_stop = in_stposi.entry_orderrate - temp_stop; // オーダーレートを基にストップレートを算出
        }
    } else {                                              // 上弦タッチは逆張り売り
        in_stposi.entry_dir       = OP_SELL;              // エントリーオーダータイプ:買い設定
        in_stposi.entry_orderrate = Bid;                  // エントリーオーダーレート:Bid値設定

        if ( temp_limit > 0 ) {                           // リミット指定がある場合
            in_stposi.set_limit = in_stposi.entry_orderrate - temp_limit; // オーダーレートを基にリミットレートを算出
        }

        if ( temp_stop > 0) {                             // ストップ指定がある場合
            in_stposi.set_stop = in_stposi.entry_orderrate + temp_stop;// オーダーレートを基にストップレートを算出
        }
    }
    

    double templot;
    templot = NormalizeDouble(Input_EntryLot,2);          // ロットを正規化
    if ( templot < 0.01 ) {                               // ロットが最小値以下の場合、最小値設定にする
        templot = 0.01;
    }
    in_stposi.entry_lot        = templot;


    int        order_resend_num;                          // エントリー試行回数カウンタ
    int        ea_ticket_res;                             // オーダー執行結果
    int        err_code;                                  // エラーコード

    in_stposi.entry_orderrate = NormalizeDouble( in_stposi.entry_orderrate , Digits );        // オーダーレートを正規化
    in_stposi.set_limit       = NormalizeDouble( in_stposi.set_limit       , Digits );        // リミットレートを正規化
    in_stposi.set_stop        = NormalizeDouble( in_stposi.set_stop        , Digits );        // ストップレートを正規化
    
    // オーダー約定するまで指定回数ループ
    for ( order_resend_num = 0; order_resend_num < EA_ORDER_TIMES_INTERVAL; order_resend_num++ ) {

        // 新規オーダー
        ea_ticket_res = OrderSend(
            Symbol(),                       // 通貨ペア
            in_stposi.entry_dir,            // オーダータイプ[OP_BUY / OP_SELL]
            in_stposi.entry_lot,            // ロット[0.01単位]
            in_stposi.entry_orderrate,      // オーダープライスレート
            ORDER_SLIPRATE,                 // スリップ上限    (int)[分解能 0.1pips]
            0,                              // ストップレート
            0,                              // リミットレート
            "ボリバン逆張りサンプルEA",     // オーダーコメント
            MAGIC_NO,                       // マジックナンバー(管理用)
            0,                              // オーダーリミット時間
            clrAqua                         // オーダーアイコンカラー
        );

        err_code = GetLastError();          // エラーコード取得

        if ( ea_ticket_res == -1 ) {                                       // オーダーエラーの場合
            if ( err_code == ERR_NO_CONNECTION ) {                         // 通信フェールの場合
                int    regetno = EA_ConnectFailCheck(in_stposi.entry_dir); // 再接続待ち・オーダー取得チェックを行う
                
                if ( regetno > -1 ) {            // 通信フェール復帰し、オーダー取得出来た場合
                    ea_ticket_res = regetno;     // 取得したオーダーのチケットNoを設定する
                    debug_print( __LINE__ , StringFormat("再取得したチケットナンバーで更新 %d" , ea_ticket_res));
                }
                
            }
        }
        
        if ( ea_ticket_res == -1) {         // オーダーエラーの場合(通信フェール以外)
            debug_print(__LINE__,StringFormat("エントリーオーダー試行回数:%d" , order_resend_num));
            
            Sleep(500);                    // スリープ:500msec待ち

        } else {    // オーダー正常完了
            entry_comp = true;             // 戻り値設定

            bool ea_orderret = OrderSelect(ea_ticket_res,SELECT_BY_TICKET,MODE_TRADES); // チケットNo指定で注文選択
            if ( ea_orderret == false ){                                                 // 注文選択失敗
                debug_print(__LINE__ , StringFormat("TicketOrderSelectErr:%d" , GetLastError()) );
            } else {                                                                    // 注文選択成功
                in_stposi.entry_donerate = OrderOpenPrice();                            // 約定価格を保存
                in_stposi.ticket_no      = OrderTicket();                               // チケットNoを保存

                if ( in_stposi.set_limit != 0 || in_stposi.set_stop != 0) {             // リミット・ストップ指定がある場合
                    // オーダー変更
                    EA_Modify_Order( in_stposi.ticket_no , in_stposi.set_limit , in_stposi.set_stop, __LINE__ );
                }
            }
            break;
        }
    } // for

    if ( entry_comp == false ) {                 // 新規オーダーが正常完了出来なかった場合
        debug_print(__LINE__, StringFormat("オーダー取消し。執行回数:%d" , order_resend_num) );
        ClearPosiInfo(in_stposi);                // ポジション情報を初期化
    }

    return entry_comp;    // 戻り値に結果を返す

}

//+------------------------------------------------------------------+
//| オーダー変更
//+------------------------------------------------------------------+
void EA_Modify_Order( int in_ticket , double in_limit , double in_stop , int in_line) {

    int     icount;
    int     interval;
    double  limit_set = 0;
    double  stop_set  = 0;
    double  entry_rate = 0;
    int     errcode;
    
    bool selbool = OrderSelect( in_ticket ,SELECT_BY_TICKET,MODE_TRADES); // チケット指定で注文選択
    if (selbool == false){                                                 // 対象注文無し
        debug_print(__LINE__ , StringFormat("TicketOrderSelectErr:%d" ,GetLastError()) );
    } else {
                                                                          // 対象注文があった場合
        entry_rate = OrderOpenPrice();                                    // エントリー価格取得
        if ( in_limit > 0 ) {                                             // リミット指定があった場合
            limit_set = in_limit;                                         // リミット価格を設定
        }
        if ( in_stop > 0 ) {                                              // ストップ指定があった場合
            stop_set = in_stop;                                           // ストップ価格を設定
        }

        // 初回は強制100msec待ち
        Sleep(100);

        // オーダー変更完了するまで指定回数繰り返す
        for ( icount = 0; icount < EA_ORDER_TIMES_INTERVAL; icount++ ) {
            
            errcode        = 0;

            bool eabool = OrderModify(                        // オーダー変更
                                OrderTicket(),                // チケットNo
                                entry_rate,                   // エントリー価格
                                in_stop,                      // ストップロス
                                limit_set,                    // リミット
                                0,                            // 有効期限
                                clrYellow);                   // ストップリミットラインの色
            
            if ( eabool == true ) {                           // オーダー変更完了
                break;                                        // ループを抜ける
            } else {
                                                              // オーダー変更失敗
                errcode        = GetLastError();              // エラーコード取得
                if ( IsTesting() == true && errcode == ERR_INVALID_TICKET ) {    // バックテスト中で無効なチケット指定時
                    break;
                } else {
                    interval = 300 * icount;
                    
                    Sleep(interval);                                            // スリープ
                    string moderrstr    = StringFormat("OrderModifyErr:%d TicketNo:%d Open:%f Limit:%f-%f Stop:%f-%f" 
                                            , errcode , in_ticket , entry_rate
                                            , limit_set , OrderTakeProfit(), in_stop, OrderStopLoss() );
                    debug_print(in_line , moderrstr);
                }

                if ( errcode == ERR_NO_RESULT ) {    // エラーではないが、結果が不明の場合
                    debug_print(in_line , "リミット/ストップの値が変更前と同じ値に設定している可能性有り");
                    break;
                }
                
            }
            
        } // for
    }
}

//+------------------------------------------------------------------+
//| クローズオーダー
//+------------------------------------------------------------------+
bool EA_CloseOrder( int in_ticket ) {

    double      ea_order_close_price;
    bool        bool_order_sel;
    datetime    order_sel_closetime;
    int         order_close_resend_num;
    bool        closeret;
    int         interval;
    bool        order_ret;
    string      ea_debug;

    order_ret            = false;
    bool_order_sel       = false;

    if ( in_ticket > 0 ) {                                                 // チケットNoが有効値の場合
        bool_order_sel = OrderSelect( in_ticket , SELECT_BY_TICKET) ;      // チケットNo指定で注文選択
        if ( bool_order_sel == false ) {                                    // 注文選択失敗
            ea_debug = StringFormat("TicketSelectErr:%d" , GetLastError());
            debug_print(__LINE__ , ea_debug);
        }

        order_sel_closetime = OrderCloseTime();                            // 選択中の注文の決済時間を取得
        
        if ( order_sel_closetime <= 0 ) {           // 未決済の場合
            // クローズ約定するまで指定回数繰り返す
            for ( order_close_resend_num = 0; order_close_resend_num < EA_ORDER_TIMES_INTERVAL; order_close_resend_num++ ) {

                if ( OrderType() == OP_BUY){        // 買い注文の場合
                    ea_order_close_price = Bid;     // クローズ価格に売り値を設定
                } else {                            // 売り注文の場合
                    ea_order_close_price = Ask;     // クローズ価格に買い値を設定
                }

                closeret = OrderClose(          // クローズオーダー
                        in_ticket,              // チケットNo
                        OrderLots(),            // ロット
                        ea_order_close_price,   // クローズ価格
                        ORDER_SLIPRATE,         // スリップ上限    (int)[分解能 0.1pips]
                        clrWhite                   // オーダーアイコンカラー
                    );
                
                if ( closeret == true ) {       // 約定
                    order_ret = true;
                    break;                      // ループを抜ける
                } else {
                    // オーダー失敗
                    ea_debug = StringFormat("クローズオーダーエラー:%d Ticket:%d 試行回数:%d" 
                                  , GetLastError() ,in_ticket ,order_close_resend_num);
                    debug_print(__LINE__ , ea_debug);

                    bool_order_sel = OrderSelect( in_ticket , SELECT_BY_TICKET) ;    // チケットNo指定で注文選択
                    order_sel_closetime = OrderCloseTime();                          // 選択中の注文の決済時間を取得

                    if ( order_sel_closetime > 0 ) {     // 決済完了していた場合(リミット・ストップ等で決済されていた場合)
                        debug_print(__LINE__ , "既決済:" + TimeToStr(order_sel_closetime));
                        order_ret = true;
                        break;
                    } else {                                          // ポジションが決済されていない場合
                        // レートをリフレッシュしてオーダープライスを更新
                        if ( order_close_resend_num > 0 ) {           // 二回目以降
                            interval = 300 * order_close_resend_num;
                        } else {                                      // 初回エラー
                            interval = 300;                           // 初回インターバル
                        }

                        Sleep(interval);
                        debug_print(__LINE__ , StringFormat("クローズオーダー試行回数:%d %d" 
                                    , order_close_resend_num , interval));
                        RefreshRates();                               // レート更新
                    }
                }
            } // for
        } else {    // リミットストップによる決済済み
            order_ret = true;
        }
            
    } else {    // チケット無効
        order_ret = false;
    }

    return order_ret;
}


//+------------------------------------------------------------------+
//| 接続断線チェック
//+------------------------------------------------------------------+
int EA_ConnectFailCheck( int in_cmd ) {
    
    int tempret;
    int icount;
    int waittime;
    tempret     = -1;
    waittime    = 1; // 1sec
    
    // サーバー接続確認出来るまで指定回数繰り返す
    for ( icount = 0; icount < 11; icount++ ) {
        waittime = waittime * 2;
        debug_print( __LINE__ , StringFormat("再接続待ち:%d - %d[msec]" ,icount , waittime) );
        Sleep(waittime);                    // スリープ

        if ( IsConnected() == true ) {                          // 再接続チェック

            int                total_order;
            int                pos;

            total_order     = OrdersTotal();                    // 保有中のポジション数を取得

            // 保有中のポジションを全てチェックする
            for ( pos = 0 ; pos < total_order ; pos++ ) {
                if ( OrderSelect( pos , SELECT_BY_POS ) == true ) {    // インデックス指定で注文選択

                    if ( OrderMagicNumber() != MAGIC_NO ) {           // マジックNoの異なるポジションはスルー
                        continue;
                    }

                    if ( OrderSymbol() != Symbol() ) {          // 通貨ペアの異なるポジションはスルー
                        continue;
                    }

                    if ( OrderType() != in_cmd ) {              // エントリー方向の異なるポジションはスルー
                        continue;
                    }

                    tempret    = OrderTicket();                 // チケットNo取得
                    break;
                }
            }

            if ( tempret < 0 ) {
                debug_print( __LINE__ , "対象ポジション情報無し" );
                break;
            }
        }
        
        if ( tempret > -1 ) {
            break;
        }
    }
    
    
    return tempret;
}


//+------------------------------------------------------------------+
//| デバッグ情報出力
//+------------------------------------------------------------------+
void debug_print( int in_line , string in_str ){
    if ( Input_Debug == true ) {
        printf("【%d】%s"  , in_line , in_str);
    }
}


注意事項:

上記サンプルソースは、実際に売買を行う処理が含まれているので、絶対にライブ口座では実行しないで下さい。
念の為、デモ口座でしか処理しない対策処理を施しています。
これはあくまで勉強用のソースコードです。





スポンサーリンク
スポンサーリンク


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


Top

inserted by FC2 system