# Lot size - page 3

229

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.
225

Hi,

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

Best regards,

62

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 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)
{
//---
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
{
if(OrderType()==OP_SELL) sells++;
}
}
//--- return orders volume
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
//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
&& (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;
}
&& (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;
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;
return;
}
//---
}

//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
//--- check for history and trading
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)
{
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);
}```
25060

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;
}```
225

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)));`

Best regards,

229

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:

Best regards,

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

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

225

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

229

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

62

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:

Best regards,

Thanks so much sir It works very well now

62

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:

Best regards,

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

```#property copyright "Copyright © 2021"
#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)
{
//---
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
{
if(OrderType()==OP_SELL) sells++;
}
}
//--- return orders volume
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
//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
&& (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;
}
&& (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;
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;
return;
}
//---
}

//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
//--- check for history and trading
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)
{
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);
}```