EA自作企画第4弾!準備がまだ!って人は先に準備しましょう!こっちのページを参照してね!

こちらのサイトのようなところへ行けば、EA自体は購入が可能です。

投資家の祭典 GogoJungle AWARD 2023

前回、ちょっとだけプログラミングしてみましたが、えぇ、ちょっとすぎて何もしてないのと一緒…ってことで今回はもう少しやってみましょう。

目標とするEAに近づけたい…

自作EAの条件

損切しない!

スワップが増える方向にだけエントリー

似たようなところでエントリーしない!

最大ポジション数を取った時にレバレッジ10倍を超えない!

こんな感じのEAを設定していましたね。さて、これらを設定できるようにexternしてみましょう。

損切しない!ってのは設定しなければいいだけなので、何もしません。

スワップが~の項目は基本的にはLong、Shortどちらかに絞れば良いので、前回の、LongOn,ShortOnで解決できました。

今回は、似たようなところでエントリーしない!ってのと、最大ポジション数を取った時にレバレッジ10倍を超えない!ってのをexternしてみます。

レバレッジ10倍は、関数の都合上10%とすると、Lotが四捨五入して繰り上がっても耐えられるはずです。

#property copyright "Copyright 2025, FPshima"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern bool LongOn = true; //ロングを許可
extern bool ShortOn = false;//ショートを許可

extern int zone = 50;   //エントリー不可範囲 次回やります
extern int maxPosition = 4;  //最大ポジション数
extern double risk = 10; //取りうる最大リスク(%)

double calculateLotSize() // 1ポジションあたりのロットサイズを計算する関数を宣言
{
   double accountBalance = AccountBalance();//現在残高を取得
   double totalRiskAmount = accountBalance * risk/100;// 残高とリスク(%)から使える最大額を計算
   double eachPositionRisk = totalRiskAmount/maxPosition;//各ポジションで使える額に変換
   double minLot = MarketInfo(NULL,MODE_MINLOT);//この通貨の最小ロットを取得
   double marginRequire = MarketInfo(NULL,MODE_MARGINREQUIRED)*minLot;//最小ロットの証拠金を計算
   double lotSize = (eachPositionRisk / marginRequire)*minLot;//最適ロットサイズを計算

   if(lotSize <= minLot)//場合分け、最小ロットよりも小さいとエラーが出るので
   {
      lotSize = minLot;//そんな時は最小ロットでトレード
   }
   if(lotSize <= 20.0)//大体どの会社もMax20Lotなのでそれまでの値は採用
   {
     lotSize = NormalizeDouble(lotSize,2);//小数点以下2位より先の値があるとエラーが出るので
   }
   if(lotSize > 20.0)
   {
      lotSize = 20.0;//20Lotを超える値が計算されたら上限値トレード
   }
   return lotSize;//calculateLotSize()関数が使われたときに、この値を計算結果とする
}
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

   double tradeLot = calculateLotSize();//calculateLotSize()関数で計算した値をtradeLotとして格納
   Comment("lotSize",tradeLot);//確認用にチャートに出るようにした。
  }
//+------------------------------------------------------------------+

いきなり少し長いですね…

まずはテンプレートよりも外側のグローバル領域で、自作の関数として

double calculateLotSize()

を宣言しました。この関数は{}内の計算を行ってreturn ローカル変数lotSizeを教えてくれます。

   double accountBalance = AccountBalance(); //現在残高を取得
   double totalRiskAmount = accountBalance * risk/100; // 残高とリスク(%)から使える最大額を計算
   double eachPositionRisk = totalRiskAmount/maxPosition;//各ポジションで使える額に変換
   double minLot = MarketInfo(NULL,MODE_MINLOT);//この通貨の最小ロットを取得
   double marginRequire = MarketInfo(NULL,MODE_MARGINREQUIRED)*minLot;//最小ロットの証拠金を計算
   double lotSize = (eachPositionRisk / marginRequire)*minLot;//最適ロットサイズを計算

AccountBalance()関数はMQLにある関数で、現在の残高を教えてくれます。この値をaccountBalanceにdoubleで宣言して格納しています。

続いて、externで設定したriskを100で割って%にし、現在の残高にかけることで、トレードに使える最大額を計算します。その後、maxPosition数で割ることで、各ポジションで使える金額を計算しました。

minLotにはMQLの関数MarketInfo(NULL,MODE_MINLOT)を使用して、その通貨ペアで選択できる最小ロットを調べています。MarketInfo()関数は非常に多くの値が取得できますが、とりあえずMODE_MINLOTを入れると最小値がわかります。第1引数にはNULLを使ってますが、すごく便利で、現在使っている通貨ペアを勝手に選んでくれます。

続いて、marginRequireではMarketInfo()関数で必要証拠金を取得し、最小ロットminLotを掛けることで、最小ロットの必要証拠金を算出しています。

最後にロットサイズを求めています。各ポジションで使える残高から最小ロットの証拠金で割ることで、何単位の最小ロットの購入できるかを求め、最小ロットをかけて、ロットサイズを計算しています。

最後にif文で条件分けをして、最小0.01 最大20.0 それまでの計算結果は、小数点第3位で四捨五入して小数点第2位としています。

実際の計算は以下のようになります。

計算

USDJPY 

残高 = 10000ドル

最小ロット 0.01

必要証拠金 4000/Lot

accountBalance = AccountBalance() =10000

totalRiskAmount = accountBalance * risk/100 risk=10から 1000

eachPositionRisk = totalRiskAmount/maxPosition maxポジションは4なので 250

minLot = MarketInfo(NULL,MODE_MINLOT) =0.01

marginRequire = MarketInfo(NULL,MODE_MARGINREQUIRED)*minLot 1Lotに4000必要なので最小ロットだと40

lotSize = (eachPositionRisk / marginRequire)*minLot 250を40で割ると6.25でminLot0.01だからlotSizeは0.06

OnTickの中も見てみましょう

void OnTick()
  {
//---

   double tradeLot = calculateLotSize();//calculateLotSize()関数で計算した値をtradeLotとして格納
   Comment("lotSize",tradeLot);//確認用にチャートに出るようにした。
  }
//+------------------------------------------------------------------+

tradeLot = calculateLotSize()さっき作った関数での計算結果をtradeLotに格納しています。計算が間違っていなければ0.06になっているはずですが、現段階では実際のトレードはされないので、Comment()で表示させています。

()内に,で区切って表示させたいものを格納すると、画面に表示してくれます。ここでは文字列lotSize(””で囲った文字は文字列として認識されます。)の後に、tradeLotが表示される様にしています。

見づらいかもしれませんが、ちゃんと左上にlotSize0.06が表示されていますね!

続きはまた次回!

楽天証券(FX)

おすすめFXアイテム

過去検証や分析はMT4かFT4、Trading viewがおすすめです。

無料が良い人はMT4で、MT4を使わせてくれる口座を使用すると良いです。おすすめはFXTF

ガチで過去検証をやりたい人はFT4、

チャート分析に毎月課金してもいいよって人はTrading viewがおすすめです。無料もあります

Twitterでフォローしよう

おすすめの記事