本記事で公開しているライブラリーは公開当時のままで、古くなっております。最新版のライブラリーはメルマガ登録いただくことでダウンロードできます。
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);
}
