How to calculate % of free margin for opening order?

 

I am currently in the process of studying MQL4, but I'll be honest with you - I suck at math!

Could someone be so kind as to explain to me this block of code?

//...
string Symb=Symbol();
double Prots=0.07; // Percent of free margin
//...

//--------------------------------------------------------------- 7 --
   // Order value
   RefreshRates();                              // Refresh rates
   Min_Lot=MarketInfo(Symb,MODE_MINLOT);        // Minimal number of lots 
   Free   =AccountFreeMargin();                 // Free margin
   One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);// Price of 1 lot
   Step   =MarketInfo(Symb,MODE_LOTSTEP);       // Step is changed
 
   if (Lots > 0)                                // If lots are set,
      Lts =Lots;                                // work with them
   else                                         // % of free margin
      Lts=MathFloor(Free*Prots/One_Lot/Step)*Step;// For opening
 
   if(Lts < Min_Lot) Lts=Min_Lot;               // Not less than minimal
   if (Lts*One_Lot > Free)                      // Lot larger than free margin
     {
      Alert(" Not enough money for ", Lts," lots");
      return;                                   // Exit start()
     }
//--------------------------------------------------------------- 8 --

Specifically this calculation:

Lts=MathFloor(Free*Prots/One_Lot/Step)*Step;

1. Why is MathFloor used? What does it do?

2. I understand Free*Prots part = certain percentage of Free Margin,

3. but why do you divide by One_Lot then by Step, and then Multiply it all by step?


Sorry I know this is very basic. I don't know if I'm just tired or what not, but I just don't have the brain power at the moment to figure this out.

If you can briefly explain the above calculation to me I would be eternally grateful!


P.S - The above is an example from the MQL4 Book. I tried to run just that particular block of code as a script on MetaTrader4 but I got an error: "zero divide".

Apparently Minimum Lots = 0 And Lot Step = 0 with my broker (FXOpen). So the example script above would not work in "real world" conditions. Is this right or am I missing something here?

 

Be careful when calculating this. you can empty your account real quick if the market doesn't go your way. I use a standard deviation channel to calculate what lot size to use.

I calculate the lot size by where the lower value of the (Bid - lower chanel) / AccountFreeMargin. From this I work out the lot size. I make sure the lower channel line has not been hit recently as a margin of safty.

If you like I will post the code snippet. I use this code in an EA that returned 51% last week (Live Account) so I know it works. The thing that you have to plan carfully is the deviation and duration of the channels.

 

All lot sizes must be a multiple of step and at least minlot. Min lot could be 0.1 and step 0.01. Therefor lot sizes must be 0.10 0.11 0.12 etc

Math floor returns the smallest integer so 1.234/0.01 = 123.4 floor=123 123*0.01=1.23 lotsize as a multiple of lot step.

if lot step was 0.05 then 1.234/0.05 = 24.68 floor=24 and 24*0.05=1.20 lots. This is why you can NOT use normalizeDouble which assumes lotstep is a multiple of 10 (0.1/0.01)

if FXOpen are not supplying proper values complain to them. Their server is misconfigured.

 
mbirrell:

Be careful when calculating this. you can empty your account real quick if the market doesn't go your way. I use a standard deviation channel to calculate what lot size to use.

I calculate the lot size by where the lower value of the (Bid - lower chanel) / AccountFreeMargin. From this I work out the lot size. I make sure the lower channel has not been hit recently as a margin of safty.

If you like I will post the code snippet. I use this code in an EA that returned 51% last week (Live Account) so I know it works. The thing that you have to plan carfully is the deviation and duration of the channels.


Hi mbirrel,

First of all congratulations on your success in trading! And thank you for taking the time to answer my post.

Yes, I would love to take a look at your code snippet. Plus, could you please briefly explain what you are referring to when you mention 'lower channel' ?

Thanks!!

 
WHRoeder:

All lot sizes must be a multiple of step and at least minlot. Min lot could be 0.1 and step 0.01. Therefor lot sizes must be 0.10 0.11 0.12 etc

Math floor returns the smallest integer so 1.234/0.01 = 123.4 floor=123 123*0.01=1.23 lotsize as a multiple of lot step.

if lot step was 0.05 then 1.234/0.05 = 24.68 floor=24 and 24*0.05=1.20 lots. This is why you can NOT use normalizeDouble which assumes lotstep is a multiple of 10 (0.1/0.01)

if FXOpen are not supplying proper values complain to them. Their server is misconfigured.

Thank you for your reply and explanation. I think I got the hang of it now!!

Strange about FXOpen having a misconfigured server... they're a pretty big broker supposedly. I'll have to contact them about it!

 

Sorry I ment lower channel line. You have 3 lines in total - upper, mid and lower. I will post the code tonight when I get home. If you are going to use it make sure you thoughly understand what it is doing. Be warned I do not use stop loss with this system and rely entirly that the lower channel line does not get hit. Using this technique you should NEVER have all your hard earned money in the account and be prepaired to lose everything that you put in the account if you get it wrong. Make sure you have a good risk management stratergy.

 

Here is the code snippet - Obviously there are other parts that tie into it that I haven't included. I will tell you that there is a custom indicator that the code calls as you can probably see. You can download the indicator from this web site if you do a search. I have also changed the default values of the custom indicator so make sure you change them to best suit your needs.


void CalcLotSize()
{
 double Pip = 0.0001;
 double AUDValue = Bid;
 
 double Margin = 0;
 double LotSize = 0;
 int BarsToCount = 6000;
 double PipRange = (AUDValue - iCustom(NULL, 0,"!LinRegrBuf",true,BarsToCount,1,0))* 10000;

 for(int i=100;i>0.1;i=i-0.1)
   {
   for(int x=1;x>PipRange;i++)
      {
      LotValue = (Pip/AUDValue) * AccountLeverage();
      Margin = Margin + (LotValue * i);
      AUDValue = AUDValue - Pip; 
      }
   if(Margin < AccountFreeMargin()/MaxOpenOrders)
      {
      LotSize = i;
      return;
      }
   AUDValue = Bid;
   Margin = 0;
   }
}
Reason: