MT4 Broker - Units instead of lots? (Does this effect my code?)

 

Quick one. Broker ILQ is allowing me to trade with units (right the way down to just 1 unit!) on a very small account of $1k to forward test in a life environment my EA. I would appreciate someone to just simply confirm if I need to make changes to the following, to cater for this type of broker. (Where you would usually put a lot value in MT4, i.e. 0.40, you would put 40,000... notional value) -- See the arrows. Forget about the braces and indenting if thats ok, as I have not posted up the entire thing....

Thanks in advance!

void OrderEntry(int direction)
{
   //determine amount to risk on this trade based on RiskPercent Above.
   double LotSize = 0; 
   double Equity = AccountBalance();
   double RiskedAmount = Equity*RiskPercent*0.01;  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

   
   double ATR_Pad = iATR(NULL,60,14,1)/2; 
   double Buy_Pad = NormalizeDouble(ATR_Pad,Digits);
   double Sell_Pad = NormalizeDouble(ATR_Pad,Digits);
   
   //Get Highest Price in our lookback range and set buy price above it.
   int iTBT = iBarShift(NULL,60, triggerBarTime, true),
   iHH = iHighest(NULL,60, MODE_HIGH, iTBT + CandlesBeforeBiasObtained, 0);
   double Buy_Here = High[iHH] + Buy_Pad;
   double buyPrice= NormalizeDouble(Buy_Here,Digits);

   //Get Lowest Price in our lookback range and set sell price below it.
   int iTBT_1 = iBarShift(NULL, 60, triggerBarTime, true),
   iLL = iLowest(NULL, 60, MODE_LOW, iTBT_1 + CandlesBeforeBiasObtained, 0);
   double Sell_Here=Low[iLL] - Sell_Pad;
   double sellPrice= NormalizeDouble(Sell_Here,Digits);
   
   //Stop calculations.    
   double ATR = iATR(NULL,60,14,1);
   double MA = iMA(NULL,60,MA_Period,0,1,0,1);
   double BuyStopPriceMath = MA - ATR;
   double SellStopPriceMath = MA + ATR;
   double BuyStopPrice = NormalizeDouble(BuyStopPriceMath,Digits);
   double SellStopPrice = NormalizeDouble(SellStopPriceMath,Digits);


   //get our buystop price from below the ma and our takeprofit based on our r:r ratio.
   double pips_to_bsl=buyPrice-BuyStopPrice;
   double buy_tp_price=(pips_to_bsl*RewardRatio)+buyPrice;
   double buy_takeprofit_price= NormalizeDouble(buy_tp_price, Digits);

   //get our sellstop price from below the ma and our takeprofit based on our r:r ratio.
   double pips_to_ssl=SellStopPrice-sellPrice;
   double sell_tp_price=sellPrice-(pips_to_ssl*RewardRatio);
   double sell_takeprofit_price= NormalizeDouble(sell_tp_price, Digits);
   


//+-------------------------------------------------------------------------------------+
//| Order Buy Function                                                                  |
//+-------------------------------------------------------------------------------------+   

//Place a pending buystop if no orders exists.. pending or otherwise.
if(direction==0)
{ 
      double btp=buy_takeprofit_price;
      double Min_Lot = MarketInfo(Symbol(),MODE_MINLOT);
      double Lot_Step = MarketInfo(Symbol(),MODE_LOTSTEP);
 
      double BuyLotSize =(RiskedAmount/(pips_to_bsl/pips))/10;
      double Lots = NormalizeDouble(BuyLotSize,2);
      LotSize = MathFloor(Lots/Lot_Step)*Lot_Step; //<<<<<<<<<<<<<<<<<<<<<<
      int PositionIndex1;   
      int TotalNumberOfOrders1;   
      TotalNumberOfOrders1 = OrdersTotal();  
      static double Stored_BuyPrice;

      if(OpenOrdersThisPair(Symbol())==0)
         {
         int BuyTicketOrder = OrderSend(Symbol(),OP_BUYSTOP,LotSize,buyPrice,3,BuyStopPrice,btp,NULL,MagicNumber,0,Green);
         if(BuyTicketOrder == -1)Print("First Buy Order Last Error = ",GetLastError(), " On: ", Symbol());
         if(BuyTicketOrder > 0)Print("FIRST BUY ORDER PLACED: ", Symbol());//DoubleToStr(LotSize,Digits)," Entry Price: ",DoubleToStr(buyPrice,Digits),
         } 
 

I can't see anywhere that a value is assigned to the variable pips, so have no idea what this does

double BuyLotSize =(RiskedAmount/(pips_to_bsl/pips))/10;
 
GumRai:

I can't see anywhere that a value is assigned to the variable pips, so have no idea what this does


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   switch(Trail_Type)
     {
      case 0:break;
      case 1:Use_MA_Trail=True;break;
      case 2:UseTrailingStop=True;break;
      case 3:UseCandleTrail=True;break;
      default:Use_MA_Trail=True;break;
     }
   double ticksize=MarketInfo(Symbol(),MODE_TICKSIZE);
   if(ticksize==0.00001 || ticksize==0.001) 
      pips=ticksize*10;
   else pips=ticksize;
   return(0);
  }
 
Could someone be kind enough to simply check if my math is correct if I changed the following for notional feed broker (0.01 || 1000)???
double BuyLotSize =(RiskedAmount/(pips_to_bsl/pips))/10;  <<<<< Currently in use for Lots (0.01)

double BuyLotSize =(RiskedAmount/(pips_to_bsl/pips))*1000;   <<<<< New - Gives me a notional unit value

//This would look like (200 / (50))*1000 = 4,000 notional lots (0.40)
///////////////////////($risk / pips to stop)*1000/////////////////// 
 

From my understanding, using

double BuyLotSize =(RiskedAmount/(pips_to_bsl/pips))/10;  <<<<< Currently in use for Lots (0.01)

double BuyLotSize =(RiskedAmount/(pips_to_bsl/pips))*1000;   <<<<< New - Gives me a notional unit value

assumes that a one pip move will always be valued at 10 units of your account currency, which I think will only be true when your account currency is the same as the 2nd part of the currency pair. Ie if your account currency is USD, then it will be true with EURUSD, GBPUSD, but not with USDCHF.

I believe that you will have to use TickSize and TickValue to calculate the proper lot size.

as a matter of interest, paste this into a script and see what the result is. Mind you if 1 Lot is 1 unit, I would think that TickValue, would be so small that you would have to multiply it first to be able to see it.

string ts= DoubleToStr(MarketInfo(Symbol(),MODE_TICKSIZE),Digits);
 string tv= DoubleToStr(MarketInfo(Symbol(),MODE_TICKVALUE),Digits);
 Alert("TickSize= ",ts,", TickValue=",tv);
 
GumRai:

From my understanding, using

assumes that a one pip move will always be valued at 10 units of your account currency, which I think will only be true when your account currency is the same as the 2nd part of the currency pair. Ie if your account currency is USD, then it will be true with EURUSD, GBPUSD, but not with USDCHF.

I believe that you will have to use TickSize and TickValue to calculate the proper lot size.

as a matter of interest, paste this into a script and see what the result is. Mind you if 1 Lot is 1 unit, I would think that TickValue, would be so small that you would have to multiply it first to be able to see it.


I've pasted that script and its returned "TickSize = 0.00001, TickValue = 0.00001".

I'm sure you're right with regards to the account denomination and the currency pair traded. What are your thoughts on how I can properly adjust the lot calculation to cater for different denominations? I.e. if I just dropped my EA onto a USDCHF chart where-by the account was denominated in GBP, it could just automatically factor all these variables in? I'm not entirely certain my math is correct for this situation?

Yup, 1 lot is 1 unit to confirm too.

Would this not make sense, irrespective of the account denomination and the pair traded? (Sorry if I am being a complete moron!)

double BuyLotSize =(RiskedAmount/(pips_to_bsl/pips))*10000; ?
 

You could try this

     double risk_amount = AccountEquity( )*RiskPercent/100;
         double Lot_Step = MarketInfo(Symbol(), MODE_LOTSTEP);
         double ts = MarketInfo(Symbol(), MODE_TICKSIZE);
         double tv = MarketInfo(Symbol(), MODE_TICKVALUE);
         
         double loss_for_1_lot = pips_to_bsl/ ts * tv ;
         Alert(loss_for_1_lot);
         double LotSize = MathFloor( risk_amount / loss_for_1_lot/ Lot_Step) * Lot_Step ;
         Alert(LotSize);
         
         
      static datetime LSAlert;
      if(LotSize < MarketInfo(Symbol(), MODE_MINLOT))
              {
              if(Time[0]!=LSAlert)
                {
                Alert (Symbol()," Calculated Lotsize is too small to trade") ;
                LSAlert = Time[0];
                }
              }
 
GumRai:

You could try this


Ah nice - I see what you've done there. I'll have a little play with what you've written and confirm it! Thank you kindly!

If you wouldn't mind, I assume I am right in saying that I essentially need to change my lot formula if my account was denominated in GBP and I was trading cross currency's? I am concerned that the correct lot sizing is not actually being done based upon what I've written. It only assumes that the base currency is a USD and the trading account is denominated in USD too... right? (trying to work out how I tweak the code to facilitate a rule based formula' where-by the code knows the trading account denomination and the currency pair traded.)

Thanks!

 

Just to confirm, you're code you've pasted above is working really well! Thank you very much for your time in helping out :)

How would I factor in the denomination of the account and the corresponding pair traded to make sure the position sizing is correct?

 
DomGilberto:

Just to confirm, you're code you've pasted above is working really well! Thank you very much for your time in helping out :)

How would I factor in the denomination of the account and the corresponding pair traded to make sure the position sizing is correct?


Tickvalue is the value of a 1 tick move, expressed in the account currency, so the calculation should work for all pairs and any account currency.

Just test it to be sure.

 
GumRai:


Tickvalue is the value of a 1 tick move, expressed in the account currency, so the calculation should work for all pairs and any account currency.

Just test it to be sure.


Yup, you've nailed it! Thank you very kindly for your time in helping me :D - Really appreciate it. Works perfectly :) (And obviously for any broker feed notional or lots!)