Issue with MarketInfo(NULL,MODE_SPREAD) on live account

 
double Spread = MarketInfo(NULL,MODE_SPREAD) / 100000;
double COpen = iOpen(NULL,240,0);
double P2Low = iLow(NULL,240,2);

double BuySL = P2Low - 0.0001;
double BuySLDist = COpen + Spread - BuySL;
double BuyTP = COpen + Spread + BuySLDist * 6;

Above snippet works fine in backtest, but first trade on live and BuyTP is short by exactly 6 * Spread + slippage. The shortage from slippage (if any) makes perfect sense, but any idea why Spread seems to have returned 0 in this instance? (Average spread at this broker is .4 pips and this was during Asia so really doubt spread was 0 when trade occurred).

‌Consensus seems to be use symbol() instead of NULL, but don't think this is issue.

‌Can easily rectify with an order modify after trade entry and will do this to account for slippage, but would like to fix spread issue at source.

‌Any help would be much appreciated.

 
shyftus: Above snippet works fine in backtest, but first trade on live and BuyTP is short by exactly 6 * Spread + slippage. The shortage from slippage (if any) makes perfect sense, but any idea why Spread seems to have returned 0 in this instance? (Average spread at this broker is .4 pips and this was during Asia so really doubt spread was 0 when trade occurred). ‌Consensus seems to be use symbol() instead of NULL, but don't think this is issue.

‌Can easily rectify with an order modify after trade entry and will do this to account for slippage, but would like to fix spread issue at source. ‌Any help would be much appreciated.

‌Spread alternatives:

double Spread = Ask - Bid;
// Or
double Spread = MarketInfo( _Symbol, MODE_SPREAD ) * _Point; // MarketInfo Spread is in Points
// Or
double Spread = SymbolInfoInteger( _Symbol, SYMBOL_SPREAD ) * _Point; // Compatible with both MQL4 and MQL5

And, don't Hard-Code your constants:

double
   COpen = iOpen( NULL, PERIOD_H4, 0 ),
   P2Low = iLow(  NULL, PERIOD_H4, 2 );

Also‌, don't just assume that your stops will work. You should check the Broker's conditions (such as StopLevel): Requirements and Limitations in Making Trades

Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
  • book.mql4.com
Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
 

W‌hy do you divide with 100000? It is already in points.

double Spread = MarketInfo(NULL,MODE_SPREAD) / 100000;
 
Irwan Adnan: W‌hy do you divide with 100000? It is already in points.
That is exactly the reason! The OP is converting the "points" into "price delta". That is why in my example, I showed that the correct way is by using " * _Point " instead of " / 100000", because different symbols have different Point sizes.
 
shyftus: ‌Consensus seems to be use symbol() instead of NULL, but don't think this is issue.
double Spread = MarketInfo(NULL,MODE_SPREAD) / 100000;
double COpen = iOpen(NULL,240,0);
double P2Low = iLow(NULL,240,2);
  1. The 240 was mentioned above. Don't hard code constants.
  2. MT5 doesn't have a MarketInfo so why did you post in the forum / MT5 Expert Advisors section instead of the MT4 section? I Assume you meant MT4.
  3. You can only use NULL in those calls where the documentation specifically mentions it and those are mostly to substitution for _Symbol. MI is not one of those. Don't use NULL (except for pointers where you explicitly check for it.)
  4. Spread returns the number of points, usually in the 5 - 50 range (0.5-5.0 pips on a 5 digit broker.) If you want the number of points, don't divide.
  5. If you want the spread as a price change, multiply by _Point (or subtract Bid from Ask.) Don't hard code constants (1/100K) is _Point for non-JPY/5 digit broker pairs, but your code fails on Yen pairs or 4 digit brokers.
  6. You must adjust SL, TP, and slippage for 4/5 digit brokers and for JPY pairs.
    double   pip          = StringFind(_Symbol,"JPY") < 0 ? 0.01 : 0.0001;
    int      pipDigits    = (int)MathLog10(pip/_Point);
    int      pipsToPoints = int(pip / _Point);
    int      slippage     = 3 * pipsToPoints;

 
whroeder1If you want the spread as a price change, multiply by _Point (or subtract Bid from Ask.) Don't hard code constants (1/100K) is _Point for non-JPY/5 digit broker pairs, but your code fails on Yen pairs or 4 digit brokers. You must adjust SL, TP, and slippage for 4/5 digit brokers and for JPY pairs.
double   pip          = StringFind(_Symbol,"JPY") < 0 ? 0.01 : 0.0001;
Just as an extra note, special case is not just the JPY but also the RUB (and some metals, CFDs and others).
 
Fernando Carreiro:

‌Spread alternatives:you

double Spread = Ask - Bid;
// Or
double Spread = MarketInfo( _Symbol, MODE_SPREAD ) * _Point; // MarketInfo Spread is in Points
// Or
double Spread = SymbolInfoInteger( _Symbol, SYMBOL_SPREAD ) * _Point; // Compatible with both MQL4 and MQL5

And, don't Hard-Code your constants:

double
   COpen = iOpen( NULL, PERIOD_H4, 0 ),
   P2Low = iLow(  NULL, PERIOD_H4, 2 );

Also‌, don't just assume that your stops will work. You should check the Broker's conditions (such as StopLevel): Requirements and Limitations in Making Trades

Hi Fernando thanks for the reply

I note the second spread alternative is near identical to what I have, though it explicitly calls for current symbol ‌rather than using NULL and * _Point is much more versatile if I want to work with JPY etc - you think this will fix my problem?

‌Re‌garding Hardcoding Chart Timeframe constants - why is this an issue? Whether I type the Value or ID here function exactly the same no? Former just requires less key strokes.

Regarding Stops - I (and I think most people these days) only work with 'True' ECNs that don't have limitations like this, so not really an issue.

Fernando Carreiro:
That is exactly the reason! The OP is converting the "points" into "price delta". That is why in my example, I showed that the correct way is by using " * _Point " instead of " / 100000", because different symbols have different Point sizes.
Yep this is a much better option, I previously had used an if  to hardcode different value for USDJPY - thanks for the tip!

 
shyftus: Hi Fernando thanks for the reply
  1. I note the second spread alternative is near identical to what I have, though it explicitly calls for current symbol ‌rather than using NULL and * _Point is much more versatile if I want to work with JPY etc - you think this will fix my problem?
  2. ‌Re‌garding Hardcoding Chart Timeframe constants - why is this an issue? Whether I type the Value or ID here function exactly the same no? Former just requires less key strokes.
  3. Regarding Stops - I (and I think most people these days) only work with 'True' ECNs that don't have limitations like this, so not really an issue.
  1. Hopefully yes, because we are unable to see the rest of your code in order to verify! Please also see posted comments by @whroeder1.
  2. Because that is the correct way to work with constants and enums because they may change in future. Do it correctly, and don't cut corners.
  3. That is no excuse to write bad code! Always check those values, irrespective of what you might "think" is best. An ECN account is not always the best fit for certain types of Strategies, and I for one use both types of accounts depending on which one best fits the strategy. So don't assume things!
 
whroeder1:
  1. The 240 was mentioned above. Don't hard code constants.
  2. MT5 doesn't have a MarketInfo so why did you post in the forum / MT5 Expert Advisors section instead of the MT4 section? I Assume you meant MT4.
  3. You can only use NULL in those calls where the documentation specifically mentions it and those are mostly to substitution for _Symbol. MI is not one of those. Don't use NULL (except for pointers where you explicitly check for it.)
  4. Spread returns the number of points, usually in the 5 - 50 range (0.5-5.0 pips on a 5 digit broker.) If you want the number of points, don't divide.
  5. If you want the spread as a price change, multiply by _Point (or subtract Bid from Ask.) Don't hard code constants (1/100K) is _Point for non-JPY/5 digit broker pairs, but your code fails on Yen pairs or 4 digit brokers.
  6. You must adjust SL, TP, and slippage for 4/5 digit brokers and for JPY pairs.
    double   pip          = StringFind(_Symbol,"JPY") < 0 ? 0.01 : 0.0001;
    int      pipDigits    = (int)MathLog10(pip/_Point);
    int      pipsToPoints = int(pip / _Point);
    int      slippage     = 3 * pipsToPoints;

1. Fair call

2. Right, sorry.‌

3.‌ Thanks, just noticed doc for MI doesn't say 'NULL means the current symbol.'

4 / 5. Yes wanted price and yes * _Point much more efficient.

6. See my comment about stop limitations. This EA is for private use ... do 4 digit brokers still exist? Have JPY sorted in full code.

Fernando Carreiro:
  1. Hopefully yes, because we are unable to see the rest of your code in order to verify! Please also see posted comments by @whroeder1.
  2. Because that is the correct way to work with constants and enums because they may change in future. Do it correctly, and don't cut corners.
  3. That is no excuse to write bad code! Always check those values, irrespective of what you might "think" is best. An ECN account is not always the best fit for certain types of Strategies, and I for one use both types of accounts depending on which one best fits the strategy. So don't assume things!

1. Great yep after WH pointed out doc doesn't mention NULL works makes sense.

2. Fair call.

3. See above, EA for private use. Waste of time coding for this when I never trade with MMs or pseudo-ECNs but fair call re: best practice / good code.

Thanks guys, always a pleasure and once again sorry re: wrong forum

 
shyftus: See above, EA for private use. Waste of time coding for this when I never trade with MMs or pseudo-ECNs but fair call re: best practice / good code.

Don't assume that non-ECN automatically means MM/DD. There are other types of NDD (non MM/DD) accounts besides ECN, such as STP, DMA and other hybrids and variations.

Also, even if you are just coding for yourself, there might come a time when you want to use your EA in other environments and brokers, at which time it won't work correctly and you will waste time trying to fix something that could have done correctly the first time around. The added bonus of doing it right the first time, is that you can reuse the code for other EA projects.

Think like a professional coder and don't slack off. The same "professional" attitude is also required for successful trading. If you tend to slack-off in one area of your life, you probably do it in other areas too. So develop that trait in yourself to be rigorous in all that you do.

Reason: