EAを動かす通貨ペア・時間足を限定する
EAは、特定の通貨ペアと時間足を前提にロジックやパラメータを作るのが一般的です。想定していないチャートに設定されると、意図しないエントリーをしてしまうおそれがあります。
そこで、EAを設定したチャートの通貨ペアと時間足をプログラム側で確認し、違っていたらアラートで知らせて動作を止めるようにしておくと安全です。チャートの通貨ペアと時間足は、次の関数で取得できます。
- Symbol():通貨ペア(シンボル名)
- Period():時間足
Symbol()
チャートで使われている通貨ペア名は、Symbol()で文字列として取得できます。
|
1 |
string Symbol(); |
Ref: Symbol – Chart Operations – MQL4 Documentation
注意点として、Symbol()が返す名前はFX業者や口座の種類によって異なります。多くの業者は「USDJPY」の後ろに独自の文字列(サフィックス)を付けています。たとえば「USDJPY」の場合、執筆当時(2020年)は次のようになっていました。
- USDJPY-b:OANDA(New York)
- USDJPY-oj5k:OANDA(東京)
- USDJPY-oj3m:OANDA(東京)
- USDJPY-cd:FXTF
- USDJPY:GaitameFinest
- USDJPY:Dukascopy
- など
同じ業者でも、取引できるロット数など口座の種類によってサフィックスを変えている場合があります。そのため、Symbol()の戻り値を「USDJPY」とそのまま比較すると、サフィックス付きの口座では一致しません。
StringSubstr()で先頭6文字を取り出す
文字列の一部を切り出すStringSubstr()を使うと、必要な部分だけを取り出せます。
|
1 2 3 4 5 |
string StringSubstr( string string_value, // string int start_pos, // position to start with int length=0 // length of extracted string ); |
Symbol()の戻り値から先頭の6文字だけを取り出せば、サフィックスに関係なく「USDJPY」かどうかを判定できます。
|
1 |
StringSubstr(Symbol(), 0, 6); |
ただし、業者によっては「#USDJPY」のように名前の前に文字(プレフィックス)が付く場合もあり、その場合はこの方法では判定できません。そのようなときは、次のSymbolInfoString()で通貨そのものを確認する方法が確実です。
SymbolInfoString()で通貨を確認する
SymbolInfoString()に取得したい項目のIDを指定すると、通貨ペアのさまざまな情報を文字列で取り出せます。
|
1 2 3 4 |
string SymbolInfoString( string name, // Symbol ENUM_SYMBOL_INFO_STRING prop_id // Property identifier ); |
Ref: SymbolInfoString – Market Info – MQL4 Documentation
主なID(ENUM_SYMBOL_INFO_STRING)と、USDJPYでの戻り値の例は次のとおりです。
| ID | 内容 | USDJPYでの例 |
| SYMBOL_CURRENCY_BASE | 基軸通貨 | USD |
| SYMBOL_CURRENCY_PROFIT | 損益通貨(損益の計算に使う通貨) | JPY |
| SYMBOL_CURRENCY_MARGIN | 証拠金通貨(必要証拠金の計算に使う通貨) | USD(※) |
| SYMBOL_DESCRIPTION | シンボルの説明 | US Dollar vs Japanese Yen |
| SYMBOL_PATH | シンボル一覧の中での階層パス | Forex\USDJPY |
※証拠金通貨・説明・パスの値は業者の設定によって異なります。FXの通貨ペアでは、証拠金通貨は通常は基軸通貨(USDJPYならUSD)です。
基軸通貨が「USD」、損益通貨が「JPY」かどうかで判定すれば、サフィックスやプレフィックスが付いていても米ドル円を見分けられます。
|
1 2 3 |
string base = SymbolInfoString(Symbol(), SYMBOL_CURRENCY_BASE); // "USD" string profit = SymbolInfoString(Symbol(), SYMBOL_CURRENCY_PROFIT); // "JPY" bool isUSDJPY = (base == "USD" && profit == "JPY"); |
Period()
チャートの時間足はPeriod()で取得できます。戻り値は、時間足の長さを「分」で表した整数です。
|
1 |
int Period(); |
Ref: Period – Chart Operations – MQL4 Documentation
比較するときは「5」のように数字を直接書くよりも、次の定数を使うとコードが読みやすくなります。
| 定数 | 時間足 | 値(分) |
| PERIOD_M1 | 1分足 | 1 |
| PERIOD_M5 | 5分足 | 5 |
| PERIOD_M15 | 15分足 | 15 |
| PERIOD_M30 | 30分足 | 30 |
| PERIOD_H1 | 1時間足 | 60 |
| PERIOD_H4 | 4時間足 | 240 |
| PERIOD_D1 | 日足 | 1440 |
| PERIOD_W1 | 週足 | 10080 |
| PERIOD_MN1 | 月足 | 43200 |
サンプルコード(OnInit()でチェック)
通貨ペアが「USDJPY」以外、または時間足が5分足以外のチャートに設定された場合に、アラートとログでエラーを知らせてEAを停止するコードです。チェックはOnInit()で行います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#property strict int OnInit() { if(StringSubstr(Symbol(), 0, 6) != "USDJPY" || Period() != PERIOD_M5) { Alert("Set EA on USDJPY M5"); Print("Set EA on USDJPY M5"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } void OnTick() { // ... } |
OnInit()が0以外の値(ここではINIT_FAILED)を返すと初期化失敗となり、EAは動作を停止します。なお、OnInit()の戻り値が判定に使われるのは「#property strict」を付けてコンパイルした場合だけなので注意してください。
「OnInit()でチェックすると、EAを設定した後でチャートの通貨ペアや時間足を切り替えられたときに対応できないのでは?」と思うかもしれません。実際には、チャートの通貨ペアや時間足を変更すると、EAはいったん終了処理(OnDeinit()、理由コードはREASON_CHARTCHANGE)を経てから、OnInit()がもう一度呼び出されます。そのため、チェックはOnInit()に書いておけば途中の切り替えにも対応できます。
一方、チェックをOnTick()に書くと、ティックが来るたびに判定が実行されるうえ、条件に合わないチャートではティックごとにアラートが出続けてしまいます。チェックはOnInit()で1回だけ行うのがおすすめです。
Ref: Event Handling Functions – MQL4 Documentation
Ref: Uninitialization Reason Codes – MQL4 Documentation




















