ここでは、MetaTrader4のEA(Expert Advisor)に複利機能(マネーマネジメント機能)を追加する方法を紹介します。
EAに複利機能を搭載する方法
今回はシンプルに、証拠金残高の増減でロット数を増減させる方法を紹介します。
例えば、残高10万円でロット数0.01ロットとして、残高が20万円で0.02ロット、残高が50万円で0.05ロットになるような計算をします。
説明の前に全体のコードを見てみるぞい!
extern double Lots = 0.01; extern bool UseMM = true; extern double BalancePerLots = 100000; double max_lot; // 最大ロット数 double min_lot; // 最小ロット数 int lot_digit; // ロット小数桁数 int OnInit() { max_lot = MarketInfo(Symbol(), MODE_MAXLOT); min_lot = MarketInfo(Symbol(), MODE_MINLOT); double lotstep = MarketInfo(Symbol(), MODE_LOTSTEP); if(NormalizeDouble(lotstep, 3) <= 0.001) lot_digit = 3; else if(NormalizeDouble(lotstep, 2) <= 0.01) lot_digit = 2; else if(NormalizeDouble(lotstep, 1) <= 0.1) lot_digit = 1; else lot_digit = 0; return(INIT_SUCCEEDED); } void OnTick() { // ロット数を算出 double lots = Lots; if (UseMM == true) { lots = AccountBalance() / BalancePerLots * Lots; lots = MathFloor(lots * MathPow(10, lot_digit)) * MathPow(0.1, lot_digit); if (lots > max_lot) lots = max_lot; if (lots < min_lot) lots = 0; } }
MM機能搭載例のサンプルEA【Sample_MM.mq4】をダウンロード
パラメーターを設置する
次のように、「ロット数」・「複利機能ON/OFF」・「証拠金ステップ額」のパラメーターを設置します。
extern double Lots = 0.01; extern bool UseMM = true; extern double BalancePerLots = 100000;
取引業者のロットの最大値・最小値と小数以下桁数を取得する
まず、最大ロット数・最小ロット数・ロット小数以下桁数を格納するグローバル変数を宣言します。
double max_lot; // 最大ロット数 double min_lot; // 最小ロット数 int lot_digit; // ロット小数桁数
OnInit()関数内で、それぞれの値を取得します。
max_lot = MarketInfo(Symbol(), MODE_MAXLOT); min_lot = MarketInfo(Symbol(), MODE_MINLOT); double lotstep = MarketInfo(Symbol(), MODE_LOTSTEP); if(NormalizeDouble(lotstep, 3) <= 0.001) lot_digit = 3; else if(NormalizeDouble(lotstep, 2) <= 0.01) lot_digit = 2; else if(NormalizeDouble(lotstep, 1) <= 0.1) lot_digit = 1; else lot_digit = 0;
※最小ロット数とロットの最小ステップ数が違う場合があるので、ロットの最小ステップ数で小数以下桁数が決まるようにしています。
証拠金残高からロット数を算出する
OnTick()関数のエントリー注文のコードの手前あたりで、次のようにロット数を算出します。
double lots = Lots; if (UseMM == true) { lots = AccountBalance() / BalancePerLots * Lots; lots = MathFloor(lots * MathPow(10, lot_digit)) * MathPow(0.1, lot_digit); if (lots > max_lot) lots = max_lot; if (lots < min_lot) lots = 0; }
lots に Lots を代入 もし UseMM が true なら { lots は 残高 ÷ BalancePerLots × Lots lots は 小数以下桁数 lot_digit に切り捨て lots が max_lot より大きい場合、 lots は max_lot lots が min_lot より小さい場合、 lots は 0 }
切り捨てのところが少しややこしいので、簡単な例で説明します。
lots = MathFloor(lots * MathPow(10, lot_digit)) * MathPow(0.1, lot_digit);
このコードに使用しているMathFloor()関数は小数以下を切り捨てる関数です。MathPow()関数は累乗をする関数です。
例えば、ロット数が1.2345でlot_digitが2の場合、次のような計算をします。
lots * MathPow(10, lot_digit)
→ 1.2345 × 100 = 123.45
MathFloor(123.45)
→ 123
123 * MathPow(0.1, lot_digit)
→ 123 × 0.01 = 1.23
この場合、lotsの計算結果は1.23になります。
あとがき
切り捨ての計算が難しい場合は、少し妥協して四捨五入のNormalizeDouble(lots, lot_digit)としてもよいと思います。それ以外は意外と簡単ですね^^
パラメーターBalancePerLotsは、日本円口座やドル口座など口座通貨によって入力値を調整してください。
続きの記事では、連勝・連敗によってロット数を変化させる方法を解説しています。
はじめまして、M.Iと申します。
Dr.EAblogを見て日々MQL4の勉強に励んでいます、なかなか手ごわくて苦労しています。
こんな質問を受けていただけるのか分かりませんが、下記の件でお尋ねします。
メタトレーダー4を運用している証券会社ごとに一回に掛けられる最高Lots数が違うようです。
そこで、その会社の最高Lots数を取得するには、どのようなコードでプログラムすればよろしいのでしょうか?
ぜひ教えてください。
この件で、コードに「MODE_MAXLOT」を使うと、121証券もFXDDもおなじ25Lotsとなってしまいます。
実際は、121証券は30LotsまでOKです。
また、FXDDは50LotsまでOKです。
どちらもライブ口座です。
そのため、実際の運用時の一回に掛けられる最大Lots数をどのようなコードでプログラムしたらいいのかをご教授ください。
コメントではなくてすみません、いきなりな質問で申し訳けありません。
宜しくお願いしたします。
M.Iさん
こんにちわ!
ロットの最大値は、
MarketInfo(Symbol(),MODE_MAXLOT)
で取得できますよ^^