ループ処理をマスターする|MQL入門(5回目)

2018年11月9日

ループ

今回は、「ループ処理」について学んでいきます。

条件分岐と同じくとても重要な項目なので、しっかり覚えていきましょう。

第4回目までを確認いただいている前提で進めますので、まだ見ていない方は先にご確認いただければと思います。

初心者でも分かる!MT4/MT5のプログラミング入門|MQL入門(1回目)

MT4/MT5のコメントと変数について|MQL入門(2回目)

MT4/MT5で数値の計算をしてみる|MQL入門(3回目)

条件分岐をマスターする|MQL入門(4回目)

ループの基本

ループ処理の方法

ループ処理をするにはforかwhileを使います。

( )内の条件が成立している間、{ }内の処理を実行します。

カウンタ初期化
while (ループ条件) {
条件が成立したときの処理
カウンタ更新
}
for (カウンタ初期化、ループ条件、カウンタ更新) {
条件が成立したときの処理
}

 

whileでのループ

プログラムの準備

MetaEditorを開いて「Practice004」を作成しましょう。

作成したら以下のようにプログラムを変更してください。

プログラムの解説をします。

  • [初期化] カウンタnを0で初期化
  • [ループ条件] nが3より小さい間
  • [処理] メッセージを表示
  • [更新] カウンタに1プラス

 

実行する

基本パターン

実行すると以下のようになったかと思います。

実行結果確認

 

どのような順序で処理が行われたかを見ていきましょう。

少し冗長ですが、初回なので1行1行説明していきます。

カウンタnを0で初期化

n(=0)は3より小さいのでループ条件クリア
「n(=0)回目の処理」と表示

n(=0)にプラス1するので、n(=1)になる

n(=1)は3より小さいのでループ条件クリア
「n(=1)回目の処理」と表示

n(=1)にプラス1するので、n(=2)になる

n(=2)は3より小さいのでループ条件クリア
「n(=2)回目の処理」と表示

n(=2)にプラス1するので、n(=3)になる

n(=3)は3と同じなのでループ条件クリアできない
ループを終了する

 

カウンタ更新を2つ飛ばし

カウンタの更新は必ず1である必要はなくて、2でも3でも動かすことができます。

試しにwhile(n < 10)、n+=3として実行してみましょう。

カウンタ2つ飛ばし確認

nの値が0→3→6→9と変わり、最後は12となってn<10を満たせなくなったのでループが終了しました。

 

カウンタ更新を逆に

カウンタは逆に減らしていくことができます。

※実行する前に、すぐ下にある「無限ループに注意する」をご確認ください。

※変更部分が分かりづらいと思いますので、以下をコピーして使ってください。

 

先ほどとは逆にカウンタが更新されたかと思います。

逆カウンタ確認

 

無限ループに注意する

プログラムに慣れていないうちによくやってしまうのが、無限ループです。

例えば以下のようなプログラムを書いてしまうと無限ループになります。(ここは実行しないでください。)

n=4で、カウンタ更新は+1なので、「3, 4, 5, 6…」とnが変わっていきます。

ループ条件はnが3より大きい間なので、無限に条件を満たし続けてしまいます。

これをやってしまうとPCが固まったり、場合によってはディスク容量を圧迫しますので注意しましょう。

上記プログラムを私の環境で実行した結果を貼っておきます。

まだ途中の状態ですが、既に1億回以上ループ処理が行われています。

無限ループ

実は1億回のループ自体はプログラムの世界では、大した数値ではありません。

しかし、MT4/MT5ではコンソールに出力された文字が裏でファイルにも出力されています。

※コンソール上で「右クリック→開く」でファイル本体を確認することができます。

ログフォルダを開く

 

ファイルを確認したところ1GB近いサイズとなっており、大きすぎてファイルが開けなくなっていました。

これはあまり良い状態ではありません。

ログファイルのサイズ

 

MT4/MT5自体を閉じて、強制終了させました。

そのままMT4/MT5を起動するとまた無限ループが始まってしまうので、ループ部分のプログラムを全てコメントアウトしてコンパイルしておきます。

ここまでやった後に、何が悪くて無限ループになったかを考えるようにしましょう。

 

 

forでのループ

無限ループの話をしてしまったので、ループが怖いように感じたのではないでしょうか。

そこで、プログラムに慣れるまではwhileではなくforを使ってください。

経験上、forの方が圧倒的に無限ループになりにくいからです。

最初に掲載したwhileとforの構文をもう一度見てみましょう。

カウンタ初期化
while (ループ条件) {
条件が成立したときの処理
カウンタ更新
}
for (カウンタ初期化、ループ条件、カウンタ更新) {
条件が成立したときの処理
}

whileが無限ループになりやすいのは、「カウンタの初期化、ループ条件、カウンタ更新」がそれぞれ別の場所にあるからです。

よくあるのがカウンタ更新の処理を忘れることですね。

一方でforは、すべてを一か所に書きますのでミスを大幅に減らすことができます。

「それなら最初からforで説明してよ。」ということになるかと思いますが、ループ自体の理解としては処理が分かれていたほうが説明しやすかったのでwhileを先にしました。

 

 

プログラムの準備

MetaEditorを開いて新しいプログラムを作成しましょう。

 

実行する

whileの時と同じ結果になったかと思います。

forの実行結果

 

補足新しく「n++」が出てきましたが、「n+=1」と同じ意味です。

for内の「n++」を「n+1」に置き換えて実行してみてください。

 

先ほどと同じ結果になったと思います。

 

n++は一瞬で+1していると人間が理解できるメリットがあり、1だけプラスするときはこのように書かれることが多いです。

 

それと、「++n」という構文も存在します。

「++n」は処理前に+1する。

「n++」は処理後に+1する。

言葉では少し分かりづらいので実際にプログラムを書いてみてみましょう。

[++nの場合]

[結果]

++nの確認

 

[n++の場合]

[結果]

n++確認

 

++nではprintf(“%d”, ++n);とした時点で数値が11に変化しましたが、n++はその時点では変わらず、その後のprintf(“%d”, n);で11に変わりました。

実際にプログラムを書いて試してみると、処理の内容が理解しやすくなります

 

それでは、forの中のn++はどういう動きをしたでしょうか?

 

forのループが1回終わった時点で+1する動きとなります。

少し違和感があるかもしれませんが、forは{ }も含めてワンセットと考え、ワンセット終わったら+1されるのです。

結果として、最初に説明したwhileと同じ動きをしていることが分かると思います。

カウンタnを0で初期化

n(=0)は3より小さいのでループ条件クリア
「n(=0)回目の処理」と表示

ワンセット完了したので、n(=0)にプラス1され、n(=1)になる

n(=1)は3より小さいのでループ条件クリア
「n(=1)回目の処理」と表示

ワンセット完了したので、n(=1)にプラス1され、n(=2)になる

n(=2)は3より小さいのでループ条件クリア
「n(=2)回目の処理」と表示

ワンセット完了したので、n(=2)にプラス1され、n(=3)になる

n(=3)は3と同じなのでループ条件クリアできない
ループを終了する

 

実戦ではどのように使われるか

forとwhileの使い分け

プログラムに慣れてくればforもwhileも両方を使っていくことになりますが、どのように使い分けるかを説明しながら実戦での使われ方についても触れていきます。

 

for

[数値を条件としたループ処理をする時]
今回説明してきたようなプログラムです。
実戦では、取得したデータ分ループさせたりマップ[9×9など]を表現したり、様々な局面で利用されます。

 

例えば、前回説明した「FXのチャート分析で、ローソク足が3本連続で上昇したかを判定したい。」を考えた場合に「3本連続」という固定値ではなく「n本連続」とすることができます。

 

まず前回のプログラムを確認しましょう。

 

 

必ず3本ということなら問題ないですが、10本連続を判定したいとなったら・・・かなり長いプログラムになってしまいます。

 

また、頻繁に5本連続→7本連続としたい場合は、プログラムの変更量が多くとても大変です。

 

forを使って以下のように書き換えてみましょう。

 

 

これならint n = 3;の部分を書き換えるだけで、何本連続の陽線にでも対応することができます。

 

さらに3という部分をプログラムの外から変更できるようにして、全くプログラムを触らずに条件を変更できるようになるのです。

 

外から値を変更する方法は、もう少し後に学んでいきますのでお待ちください。

 

while

[あえて無限ループさせる時]

実戦では無限ループを使うケースがあります。

MQLでは使う機会が無いのですが、プログラムの入門という意味では理解しておく必要がある部分なので説明します。

 

「ビットコインの価格を取得して、条件を満たしていれば売買をする。」というプログラムを考えてみます。その場合、「取引所から価格を取得する」→「判定」という処理を永遠と繰り返す必要があります。ループは以下のようにTrueの間繰り返す、ずっとTrueなので無限ループということになります。

 

10秒ごとの無限ループ

 

無限ループは、場合によっては1秒で数千回も価格を取得しに行ってしまい、先方のサーバーに負荷を掛けてしまいます。

 

負荷によって他の方がアクセスできなくなったり、先方から罰則を受けることもありますので、Sleepなどでアクセス数を減らすのが一般的です。

 

 

MT4/MT5では基本機能の中でこのような動きをしてくれているので、利用者が無限ループを意識する必要はありません。

その他では、forで表現するのが難しいケースでwhileを使いますが、現時点でそこまで詳しく知っておく必要はありません。

 

まとめ

今回はループについて学んできましたが、少し内容が難しくなってしまいましたね。

時間があれば何度か読み直して、プログラムの数値などを変えながら実行して頂ければと思います。

次回は配列を使いこなす|MQL入門(6回目)です。

今回の記事のまとめ

  • forとwhileでループ処理を書ける
  • プログラムに慣れるまではforをメインに使う
  • 無限ループには十分注意する
  • 無限ループになったらMT4/MT5を閉じる
  • 意図的に無限ループすることもあるが、先方のサーバーに迷惑をかけないように常識的な範囲で行う

 

自動売買入門のまとめは以下をご参照ください