トップ  >  自作してみる  >  EA作成方法  >  サンプルソースコード解析
スポンサーリンク
検索
カスタム検索
MQL4リファレンスツリー
サンプルソースコード解析









MT4にはMetaQuotes Software社が作成したEAのサンプルソースコードがあります。



基本的にはこのサンプルコードを参考にしてプログラムを作成すれば、
普通に動くEAが出来ちゃいます(´∀`)

但し、このサンプルコードのコメントが全部英語で、初心者にとって理解しにくい記述が使われていたりするので・・・

初心者でも分かり易いように書き換えて、日本語コメントで解説したソースコードを用意しました。
また下記ソースコード上の関数をクリックすると、対象のリファレンスリンクページが開かれます。


注意事項:

以下サンプルソースは、MetaQuotes Software社が作成したEAのサンプルソースを分かり易くする為に改変したものです。
実際に売買を行う処理が含まれているので、絶対に実行しないで下さい。
念の為、デモ口座でしか処理しない対策処理を施していますが、実際に動作させる為に作成したプログラムではありません。
あくまで勉強用のソースコードですのでかなり簡素な造りでエラー対策のプログラムが殆どありません。
実際に運用させる為のプログラムはエラー対策のプログラムが沢山必要になります。
特にOrderSelect(),OrderSend(),OrderClose()関数回りは取引サーバーによる拒否が多いので、厳密なエラー対策が必要です。



リミット・ストップを行うサンプルソースは
ボリンジャーバンド逆張りサンプルソースコード(リミット・ストップ設定)
を参考にして下さい。


サンプルソース:
緑色の部分はコメントです。
//+------------------------------------------------------------------+
//|                                              MovingAverageJP.mq4 |
//|                                            Copyright 2015, yuki. |
//|                                       http:yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, yuki."        // 作成者名
#property link      "https://yukifx.web.fc2.com/"   // Webサイトリンク
#property version   "1.00"                         // バージョン
#property strict                                   // 厳格なコンパイルモード

#property description "移動平均サンプルEA"          // EA説明文


#define MAGICMA  20150520                           // EA識別用マジックナンバー

// 入力パラメータ宣言
input double Lots          = 0.1;                   // ロット数[分解能:10万通貨]
input int    MovingPeriod  = 12;                    // 移動平均期間
input int    MovingShift   = 6;                     // 移動平均シフト


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

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

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

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

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

    if ( IsTradeAllowed() == false ) { // 自動売買許可設定チェック
        // 自動売買禁止設定の場合、エラーメッセージを出力し処理終了
        MessageBox("自動売買禁止設定になっています","エラー",MB_ICONEXCLAMATION);
        return;               // 処理終了
    }

    if ( Bars < 100 ) {        // チャート上のバー数が100本未満の場合、処理終了
       return;
    }

    // 現在保有中のポジション数をチェック
    if ( CalculateCurrentOrders() ==0) {
        // ポジション保有していない場合
        CheckForOpen();                  // オーダー処理を行う
    } else {
        // ポジション保有している場合
        CheckForClose();                 // クローズ処理を行う
    }
}


// ■■■ サブ関数 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

//+------------------------------------------------------------------+
//| 保有中のポジションを計算                                        |
//+------------------------------------------------------------------+
int CalculateCurrentOrders( void ) {

    // ローカル変数宣言
    int buys=0;  // ロングポジション保有数
    int sells=0; // ショートポジション保有数
    int icount;  // ループカウンタ


    // 現在アカウントで保有しているポジション数分ループ処理を行う
    for ( icount = 0 ; icount < OrdersTotal() ; icount++) {

        // 注文プールからエントリー中の注文を選択する
        if( OrderSelect(icount,SELECT_BY_POS,MODE_TRADES) == false) {
            break; // 注文選択に失敗したらループ処理終了
        }

        // 選択した注文の通貨ペア名を取得し、現在チャートの通貨ペア名と一致しているかチェック
        // 選択した注文のマジックナンバーを取得し、このEAのマジックナンバーと一致しているかチェック
        // 上記の両方の条件に一致した場合のみif文内の処理を行う
        if( OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICMA) {
            if(OrderType()==OP_BUY) {  // 選択した注文がロングポジションの場合
                buys++;                // ローカル変数buysをインクリメント(1加算)
            }
            if(OrderType()==OP_SELL) { // 選択した注文がショートポジションの場合
                sells++;                // ローカル変数sellsをインクリメント(1加算)
            }
        }
    }

    // 関数戻り値を設定
    if( buys > 0) {    // ロングポジション保有数が1つ以上の場合
        return(buys);  // ローカル変数buysの値を関数戻り値として返す
    } else {           // ロングポジション保有数が0以下の場合
       return(-sells); // ローカル変数sellsに負符号をつけて、関数戻り値として返す
    }
}

//+------------------------------------------------------------------+
//| オーダー処理                                  |
//+------------------------------------------------------------------+
void CheckForOpen() {

    // ローカル変数宣言
    double ma;       // 単純移動平均用
    int    res;      // オーダー送信戻り値用
    double entrylot; // オーダー用ロット

    if( Volume[0] > 1) { 
        // 現在のtick出来高が2以上の場合は関数処理終了
        return;
    }

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

    entrylot = NormalizeDouble(Lots,1); // 入力パラメータのロット数を、小数点第一位で正規化

    // テクニカルインジケータ:移動平均の値を算出
    ma = iMA(
             NULL,         // 現在の通貨ペア
             0,            // 現在の時間軸
             MovingPeriod, // 入力パラメ―タで指定した移動平均期間
             MovingShift,  // 入力パラメータで指定した移動平均シフト
             MODE_SMA,     // 平滑化タイプ:単純移動平均
             PRICE_CLOSE,  // 終値で算出
             0);           // シフト:無し


    // 1つ前のバーの始値が移動平均値より大きい 且つ 
    // 1つ前のバーの終値が移動平均値よりも小さい場合
    if( Open[1] > ma && Close[1] < ma) { 
        
        // ショートエントリーオーダー送信
        res = OrderSend(
                        Symbol(),        // 現在の通貨ペア
                        OP_SELL,         // ショートエントリー(成行注文)
                        entrylot,        // ロット設定
                        Bid,             // 現在の売値で発注
                        3,               // スリップページ
                        0,               // ストップロス設定:無し
                        0,               // リミット設定:無し
                        "ショート",      // コメント
                        MAGICMA,         // マジックナンバー
                        0,               // 有効期限:無し
                        clrRed);            // チャート上の注文矢印の色:赤

        return; // 関数処理終了
    }

    // 1つ前のバーの始値が移動平均値より小さい 且つ 
    // 1つ前のバーの終値が移動平均値よりも大きい場合
    if ( Open[1] < ma && Close[1] > ma ) {
        res = OrderSend(
                        Symbol(),       // 現在の通貨ペア
                        OP_BUY,         // ロングエントリー(成行注文)
                        entrylot,        // ロット設定
                        Ask,            // 現在の買値で発注
                        3,              // スリップページ
                        0,              // ストップロス設定:無し
                        0,              // リミット設定:無し
                        "ロング",       // コメント
                        MAGICMA,        // マジックナンバー
                        0,              // 有効期限:無し
                        clrBlue);          // チャート上の注文矢印の色:青

        return; // 関数処理終了
    }

}
//+------------------------------------------------------------------+
//| クローズ処理                                 |
//+------------------------------------------------------------------+
void CheckForClose() {

    // ローカル変数宣言
    double ma;     // 単純移動平均用
    int    icount; // ループカウンタ用
    bool   ret;    // クローズ処理戻り値用

    if ( Volume[0] > 1 ) {
        // 現在のtick出来高が2以上の場合は関数処理終了
        return;
    }

    // テクニカルインジケータ:移動平均の値を算出
    ma = iMA(
             NULL,         // 現在の通貨ペア
             0,            // 現在の時間軸
             MovingPeriod, // 入力パラメ―タで指定した移動平均期間
             MovingShift,  // 入力パラメータで指定した移動平均シフト
             MODE_SMA,     // 平滑化タイプ:単純移動平均
             PRICE_CLOSE,  // 終値で算出
             0);           // シフト:無し


    // 現在アカウントで保有しているポジション数分ループ処理を行う
    for( icount = 0; icount < OrdersTotal(); icount++) {

        // 注文プールからエントリー中の注文を選択する
        if( OrderSelect( icount, SELECT_BY_POS, MODE_TRADES ) == false ) {
            break; // 注文選択に失敗したらループ処理終了
        }

        // 選択した注文の通貨ペア名を取得し、現在チャートの通貨ペア名と一致していないかチェック
        // 選択した注文のマジックナンバーを取得し、このEAのマジックナンバーと一致していないかチェック
        // 上記のいずれかの条件に一致した場合のみif文内の処理を行う
        if( OrderMagicNumber() != MAGICMA || OrderSymbol() != Symbol()) {
            continue; // 次のループ処理を行う
        }

        // 選択した注文がロングポジションの場合
        if( OrderType() == OP_BUY) {
            // 1つ前のバーの始値が移動平均値より大きい 且つ 
            // 1つ前のバーの終値が移動平均値よりも小さい場合
            if( Open[1] > ma && Close[1] < ma ) {

                // 指定したチケットのポジションをクローズ
                ret = OrderClose(
                                 OrderTicket(), // クローズするポジションのチケット
                                 OrderLots(),   // クローズするロット数
                                 Bid,           // クローズ価格:現在の売値
                                 3,             // スリップページ
                                 clrWhite);        // チャート上の注文矢印の色:白

                // クローズ失敗した場合、エラーログを出力する
                if( ret == false ){
                   Print("オーダークローズエラー:エラーコード=",GetLastError());
                }
            }
            
            // ループ処理終了
            break;
        }

        // 選択した注文がショートポジションの場合
        if( OrderType() == OP_SELL) {

            // 1つ前のバーの始値が移動平均値より小さい 且つ 
            // 1つ前のバーの終値が移動平均値よりも大きい場合
            if( Open[1] < ma && Close[1] > ma ) {

                // 指定したチケットのポジションをクローズ
                ret = OrderClose(
                                 OrderTicket(), // クローズするポジションのチケット
                                 OrderLots(),   // クローズするロット数
                                 Ask,           // クローズ価格:現在の買値
                                 3,             // スリップページ
                                 clrWhite);        // チャート上の注文矢印の色:白

                // クローズ失敗した場合、エラーログを出力する
                if( ret == false ){
                   Print("オーダークローズエラー:エラーコード=",GetLastError());
                }
            }

            // ループ処理終了
            break;
        }
    }
}




注意事項:

上記サンプルソースは、MetaQuotes Software社が作成したEAのサンプルソースを分かり易くする為に改変したものです。
実際に売買を行う処理が含まれているので、絶対に実行しないで下さい。
念の為、デモ口座でしか処理しない対策処理を施していますが、実際に動作させる為に作成したプログラムではありません。
あくまで勉強用のソースコードですのでかなり簡素な造りでエラー対策のプログラムが殆どありません。
実際に運用させる為のプログラムはエラー対策のプログラムが沢山必要になります。
特にOrderSelect(),OrderSend(),OrderClose()関数回りは取引サーバーによる拒否が多いので、厳密なエラー対策が必要です。





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


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


Top

inserted by FC2 system