本記事で公開しているライブラリーは公開当時のままで、古くなっております。最新版のライブラリーはメルマガ登録いただくことでダウンロードできます。
EAの作成に必須であろう2つの共通関数を紹介します。
1pips当たりの価格単位を計算する関数
我々がトレード戦略を考える時、一般的にはpipsを使いますが、MQL4にはなぜかpipsという概念がありません。MQL4では直接価格を指定したり、Point(ポイント)と呼ばれる値を使います。
Point(ポイント)はMQL4で定義された変数で、通貨の最小価格単位です。例えば、小数点以下が3桁/5桁のFX業者の場合、1ポイント=0.001(円)/0.00001(円以外)=0.1pipsになります。小数点以下が2桁/4桁の場合は、1ポイント=0.01/0.0001=1.0pipsになります。
FX業者(小数点以下の桁数)や通貨ペアによって、Pointの返す値が異なるのがやっかいです。
EAのパラメータ設定にはpipsを使って、EA内部では、FX業者(小数点以下の桁数)や通貨ペアを意識せずに、円なら0.01単位、それ以外なら0.0001単位に変換できれば便利ですよね。
そこで最初に紹介するのが、1pipsあたりの価格単位を計算する関数です。この関数で得られた価格単位にpipsを掛けあわせることで、そのpipsに対応する価格が得られます。例えば、EAのパラメータ設定に5pipsと入力すると0.0005になるイメージです。
//+------------------------------------------------------------------+ //|【関数】1pips当たりの価格単位を計算する | //| | //|【引数】 IN OUT 引数名 説明 | //| --------------------------------------------------------- | //| ○ aSymbol 通貨ペア | //| | //|【戻値】1pips当たりの価格単位 | //| | //|【備考】なし | //+------------------------------------------------------------------+ double currencyUnitPerPips(string aSymbol) { // 通貨ペアに対応する小数点数を取得 double digits = MarketInfo(aSymbol, MODE_DIGITS); // 通貨ペアに対応するポイント(最小価格単位)を取得 // 3桁/5桁のFX業者の場合、0.001/0.00001 // 2桁/4桁のFX業者の場合、0.01/0.0001 double point = MarketInfo(aSymbol, MODE_POINT); // 価格単位の初期化 double currencyUnit = 0.0; // 3桁/5桁のFX業者の場合 if(digits == 3.0 || digits == 5.0){ currencyUnit = point * 10.0; // 2桁/4桁のFX業者の場合 }else{ currencyUnit = point; } return(currencyUnit); }
aSymbolには、”USDJPY”や”EURUSD”といった通貨ペアを表す文字列が入ります。3桁/5桁のFX業者の場合のみ10.0を掛けるのが重要です。
思い出してください。小数点以下が3桁/5桁のFX業者の場合、1ポイント=0.001/0.00001=0.1pipsで、2桁/4桁のFX業者の場合、1ポイント=0.01/0.0001=1.0pipsでした。10倍の違いです。従って、3桁/5桁のFX業者の場合のみ10倍することで、3桁/5桁か2桁/4桁かに関わらず、常に1pips当たりの価格単位(0.01/0.0001)が計算されることになります。
ポイント換算した許容スリッページを計算する関数
エントリー注文を送信する場合、許容スリッページを指定できるのですが、指定する際はpipsが良いですよね。ですが、MQL4はpipsを理解できません。理解できるのは価格かポイントのどちらかです。エントリー注文の送信では、許容スリッページをポイントで指定する必要があります。
というわけで、先程と同じように、FX業者(小数点以下の桁数)を考慮した、ポイント換算した許容スリッページを計算する関数を紹介します。
//+------------------------------------------------------------------+ //|【関数】ポイント換算した許容スリッページを計算する | //| | //|【引数】 IN OUT 引数名 説明 | //| --------------------------------------------------------- | //| ○ aSymbol 通貨ペア | //| ○ aSlippagePips 許容スリッページ(pips) | //| | //|【戻値】許容スリッページ(ポイント) | //| | //|【備考】なし | //+------------------------------------------------------------------+ int getSlippage(string aSymbol, int aSlippagePips) { double digits = MarketInfo(aSymbol, MODE_DIGITS); int slippage = 0; // 3桁/5桁業者の場合 if(digits == 3.0 || digits == 5.0){ slippage = aSlippagePips * 10; // 2桁/4桁業者の場合 }else{ slippage = aSlippagePips; } return(slippage); }
構造は先程と同じです。FX業者の小数点以下の桁数によって、許容スリッページの計算方法を切り替えています。
関数の戻り値は、ポイント換算された許容スリッページとなります。
サンプルEA
関数だけではイメージが沸きづらいと思いますので、サンプルEAを載せておきます。
//+------------------------------------------------------------------+ //| Sample.mq4 | //| Copyright (c) 2014, りゅーき | //| https://autofx100.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright (c) 2014, りゅーき" #property link "https://autofx100.com/" #property version "1.00" //+------------------------------------------------------------------+ //| EAパラメータ設定情報 | //+------------------------------------------------------------------+ extern int SlippagePips = 5; //+------------------------------------------------------------------+ //| グローバル変数 | //+------------------------------------------------------------------+ double gPipsPoint = 0.0; int gSlippage = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { gPipsPoint = currencyUnitPerPips(Symbol()); gSlippage = getSlippage(Symbol(), SlippagePips); Print("1pips当たりの価格単位 = ", gPipsPoint); Print("許容スリッページ = ", gSlippage, "ポイント"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { } //+------------------------------------------------------------------+ //|【関数】1pips当たりの価格単位を計算する | //| | //|【引数】 IN OUT 引数名 説明 | //| --------------------------------------------------------- | //| ○ aSymbol 通貨ペア | //| | //|【戻値】1pips当たりの価格単位 | //| | //|【備考】なし | //+------------------------------------------------------------------+ double currencyUnitPerPips(string aSymbol) { // 通貨ペアに対応する小数点数を取得 double digits = MarketInfo(aSymbol, MODE_DIGITS); // 通貨ペアに対応するポイント(最小価格単位)を取得 // 3桁/5桁のFX業者の場合、0.001/0.00001 // 2桁/4桁のFX業者の場合、0.01/0.0001 double point = MarketInfo(aSymbol, MODE_POINT); // 価格単位の初期化 double currencyUnit = 0.0; // 3桁/5桁のFX業者の場合 if(digits == 3.0 || digits == 5.0){ currencyUnit = point * 10.0; // 2桁/4桁のFX業者の場合 }else{ currencyUnit = point; } return(currencyUnit); } //+------------------------------------------------------------------+ //|【関数】ポイント換算した許容スリッページを計算する | //| | //|【引数】 IN OUT 引数名 説明 | //| --------------------------------------------------------- | //| ○ aSymbol 通貨ペア | //| ○ aSlippagePips 許容スリッページ(pips) | //| | //|【戻値】許容スリッページ(ポイント) | //| | //|【備考】なし | //+------------------------------------------------------------------+ int getSlippage(string aSymbol, int aSlippagePips) { double digits = MarketInfo(aSymbol, MODE_DIGITS); int slippage = 0; // 3桁/5桁業者の場合 if(digits == 3.0 || digits == 5.0){ slippage = aSlippagePips * 10; // 2桁/4桁業者の場合 }else{ slippage = aSlippagePips; } return(slippage); }