2021年06月25日
EA上で自動的にLot数を計算するMQL5の書き方を説明します。
現在の資金に応じて設定レバレッジ分のロット数を算出するサンプルコードを説明します。
その前に必要な関数をそれぞれ説明していきましょう。
まず残高を取得する関数を使います。
AccountInfoDoubleを使います。
double margin_free=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
ACCOUNT_MARGIN_FREEは余剰証拠金です。
もしポジションを持っていないのであれば、口座残高と等しい値になります。
ポジションを持っている場合は、今持っているポジションの証拠金(必要証拠金)を引いた額が余剰証拠金になります。
④余剰証拠金=②有効証拠金-③必要証拠金
他にも口座残高や含み益などが取得できます。
この図はAccountInfoDoubleの引数と取得できる情報をまとめたものです。
②有効証拠金=①残高+⑥(含み)損益になっています。
余っている証拠金をベースにロット数を決めていきましょう。
この記事で1lotが何通貨か取得する方法を説明しました。
lot数を決める際に必要な下記をSymbolInfoDoubleで取得します。
double oneLotSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
double volume_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP)*oneLotSize;
double volume_min = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN));
double volume_max = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX));
口座によってlot数が異なるのでこのように取得する必要があります。
クロス円、つまりUSDJPYのような通貨ペアであればレートから直接購入金額がわかります。
しかしEURUSDやXAUUSD(金/ドル)は直接円で購入金額が分かりません。
そこでOrderCalcMarginを使います。
この関数は、必要な証拠金を『口座の預金通貨で』計算します。
つまりEURUSDやXAUUSDでも円で証拠金を算出してくれます。(もちろんUSDJPYでも円で算出されます)
MqlTick last_tick;
double margin = 0; // ここに証拠金が入る
bool orderCalcMargin = OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1,last_tick.ask,margin);// marginに証拠金を格納
int account_max_leverage = AccountInfoInteger(ACCOUNT_LEVERAGE);// 口座の設定レバレッジ取得
double oneUnitPrice = margin*account_max_leverage/oneLotSize
MqlTick last_tick で現在の価格を取得します。OrderCalcMarginに現在の価格を渡すためです。
そして変数marginを初期化し、下のOrderCalcMarginに渡します。この変数に必要証拠金が格納されます。
OrderCalcMarginの返り値はtrue falseで取得できればtrueが返ってきます。引数の変数に値を書き込むタイプの関数ですね。
そしてこの必要証拠金marginは口座の設定した最大レバレッジがかけられた上での証拠金になります。
口座によってレバレッジは異なるので、レバレッジを無くしましょう。
AccountInfoIntegerにACCOUNT_LEVERAGEを渡せば口座の設定レバレッジを取得できます。
marginにレバレッジをかけ、その値を1lotの通貨数(1万とか10万とか)で割ればレバレッジがかかっていない1通貨の購入金額oneUnitPriceが取得できます。
もちろんこれはUSDJPYなどの対円通貨ならoneUnitPrice=last_tick.ask(=110.532円)のようになりますが、
この方法であればEURUSDといったドルストレートやゴールドなどどんなペアも円で購入金額が算出できます。
余剰証拠金をレバレッジ倍した資産額で買える分のLotを計算するサンプルコードです。
余剰証拠金取得
→ロット情報取得
→購入金額算出
→レバレッジ倍した資産で買えるLot数算出
→刻み幅に合わせた上で最大最小Volume範囲内の確認
//+------------------------------------------------------------------+
int OnInit()
{
//---
double leverage = 10;
double lot = lotSizebyLeverage(leverage);
printf(lot);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
double lotSizebyLeverage(double leverage)
{
//余剰証拠金取得
double margin_free = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
//ロット情報取得
double one_lot_Size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
double volume_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP)*one_lot_Size;
//購入金額取得
MqlTick last_tick;
SymbolInfoTick(Symbol(),last_tick); // Assign current prices to structure
//購入金額算出
double margin = 0;
bool orderCalcMargin = OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1,last_tick.ask,margin);
//レバレッジ倍した資産で買えるLot数算出
int account_max_leverage = AccountInfoInteger(ACCOUNT_LEVERAGE);
double one_unit_price = margin*account_max_leverage/one_lot_Size;//yen or setting account currency
double calculated_Volume = margin_free*leverage/one_unit_price;
//刻み幅に合わせた上で最大最小Volume範囲内の確認
double calculated_Lot = MathFloor(calculated_Volume/volume_step)*volume_step/one_lot_Size;
if(calculated_Lot < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
{
printf("No money to trade the smallest lot. Up leverage or add money to account.");
}
if(calculated_Lot > SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX))
{
calculated_Lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
printf("Forced to maximum lot");
}
return calculated_Lot;
}
をそれぞれ使ってLotサイズを算出する流れを説明しました。
コントラは最高のFXアプリを
目指して誠意開発を続けております。
機能の要望や、不具合などありましたらご遠慮なくヘッダーの問い合わせ、フィードバックからご連絡ください。またツイッターからでも大丈夫です!
皆様のFXトレードのお力になるFXアプリを目指しますので、これからもよろしくお願いいたします。