【MQL】資産のN%の損失許容額からロットを計算する

f:id:umerin_fx:20211110172304p:plain
複利でお金を増やしていきたいなと思い、資金のN%の損失許容額からロットを計算するコードを書きました。
資産管理は今だにきちんとは理解できていませんが、色々な方のコードを参考にしました。

パラメータ(#property strictの下)

enum lotCalc
{
    fix=0, //固定
    change=1, //変動
};

enum lotAsset
{
    balance=0, //残高
    freeMargin=1, //余剰証拠金
};

input string lotSetting; //▼ ロット設定
input lotCalc Calc=fix; //  方式(固定/変動)
input double LOT=0.1; //  [固定] ロット数
input lotAsset Asset=freeMargin; //  [変動] 計算資産
input double allowLoss=2.0; //  [変動] 損失許容%

方式で固定を選んだ場合は[固定]のパラメータが、変動を選んだ場合は[変動]のパラメータが使用されます。
f:id:umerin_fx:20211110174420p:plain

ロット計算(OnTick内)

// 残高
double balance=AccountBalance();
   
// 余剰証拠金
double freeMargin=AccountFreeMargin();
   
// 損失許容額
double lossPerAmount=0;
     
if(Asset==balance){
   lossPerAmount=balance*allowLoss/100.0;
}else{
   lossPerAmount=freeMargin*allowLoss/100.0;
}

// 損切幅(Pips)
double sl=iATR(NULL,PERIOD_D1,14,1)*100;
   
// ロット単位
double lotStep=MarketInfo(NULL,MODE_LOTSTEP);
   
// Tickバリュー(1ロット当たりいくら変動するかを示す値)
double tickValue=MarketInfo(NULL, MODE_TICKVALUE);

// 3/5桁業者の場合は10倍にする
if(MarketInfo(NULL, MODE_DIGITS)==3 ||
   MarketInfo(NULL, MODE_DIGITS)==5){
      tickValue*=10;
}

// 最小ロット
double minLot=MarketInfo(NULL, MODE_MINLOT);

// 最大ロット
double maxLot=MarketInfo(NULL, MODE_MAXLOT);


double lot=0;
   
if(lotStep>0 && sl>0 && tickValue>0){
      
   // ロット計算
   lot=lossPerAmount/(sl*tickValue);
      
   // ロット単位に丸める
   lot=MathFloor(lot/lotStep)*lotStep;
   
   // 最小ロットに満たない場合は最小ロットにする
   if(lot<minLot){
      lot=minLot;
   }
      
   // 最大ロットを超える場合は最大ロットにする
   if(lot>maxLot){
      lot=maxLot;
   }
}

損切幅はsl=100;とすれば100Pipsです。

エントリー(OnTick内)

//固定ロットの場合
if(Calc==fix){
   
   // ロング
   if(条件){
        Ticket=OrderSend(NULL,OP_BUY,LOT,Ask,SLIP,Ask-ATR,Ask+PROFIT*10*Point,"test",MAGIC,0,clrBlue);
   }

   // ショート
   if(条件){
        Ticket=OrderSend(NULL,OP_SELL,LOT,Bid,SLIP,Bid+ATR,Bid-PROFIT*10*Point,"test",MAGIC,0,clrRed);
   }

//変動ロットの場合      
}else{

   // ロング
   if(条件){
        Ticket=OrderSend(NULL,OP_BUY,lot,Ask,SLIP,Ask-ATR,Ask+PROFIT*10*Point,"test",MAGIC,0,clrBlue);
   }
   
   // ショート
   if(条件){
        Ticket=OrderSend(NULL,OP_SELL,lot,Bid,SLIP,Bid+ATR,Bid-PROFIT*10*Point,"test",MAGIC,0,clrRed);
   }   
}

固定ロットの場合はパラメータにあるLOTを指定しています。
変動ロットの場合は上記で計算したlotを指定しています。

ぼやき

損切幅をATRにすると結構深めに設定されます。(ボラがある通貨は特に)
そうすると資金が少ないうちは大体最小ロットの0.01になるので勝ってもあまり増えない…。
最初は固定ロットにするか、損失許容%を上げるかしてリスクをとるのがいいと思いました。