「変数」
「配列」
「if文」
「for文」に続いて、この記事では繰り返し処理の仲間である`do-while`文を扱います。
すでに`while`文を知っている人は、「`while`文と何が違うのか」
が最初の疑問になるはずです。
結論から言うと、`do-while`文は「条件を確認する前に、
処理を必ず1回は実行する」という点が`while`文と異なります。
この違いが、実際のEA開発でどう役立つのかまで含めて解説します。
do-while文の書き方
`do-while`文の基本構文は以下のとおりです。
do
{
//実行する処理
}
while(条件式);
`while`文は`while(条件式) { … }`のように条件を先に書きますが、
`do-while`文は処理のブロックを先に書き、条件は最後の`while(…)`にまとめて書きます。
最後の`while(条件式);`の後ろのセミコロン(;)を忘れると、
コンパイルエラーになります。
これは`do-while`文特有の書き忘れやすいポイントです。
while文との違い:条件を先に見るか、後で見るか
`while`文は、ループに入る前に条件をチェックします。
そのため、最初から条件が満たされていなければ、ブロックの中身は1回も実行されません。
一方`do-while`文は、まずブロックの中身を1回実行してから、
続けるかどうかを判定します。
つまり、条件がどうであれ、最低1回は必ず実行されるという違いがあります。
int j = 10;//条件(j <= 5)をすでに満たしていない値
//while文の場合、この中身は1回も実行されない
while(j <= 5)
{
Print("while文はここに来ない");
}
//do-while文の場合、条件を見る前に必ず1回実行される
do
{
Print("do-while文は条件を見る前に必ず1回実行される。j=", j);
}
while(j <= 5);
「少なくとも1回は実行してから、続けるかどうかを判断したい」
処理があるときに、`do-while`文が向いています。
実務での使いどころ:発注のリトライ処理
EA開発で`do-while`文が活躍する典型例が、注文送信の再試行処理です。
相場が動いている間に価格が変わってしまい、`OrderSend()`がエラーコード135(価格が変わった)で失敗することがあります。
この場合、最新の価格を取得し直して再送信すれば成功する可能性があります。
「まず1回発注してみて、特定のエラーだったときだけ数回までリトライする」
という流れは、`do-while`文の「最低1回は実行してから判定する」
という性質にそのまま合致します。
以下は考え方を示す概念コードです(`Lots`・`StopLoss`・`TakeProfit`・`Slippage`・`MagicNumber`は、
以前の記事のEAと同様にinput変数として別途宣言されている前提です。
このままではコピペしても動きません)。
int attempts = 0;
int ticket = -1;
int lastError = 0;
do
{
ResetLastError();//前回のエラーコードをクリアしてから発注する
RefreshRates();//最新の価格に更新
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage,
Ask - StopLoss * Point * 10, Ask + TakeProfit * Point * 10,
"retry-demo", MagicNumber, 0, Red);
attempts++;
if(ticket < 0)
{
lastError = GetLastError();
Print(attempts, "回目の発注に失敗。エラーコード=", lastError);
}
}
while(ticket < 0 && lastError == 135 && attempts < 3);//価格が変わった(135)場合のみ、最大3回まで再試行
`ResetLastError()`を呼んでいるのは、`GetLastError()`が自動でリセットされないためです。
呼び忘れると、前回のエラーコードが残ったまま次のループの判定に使われてしまい、
意図しない条件で再試行が続く(または止まる)原因になります。
実際に動くコード全体
ここまでの内容のうち、while文との違いを確認できる部分をまとめた、
実際にMetaEditorでコンパイルできるスクリプトです。
//+------------------------------------------------------------------+
//| DoWhileDemo.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int i = 1;
//基本のdo-while文: 1から5までPrintする
do
{
Print(i, "回目のループです。");
i++;
}
while(i <= 5);
Print("ループ終了。iの最終値=", i);
//while文との違い: 条件をすでに満たしていない場合の比較
int j = 10;//条件(j <= 5)をすでに満たしていない値
int whileCount = 0;
while(j <= 5)
{
whileCount++;
}
Print("while文の実行回数: ", whileCount, "(条件を先に見るため0回)");
int doWhileCount = 0;
do
{
doWhileCount++;
}
while(j <= 5);
Print("do-while文の実行回数: ", doWhileCount, "(条件を見る前に必ず1回実行される)");
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MT4の「ツール」→「MetaQuotes Language Editor」でMetaEditorを開く
- 「ファイル」→「新規作成」→「スクリプト」を選び、名前を「DoWhileDemo」にして作成する(中身は空のテンプレートで構いません)
- テンプレートの中身を全て削除し、上のコードを丸ごと貼り付ける
- F7キー(またはコンパイルボタン)でコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- MT4の「ナビゲーター」パネルからスクリプトを探し、任意のチャートへドラッグ&ドロップする
- 「表示」→「ターミナル」の「エキスパート」タブに、1〜5回目のログとwhile文/do-while文の実行回数の比較が出力されれば成功です
コピペしてコンパイルが通らないときに確認すること
- `while(条件式);`の末尾のセミコロンが抜けていないか(`do-while`文で最もよくあるコンパイルエラーの原因です)
- ループの条件を変える変数(このコードの`i`や`j`)をブロックの中で更新し忘れていないか。更新を忘れると、条件が永遠に成立し続ける無限ループになります
まとめ
`do-while`文は、`while`文と同じ繰り返し処理でありながら、
「条件を確認する前に、処理を必ず1回は実行する」という点が異なります。
この性質は、EA開発における発注リトライ処理のように「まず1回試してから、
特定の条件のときだけ繰り返す」場面と相性が良く、覚えておくと実務でも使う機会があります。
`while(条件式);`の末尾のセミコロンを忘れないように注意してください。
コメント