EA doesn't calculate lot size on AUS cfds like it does on US cfds, currencies and cryptos. - page 2

 
Fernando Carreiro #:

Please note that according to your table, WES.asx is reporting a Tick Value of 0.0, which is invalid and will mess with your calculation. Your broker is not reporting it correctly.

Here is my take on the script:

Thanks so much, very helpful.  Could you please explain this to me?  I've added the following code to workout the 'proposed risk ($)' of the position using the lotsize calculated from the above script.

double risk_amount = oSymbol.Point() * dbVolume * ((i_dbStopLossPrice - i_dbEntryPrice) / oSymbol.Point());
Print( "Proposed risk ($):   ", DoubleToString(risk_amount)                               );

Simplified, that formula is: risk amount = point value * risk lots * risk points.

On SHOP.nyse (left) and GPS.nyse this looks like:

Inputs: Inputs:
Entry: 817.539 Entry: 16.471
S/L: 1000.000 S/L: 19.000
Risk %: 2.000 Risk %: 2.000
Output: Output:
Volume: 10.0 Volume: 99.0
Account: Account:
Balance: 12592.03 (USD) Balance: 12592.03 (USD)
Symbol: Symbol:
Point size: 0.001 Point size: 0.001
Tick size: 0.001 Tick size: 0.001
Tick value: 0.001 Tick value: 0.001
Tick value (profit): 0.001 Tick value (profit): 0.001
Tick value (loss): 0.001 Tick value (loss): 0.001
Lots (minimum): 10.0 Lots (minimum): 10.0
Lots (maximum): 1000.0 Lots (maximum): 1000.0
Lots (step): 1.0 Lots (step): 1.0
Proposed risk ($): 1824.61000000 Proposed risk ($): 250.37100000

So what's happening with SHOP here is that the CheckOpenShort function determined to use the minimum lot size but because the distance between the entry and sl is so big the proposed risk $ exceeds 2% balance, whereas GPS's proposed risk $ was limited to 2% because the entry to sl distance was so much smaller.  So I have to do this test on the returned lot size to confirm it doesn't exceed 2% of balance.  The more expensive the stock the more points will be involved in a 1% movement.

Thanks for helping me understand that!

 
brettles #:

So what's happening with SHOP here is that the CheckOpenShort function determined to use the minimum lot size but because the distance between the entry and sl is so big the proposed risk $ exceeds 2% balance, whereas GPS's proposed risk $ was limited to 2% because the entry to sl distance was so much smaller.  So I have to do this test on the returned lot size to confirm it doesn't exceed 2% of balance.  The more expensive the stock the more points will be involved in a 1% movement.

Thanks for helping me understand that!

Your equation for the proposed risk is incorrect. You should use the Tick Size and Tick value as follows: {Volume] x [Stop Loss Size] x [Tick Value] / [Tick Size]

Given that for SHOP, the broker's minimum volume is 10 Lots, then the risk will be higher than the desired 2% risk. If less then 10 lots were allowed then the volume would have been 1.38 Lots.

Since the contract size does not allow it, then you only have 3 options:

  1. You don't place the order at all.
  2. You place the order at that Stop-Loss and accept the higher risk.
  3. You place the order with a reduced stop-loss size so as to reduce the risk.
 
Fernando Carreiro #:

Your equation for the proposed risk is incorrect. You should use the Tick Size and Tick value as follows: {Volume] x [Stop Loss Size] x [Tick Value] / [Tick Size]

Given that for SHOP, the broker's minimum volume is 10 Lots, then the risk will be higher than the desired 2% risk. If less then 10 lots were allowed then the volume would have been 1.38 Lots.

Since the contract size does not allow it, then you only have 3 options:

  1. You don't place the order at all.
  2. You place the order at that Stop-Loss and accept the higher risk.
  3. You place the order with a reduced stop-loss size so as to reduce the risk.

I tried both the way you suggested in the quote above and using [Point].  Point appears to provide a correct calcuation of proposed risk $ on GSE.  On USDJPY neither point nor tickvalue and ticksize provide a correct calculation of proposed risk $.  The lot size does seem right though.

#include <Trade\AccountInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Expert\Money\MoneyFixedRisk.mqh>

input double
i_dbEntryPrice     = 115.973,
i_dbStopLossPrice  = 115.421,
i_dbRiskPercentage = 2.0;

double sl_size;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   bool
   bIsLong  = i_dbEntryPrice > i_dbStopLossPrice,
   bIsShort = i_dbEntryPrice < i_dbStopLossPrice;

   if(bIsLong || bIsShort)
     {
      CSymbolInfo oSymbol;
      if(oSymbol.Name(_Symbol))
        {
         CMoneyFixedRisk oMoney;
         if(oMoney.Init(GetPointer(oSymbol), _Period, oSymbol.Point()))
           {
            oMoney.Percent(i_dbRiskPercentage);
            CAccountInfo oAccountInfo;
            double dbVolume = bIsLong
                              ? oMoney.CheckOpenLong(i_dbEntryPrice, i_dbStopLossPrice)
                              : oMoney.CheckOpenShort(i_dbEntryPrice, i_dbStopLossPrice);

            Print("Inputs:");
            Print("   Entry:               ", DoubleToString(i_dbEntryPrice,     oSymbol.Digits()));
            Print("   S/L:                 ", DoubleToString(i_dbStopLossPrice,  oSymbol.Digits()));
            Print("   Risk %:              ", DoubleToString(i_dbRiskPercentage, 3));
            Print("Output:");
            Print("   Volume:              ", dbVolume);
            Print("Account:");
            Print("   Balance:             ", DoubleToString(oAccountInfo.Balance(), 2),
                  " (", oAccountInfo.Currency(), ")");
            Print("Symbol:");
            Print("   Point size:          ", DoubleToString(oSymbol.Point(),    oSymbol.Digits()));
            Print("   Tick size:           ", DoubleToString(oSymbol.TickSize(), oSymbol.Digits()));
            Print("   Tick value:          ", oSymbol.TickValue());
            Print("   Tick value (profit): ", oSymbol.TickValueProfit());
            Print("   Tick value (loss):   ", oSymbol.TickValueLoss());
            Print("   Lots (minimum):      ", oSymbol.LotsMin());
            Print("   Lots (maximum):      ", oSymbol.LotsMax());
            Print("   Lots (step):         ", oSymbol.LotsStep());

            sl_size = (i_dbEntryPrice - i_dbStopLossPrice) / oSymbol.Point();
            if(sl_size < 0)
               sl_size *= -1;

            double risk_amount = dbVolume * sl_size * oSymbol.TickValue() / oSymbol.TickSize();
            Print("Proposed risk using tick value and tick size ($):   ", DoubleToString(risk_amount));

            risk_amount = dbVolume * sl_size * oSymbol.Point();
            Print("Proposed risk using point ($):   ", DoubleToString(risk_amount));
           }
         else
            Print("Error: Unable to initialise fixed risk money management!");
        }
      else
         Print("Error: Unable to assign symbol name!");
     }
   else
      Print("Error: Invalid entry and/or stop-loss price!");
  };
GSE.nyse USDJPY
Inputs: Inputs:
Entry: 16.471 Entry: 115.973
S/L: 19.000 S/L: 115.421
Risk %: 2.000 Risk %: 2.000
Output: Output:
Volume: 99.0 Volume: 0.52
Account: Account:
Balance: 12592.03 (USD) Balance: 12592.03 (USD)
Symbol: Symbol:
Point size: 0.001 Point size: 0.001
Tick size: 0.001 Tick size: 0.001
Tick value: 0.001 Tick value: 0.8657633868663693
Tick value (profit): 0.001 Tick value (profit): 0.8657633868663693
Tick value (loss): 0.001 Tick value (loss): 0.865935816837256
Lots (minimum): 10.0 Lots (minimum): 0.01
Lots (maximum): 1000.0 Lots (maximum): 200.0
Lots (step): 1.0 Lots (step): 0.01
Proposed risk using tick value and tick size ($): 250371.00000000 Proposed risk using tick value and tick size ($): 248508.72256612
Proposed risk using point ($): 250.37100000 Proposed risk using point ($): 0.28704000


Your advice much appreciated.

 

Please note, that in your code, you are dividing your Stop-Loss size by Point size before calculating the risk with Tick Value and Tick Size. That is incorrect.

#property script_show_inputs

#include <Trade\AccountInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Expert\Money\MoneyFixedRisk.mqh>

input double
   i_dbEntryPrice     = 115.973,    // Entry Price
   i_dbStopLossPrice  = 115.421,    // Stop-Loss Price
   i_dbRiskPercentage = 2.0;        // Risk Percentage

void OnStart()
{
   bool
      bIsLong  = i_dbEntryPrice > i_dbStopLossPrice,
      bIsShort = i_dbEntryPrice < i_dbStopLossPrice;

   if( bIsLong || bIsShort )
   {
      CSymbolInfo oSymbol;
      if( oSymbol.Name( _Symbol ) )
      {
         CMoneyFixedRisk oMoney;
         if( oMoney.Init( GetPointer( oSymbol ), _Period, oSymbol.Point() ) )
         {
            oMoney.Percent( i_dbRiskPercentage );
            CAccountInfo oAccountInfo;
            double
               dbVolume       = bIsLong
                              ? oMoney.CheckOpenLong(  i_dbEntryPrice, i_dbStopLossPrice )
                              : oMoney.CheckOpenShort( i_dbEntryPrice, i_dbStopLossPrice ),
               dbStopLossSize = fabs( i_dbStopLossPrice - i_dbEntryPrice ),
               dbStopLossRisk = dbStopLossSize * dbVolume
                              * oSymbol.TickValueLoss() / oSymbol.TickSize();

            Print( "Inputs:"                                                                          );
            Print( "   Entry Price:         ", DoubleToString( i_dbEntryPrice,     oSymbol.Digits() ) );
            Print( "   Stop-Loss Price:     ", DoubleToString( i_dbStopLossPrice,  oSymbol.Digits() ) );
            Print( "   Stop-Loss Size:      ", DoubleToString( dbStopLossSize,     oSymbol.Digits() ) );
            Print( "   Risk %:              ", DoubleToString( i_dbRiskPercentage, 3                ) );
            Print( "Output:"                                                                          );
            Print( "   Volume:              ", DoubleToString( dbVolume, 2 )                          );
            Print( "   Risk Value:          ", DoubleToString( dbStopLossRisk, 2 ),
                                               " (", oAccountInfo.Currency(), ")"                     );
            Print( "Account:"                                                                         );
            Print( "   Balance:             ", DoubleToString( oAccountInfo.Balance(), 2 ),
                                               " (", oAccountInfo.Currency(), ")"                     );
            Print( "Symbol (", _Symbol, "):"                                                          );
            Print( "   Point size:          ", DoubleToString( oSymbol.Point(),    oSymbol.Digits() ) );
            Print( "   Tick size:           ", DoubleToString( oSymbol.TickSize(), oSymbol.Digits() ) );
            Print( "   Tick value:          ", oSymbol.TickValue()                                    );
            Print( "   Tick value (profit): ", oSymbol.TickValueProfit()                              );
            Print( "   Tick value (loss):   ", oSymbol.TickValueLoss()                                );
            Print( "   Lots (minimum):      ", oSymbol.LotsMin()                                      );
            Print( "   Lots (maximum):      ", oSymbol.LotsMax()                                      );
            Print( "   Lots (step):         ", oSymbol.LotsStep()                                     );
         }
         else
            Print( "Error: Unable to initialise fixed risk money management!" );
      }
      else
         Print( "Error: Unable to assign symbol name!" );
   }
   else
      Print( "Error: Invalid entry and/or stop-loss price!" );
};
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)     Inputs:
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Entry Price:         115.973
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Stop-Loss Price:     115.421
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Stop-Loss Size:      0.552
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Risk %:              2.000
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)     Output:
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Volume:              0.41
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Risk Value:          196.07 (USD)
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)     Account:
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Balance:             10000.66 (USD)
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)     Symbol (USDJPY):
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Point size:          0.001
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Tick size:           0.001
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Tick value:          0.8662133483476983
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Tick value (profit): 0.8662133483476983
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Tick value (loss):   0.866333417078897
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Lots (minimum):      0.01
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Lots (maximum):      500.0
2022.02.13 07:31:49.903 TestTradeVolume (USDJPY,H1)        Lots (step):         0.01
 
I wrote two examples a long time ago ( Money Fixed Risk and Money Fixed Margin ) - these examples clearly show what will happen if you set Stop Loss and if you work without Stop Loss.
Money Fixed Risk
Money Fixed Risk
  • www.mql5.com
An example for calculating the lot value in accordance with the risk per trade.
 
Fernando Carreiro #:

Please note, that in your code, you are dividing your Stop-Loss size by Point size before calculating the risk with Tick Value and Tick Size. That is incorrect.

It's working!  Thanks Fernando.  I also didn't know about fabs() which is a helpful function.  <3.

 
Vladimir Karputov #:
I wrote two examples a long time ago ( Money Fixed Risk and Money Fixed Margin ) - these examples clearly show what will happen if you set Stop Loss and if you work without Stop Loss.

Thanks for the resource.

 
brettles #: It's working!  Thanks Fernando.  I also didn't know about fabs() which is a helpful function.  <3.
You are welcome! 👍
Reason: