解決済み

if(IsTradeAllowed()==false){}について

2025/11/20 10:02
62

某証券会社でGOGOJANさんのサイトで作成したEAを運用したところ、エントリー条件を満たしているにも関わらず、エントリーしなかったため、ChatGPTに質問してみたところ、標記のコードにより、証券会社毎にEA初期化のタイミングが違うために、EAをMT5に貼った瞬間にfalse判定がででしまうため、準備の瞬間にコードチェックが引っかかっていると回答を得られました。
それにつきまして、if(IsTradeAllowed()==false){}をコメントアウトしてEAを運用させようと思うのですが、なにかアドバイスや補足説明など頂けないでしょうか。
また、if(IsTradeAllowed()==false){}に問題はなく、別の原因も考えられますでしょうか?
MT5のビジュアルモードでの動作は確認済みです。

コメント

GogoJungle
2025/11/20 19:26

ご質問の件について、結論から申しますと、今回のエントリーしなかった原因は「IsTradeAllowed()==false」よりも、「フィリングモード(FillingMode)」に起因する可能性のほうが高いと考えられます。
以下に両方のポイントをまとめます。


1. IsTradeAllowed() について

if(IsTradeAllowed()==false){} のチェックは、
**「EA が現在の環境で発注可能か」**を確認するための安全装置です。

ただし、証券会社によっては以下のようなことが起こります:

  • EA をチャートにセットした “その瞬間” だけ trade allowed が false になる
  • 初期化タイミングがブローカー側の仕様でズレる
  • その瞬間の判定だけで EA の内部ロジックが止まってしまう

そのため、このチェックが原因で発注できないケースはあります。
ただし、EA 全体の安全性のためには、本来は残しておくのが推奨です。

コメントアウト自体は可能ですが、他の要因で本当に注文が不可能な時にも EA が無理に注文しようとするリスクがあります。

そのため、完全に削除するのではなく、
**「初期化直後だけ判定しない」「必要なタイミングだけ使う」**などの改善のほうが安全です。


2. FillingMode(フィリングタイプ)による注文拒否のほうが有力

MT5 では、注文送信時に type_filling(フィリングタイプ) をブローカー仕様に合わせる必要があります。

多くの EA 自動生成ツール(GogoJungle や EA つくーる含む)では
デフォルトで ORDER_FILLING_FOK が設定されているため、
ブローカーが IOC のみ対応の場合、注文が通らずエントリーしない現象が普通に起こります。

よくあるブローカー仕様

ブローカー仕様 EAが設定すべき値
FillingMode = 1 ORDER_FILLING_FOK(デフォルト)
FillingMode = 2 ORDER_FILLING_IOC(EAが自動対応する必要あり)

証券会社により違うため、この判定は非常に重要です。

対応コード例(推奨)

int FillingMode = (int)SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);

if(FillingMode == 2){
    request.type_filling = ORDER_FILLING_IOC;
} else {
    request.type_filling = ORDER_FILLING_FOK;   // 1 の場合
}

このコードを追加しないと、
ビジュアルモードではエントリーできるのに、リアル環境ではエントリーしない
という典型的な症状が発生し得る可能性がございます。

つきましては、コードの追加をお試しいただきたく存じます。

YAMA
2025/11/20 22:45

ご教授頂きありがとうございます。
大変恐縮ですが、どこに2.FillingMode(フィリングタイプ)の対応コードを追加すればよろしいでしょうか??

GogoJungle
2025/11/25 18:22

まずは前回のご質問の続きとして、「FillingMode(フィリングタイプ)の判定コードを、EA内のどこに書けばよいか」という点について整理します。


1. 追加する場所の基本的な考え方

ポイントはとてもシンプルで、

「注文をサーバーに送る直前」

type_filling を設定する、というイメージです。

多くのMT5 EAは、以下のどちらかのパターンになっています。

  1. MqlTradeRequest / OrderSend() を直接使うパターン
  2. CTrade クラス(trade.Buy() / trade.Sell())を使うパターン

それぞれの場合の「追加位置」を例で示します。


2. MqlTradeRequest / OrderSend() を使っている場合

EAのソースの中に、次のようなコードがないか探してみてください。

MqlTradeRequest request;
MqlTradeResult  result;
ZeroMemory(request);

// ここで request.symbol, request.volume, request.type などを設定しているはず

request.type_filling = ORDER_FILLING_FOK;  // ← この行が固定で書かれていることが多いです

if(!OrderSend(request, result)){
   // エラー処理 ...
}

このような構造になっている場合は、

  1. request.type_filling を固定値で書かずに
  2. OrderSend() を呼ぶ前で、ブローカーの FillingMode に応じて設定する

ように書き換えます。

具体例は次のようになります。

MqlTradeRequest request;
MqlTradeResult  result;
ZeroMemory(request);

// ここで request.symbol, request.volume, request.type など各種設定

// --- ここから追加(または書き換え) ---
int FillingMode = (int)SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);

// ブローカーの仕様に応じて type_filling を切り替え
if(FillingMode == 2){
   request.type_filling = ORDER_FILLING_IOC;
} else {
   request.type_filling = ORDER_FILLING_FOK;   // FillingMode が 1 の場合など
}
// --- ここまで追加 ---

if(!OrderSend(request, result)){
   // エラー処理 ...
}

つまり、

  • OrderSend() を呼ぶ直前」
  • request.type_filling を設定している(または設定すべき)場所」

に、上記の FillingMode 判定を差し込むイメージになります。

もし、現在のコードが

request.type_filling = ORDER_FILLING_FOK;

のように「1行だけ固定」で書かれているようでしたら、その1行を上の if 文ブロックに置き換えてください。


3. CTrade クラス(trade.Buy() / trade.Sell())を使っている場合

EAのソース内に、次のようなコードがあるパターンです。

CTrade trade;

// どこかで
trade.Buy(lots, _Symbol, sl, tp, "comment");

この場合も考え方は同じで、

trade.Buy() / trade.Sell() を呼ぶ前」

に FillingMode を見て、CTrade のフィリングタイプを設定します。

例:

CTrade trade;

// --- ここから追加 ---
int FillingMode = (int)SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE);

if(FillingMode == 2){
   trade.SetTypeFilling(ORDER_FILLING_IOC);
} else {
   trade.SetTypeFilling(ORDER_FILLING_FOK);
}
// --- ここまで追加 ---

// その後で注文実行
trade.Buy(lots, _Symbol, sl, tp, "comment");

もし EA 内に CTrade trade; という宣言があり、trade.Buy() / trade.Sell() で発注しているようでしたら、このように「発注前に1回 SetTypeFilling を呼ぶ」形で対応するのが分かりやすいです。


4. IsTradeAllowed() のコメントアウトについての補足

前回お伝えした通り、

  • if(IsTradeAllowed()==false){ ... } が「本当に原因」の場合もありますが、
  • MT5の場合は「FillingModeの不一致でサイレントに注文が通らない」ことがよくあります。

そのため、

  1. まずは上記の FillingMode 対応を入れた状態で
  2. ストラテジーテスター(通常モード/ビジュアルモード両方)で再確認し
  3. 可能であればリアル/デモの該当ブローカーで、ログ(ターミナルの「エキスパート」「ジャーナル」タブ)にエラーが出ていないか確認

という順番で切り分けていただくほうが、安全です。

IsTradeAllowed() を完全にコメントアウトしてしまうと、

  • 取引禁止時間帯
  • 口座が「取引のみ読み取り専用」状態
  • サーバーメンテナンス中 など

「そもそも取引できない環境」でも EAが無理に注文を出そうとしてしまうため、安全装置を外すことになります。

そのため、

  • まずは FillingMode の対応を優先
  • それでもダメな場合に、IsTradeAllowed() の条件の位置やタイミングを見直す(EA開始直後だけ判定しない/一定時間後に再チェックする等)

という方向で調整するほうが、トラブルは少なくなります。


5. もし EAつくーる で作成したMT5 EAに同じ問題が出た場合

今回のご質問は GogoJungle さんのEAとのことですが、参考として EAつくーる製 MT5 EA で同じ現象が出る場合は、

  • EA本体のソースと一緒に出力される Tkool.mqh 内で
  • 注文送信処理(OrderSend または内部のラッパ関数)がまとまっている箇所

に、上記と同じ「FillingMode による type_filling の切り替え」を追加する形になります。

ただし、Tkool.mqh は共通ライブラリですので、編集する場合は「バックアップを取ってから」「他のEAにも影響する可能性がある」点にご注意ください。


まとめると、

  • 追加する場所は「OrderSend() または trade.Buy()/Sell() を呼ぶ直前」
  • そこで SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE) を見て type_filling を切り替える

というイメージで探していただければ、目的の位置にたどり着けるはずです。

YAMA
2025/11/27 16:58

大変ご丁寧に説明してくださってありがとうございます。
少し考えてみます。
本当にありがとうございました。

関連トピックス

検索結果がありません。

ノーコードで誰でも簡単EA開発!MQL言語学習にも使える! | GogoJungle

注目トピックス

検索結果がありません。