XAUUSD MODE_TICKVALUE problem

 

My position size and pip value calculation works fine on FOREX pairs, including JPY pairs, but on the metals it all goes wrong.

Comment( MarketInfo("XAUUSD",MODE_TICKVALUE) );

gives me

5

which is wrong since I have a GBP account. I am expecting something like 6.422 since GBPUSD is currently 1.5569

I can easily sanity check the point to GBP relationship by opening a position and seeing the loss on the account in points (right mouse click - display profit in Points) and in GBP.

XAGUSD is even worse as it is off by another factor of 10 as well as having the first digit as 5 :-(

Any ideas? (It is not a rounding error as I have printed it in double precision as well).

 

MODE_TICKVALUE has some limitations, especially when it comes to the cross-currency instruments.

Sounds like you are an experienced coder so I won't need to detail the code here as I'm sure you can dive right in and reverse-engineer the portions you need.

This code correctly computes the tickvalue: https://www.mql5.com/en/forum/126450/page5#331819

Some documentation on the salient parts: https://www.mql5.com/en/forum/126450/page6#332640

Let me know if the posts and/or codes are too obtuse to be of any use, I will gladly detail them even further if needed.

 
1005phillip:

MODE_TICKVALUE has some limitations, especially when it comes to the cross-currency instruments.

Sounds like you are an experienced coder so I won't need to detail the code here as I'm sure you can dive right in and reverse-engineer the portions you need.

This code correctly computes the tickvalue: https://www.mql5.com/en/forum/126450/page5#331819

Some documentation on the salient parts: https://www.mql5.com/en/forum/126450/page6#332640

Let me know if the posts and/or codes are too obtuse to be of any use, I will gladly detail them even further if needed.


Thanks Philip. That's all a bit complicated for my tastes.

I did have a massive script which figured out how to convert from this to that, but when I found the MODE_TICKVALUE parameter I just dumped the lot. Evidently that parameter doesn't work correctly on the metals so we are back to loads of nasty if-then-but constructs.

I did just open a USD demo account as a sanity check and realised that the margin is 50:1 for metals. I am used to 500:1 for the FOREX pairs so I don't normally have to worry about that :-(

I can just put in a test for XAUUSD and XAUUSD and do a special calculation for them. It would have been nice to make it general for any account currency but I can't be bothered!


As an aside, I noticed that you used ...

MarketInfo( Symbol(), MODE_POINT ) rather than Point

and

MarketInfo( Symbol(), MODE_BID ) rather than Bid

Is this some subtlety, like not requiring to do a RefreshRates() call, or some such thing?

 
dabbler:

Thanks Philip. That's all a bit complicated for my tastes.

I did have a massive script which figured out how to convert from this to that, but when I found the MODE_TICKVALUE parameter I just dumped the lot. Evidently that parameter doesn't work correctly on the metals so we are back to loads of nasty if-then-but constructs.

I did just open a USD demo account as a sanity check and realised that the margin is 50:1 for metals. I am used to 500:1 for the FOREX pairs so I don't normally have to worry about that :-(

You do need deep pockets to trade the metals on daily charts, even at the minimum 0.1 lots :-(

I can just put in a test for XAUUSD and XAUUSD and do a special calculation for them. It would have been nice to make it general for any account currency but I can't be bothered!


As an aside, I noticed that you used ...

MarketInfo( Symbol(), MODE_POINT ) rather than Point

and

MarketInfo( Symbol(), MODE_BID ) rather than Bid

Is this some subtlety, like not requiring to do a RefreshRates() call, or some such thing?


It only looks complicated because it breaks everything down into absolute elemental parameters...this is necessary to have the algorithms be general enough that they can be broker-agnostic. Doesn't matter the decimal, leverage, etc, it is all intrinsically accounted for.

I use the MarketInfo() functions because of their generality...when creating the base equation I need it to be general enough that it correctly computes the values regardless whether I am calling for Symbol() or some other currency pair's marketinfo. Once the generalized equations were created then it just so happens that there were instances of the equation that could be reduced to "Point" or "Bid"...but at that stage in the code such a substitution would be purely for aesthetics and not for improving the robustness of the code.

I'm a multi-currency multi-broker trader, so I craft my codes from the ground-up to be as symbol() and broker() agnostic as I can make them. It does make the coding more time consuming up front but entails far less maintenance and debugging over its usable life as broker changes tend to not break my ea's and so on. For folks who trade a single currency pair like EURUSD or live with a single broker like IBFX my codes are needlessly generalized, and thus overly-complicated, for their needs. (no surprise though as I wasn't coding to their needs, I was coding to my needs :))

 
double PointValuePerLot() { // Value in account currency of a Point of Symbol.
    /* In tester I had a sale: open=1.35883 close=1.35736 (0.00147)
     * gain$=97.32/6.62 lots/147 points=$0.10/point or $1.00/pip.
     * IBFX demo/mini       EURUSD TICKVALUE=0.1 MAXLOT=50 LOTSIZE=10,000
     * IBFX demo/standard   EURUSD TICKVALUE=1.0 MAXLOT=50 LOTSIZE=100,000
     *                                  $1.00/point or $10.00/pip.
     *
     * https://forum.mql4.com/33975 CB: MODE_TICKSIZE will usually return the
     * same value as MODE_POINT (or Point for the current symbol), however, an
     * example of where to use MODE_TICKSIZE would be as part of a ratio with
     * MODE_TICKVALUE when performing money management calculations which need
     * to take account of the pair and the account currency. The reason I use
     * this ratio is that although TV and TS may constantly be returned as
     * something like 7.00 and 0.00001 respectively, I've seen this
     * (intermittently) change to 14.00 and 0.00002 respectively (just example
     * tick values to illustrate). */
    return(  MarketInfo(Symbol(), MODE_TICKVALUE)
           / MarketInfo(Symbol(), MODE_TICKSIZE) ); // Not Point.
}