条件分岐と繰り返し処理

条件分岐と繰り返し処理 MQL4基礎

条件分岐と繰り返し処理の方法は複数ありますが、if文と for文 (continuebreakreturn)ができれば全てに対応できます。又、高度なプログラムもこの2つでほとんど組めるようになりますので、必ずマスターするようにしてください。

条件分岐

if文

if文は、論理値に従って「もしXならば、Yとする、XでなければZとする」といった条件によって処理を変えます。

コード

以下の if文の例では、買い価格が 100円以下であれば買いで成行注文、売り価格が 150円以上であれば売りで成行注文、それ以外はエキスパートタグのメッセージへ「注文範囲に入っていません」を出力する といった内容です。①②の数字を変えていろいろ試してみてください。

// if文の例
// 変数buy_price以下で買い成行注文、変数sel_price以上で売り成行注文します。
#property strict 
void OnInit() {

   double buy_price = 100; // ①買い注文価格の上限
   double sel_price = 150; // ②売り注文価格の下限
   int ticket = -1;        // 自動付与される注文番号
   
   if (Ask <= buy_price) {   
      ticket = OrderSend(_Symbol, OP_BUY, 0.01, Ask, 30, 0, 0, "Buy", 1001, 0, clrNONE);
      Print("注文番号 ", ticket, "番で注文しました");
      
   } else if (Bid >= sel_price) {   
      ticket = OrderSend(_Symbol, OP_SELL, 0.01, Bid, 30, 0, 0, "Sell", 2001, 0, clrNONE);
      Print("注文番号 ", ticket, "番で注文しました");
      
   } else {
      Print("注文範囲に入っていません");
   }
}

このコードをコンパイルして実行するのに、自動売買を許可しておく必要があります。
自動売買を許可する方法はこちら、コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

switch文

switch文は、条件に応じて多分岐させる処理です。多くの分岐がある時は switch文で書くとプログラムの内容が見やすくなります。

但し、整数又は、文字列(1文字のみ、ushort型)で一致するかどうかの判定のみになります。「100円で買いの成行注文をする」ということはできますが、if文のように「100円以下で買いの成行注文をする」のような判定はできません。ですので、取引中に値が飛んだりして99.9円になってしまうと注文は成立しません。使いどころを選ぶ条件処理です。

「case」の行の終わりはセミコロン「;」ではなく、コロン「:」になっているので注意してください。

コード 1

注文方法を switch文で出力します。①の注文方法をこちらを参考に変えて試してみてください。

// 例1 整数で判定する例
// 注文方法を出力する
#property strict
void OnInit() {

   int ordertype = OP_BUY; // ①注文方法を設定してください
   Print("ordertypeの整数型:", ordertype);
   
   switch(ordertype) {
      case 0:
         Print("買い成行注文");
         break;
            
      case 1:
         Print("売り成行注文");
         break;
         
      case 2:
         Print("買い指値注文");
         break;
         
      case 3:
         Print("売り指値注文");
         break;
         
      case 4:
         Print("買い逆指値注文");
         break;
         
      default: // 0~4以外の数字の時
         Print("売り逆指値注文");
         break;
   }  
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果


コード 2

次は ushort型の文字列を使った switch文の例です。
文字列の時は 1文字をシングルクォーテーション「’」で囲んでください。

①の「ordertype」に入力する文字列として、A:買い成行注文、B:売り成行注文、C:買い指値注文、D:売り指値注文、E:買い逆指値注文、F (A~E以外):売り逆指値注文 が出力されます。①注文方法を A~Eで設定して試してみてください。

// 例2 ushort型の文字列で判定する例
// 注文方法を出力する
#property strict
void OnInit() {

   ushort ordertype = 'C'; // ①注文方法をA~Eで設定してください
   Print("ordertypeのushort型:", ordertype);
   
   switch(ordertype) {
      case 'A':
         Print("買い成行注文");
         break;
            
      case 'B':
         Print("売り成行注文");
         break;
         
      case 'C':
         Print("買い指値注文");
         break;
         
      case 'D':
         Print("売り指値注文");
         break;
         
      case 'E':
         Print("買い逆指値注文");
         break;
         
      default: // A~E以外の文字の時
         Print("売り逆指値注文");
         break;
   }  
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

繰り返し処理

for文

for文は、条件が合う間は繰り返し処理を実行し続けます。

コード 1

1~10の数字を順次足していく for文を使ったコードです。コードは10までの合計ですが、20まで足すなどいろいろ試してみてください。

// 例1 for文 変数iの合計
#property strict
void OnInit() {

   int i,s=0;              // 変数
   for(i=0; i<=10; i++) {  // iが10以下の時は繰り返し処理を実行する
      s = s + i;           // sにiを順次プラスする(0~10の合計)
   }
   Print("iの合計:", s);  // iの合計:55
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果


コード 2

0~9の数字を文字列として順次並べていく for文を使ったコードです。

// 例2 for文 文字列として変数iの取得状況
#property strict
void OnInit() {

   int i;                      // 変数
   string s;                   // iを文字列として取得する
   for(i=0; i<=9; i++) {       // iが9以下の時は処理を実行する
      s = s + (string)i;       // iを文字列にキャスト
   }
   Print("iの取得整数:", s);  // iの取得整数:0123456789
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

while文

while文は、for文と同様に条件が合う間は繰り返し処理を実行し続けます。for文との違いは、ループに入る前に for文は初期化を行ないますが、while文にはそれがありません。ですので、初期化が必要な時はwhile文の前に設定する必要があります。

コード

// 例  while文 変数iの合計
#property strict
void OnInit() {

   int i=0, s=0;          // 変数 ゼロに初期化しておく
   while(i<=10) {         // iが10以下の時は繰り返し処理を実行する
      s = s + i;          // sにiを順次プラスする(0~10の合計)
      i++;                // iに1をプラスする(i=i+1と同じ)
   }
   Print("iの合計:", s); // iの合計:55
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

do while文

do while文は、while文と同様に条件が合う間は繰り返し処理を実行し続けます。for文や while文との違いは、for文や while文はループの最初にループの終了をチェックしますが、do while文はループの最後にループ終了をチェックします。

コード

// 例  do while文 変数iの合計
#property strict
void OnInit() {

   int i=0, s=0;          // 変数 ゼロに初期化しておく
   do {
      s = s + i;          // sにiを順次プラスする(0~10の合計)
      i++;                // iに1をプラスする(i=i+1と同じ)
   } while( i <= 10);     // iが10以下の時は繰り返し処理を実行する
   Print("iの合計:", s); // iの合計:55
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

その他の処理

以下の処理は、上記の条件分岐や繰り返し処理に合わせて用いられます。

continue

繰り返し処理の時に、条件分岐を用いて continue処理をすると、そこから直近の繰り返し処理の最初に飛んで続きの処理を実行し続けます。

コード

0~9の数字で、3の倍数以外の数字を文字列として順次並べていきます。for文と continue を使ったコードです。

// 例  continueとfor文 文字列として変数iの取得状況
// 結果は、3の倍数以外が取得されます
#property strict
void OnInit() {

   int i;                     // 変数
   string s;                  // iを文字列として取得する
   for(i=1; i<=9; i++) {      // iが9以下の時は処理を実行する
   
      if(i%3==0) {
         continue;            //3の倍数の時はfor文の最初に戻る
      }
      s = s + (string)i;      // iを文字列にキャスト
   }
   Print("iの取得整数:", s); // iの取得整数:124578
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

break

break処理は最も近くにある外側の for文、switch文、while文、do while文の処理から抜けます。

「繰り返し処理」の時に、条件分岐「if文」を用いて break処理をすると、そこで直近の「繰り返し処理」を抜けて次の処理にいきます。

但し、条件分岐「switch文」の中にある break処理は switchの条件分岐を抜けるだけで、外側に「繰り返し処理」がある場合でも、「繰り返し処理」からは抜けて次の処理にはいきません。(コード2参照)

コード 1

1~9までの数字を文字列として取得します。但し、6以降の数字は取得しないようにします。

// 例1  breakとfor文 文字列として変数iの取得状況
// 結果は、1~5の値が取得され、6以降は取得されません
#property strict
void OnInit() {

   int i;                     // 変数
   string s;                  // iを文字列として取得する
   for(i=1; i<=9; i++) {      // iが9以下の時は処理を実行する
   
      if(i==6) {
         break;               // iが6の時、for文から抜けて次のPrint処理にいきます
      }
      s = s + (string)i;      // iを文字列にキャスト
   }
   Print("iの取得整数:", s); // iの取得整数:12345
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果


コード 2

switch文中にある breakでは for文は抜けない(終了しない)例です。breakで for文を抜けた場合は、結果は[買い成行注文] が 1回しか表示されませんが、for文を抜けていないので結果は [買い成行注文] が3回表示されます。

// 例2  breakとswitch文
// switch文の中にbreakがあるが、for文は抜けない(終了しない)例
// [買い成行注文] が 3回表示されます
#property strict
void OnInit() {
   for(int i=1; i<=3; i++) {
      int ordertype = OP_BUY; // ①注文方法を設定してください
      
      switch(ordertype) {
         case 0:
            Print("買い成行注文");
            break;
         case 1:
            Print("売り成行注文");
            break;
         case 2:
            Print("買い指値注文");
            break;
         case 3:
            Print("売り指値注文");
            break;
         case 4:
            Print("買い逆指値注文");
            break;
         default: // 0~4以外の数字の時
            Print("売り逆指値注文");
            break;
      }
   }  
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

return

return処理は、現在の関数を終了させ次の処理へ進めます。戻り値がある時は、その値を returnで返します。但し、returnで戻り値を取得する関数は取得する値とデータ型を合わせる必要があります。

コード

コードの内容は、1~5までの数字を順番に足して結果を出力させる というものです。1~5までの足し算を行なう関数を別に作成して値を取得させるようにします。

Print関数の中にある「return_test()」関数からデータを取得して、エキスパートタグのログに結果を表示します。

作成した「return_test()」関数からデータを取得する時は、「return()」が必要です。今回の場合、整数を取得するのでこの関数のデータ型は int型 になります。

// 例  return文
// return_test関数を作成して、その計算結果を取得する
#property strict

void OnInit() {
   Print("iの合計:", return_test()); // iの合計:15
                                      //「return_test()」関数に「15」が返ってきます
}

int return_test() {                   // 作成した関数。戻り値のデータ型のint型の関数にする

   int i,s=0;                         // 変数
   for(i=1; i<=5; i++) {              // iが5以下の時は処理を実行する
      s = s + i;                      // sにiを順次プラスする(1~5の合計)
   }
   return(s);                         // returnでこの関数の結果「15」を返す
}

コードをコンパイルして実行する方法はこちらを参考にしてください。(デモ口座でお試しください)

結果

タイトルとURLをコピーしました