Forum on trading, automated trading systems and testing trading strategies
Serious bug in the OrderCalcProfit() function
Fernando Carreiro, 2023.01.07 14:47
In actuality, it is not a bug in the OrderCalcProfit() function, and it works as expected. The problem or “bug” is in the naming of the SYMBOL_TRADE_TICK_VALUE_PROFIT and SYMBOL_TRADE_TICK_VALUE_LOSS properties. They would be better named the tick value based on “Ask” and “Bid”, instead of “Profit” and “Loss”.
If you consider them that way, then for a Buy position that closes on the Bid, one would require the tick value for bid (which is the “SYMBOL_TRADE_TICK_VALUE_LOSS”), and for a Sell position that closes on the Ask, one would require the tick value for ask (which is the “SYMBOL_TRADE_TICK_VALUE_PROFIT”).
In both cases, however, the calculations are only approximations, because both the Bid and Ask values would change by the time (and price) it reaches one of the stops.
This naming problem of these two properties has been reported and extensively covered on the Russian forum (can’t remember the link), but MetaQuotes has ignored it and not changed the names.
Forum on trading, automated trading systems and testing trading strategies
Serious bug in the OrderCalcProfit() function
Fernando Carreiro, 2023.02.18 21:25
Yes, and it is not counter intuitive because as I mentioned in my post #1
- Buy positions close at the Bid price irrespective of Profit or Loss, and the SYMBOL_TRADE_TICK_VALUE_LOSS should actually be called SYMBOL_TRADE_TICK_VALUE_BID.
- Sell positions close at the Ask price irrespective of Profit or Loss, and the SYMBOL_TRADE_TICK_VALUE_PROFIT should actually be called SYMBOL_TRADE_TICK_VALUE_ASK.
You are both wrong. The tick value is independent of the direction of a trade (BUY or SELL).
The market is closed, so I can't prove it with data for now.
But let see some theory in the first place :
What is a tick ? It's the smallest price movement for a considered symbol. Let's take EURUSD, with a 5 digits standard quotation, so a tick is 0.00001 (tick size).
What is a tick value ? is the value, in account currency, of this minimal price movement (tick or tick size), considering a traded volume of 1 lot (let's say a standard lot so 100,000 units).
How do we calculate the value of a tick ?
- Firstly we get the value considering the traded symbol, the unit is always the second currency in a pair (USD in our case), by the quotation definition. So the profit/loss, for 1 standard lot is 0.00001 * 100000 = 1 USD. Or 100 JPY (0,001 * 100000) on EURJPY, or 1 CAD on USDCAD (0.00001 * 100000), etc...
- Secondly, if necessary, make the conversion to account currency and it's in this step that relies all the subtleties. As yes, you have to take into account if it's a loss or a profit, and additionally if the conversion is "direct" (from USD to a JPY account using USDJPY) or "indirect" (from JPY to USD account using JPYUSD). The conversion rate will of course use either the bid or the ask, of the symbol needed for the conversion which may be the same as the traded symbol OR NOT, so this is completely independent of the considered trade direction !
Let's take some examples.
Account in EUR. All trades will require a conversion because no symbol is using EUR as profit (loss) currency.
- EURUSD trade. BUY or SELL, doesn't matter.
In profit, we have win 10 USD, we need to sell them to get EUR, as the symbol is EURUSD we will BUY EURUSD at ask price.
In loss, we have lost -10 USD, we need to sell some EUR to pay for it, so we will SELL EURUSD at bid price.
- GBPJPY trade. BUY or SELL, doesn't matter.
In profit, we win 2500 JPY, we need to sell them by buying EUR, so we BUY EURJPY at ask price.
In loss, we have lost -2500 JPY, we need to sell some EUR to pay for it, we will SELL EURJPY at bid price.
So with an EUR account, SYMBOL_TRADE_TICK_VALUE_PROFIT is always the ASK price of the conversion symbol needed, which may or may not be the traded symbol. And SYMBOL_TRADE_TICK_VALUE_LOSS is always the bid price of the conversion symbol.
Account USD. Here, we have more possibilities.
- EURUSD trade. BUY or SELL, doesn't matter.
In profit, or in loss, there is no need for conversion, as the profit currency is USD and the account currency is USD too. By the way it's the profit that the trade direction doesn't matter, but the conversion matters.
- GBPJPY trade. BUY or SELL, doesn't matter.
In profit, we win 2500 JPY, we need to sell them by buying USD, so we BUY USDJPY at ask price.
In loss, we have lost -2500 JPY, we need to sell some USD to pay for it, we will SELL USDJPY at bid price.
- EURNZD trade. BUY or SELL, doesn't matter.
In profit, we win 15 NZD, we need to sell them by buying USD, as the symbol is NZDUSD we will SELL NZDUSD at bid price.
In loss, we have lost -15 NZD, we need to buy some NZD to pay it, we will BUY NZDUSD at ask price.
Symbols with USD as the profit (loss) currency will not need conversion. Symbols with direct conversion will have SYMBOL_TRADE_TICK_VALUE_PROFIT matching bid conversion price, and SYMBOL_TRADE_TICK_VALUE_LOSS will match the ask conversion price. In reverse, for symbols with "indirect" conversion, SYMBOL_TRADE_TICK_VALUE_PROFIT matching ask conversion price, and SYMBOL_TRADE_TICK_VALUE_LOSS will match the bid conversion price.
Account JPY.
I will not give the details, the logic is the same.
There is never a conversion needed when JPY is implied, as JPY is always the profit/loss currency.
When a conversion is needed the conversion is always "direct" as JPY is always the second part of a symbol, so on an JPY account, SYMBOL_TRADE_TICK_VALUE_PROFIT is always the BID price of the conversion symbol needed, which is never the traded symbol. And SYMBOL_TRADE_TICK_VALUE_LOSS is always the ask price of the conversion symbol.
There are some specific cases, mainly when the trading is in a more "exotic" currency, like for example SGD (Singapour dollar) where it happens the crosses pairs needed for conversion is not available. Say a CADCHF trade, which would require a SGDCHF symbol to convert in CHF profit/loss in SGD, but this SGDCHF pair is not available, in such case, there will be a double conversion using USD. So from CHF to USD using USDCHF, then from USD to SGD using USDSGD.
please see the discussion here
Forum on trading, automated trading systems and testing trading strategies
Serious bug in the OrderCalcProfit() function
amrali, 2023.02.18 22:29
Yes, the names are buggy. So, if those profit calculations were not correct for a trading platform (which is not the case), then it is really a serious problem with the platform.
The names of those tick_value_xxx do not confer what they are supposed to do.
Edit:
It should be clearly stated in the documentation of these tick values that
SYMBOL_TRADE_TICK_VALUE_PROFIT is used to calculate profit of SELL orders.
SYMBOL_TRADE_TICK_VALUE_LOSS is used to calculate profit of BUY orders.
- 2023.02.18
- www.mql5.com
Alain seems convinced so I'm going to try to understand his explanation a bit better this week when I have time, I also saw you Amrali mentioning (in the discussion you posted) that it's different for non-forex symbols, so I'm going to look into that too. I'm glad Fernando is also giving his perspective, hopefully we get to the bottom of this, and if it turns out there is no error in the end I'll add an edit to my original post.
My above post contain errors in the details, as with indirect conversion (when you profit on USD on an EUR account for example), you need to divide to convert, so it's not the ask price which is use but (1/bid), and the reverse for bid (we will use 1/ask).
But my point about SYMBOL_TRADE_TICK_VALUE_PROFIT/LOSS remains unchanged.
Right now I'm even more confused than before. I think it's because of what you mention about how the returned values are approximations because when I do a simple test of placing a stop loss or take profit at 1000 points away from the entry price, I can see that the total loss or profit is not what I would get from a formula using either SYMBOL_TRADE_TICK_VALUE_LOSS or SYMBOL_TRADE_TICK_VALUE_PROFIT. The true loss or profit always seems to be a bit different than the number I get by using the tick value (by a very small amount but I was expecting the number to be exactly the one I got from my formula) so now I'm wondering what I'm doing wrong...
Right now I'm even more confused than before. I think it's because of what you mention about how the returned values are approximations because when I do a simple test of placing a stop loss or take profit at 1000 points away from the entry price, I can see that the total loss or profit is not what I would get from a formula using either SYMBOL_TRADE_TICK_VALUE_LOSS or SYMBOL_TRADE_TICK_VALUE_PROFIT. The true loss or profit always seems to be a bit different than the number I get by using the tick value (by a very small amount but I was expecting the number to be exactly the one I got from my formula) so now I'm wondering what I'm doing wrong...
***edit*** I now think everything I say in this specific reply is incorrect and came from biased conclusions where I was looking at the tick value on a pair where the spread was also 1 tick (this led me to interpret the results incorrectly).
I just realized my mistake: in the example where your account is in USD, if you open a 1 lot position on USDCAD at 1.35000 and close it at a loss at 1.34999, the move is 1 tick, but the value of that move is NOT the tick value at 1.35000 (1 / 1.35000 = 0.7407407...), the correct value for that move is the tick value at 1.34999 (1/1.34999 = 0.7407462...).
Now I feel like an idiot for using SYMBOL_TRADE_TICK_VALUE_LOSS or SYMBOL_TRADE_TICK_VALUE_PROFIT to calculate the correct lot size before I open a position, feel free to laugh, but I hadn't realized that this would make a difference... it didn't really make a difference on small accounts because the lot size would usually still be correct, but on large accounts with large lot sizes, it starts to make a difference.
I just realized my mistake: in the example where your account is in USD, if you open a 1 lot position on USDCAD at 1.35000 and close it at a loss at 1.34999, the move is 1 tick, but the value of that move is NOT the tick value at 1.35000 (1 / 1.35000 = 0.7407407...), the correct value for that move is the tick value at 1.34999 (1/1.34999 = 0.7407462...).
Now I feel like an idiot for using SYMBOL_TRADE_TICK_VALUE_LOSS or SYMBOL_TRADE_TICK_VALUE_PROFIT to calculate the correct lot size before I open a position, feel free to laugh, but I hadn't realized that this would make a difference... it didn't really make a difference on small accounts because the lot size would usually still be correct, but on large accounts with large lot sizes, it starts to make a difference.
So, I use OrderCalcProfit() to calculate the expected loss at the (future) exit price. This only applies for Forex symbols where the base currency == account currency, which calculates a correct loss. It applies the necessary adjustment for the tick value, and profit/loss.
Thanks a lot for the tip!
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
*edit: when I posted the thread, I was confused about the correct way to calculate position size based on entry price and stop loss price, so don't take anything I say here as truth, unless someone else verifies it in the comments.*
----------------------------------------------------------------------------
From the documentation:
SYMBOL_TRADE_TICK_VALUE
Value of SYMBOL_TRADE_TICK_VALUE_PROFIT
double
SYMBOL_TRADE_TICK_VALUE_PROFIT
Calculated tick price for a profitable position
double
SYMBOL_TRADE_TICK_VALUE_LOSS
Calculated tick price for a losing position
double
I'm pretty sure this is incorrect... (but I could be wrong!)
SYMBOL_TRADE_TICK_VALUE_PROFIT or SYMBOL_TRADE_TICK_VALUE gives you the tick value for shorts (based on the ASK as the closing price)
SYMBOL_TRADE_TICK_VALUE_LOSS gives you the tick value for longs (based on the BID as the closing price)
I'll leave this here because the documentation should probably be changed but until it is, it's really hard to find the correct information with a google/forum search (it's easier to verify the information yourself with manual calculations). Also, I noticed a lot of posts providing incorrect information on the forum (they seem to repeat the definition found in the documentation).
If anyone knows why the documentation is like that or thinks it's correct, I'm curious to know why...