システムトレード実装入門 プログラム解説編

ここでは先程実装したEAのプログラムについて解説します。
まだ、こちらを読んでいない方は以下からどうぞ
システムトレード実装入門

では早速、プログラムを見てみましょう。

わかりやすいようにコメントを追加しました

#property version "1.0"
#property strict

// 外部パラメータ
extern int MAGIC = 10000;        // マジックナンバー
extern int MA_FAST_PERIOD = 20;  // 短期移動平均
extern int MA_SLOW_PERIOD = 50;  // 長期移動平均
extern double LOTS = 1.0;        // 取引ロット数
extern int SLIP = 20;            // 許容スリッページ数
extern string COMMENT = "";      // コメント

// 内部グローバル変数
int Ticket_L = 0;

// tick毎に動く関数
int start() {
    // 20MAの値を計算し、ma_fastに定義する。
    double ma_fast = iMA(NULL, 0, MA_FAST_PERIOD, 0, 0, 0, 0);
    
    // 50MAの値を計算し、ma_fastに定義する。
    double ma_slow = iMA(NULL, 0, MA_SLOW_PERIOD, 0, 0, 0, 0);
    
    // 条件 20MA が 50MA を上回ったとき、if{}内の処理を実行し、満たさない場合は、else{}の処理を実行する。
    if (ma_fast >= ma_slow) {
        // 条件 Ticket_L が 0 であるなら、 if{}内の処理を実行する。
        if (Ticket_L == 0) {
            // 注文を実行し、チケットナンバーを Ticket_L に保持する。 
            Ticket_L = OrderSend(Symbol(), OP_BUY, LOTS, Ask, SLIP, 0, 0, COMMENT, MAGIC, 0, Red);
        }
    } else {  // 条件 20MA が 50MA を上回っていないときの処理
        // ポジションの数だけ、処理1を繰り返す。例えばポジションを2つもっている場合は、処理1が2回実行されることになる。
        for (int i=0; i<=OrdersTotal(); i++) {      // ・・・・※1
            /** 処理1 ---- ここから **/
            // i番目のポジション状況を保持する。
            bool selected = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
            
            // i番目のポジションのマジックナンバーが、外部パラメーターで設定されたマジックナンバーでないなら、以下の{}に入る。
            if (OrderMagicNumber() != MAGIC) {
                // スキップする。(この回の処理はここで処理を終了し、※1に戻って次のポジションの処理を続行して下さいという意味。)
                continue;
            }
            
            // ポジションをクローズし、クローズ出来たらtrueを、できなかった場合はfalseという情報を、closedに保持する。
            bool closed = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

            // ポジションがクローズできたなら、以下の処理を続行する。(先ほどの処理でclosedにはtrueかfalseが入っている)
            if (closed) {
                // Ticket_Lの値を 0 に設定する。
                Ticket_L = 0;
            }
            /** 処理1 ---- ここまで **/
        }
    }
    // start()の処理はここまで。
    return 0;
}

 

プログラムの動き

とりあえずは、上から順番に実行されると思って頂いて大丈夫です。

初回は以下のように順番に処理が走ります。

以下、簡単な動きの説明です。

外部パラメータを保持し、内部グローバル定数を定義します。
その後、start()関数に入り、20MA,50MAの値を計算し、それぞれ、ma_fast、ma_slowに保持します。
※ iMA()は与えられたパラメータを元に、移動平均線の値を計算する関数です。

そのあと、条件式で [20MA > 50MA] をチェックし、それが正しい(true)だったので、その中の処理に入り、
さらに Ticket_L が 0 かをチェックします。
先程 Ticket_L = 0 と定義したので、条件式 [Ticket_L = 0] は正しい(true)ので 、その中の処理に入り、
OrderSendで注文を発注し、その後 Ticket_L に チケットナンバーを保持します。
returnで処理を終えます。

 

外部パラメータ

外部パラメータとは、以下の画面で設定できるパラメータです。
つまり、プログラムを外から操作できるパラメータになります。

extern int MAGIC = 10000;        // マジックナンバー
extern int MA_FAST_PERIOD = 20;  // 短期移動平均
extern int MA_SLOW_PERIOD = 50;  // 長期移動平均
extern double LOTS = 1.0;        // 取引ロット数
extern int SLIP = 20;            // 許容スリッページ数
extern string COMMENT = "";      // コメント

MAGIC、MA_FAST_PERIODはこちらで適当な名前をつけて定義しましたが、
その前に int, double, string がついています。
これはintには整数、doubleは浮動小数点、stringは文字列という情報を付加しています。
また extern は 外部パラメータとして定義します(他にもinputも使えます)

extern int MAGIC = 10000 

これは
「MAGICという名前の整数を入れる箱を用意し、その中に10000を保存しておいてね」
という意味です。

 

start関数

start()の中に書かれたものはtickが動くと実行される処理です。
ちなみに、その中で定義された変数や定数は、その中でしか使えません。
その処理が終えると全てなくなります。

ちなみに保持する方法もありますが、話を簡単にするため
処理を抜けると計算してたものも含め、全部なくなると覚えて下さい。

 

内部グローバル変数

いや、でも計算した値とか他に使いたい場合とかあるし、とっておきたい場合があるよ…
例えば、これとか

Ticket_L = OrderSend(Symbol(), OP_BUY, LOTS, Ask, SLIP, 0, 0, COMMENT, MAGIC, 0, Red);

チケットナンバーが0がそうでないかで、新規のポジションを取るか判断しているため、
Ticket_L が 0 だと、毎回この条件式に入ることになります。

手前の処理で注文が成功していれば、Ticket_Lに0以外の数値が入っていて、その値で判断しているので、
処理が終わる毎に毎回 0 だと困りますが、
そのためのあるのが、内部グローバル変数です。
このstart()の外に定義してやります。

int Ticket_L = 0;

そうすることで、計算した内容は消えません。
グローバルに定義する、プログラム内部で使う変数なので、
内部グローバル変数です。

 

ここで七分目くらい

ここで大方説明の7割を終えました。
ただ、ちょっと長くなりそうなので続きは次回へまわします。

システムトレード実装入門 プログラム解説編 続