はじめに
EA(エキスパートアドバイザー)を自作しようとしたとき、「ローソク足(バー)をどう使えばいいの?」「陽線・陰線の数を数えるってどうやるの?」と疑問に思ったことはありませんか?
この記事では、MT4でEAを作成する際に役立つバー(ローソク足)関連の処理方法を、関数コード付きで初心者向けにわかりやすく解説します。
この記事でわかること
- ローソク足を使ったEAの基本的な処理
- 陽線・陰線のカウント方法
- バーの出現タイミングに合わせた処理の書き方
- 決済タイミングの作り方
バー関連処理の重要性とは?
ローソク足の状態を把握する意義
ローソク足は、価格の始値・終値・高値・安値を示す重要な情報です。特に自動売買では、一定本数の陽線や陰線をパターンとしてとらえ、売買の判断に使うことが多くあります。
インジケーターではなく「バー」で判断する理由
インジケーターは価格の変動を加工したもので、ややタイムラグがあります。それに対しバーの状態は生の情報であり、より早く正確に判断するために使われます。
MT4 EAで使えるバー関連関数5選
1. エントリーから何本のバーが経過したかを判定する関数
▸ 関数
int CountBarsSinceEntry(int positionType)
{
datetime entryTime = 0;
// 指定タイプのポジションを探す(現在のシンボル)
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderType() == positionType)
{
entryTime = OrderOpenTime();
break; // 最初に見つけたポジションだけ使う
}
}
}
if (entryTime == 0)
{
return -1;
}
int barCount = 1;
for (int i = 1; i < Bars; i++) // 確定済み足のみ
{
if (Time[i] <= entryTime)
break;
barCount++;
}
return barCount;
}
▸ 引数と戻り値
- 引数:
OP_BUY
またはOP_SELL
- 戻り値:エントリーから経過したバー数。ポジションがない場合は-1
▸ 使用例
//新規注文(買い)から10バー経過でクローズ
if(CountBarsSinceEntry(OP_BUY) >= 10){
funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
}
//新規注文(売り)から30バー経過でクローズ
if(CountBarsSinceEntry(OP_SELL) >= 30){
funcOrder_Close(OP_SELL,0,MAGIC_NO,clrGray);
}
新規注文から一定期間(バー数)経過で決済をしています。
2. 直近の陽線(上昇ローソク足)をカウントする関数
▸ 関数
// 直近countBars本のローソク足で陽線の数をカウントする関数
int CountYousen(int countBars)
{
int bearishCount = 0;
for (int i = 1; i <= countBars; i++) // i=1から。i=0は未確定足のため除外
{
if (Close[i] > Open[i]) {
bearishCount++;
}
}
return bearishCount;
}
▸ 引数と戻り値
- 引数:直近から何本分カウントするかを渡しましょう。
- 戻り値:陽線の数
▸ 使用例
if(CountYousen(5) >= 5){
Print("陽線が5本連続したためクローズします");
funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
}
陽線が5本連続したらクローズ。
3. 直近の陰線(下降ローソク足)をカウントする関数
先ほどの陽線とは逆の陰線バージョンです。
▸ 関数
// 直近countBars本のローソク足で陰線の数をカウントする関数
int CountInsen(int countBars)
{
int bearishCount = 0;
for (int i = 1; i <= countBars; i++) // i=1から。i=0は未確定足のため除外
{
if (Close[i] < Open[i]) {
bearishCount++;
}
}
return bearishCount;
}
▸ 引数と戻り値
- 引数:直近から何本分カウントするかを渡しましょう。
- 戻り値:陰線の数
▸ 使用例
if(CountInsen(20) >= 10){
Print("陰線が複数確認されたので決済します");
funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
}
直近のローソク足20本中に陰線が10本確認されたらクローズ。
4. エントリー後、バーが○本経過&損失中で決済する関数
▸ 関数の説明
// エントリー後、バーが〇本を経過&損失中で決済する関数
void CountCloseChk(int countBars)
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){
//オーダー後、バーが10本を超えた かつ 損失中の場合決済する
if(OrderOpenTime() < iTime(NULL, 0, countBars) && OrderProfit() < 0){
OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);
}
}
}
▸ 引数と戻り値
- 引数:バー何本から決済チェックするか
- 戻り値:なし
▸ 使用例
//エントリー後、バーが10本を経過&損失中で決済する
CountCloseChk(10);
基本呼び出すだけ(損切りロジックに組み込み)でOKです。
5. バーが新たに出来た時だけ処理を行う仕組み
▸ Time[0]とprevtimeによる制御の基本
datetime prevtime = 0;
void OnTick()
{
//新しい足ができた時だけ処理する
if(Time[0] != prevtime){
//時間を更新して処理を続行する
prevtime = Time[0];
}else{
//処理せずに終わる
return;
}
~~~~~~~~~~~~
▸ 解説
この仕組みで「1バーに1回だけ処理する」EAを作ることができ、過剰な注文やエラーを防げます。
まず、Time[0]の値をセット(退避)するためにprevtimeというグローバル変数を設けます。
Time[0]は新しい足ができた時の時間がセットされているので、簡単に15分足とかでイメージしてもらうと 2021/04/01 18:15:00.000のような感じの値がセットされています。(実際は秒数)
このTime[0]は2021/04/01 18:30:00.000になるまで変わりません。
よって、2021/04/01 18:18:40.000とかの場合は、
Time[0]=2021/04/01/ 18:15:00.000
prevtime=2021/04/01/ 18:15:00.000
で同じ値となるためreturn;が実行されるので、以降処理はしない作りになっています。よって、エントリーもしないしエントリーするかどうかの判断もなくなります。
時間が進み2021/04/01 18:30:00.000になったジャストタイミングで、
Time[0]=2021/04/01/ 18:30:00.000
prevtime=2021/04/01/ 18:15:00.000
という状況になります。この場合は値が違うので、prevtimeに2021/04/01/ 18:30:00.000をセットし、
エントリーするかどうかの判断をしたりエントリーする場合はエントリーするといった形になります。
※if文の条件からreturn;は実行されません
こうすることで、『バーが新たに出来た時だけ処理を行う』という事ができるわけです。
※私が作っているサンプルソースは基本殆どがこの形です
コーディングの注意点とアドバイス
- 未確定足(i=0)は基本使わない:動いている最中の足なので、誤判定を招く可能性があります。
- グローバル変数は慎重に設計:
prevtime
のように時間を保持する変数は、意図しない挙動を避けるために適切に初期化しましょう。 - 決済関数(funcOrder_Closeなど)との連携:処理ミスでクローズできない場合に備えて、ログ出力も検討しましょう。
まとめ
本記事では、MT4でローソク足(バー)を使ったEA処理の基本を、5つの関数(処理)を通じて学んでいただきました。
自動売買EAを作るうえで、”バー”は最もシンプルで強力な判断材料です。 ぜひ、あなたのオリジナルEA作成にチャレンジしてみてください!
✅ 他にも多数のEAサンプルを公開中!
今回紹介した内容以外にも、当サイトではさまざまなFX自動売買EAのサンプルコードを提供しています。
自分に合った戦略のEAを見つけたい方は、ぜひチェックしてみてください。
EA開発初心者向けに、今後も実践的なMQL4関数を紹介していきます。
気になる機能やロジックがあれば、ぜひ他の記事もあわせてご覧ください!
コメント