Lot size - page 3

 
Tan Chee Ho:
what if make use of the monthly candle opening. every time new monthly candle created, then take the balance of that point. Will that works?
datetime CurMonthCandle = iTime(NULL,PERIOD_MN1,0);
   datetime MonthCandle;
   double AccBal;
   
   if(MonthCandle != CurMonthCandle){
   AccBal=AccountBalance();
   MonthCandle=CurMonthCandle;
   }

Lots=(((AccBal() * MaximumRisk / 100) / (StopLoss)));
I am also new to coding MQL4, many to learn. I am not sure this code above will work. but the idea is to update the Account Balance every time new monthly candle created. Please correct me if this code is no good. 
 

Hi,

please try my last post (yesterday 16:25) I have tested it and it works really fine in my environment.

Best regards,

 
Werner Klehr:

Hi there,

i have changed the function for you and now it saves the date of the last update into the file:

I hope, this one works better for you.

Best regards,

I tried but it does not work, I think there is a problem in my code :-(

#property copyright "Copyright © 2021"
#property link      "http://www.mql5.com/"
#property description "Author: STEEVE NIRINA"


#define MAGICMA  20131111
//--- Inputs
int Injection;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =20;
input int    MovingShift   =0;
input string SL_COMMENT    ="Set sl to TRUE for automated the SL value";
input bool   sl            =true;
input double SL_initial    =500;
string EA_Comment="Steeve_Nirina_EA";
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }

//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma12;
   double ma4;
   int    res;
   double lots,Lots;
   double SL;
   double TP;
   double ma;
   double closeM5;
   double _sl;
   
   
   //END
   
   //TIME FILTER
   string TradeStartTime = "03:30";
   string TradeStopTime = "23:00";
   //END TIME FILTER

//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;

//--- SELL 
   ma12=iMA(NULL,PERIOD_M15,12,0,MODE_EMA,PRICE_MEDIAN,1);
   ma4=iMA(NULL,PERIOD_M15,4,0,MODE_EMA,PRICE_TYPICAL,1);//--- sell conditions
   if(TimeCurrent()>StrToTime(TradeStartTime) && TimeCurrent()<StrToTime(TradeStopTime)
     && (ma4<ma12))
     {
      ma=iMA(NULL,PERIOD_M15,1,0,MODE_EMA,PRICE_TYPICAL,1);
      closeM5=iClose(Symbol(), PERIOD_M15, 1);
      if(sl==TRUE){
         if(MathRound(closeM5-ma)/Point<=500)
            {_sl=600;}
         else _sl=MathRound(closeM5-ma)/Point;
      double StopLoss=1.5*_sl*Point;
      double TakeProfit=1*_sl*Point;
      if (_sl == 0) {SL = 0;} else{SL = Bid + 1.5*_sl*Point;}
      if (_sl == 0){ TP = 0;} else{TP = Bid - 1*_sl*Point;}
      }
    if(sl==FALSE) {
                    _sl=SL_initial;
                    if (_sl == 0) {SL = 0;} else{SL = Bid + 1.5*_sl*Point;}
                    if (_sl == 0){ TP = 0;} else{TP = Bid - 1.5*_sl*Point;}
      StopLoss=1.5*_sl*Point;
      TakeProfit=1.5*_sl*Point;
                   }
      Lots=(((AccountBalance() * MaximumRisk / 100) / (StopLoss)));
      lots=Lots;
      res=OrderSend(Symbol(),OP_SELL,NormalizeLots(lots,Symbol()),Bid,3,SL,TP,EA_Comment,MAGICMA,0,Red);
      return;
     }
      //--- BUY
   if(TimeCurrent()>StrToTime(TradeStartTime) && TimeCurrent()<StrToTime(TradeStopTime)
     && (ma4>ma12))
     {
      ma=iMA(NULL,PERIOD_M15,1,0,MODE_EMA,PRICE_TYPICAL,1);
      closeM5=iClose(Symbol(), PERIOD_M15, 1);
      if(sl==TRUE){
         if(MathRound(ma-closeM5)/Point<=500)
            {_sl=600;}
         else _sl=MathRound(ma-closeM5)/Point;
      StopLoss=1.5*_sl*Point;
      TakeProfit=1.5*_sl*Point;
      Alert(_sl);
      if (_sl == 0) {SL = 0;} else{SL = Ask - 1.5*_sl*Point;}
      if (_sl == 0){ TP = 0;} else{TP = Ask + 1.5*_sl*Point;}
      }
    if(sl==FALSE) {
                    _sl=SL_initial;
                    if (_sl == 0) {SL = 0;} else{SL = Ask - 1.5*_sl*Point;}
                    if (_sl == 0){ TP = 0;} else{TP = Ask + 1.5*_sl*Point;}
      StopLoss=1.5*_sl*Point;
      TakeProfit=1.5*_sl*Point;
                   }
      Lots=(((AccountBalance() * MaximumRisk / 100) / (StopLoss)));
      lots=Lots;
      res=OrderSend(Symbol(),OP_BUY,NormalizeLots(lots,Symbol()),Ask,3,SL,TP,EA_Comment,MAGICMA,0,Blue);
      return;
     }
//---
  }

//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   GetInitAccount();
//---
int maxDuration = 15 * 60; 
   for(int pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
    OrderSelect(pos, SELECT_BY_POS) &&  OrderSymbol()== Symbol())
    {
      int duration = TimeCurrent() - OrderOpenTime();
      if (duration >= maxDuration) OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(),3*Point);
    }
//---
  }

//make lots to right format
double NormalizeLots(double _lots,string pair="")
  {
   if(pair=="") pair=Symbol();
   double  lotStep=MarketInfo(pair,MODE_LOTSTEP),
   minLot=MarketInfo(pair,MODE_MINLOT);
   _lots=MathRound(_lots/lotStep)*lotStep;
   if(_lots<MarketInfo(pair,MODE_MINLOT)) _lots=MarketInfo(pair,MODE_MINLOT);
   if(_lots>MarketInfo(pair,MODE_MAXLOT)) _lots=MarketInfo(pair,MODE_MAXLOT);
   return(_lots);
  }

double GetInitAccount()
{
        int FileHandle;
        string FileName = "MyAccountBalance.dat";
        double InitAccount = 0.0;
        double TmpValue = 0.0;
        int LastMonth = 0;

        FileHandle = FileOpen(FileName, FILE_READ | FILE_BIN); 
        if (FileHandle != INVALID_HANDLE)
        {
                TmpValue    = FileReadDouble(FileHandle, DOUBLE_VALUE);
                InitAccount = FileReadDouble(FileHandle, DOUBLE_VALUE);
                FileClose(FileHandle);

                LastMonth = TimeMonth((datetime) TmpValue);
        }

        if ((LastMonth != TimeMonth(TimeCurrent())) || (LastMonth == 0))
        {
                FileHandle = FileOpen(FileName, FILE_WRITE | FILE_BIN); 
                if (FileHandle == INVALID_HANDLE)
                {
                        Print("FileOpen failed / FileName: " + FileName + " / Error: " + IntegerToString(GetLastError()));
                        return(-1.0);
                }

                InitAccount = AccountBalance();

                FileWriteDouble(FileHandle, (double) TimeCurrent());    
                FileWriteDouble(FileHandle, InitAccount);
                FileClose(FileHandle);
        }

        return(InitAccount);
}
 
SteeveNi25: however it shoud get the value of TP once per month
bool isNewMonth(){
    static int monthCurrent  = 0;
           int monthPrevious = monthCurrent;
               monthCurrent  = Month();
   return monthCurrent != monthPrevious;
}
 

Hi Steeve,

the GetInitAccount() function returns the value of the Account on the first day of the month (or

the first day with a tick, when the first day is a Sunday) You should put the return value of the function
into a double variable and you can print the value like this:

double InitAccount = GetInitAccount();

Print("InitAccount: ", DoubleToString(InitAccount));

It is not a good idea to call the GetInitAccount every tick, cause it costs a little bit of performance to
open the file and read it. You can use the isNewMonth function form William or you can call the function
only, when you open an order.

Second point: At the calculaton of the lot-size you use the AccountBalance() function, whitch
returns the current balance and not the Balane at the first day of the month.

Lots=(((AccountBalance() * MaximumRisk / 100) / (StopLoss)));

Instead of this you could use the GetInitAccount function like this:

Lots=(((GetInitAccount() * MaximumRisk / 100) / (StopLoss)));

I hope, this will help you ...

Best regards,

 
Werner Klehr:

Hi Steeve,

the GetInitAccount() function returns the value of the Account on the first day of the month (or

the first day with a tick, when the first day is a Sunday) You should put the return value of the function
into a double variable and you can print the value like this:

It is not a good idea to call the GetInitAccount every tick, cause it costs a little bit of performance to
open the file and read it. You can use the isNewMonth function form William or you can call the function
only, when you open an order.

Second point: At the calculaton of the lot-size you use the AccountBalance() function, whitch
returns the current balance and not the Balane at the first day of the month.

Instead of this you could use the GetInitAccount function like this:

I hope, this will help you ...

Best regards,

Lots=(((GetInitAccount() * MaximumRisk / 100) / (StopLoss)));

if the "GetInitAccount()" function is called at here, wouldn't it also run this function quite frequently?

 

Hi Steeve,

in this case the "GetInitAccount()" function is only called before you open an order and that
shouldn't be as often as every tick?

Best regards

 
Werner Klehr:

Hi Steeve,

in this case the "GetInitAccount()" function is only called before you open an order and that
shouldn't be as often as every tick?

Best regards

thanks

 
Werner Klehr:

Hi Steeve,

the GetInitAccount() function returns the value of the Account on the first day of the month (or

the first day with a tick, when the first day is a Sunday) You should put the return value of the function
into a double variable and you can print the value like this:

It is not a good idea to call the GetInitAccount every tick, cause it costs a little bit of performance to
open the file and read it. You can use the isNewMonth function form William or you can call the function
only, when you open an order.

Second point: At the calculaton of the lot-size you use the AccountBalance() function, whitch
returns the current balance and not the Balane at the first day of the month.

Instead of this you could use the GetInitAccount function like this:

I hope, this will help you ...

Best regards,

Thanks so much sir It works very well now

 
Werner Klehr:

Hi Steeve,

the GetInitAccount() function returns the value of the Account on the first day of the month (or

the first day with a tick, when the first day is a Sunday) You should put the return value of the function
into a double variable and you can print the value like this:

It is not a good idea to call the GetInitAccount every tick, cause it costs a little bit of performance to
open the file and read it. You can use the isNewMonth function form William or you can call the function
only, when you open an order.

Second point: At the calculaton of the lot-size you use the AccountBalance() function, whitch
returns the current balance and not the Balane at the first day of the month.

Instead of this you could use the GetInitAccount function like this:

I hope, this will help you ...

Best regards,

It works well sir but when I backtest on JANUARY, it can not get the current balance

#property copyright "Copyright © 2021"
#property link      "http://www.mql5.com/"
#property description "Author: STEEVE NIRINA"


#define MAGICMA  20131111
//--- Inputs
int Injection;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =20;
input int    MovingShift   =0;
input string SL_COMMENT    ="Set sl to TRUE for automated the SL value";
input bool   sl            =true;
input double SL_initial    =500;
string EA_Comment="Steeve_Nirina_EA";
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }

//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma12;
   double ma4;
   int    res;
   double lots,Lots;
   double SL;
   double TP;
   double ma;
   double closeM5;
   double _sl;
   double InitAccount=GetInitAccount();
   
   
   //END
   
   //TIME FILTER
   string TradeStartTime = "03:30";
   string TradeStopTime = "23:00";
   //END TIME FILTER

//--- go trading only for first tiks of new bar
   if(Volume[0]>1) return;

//--- SELL 
   ma12=iMA(NULL,PERIOD_M15,12,0,MODE_EMA,PRICE_MEDIAN,1);
   ma4=iMA(NULL,PERIOD_M15,4,0,MODE_EMA,PRICE_TYPICAL,1);//--- sell conditions
   if(TimeCurrent()>StrToTime(TradeStartTime) && TimeCurrent()<StrToTime(TradeStopTime)
     && (ma4<ma12))
     {
      ma=iMA(NULL,PERIOD_M15,1,0,MODE_EMA,PRICE_TYPICAL,1);
      closeM5=iClose(Symbol(), PERIOD_M15, 1);
      if(sl==TRUE){
         if(MathRound(closeM5-ma)/Point<=500)
            {_sl=600;}
         else _sl=MathRound(closeM5-ma)/Point;
      double StopLoss=1.5*_sl*Point;
      double TakeProfit=1*_sl*Point;
      if (_sl == 0) {SL = 0;} else{SL = Bid + 1.5*_sl*Point;}
      if (_sl == 0){ TP = 0;} else{TP = Bid - 1*_sl*Point;}
      }
    if(sl==FALSE) {
                    _sl=SL_initial;
                    if (_sl == 0) {SL = 0;} else{SL = Bid + 1.5*_sl*Point;}
                    if (_sl == 0){ TP = 0;} else{TP = Bid - 1.5*_sl*Point;}
      StopLoss=1.5*_sl*Point;
      TakeProfit=1.5*_sl*Point;
                   }
      Print("InitAccount: ", DoubleToString(InitAccount));
      Lots=(((GetInitAccount() * MaximumRisk / 100) / (StopLoss)));
      lots=Lots;
      res=OrderSend(Symbol(),OP_SELL,NormalizeLots(lots,Symbol()),Bid,3,SL,TP,EA_Comment,MAGICMA,0,Red);
      return;
     }
      //--- BUY
   if(TimeCurrent()>StrToTime(TradeStartTime) && TimeCurrent()<StrToTime(TradeStopTime)
     && (ma4>ma12))
     {
      ma=iMA(NULL,PERIOD_M15,1,0,MODE_EMA,PRICE_TYPICAL,1);
      closeM5=iClose(Symbol(), PERIOD_M15, 1);
      if(sl==TRUE){
         if(MathRound(ma-closeM5)/Point<=500)
            {_sl=600;}
         else _sl=MathRound(ma-closeM5)/Point;
      StopLoss=1.5*_sl*Point;
      TakeProfit=1.5*_sl*Point;
      Alert(_sl);
      if (_sl == 0) {SL = 0;} else{SL = Ask - 1.5*_sl*Point;}
      if (_sl == 0){ TP = 0;} else{TP = Ask + 1.5*_sl*Point;}
      }
    if(sl==FALSE) {
                    _sl=SL_initial;
                    if (_sl == 0) {SL = 0;} else{SL = Ask - 1.5*_sl*Point;}
                    if (_sl == 0){ TP = 0;} else{TP = Ask + 1.5*_sl*Point;}
      StopLoss=1.5*_sl*Point;
      TakeProfit=1.5*_sl*Point;
                   }
      Print("InitAccount: ", DoubleToString(InitAccount));
      Lots=(((GetInitAccount() * MaximumRisk / 100) / (StopLoss)));
      lots=Lots;
      res=OrderSend(Symbol(),OP_BUY,NormalizeLots(lots,Symbol()),Ask,3,SL,TP,EA_Comment,MAGICMA,0,Blue);
      return;
     }
//---
  }

//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
//---
int maxDuration = 15 * 60; 
   for(int pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
    OrderSelect(pos, SELECT_BY_POS) &&  OrderSymbol()== Symbol())
    {
      int duration = TimeCurrent() - OrderOpenTime();
      if (duration >= maxDuration) OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(),3*Point);
    }
//---
  }

//make lots to right format
double NormalizeLots(double _lots,string pair="")
  {
   if(pair=="") pair=Symbol();
   double  lotStep=MarketInfo(pair,MODE_LOTSTEP),
   minLot=MarketInfo(pair,MODE_MINLOT);
   _lots=MathRound(_lots/lotStep)*lotStep;
   if(_lots<MarketInfo(pair,MODE_MINLOT)) _lots=MarketInfo(pair,MODE_MINLOT);
   if(_lots>MarketInfo(pair,MODE_MAXLOT)) _lots=MarketInfo(pair,MODE_MAXLOT);
   return(_lots);
  }

double GetInitAccount()
{
        int FileHandle;
        string FileName = "MyAccountBalance.dat";
        double InitAccount = 0.0;
        double TmpValue = 0.0;
        int LastMonth = 0;

        FileHandle = FileOpen(FileName, FILE_READ | FILE_BIN); 
        if (FileHandle != INVALID_HANDLE)
        {
                TmpValue    = FileReadDouble(FileHandle, DOUBLE_VALUE);
                InitAccount = FileReadDouble(FileHandle, DOUBLE_VALUE);
                FileClose(FileHandle);

                LastMonth = TimeMonth((datetime) TmpValue);
        }

        if ((LastMonth != TimeMonth(TimeCurrent())) || (LastMonth == 0))
        {
                FileHandle = FileOpen(FileName, FILE_WRITE | FILE_BIN); 
                if (FileHandle == INVALID_HANDLE)
                {
                        Print("FileOpen failed / FileName: " + FileName + " / Error: " + IntegerToString(GetLastError()));
                        return(-1.0);
                }

                InitAccount = AccountBalance();

                FileWriteDouble(FileHandle, (double) TimeCurrent());    
                FileWriteDouble(FileHandle, InitAccount);
                FileClose(FileHandle);
        }

        return(InitAccount);
}