注意事項
iCustomを使用する際の注意事項
呼び出したインジケータ内でフラグ初期化等をしている可能性がある
EA自身の処理ではなく、インジケータ(シグナルを生成しているMQLプログラム)やチャート上の別のEA/スクリプトによってフラグ初期化等をしている場合、予期せずにオブジェクトの消去がされる可能性がある。
原因: カスタムインジケータのロードによる影響
iCustom() でインジケータをロードすると、そのインジケータの OnInit()、OnCalculate()、OnDeinit() などの関数がEAから独立して実行されます。
このカスタムインジケータ の内部ロジックで、主機能の波形作成ではない処理が入っていると挙動がおかしくなる可能性がある。
iCustomで呼び出した場合と、チャートにインジケータを適用使用する場合で挙動を変えることで対応する
iCustom() で呼び出された場合と、ユーザーが手動でチャートに適用した場合とで、インジケータの挙動を変えることは、MQL5で最も確実な方法として実現可能です。
これは、インジケータ側に新しい入力パラメータを追加し、iCustom() で呼び出す際にそのパラメータに特定の値を渡すことで実現します。
ステップ 1: カスタムインジケータにパラメータを追加する
RSI_MA_custom_entry.mq5 のファイルを開き、入力パラメータのセクションに以下の新しいパラメータを追加します。
//+-------------------------------------------------------------+ //| カスタムインジケータ内の修正 |
//+-------------------------------------------------------------+ // ... 既存の入力パラメータ ...
// iCustomから呼び出されたかどうかを判定するための新しい入力
input bool InpCalledByEA = false; // EAによって呼び出されましたか?
// ... 既存のコード ...
ステップ 2: 削除ロジックに判定条件を追加する
カスタムインジケータ側でEA時には処理してほしくない箇所をステップ1で追加したパラメータで実行を制御します。
コード スニペット
//+--------------------------------------------------------------+ //| カスタムインジケータ内の削除ロジック | //+--------------------------------------------------------------+ // ... 削除が行われている場所 ... // 【修正後】 // InpCalledByEA が false の場合のみ、削除処理を実行する if(!InpCalledByEA) { // 例:... その他のオブジェクト削除処理 ... }
ステップ 3: EA側で iCustom 呼び出しを修正する
EA側で iCustom を呼び出している箇所を探し、新しいパラメータ InpCalledByEA に明示的に true を渡します。
これにより、EAから呼び出されたカスタムインジケータは、削除処理をスキップします。
//+-----------------------------------------------------------+ //| EA側の OnInit() 関数の修正 | //+-----------------------------------------------------------+ // 【修正後】 // iCustomの最後の引数として true を渡し、オブジェクト削除を無効化する handle_RSI_MA_M5 = iCustom(_Symbol, PERIOD_M5, "personal\\RSI_MA_custom_entry", // ... その他の既存パラメータ ... true // <-- これが新しい InpCalledByEA パラメータ );
まとめ
この修正を行うことで、
-
EAから呼び出した場合 (
iCustom):InpCalledByEAがtrueになり、オブジェクト削除ロジックがスキップされます。 -
チャートに直接適用した場合:
InpCalledByEAはデフォルト値のfalseのままとなり、オブジェクト削除ロジックが実行されます。
なぜインジケータ上のinputとiCostumのパラメータが関連付けされるのか
コードを追加し、順番を正しく指定することでリンクされます。ただし、その関連付けは「パラメータの順番によってのみ行われます」となります。
MQL5のiCustom()関数におけるパラメータの関連付けは、他の多くのプログラミング言語のように「パラメータ名」で行われるのではなく、**厳密に「位置と順番」**によって決定されます。
MQL5 iCustomのパラメータ関連付けの仕組み
iCustom()関数は、引数(渡す値)の順番と、カスタムインジケータ内の入力変数(input)の定義順を1対1で対応させています。
1. MQL5がインジケータを呼び出す際の構造
iCustom() の書式は以下のようになっています。
| 位置 | iCustomの引数 |
説明 |
| 1 | symbol |
銘柄名 |
| 2 | period |
時間軸 |
| 3 | name |
インジケータのファイル名(パス) |
| 4以降 | カスタムパラメータ1, 2, 3... | カスタムインジケータの input 変数に対応 |
2. 関連付けの具体的な流れ
あなたのコードで考えると、関連付けは以下の順序で成立します。
インジケータ側の input 定義順 |
EA側の iCustom 呼び出し順 |
関連付けの仕組み |
input type Param1 |
iCustom(..., "IndicatorName", Param1_Value, ...) |
1番目のカスタムパラメータとしてリンク |
input type Param2 |
iCustom(..., "IndicatorName", Param1_Value, Param2_Value, ...) |
2番目のカスタムパラメータとしてリンク |
| ... | ... | |
input bool InpCalledByEA |
iCustom(..., true) |
最後の引数としてリンク |
インジケータに input bool InpCalledByEA = false; を一番最後に追加したと仮定すると、EA側の iCustom() の呼び出しでも、渡す値(true)を一番最後に記述する必要があります。
// カスタムインジケータの input 定義例 input double ParamA; // 1番目 input int ParamB; // 2番目 input bool InpCalledByEA = false; // 3番目 <--- これが追加された位置 // iCustom の呼び出し例 handle = iCustom(_Symbol, PERIOD_M5, "personal\\RSI_MA_custom_entry", ValueA, // 1番目 (ParamAに対応) ValueB, // 2番目 (ParamBに対応) true // 3番目 (InpCalledByEAに対応) <--- この順番が重要 );
⚠ 注意点:順番と型の厳密な一致
この仕組みが機能するために、以下の2点が厳密に一致している必要があります。
-
順番(Position): EA側で値を渡す順番と、インジケータ側で
input変数が定義されている順番が完全に一致していること。 -
型(Type): 渡す値のデータ型 (
int,double,boolなど) が、インジケータ側のinput変数のデータ型と一致していること。
もし、インジケータに10個の既存の input パラメータがあった場合、あなたの追加した InpCalledByEA は11番目になります。したがって、iCustom の呼び出しでも、その10個のパラメータの値を省略せずにすべて記述し、その後に11番目の値として true を渡す必要があります。
つまり、単にコードを追加するだけでなく、既存のすべてのパラメータの次に、新しいパラメータの値を渡す順番が重要になります。
結論
あなたの追加したコードは、カスタムインジケータの input 変数定義の最後に配置され、iCustom の呼び出しでも最後に渡されているため、MQL5のルールに従って正しく関連付けられています。