Solved : Lot Multiplier Problem

 

Hi guys,

I have problem in my code and I can't find the solution. description of my code is:


     1 - use auto lot size:

Auto Lot Size = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
  • first order on entire history : use Auto Lot Size
  • if order closed with TP then use lot multiplier for next order (Example: last order closed with TP, calculate next order lot is: for first order multiple: (Auto Lot Size:0.5) * Lot Multiplier(1.5) = 0.75,  after TP hinted, for second order multiple: (Auto Lot Size:0.6) * Lot Multiplier(1.5) = 0.9, and ..... ).
  • after continuous X trade closed with TP then lot reset to Auto Lot Size(this is like cycle).
  • if each order closed with SL then lot reset to Auto Lot Size.

     2 - use fixed manual lots

  • conditions same as auto lot size formula, just replace Auto Lot Size with fixed manual lots


The problem is I got Just 0.01 lot that is minimum lot size, appreciated if anyone can help me to solved

Auto lot function is :

extern double                LotSize             = 0.10;                                  //Manual Lot Size
extern bool                  MoneyManagement     = True;                                  //Use Auto Lot Size
extern double                Risk                = 1.0;                                   //Risk
extern bool                  UseLotMultiplier    = True;                                  //Use Lot Multiplier
extern double                LotMultiplier       = 1.5;                                   //Lot Multiplier
extern int                   StartOver           = 3;                                     //Reset Lot Multiplier After X Success Trade


double subLotSize()
{
    double          lots             = 0;
    int             TotalClosedOrder = 0;
    static int      WonOrderCount;
    static datetime OrderTime;
    double          lot_max  = MarketInfo(Symbol(), MODE_MAXLOT);
    double          lot_min  = MarketInfo(Symbol(), MODE_MINLOT);
    double          lotStep  = MarketInfo(Symbol(), MODE_LOTSTEP);
    double          contract = MarketInfo(Symbol(), MODE_LOTSIZE);
    if (lot_min == 0.01)
        LotDigits = 2;
    if (lot_min == 0.1)
        LotDigits = 1;
    if (lot_min == 1)
        LotDigits = 0;
    if (UseLotMultiplier)
    {
        for (int h = OrdersHistoryTotal() - 1; h >= 0; h--)
        {
            if (OrderSelect(h, SELECT_BY_POS, MODE_HISTORY))
            {
                if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
                {
                    if (OrderType() == OP_BUY || OrderType() == OP_SELL)
                        TotalClosedOrder++;
                    if (TotalClosedOrder >= 1)
                        break;
                }
            }
        }
        if (TotalClosedOrder == 0)
            lots = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
        else if (OrderSelect(OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY) && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
            if (OrderCloseTime() > OrderTime)
            {
                OrderTime = OrderCloseTime();
                if (WonOrderCount == StartOver)
                {
                    lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
                    WonOrderCount = 0;
                }
                else if (OrderProfit() + OrderCommission() + OrderSwap() <= 0)
                {
                    lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
                    WonOrderCount = 0;
                }
                else if (OrderProfit() + OrderCommission() + OrderSwap() > 0)
                {
                    lots = NormalizeDouble(OrderLots() * LotMultiplier, LotDigits);
                    WonOrderCount++;
                }
            }
        }
    }
    if (!UseLotMultiplier)
        lots = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
    if (lots >= lot_max)
        lots = lot_max;
    if (lots <= lot_min)
        lots = lot_min;
    return(lots);
}
 

Hi,

First you should check this condition with lot step,not min lot,

if(MarketInfo(Symbol(),MODE_LOTSTEP)==1)LotDigits =0;
if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.1)LotDigits =1;
if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.01)LotDigits =2;

The correct version of the function should be such :

double subLotSize()
  {
   int LotDigits=0;
   double          lots             = 0;
   int             TotalClosedOrder = 0;
   static int      WonOrderCount;
   datetime OrderTime;
   double          lot_max  = MarketInfo(Symbol(), MODE_MAXLOT);
   double          lot_min  = MarketInfo(Symbol(), MODE_MINLOT);
   double          lotStep  = MarketInfo(Symbol(), MODE_LOTSTEP);
   double          contract = MarketInfo(Symbol(), MODE_LOTSIZE);
   if(lotStep==0.01)
      LotDigits=2;
   if(lotStep==0.1)
      LotDigits=1;
   if(lotStep==1)
      LotDigits=0;
   if(UseLotMultiplier)
     {
      for(int h=OrdersHistoryTotal()-1; h>=0; h--)
        {
         if(OrderSelect(h,SELECT_BY_POS,MODE_HISTORY))
           {
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
              {
               if(OrderType()==OP_BUY || OrderType()==OP_SELL)
                  TotalClosedOrder++;
               if(TotalClosedOrder>=1)
                  break;
              }
           }
        }
      if(TotalClosedOrder==0)
         lots=NormalizeDouble(AccountBalance()*Risk/100*AccountLeverage()/contract,LotDigits);
      else if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY) && OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         if(OrderCloseTime()>OrderTime)
           {
            OrderTime=OrderCloseTime();
            if(WonOrderCount==StartOver)
              {
               lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
               WonOrderCount = 0;
              }
            else if(OrderProfit()+OrderCommission()+OrderSwap()<=0)
              {
               lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
               WonOrderCount = 0;
              }
            else if(OrderProfit()+OrderCommission()+OrderSwap()>0)
              {
               lots=NormalizeDouble(OrderLots()*LotMultiplier,LotDigits);
               WonOrderCount++;
              }
           }
        }
     }
   if(!UseLotMultiplier)
      lots = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract,LotDigits);
   if(lots>= lot_max)
      lots = lot_max;
   if(lots<= lot_min)
      lots = lot_min;
   return(lots);
  }
//+------------------------------------------------------------------+

you should remove the static literal for the "OrderTime" variable,because it will store last value,next time it will have the previous value,then the "if else" condition

wont be called.

So you can call this function anywhere in code.either first of the code in OnTick() function,or inside OrderSend() function.

Regards.

 
Mehrdad Jeddi:

Hi,

First you should check this condition with lot step,not min lot,

The correct version of the function should be such :

you should remove the static literal for the "OrderTime" variable,because it will store last value,next time it will have the previous value,then the "if else" condition

wont be called.

So you can call this function anywhere in code.either first of the code in OnTick() function,or inside OrderSend() function.

Regards.

Dear @Mehrdad Jeddi

Thanks so much for your reply, But still doesn't work, corrected code is :

double subLotSize()
{
    double          lots             = 0;
    int             TotalClosedOrder = 0;
    static int      WonOrderCount;
    static datetime OrderTime;
    double          lot_max  = MarketInfo(Symbol(), MODE_MAXLOT);
    double          lot_min  = MarketInfo(Symbol(), MODE_MINLOT);
    double          lotStep  = MarketInfo(Symbol(), MODE_LOTSTEP);
    double          contract = MarketInfo(Symbol(), MODE_LOTSIZE);
    if (lotStep == 0.01)
        LotDigits = 2;
    if (lotStep == 0.1)
        LotDigits = 1;
    if (lotStep == 1)
        LotDigits = 0;
    if (!UseLotMultiplier)
        lots = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
    else
    {
        for(int h=OrdersHistoryTotal()-1; h>=0; h--)
        {
         if(OrderSelect(h,SELECT_BY_POS,MODE_HISTORY))
           {
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
              {
               if(OrderType()==OP_BUY || OrderType()==OP_SELL)
                  TotalClosedOrder++;
               if(TotalClosedOrder>=1)
                  break;
              }
           }
        }
        if (TotalClosedOrder == 0)
            lots = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
        else if (OrderSelect(OrdersHistoryTotal() - 1, SELECT_BY_TICKET, MODE_HISTORY))
        {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
            {
                    if (WonOrderCount >= StartOver)
                    {
                        lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
                        WonOrderCount = 0;
                    }
                    else if (OrderProfit() + OrderCommission() + OrderSwap() <= 0)
                    {
                        lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
                        WonOrderCount = 0;
                    }
                    else if (OrderProfit() + OrderCommission() + OrderSwap() > 0)
                    {
                        lots = NormalizeDouble(OrderLots() * LotMultiplier, LotDigits);
                        WonOrderCount++;
                    }
            }
        }
        else
            Print("OrderSelect failed error code is", GetLastError());
    }
    return(NormalizeLots(lots));
}

//+------------------------------------------------------------------+
double NormalizeLots(double lots)
{
    double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    double minLot  = MarketInfo(Symbol(), MODE_MINLOT);
    double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
    lots           = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot)
        lots = minLot;
    if (lots > maxLot)
        lots = maxLot;
    return(lots);
}




 

So my previous code is working on my side:

lot

 
Mehrdad Jeddi:

So my previous code is working on my side:


Mehrdad JAAN,

I figured it out as you told me above, thanks bro, NOKARAM!


double AutoLotSize()
{
    double     lots             = 0;
    int        TotalClosedOrder = 0;
    static int WonOrderCount;
    double     lot_max  = MarketInfo(Symbol(), MODE_MAXLOT);
    double     lot_min  = MarketInfo(Symbol(), MODE_MINLOT);
    double     lotStep  = MarketInfo(Symbol(), MODE_LOTSTEP);
    double     contract = MarketInfo(Symbol(), MODE_LOTSIZE);
    if (lotStep == 0.01)
        LotDigits = 2;
    if (lotStep == 0.1)
        LotDigits = 1;
    if (lotStep == 1)
        LotDigits = 0;
    if (!UseLotMultiplier)
        lots = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
    else
    {
        for (int h = OrdersHistoryTotal() - 1; h >= 0; h--)
        {
            if (OrderSelect(h, SELECT_BY_POS, MODE_HISTORY))
            {
                if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
                {
                    if (OrderType() == OP_BUY || OrderType() == OP_SELL)
                        TotalClosedOrder++;
                    if (TotalClosedOrder >= 1)
                        break;
                }
            }
        }
        if (TotalClosedOrder == 0)
            lots = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
        else if (OrderSelect(OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY))
        {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
            {
                if (WonOrderCount == StartOver)
                {
                    lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
                    WonOrderCount = 0;
                }
                else if (OrderProfit() + OrderCommission() + OrderSwap() <= 0)
                {
                    lots          = NormalizeDouble(AccountBalance() * Risk / 100 * AccountLeverage() / contract, LotDigits);
                    WonOrderCount = 0;
                }
                else if (OrderProfit() + OrderCommission() + OrderSwap() > 0)
                {
                    lots = NormalizeDouble(OrderLots() * LotMultiplier, LotDigits);
                    WonOrderCount++;
                }
            }
        }
        else
            Print("OrderSelect failed error code is", GetLastError());
    }
    return(NormalizeLots(lots));
}

double NormalizeLots(double lots)
{
    double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    double minLot  = MarketInfo(Symbol(), MODE_MINLOT);
    double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
    lots = MathRound(lots / lotStep) * lotStep;
    if (lots < minLot)
        lots = minLot;
    if (lots > maxLot)
        lots = maxLot;
    return(lots);
}
 

Good,You're welcome,

Have a nice weekend.

Reason: