Complete formula for calculating forex pip value for XAUUSD with account funded in euros - page 2

 
Fernando Carreiro #:
  1. You can also get "LotsMax", when the stop loss is very small or your stop-loss price is in the wrong place.
  2. Don't take the absolute value of the balance as you could have a negative balance. So, simply test that the balance is actually positive before applying the calculation.
  3. You removed the part of the code that aligns the volume to the allowable volume steps. You can't just use any any value you want you have to make it a valid volume as per the allowed steps.
  4. You removed the protections of checking for the maximum and minimum allowable volume. Again, there are limits in place you must adhere to or the order will fail.
  5. The solution you came up with, is distorting the logic and not resolving the root cause of the original calculation not giving you the correct answer.

EDIT: In my example, I am using a positive Risk, not as a negative. If you want to use it as negative then adjust the calculation as such, by removing the "-" in front of "dbProfit".

    1. I think this was likely the issue with all of my tests. As I was mostly calculating  with 10 pip stoplosses. Makes sense now and your method is working with a the additional risk controls I was missing. Thank you!
    2. Great idea.
    3. Apologies, I didn't include that in my formula or example. But the max volume was derived from what MT5 returned and was not a made up value. Just to clarify, I use this:
    symbol = mt5.symbol_info(get_attr('BTCUSD', 'name', 'BTCUSD'))
    dbLotsMax = symbol.volume_max

    4 and 5 - I will use the same example to demonstrate in python format:

    # BTCUSD
    dbPriceOpen = 21525
    dbPriceStopLoss = 21200
    accountBalance = 50000
    risk = 0.01 # 1%
    symbol = mt5.symbol_info(get_attr('BTCUSD', 'name', 'BTCUSD')) dbLotsMax = symbol.volume_max
    dbLotsMax = 25.0
    dbLotsMin = symbol.volume_min dbLotsMin = 0.01
    dbLotsStep = symbol.volume_step
    dbLotsStep = 0.01
    dbRiskMax = abs(50000.0 * 0.01)
    dbRiskMax = 500.0
    dbProfit = mt5.order_calc_profit(mt5.ORDER_TYPE_BUY, BTCUSD, 25.0, 21525, 21200)
    dbProfit = -8125.0
    dbOrderLots = min( max( round( 500.0 * 25.0 / ( 8125.0 * 0.01 ) ) * 0.01, 0.01 ), 25.0 )
    dbOrderLots = 1.54

    As you can see, it is also returning units. When I use the same formula for forex currency pairs (including gold), it gives me the amount in lot sizes which is perfect. The value for the below should be 0.002 micro lot not 1.54. Or I'm simply missing a bit of logic that I will need to add in for each of these pairs that are an exception to the majority (BTCUSD, ETHUSD, US30).

    Heres a working example of XAUUSD:
    # XAUUSD dbPriceOpen = 1774
    dbPriceStopLoss = 1777 accountBalance = 50000
    risk = 0.01 # 1%
    symbol = mt5.symbol_info(get_attr('XAUUSD', 'name', 'XAUUSD')) dbLotsMax = symbol.volume_max
    dbLotsMax = 50.0
    dbLotsMin = symbol.volume_min
    dbLotsMin = 0.01
    dbLotsStep = symbol.volume_step
    dbLotsStep = 0.01
    dbRiskMax = abs(50000.0 * 0.01)
    dbRiskMax = 500.0
    dbProfit = mt5.order_calc_profit(mt5.ORDER_TYPE_BUY, XAUUSD, 50.0, 1777, 1774)
    dbProfit = -15000.0
    dbOrderLots = min( max( round( 500.0 * 50.0 / ( 15000.0 * 0.01 ) ) * 0.01, 0.01 ), 50.0 )
    dbOrderLots = 1.67
     

    TraderLloyd #:

    As you can see, it is also returning units. When I use the same formula for forex currency pairs (including gold), it gives me the amount in lot sizes which is perfect. The value for the below should be 0.002 micro lot not 1.54. Or I'm simply missing a bit of logic that I will need to add in for each of these pairs that are an exception to the majority (BTCUSD, ETHUSD, US30).
    Heres a working example of XAUUSD:

    You are mixing apples and oranges in your 2nd example.

    You acquiring info on gold ...

    symbol = mt5.symbol_info(get_attr('XAUUSD', 'name', 'XAUUSD'))

    But then doing the Profit calculation on bitcoin ...

    dbProfit = mt5.order_calc_profit(mt5.ORDER_TYPE_BUY, BTCUSD, 50.0, 1777, 1774)

    Which one is it then?

    EDIT: And in the 1st example, the answer seems correct. It is indeed 1.54, not 0.002.

    EDIT2: However, besides the "BTCUSD" in your text in the 2nd example, the returned profit of -15000 is correct for XAUUSD, and the correct lot size is in fact correct at 1.67

     
    Fernando Carreiro #:

    You are mixing apples and oranges in your 2nd example.

    You acquiring info on gold ...

    But then doing the Profit calculation on bitcoin ...

    Which one is it then?

    EDIT: And in the 1st example, the answer seems correct. It is indeed 1.54, not 0.002.

    EDIT2: However, besides the "BTCUSD" in your text in the 2nd example, the returned profit of -15000 is correct for XAUUSD, and the correct lot size is in fact correct at 1.67

    Sorry about that, I copied and pasted that line from BTC and didn't fix it. It is XAUUSD.


    And you are correct...both are correct. It turns out the calculator I've been using on my mobile phone has the wrong value.


    I can't thank you enough Fernando!

     
    TraderLloyd #:Sorry about that, I copied and pasted that line from BTC and didn't fix it. It is XAUUSD. And you are correct...both are correct. It turns out the calculator I've been using on my mobile phone has the wrong value. I can't thank you enough Fernando!
    You are welcome!
     

    Hi Guys, If you don't mind me adding to this thread because I think it is related. I have been scratching my head on this one not sure what exactly is wrong if any.

    Using the same formula above, I calculated for US30, risk amount is 500, open price 31920.40 and stop loss 31919.90. I got 1000lots. Please can anyone help me understand why this is. 

    More info

    All currency in USD

    Ticksize = 0.01

    TickPoint = 0.01


    minLot = 0.1

    maxLot = 250


    volume step = 0.1

    I will be happy to provided anymore information if required. Thanks for the assistance

     
    Henry Chigere #: Hi Guys, If you don't mind me adding to this thread because I think it is related. I have been scratching my head on this one not sure what exactly is wrong if any. Using the same formula above, I calculated for US30, risk amount is 500, open price 31920.40 and stop loss 31919.90. I got 1000lots. Please can anyone help me understand why this is. I will be happy to provided anymore information if required. Thanks for the assistance

    Show your code then, because we will not be able to see what you are doing wrong in your code without seeing it.

    As for example values you mention, a quote price difference between 31920.40 and 31919.90 for US30 would be 0.50. And given that each tick of size 0.01 is worth $0.01, that would be a risk of $0.50 for 1 lot.

    So for a $500.00 risk, you would indeed require 1000 lots, but given that the maximum allowed is 250, your risk would be $125.00 for the 0.50 quote price change.

     

    One more thing that should be considered by the OP or those following this thread ...

    After you determine your volume (lots) for your risk amount, you should then check that against the free margin, useing the OrderCalcMargin (MQL5) or order_calc_margin (Python), to verify that the amount of margin that will be required is available in your free margin.

    In fact, make sure that the required margin plus the risk is not greater than your free margin and that it will not cause a margin call or stop out.

    I personally set a margin % limit and reduce the lot size if required. For example, I set a maximum % margin of 5-10% and use the OrderCalcMargin to adjust the volume to reduce the volume should the margin be higher than my limit.

    The reason I set it to 5-10% is because I have to account for multiple positions in the market if I am trading on multiple symbols at the same time. If I were to allow a maximum margin on my balance, then I would not have any free margin left to trade on other symbols.

     
    Fernando Carreiro #:

    Show your code then, because we will not be able to see what you are doing wrong in your code without seeing it.

    As for example values you mention, a quote price difference between 31920.40 and 31919.90 for US30 would be 0.50. And given that each tick of size 0.01 is worth $0.01, that would be a risk of $0.50 for 1 lot.

    So for a $500.00 risk, you would indeed require 1000 lots, but given that the maximum allowed is 250, your risk would be $125.00 for the 0.50 quote price change.

    Thanks Fernando, thanks for confirming that at least the calculation is what it should be. I do normalise to the bounds of min and max lots size, please see extract


     if (calculatedLotSize < minLot) adjustedLotSize = minLot;
         else if (calculatedLotSize > maxLot) adjustedLotSize = maxLot;
         else adjustedLotSize = calculatedLotSize;
         
         return NormalizeDouble(MathRound(adjustedLotSize/lotStep) * lotStep, 2);


     My confusion was that I could not execute 250 lot because I get error no money but based on your follow up comment, It is clear that I should have also calculate margin and adjust against my balance. I will revise my logic and see how it that goes. I really do appreciate your assistance on this, thanks again Fernando

     
    Henry Chigere #: Thanks Fernando, thanks for confirming that at least the calculation is what it should be. I do normalise to the bounds of min and max lots size, please see extract. My confusion was that I could not execute 250 lot because I get error no money but based on your follow up comment, It is clear that I should have also calculate margin and adjust against my balance. I will revise my logic and see how it that goes. I really do appreciate your assistance on this, thanks again Fernando
    Don't use NormalizeDouble. The lots are already properly aligned with the Round and the LotStep. NormalizeDouble can actually cause problems, so don't use it.
     
    Fernando Carreiro #:
    Don't use NormalizeDouble. The lots are already properly aligned with the Round and the LotStep. NormalizeDouble can actually cause problems, so don't use it.
    Good point, thank you
    Reason: