MarketInfo(Symbol(), MODE_TICKVALUE) returns (apparently) wrong result? (MQL4)

 

Hey everyone,

I'm creating a simple EA to test indicators with. I'm currently working on the function which calculates an order position size. To do so, i need the current pip value. But when i tried to use MarketInfo(Symbol(), MODE_TICKVALUE) the value returned is different than the one i calculated. I double checked my result, and used an online pip value calculator too and they seem to be correct, yet i find it difficult to think that the built-in function is wrong.

This is the relevant portion of my code:



      double UsePoint;

        // Define Point value if the broker uses pipettes or pips
      if(MarketInfo(NULL, MODE_DIGITS) == 3 || MarketInfo(NULL, MODE_DIGITS) == 5)
        {
         UsePoint = Point * 10;
        }
      else
        {
         UsePoint = Point;
        }
double
CalcLotSize()   {    double CurrentPipVal;    // Dividing Pipvalue by the current Exchange rate, we obtain the current pip value in units    CurrentPipVal = UsePoint / Ask * MarketInfo( NULL,MODE_LOTSIZE);    Print ("**** CurrentPipVal: ", CurrentPipVal, "**** MarketInfo: ", MarketInfo(Symbol(),MODE_TICKVALUE)*10, "**** Ask: ", Ask, "**** Bid: ", Bid, "**** Symbol: ", Symbol(), "**** AccCurrency: ", AccountCurrency());   }

An example of output from backtesting:

2019.10.23 21:00:55.644 2018.01.03 00:00:00  My ExpertAdvisor EURGBP,Daily: **** CurrentPipVal: 11.26887536623845**** MarketInfo: 11.59890970248797**** Ask: 0.8874**** Bid: 0.88722**** Symbol: EURGBP**** AccCurrency: EUR

Please note that i'm calculating CurrentPipVal only in the pair EURGBP, and the account balance is in EUR. I tried using NULL, Symbol() and _Symbol in MarketInfo, with no better result. 
I printed the Symbol() and AccountCurrency() to be 100% sure that i'm converting in the same currency as the function. Anyone has any ideas why this happens? Am i using the function wrong?

 
  1. Don't use NULL.
    • You can use NULL in place of _Symbol only in those calls that the documentation specially says you can. iHigh does, iCustom does, MarketInfo does not. OrderSend does not.
    • Don't use NULL (except for pointers where you explicitly check for it.) Use _Symbol and _Period, that is minimalist as possible and more efficient.
    • Zero is the same as PERIOD_CURRENT which means _Period. Don't hard code numbers.
    • MT4: No need for a function call with iHigh(NULL,0,s) just use the predefined arrays, i.e. High[].
  2. Never risk more than a small percentage of your account, certainly less than 2% per trade, 6% total to the account.
    1. In code (MT4): Risk depends on your initial stop loss, lot size, and the value of the pair. It does not depend on margin and leverage.
      1. You place the stop where it needs to be — where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
      2. AccountBalance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the spread, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
      3. Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
                  MODE_TICKVALUE is not reliable on non-fx instruments with many brokers - MQL4 programming forum 2017.10.10
                  Is there an universal solution for Tick value? - Currency Pairs - General - MQL5 programming forum 2018.02.11
                  Lot value calculation off by a factor of 100 - MQL5 programming forum 2019.07.19
      4. You must normalize lots properly and check against min and max.
      5. You must also check FreeMargin to avoid stop out

      Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.

 
William Roeder:
if you want calculate Lot size, you must have ben SL and Risk value. Lot=Risk/(TP*tickValue). And if you calculate Currentpipvalue you must have Lot size value, Currentpipvalue = Lot * tickValue.
 
Amir Syarifudin: Currentpipvalue = Lot * tickValue.

Wrong. Current PIP value = pip * TickValue/TickSize. A trade is worth per pip = lots * pip value.

 
William Roeder:

Thank you for taking the time to respond!

1. I will remove NULL from my code, but as i said, i already tried Symbol() and _Symbol and was just checking if that changed anything. It didn't.

2. People seem to have unreliable results with TICKVALUE on other instruments than Forex, which is the one i'm using. So TICKVALUE should be returning results in my balance currency (EUR). To be 100% sure i tried to convert to USD too but that's completely off too.

as for trade risk, SL, TP and lot amount it's all there, i just didn't write to not add clutter.

But to clarify i have a SL and a risk (2%). WIth that i can find a target pip value, then i divide that for current pip value and find the lot size of the trade. At this point i might just use my own calculation for CurrentPipVal and then manually check if the risk is actually 2% on a placed order as it should be as a last resort. I was just curious as what would make my own calculation differ from TICKVALUE.

thanks again for the helpful links, especially your EA, I will probably will study it to better build my own.

Reason: