MQL5 Numerous intermitten 'Invalid Price' (retcode:10015) for market price orders

 

I am unable to determine why the below code fails for 8/10 orders for the '.USTECHCash' (Nasdaq100 Index) in Strategy Tester. It seems to work fine for currency symbols (not 100% verified). I have reached out to support but eventually that didn't go anywhere.

I am hoping someone reading this can tell me what I am doing wrong; note I have distilled the problem to the basics, I don't specify a price (so it's a market order) and have set a large deviation on purpose. 

A video recording of my debugging a successful and failed order can be found here: https://1drv.ms/v/s!AkWFtUMYnskYjocmP-V00KVDekhDjA , below you can see a screenshot of debugged  MqlRequest object for a successful and failed order entry as well. 

Is the history for '.USTECHCash' from MT servers or from my broker ? (myfxchoice), I ask this because it seems the broker can prevent an execution of an order and maybe that flag is part of the Strategy Tester history? 

Failed order

Successful order

Code excerpt

...
if (bEnterTrade == true) {
MqlTradeRequest oTradeRequest = { 0 }; // initalize empty - see: https://www.mql5.com/en/docs/constants/structures/mqltraderequest, https://stackoverflow.com/questions/11152160/initializing-a-struct-to-0
oTradeRequest.action = TRADE_ACTION_DEAL;
oTradeRequest.symbol = SymbolName(i, false);
oTradeRequest.volume = 0.01;
oTradeRequest.type = ORDER_TYPE_BUY;
oTradeRequest.type_filling = _iGetFillingMode(SymbolName(i, false));

// FIXME: which one to use below?
//                              oTradeRequest.price = _dNormalizePrice(SymbolInfoDouble(SymbolName(i, false), SYMBOL_ASK), SymbolName(i, false));
//oTradeRequest.price =  _dNormalizePrice(aCustomEP[0], SymbolName(i, false));

//oTradeRequest.price = 3726.00;

oTradeRequest.deviation = 50 * SymbolInfoInteger(SymbolName(i, false), SYMBOL_SPREAD); //20; // FIXME: strategy tester needs slippage parameter, but we don't seem to for live trading - is using NULL broken but works in live account? someething to do with: https://www.mql5.com/en/forum/31987?
//oTradeRequest.price = aCustomEP[0];

if (bTRADE_ENTERES_IGNORE_SL_TP_IF_PRESENT == false && aCustomSL[0] != EMPTY_VALUE) {
        double dTemp = MathMax(aCustomSL[0], _dAccountEquityMaxRiskAsSymbolPriceStopLoss(Symbol(), dMAX_ACCOUNT_BALANCE_RISK_PERCENT, 0.01));
//                                      oTradeRequest.sl = _dNormalizePrice(dTemp, SymbolName(i, false));
}

if (bTRADE_ENTERES_IGNORE_SL_TP_IF_PRESENT == false && aCustomTP[0] != EMPTY_VALUE) {
//                                      oTradeRequest.tp = _dNormalizePrice(aCustomTP[0], SymbolName(i, false));
}

// see https://www.mql5.com/en/forum/7709
oTradeRequest.comment = EnumToString(iTRADE_ENTERES_SIGNAL); // used to extract the original order number at our custom optimization/testing report generation
MqlTradeResult oTradeResult = { 0 };
ResetLastError();
bool bTradeSuccess = OrderSend(oTradeRequest, oTradeResult);
if (false == bTradeSuccess) {
        string sMarketMode = EnumToString((ENUM_SYMBOL_TRADE_EXECUTION) SymbolInfoInteger(Symbol(), SYMBOL_TRADE_EXEMODE));
        //SymbolInfoInteger(Symbol(),SYMBOL_TRADE_MODE);
        string sTradeAllowed = EnumToString((ENUM_SYMBOL_TRADE_MODE) SymbolInfoInteger(Symbol(), SYMBOL_TRADE_MODE));
        Alert("===OnTick() trade failed: `oTradeResult.retcode=" + oTradeResult.retcode + "`, `_LastError ="
                        + _LastError + "`" + "`, `ErrorDescription(_LastError)=" + ErrorDescription(_LastError)
                        + "`");
}
else {
        string sMarketMode = EnumToString((ENUM_SYMBOL_TRADE_EXECUTION) SymbolInfoInteger(Symbol(), SYMBOL_TRADE_EXEMODE));
        string sTradeAllowed = EnumToString((ENUM_SYMBOL_TRADE_MODE) SymbolInfoInteger(Symbol(), SYMBOL_TRADE_MODE));

        Alert("===OnTick() trade worked: `oTradeResult.retcode=" + oTradeResult.retcode + "`, `_LastError ="
                        + _LastError + "`" + "`, `ErrorDescription(_LastError)=" + ErrorDescription(_LastError)
                        + "`");
}
...
Microsoft OneDrive - Access files anywhere. Create docs with free Office Online.
  • onedrive.live.com
Store photos and docs online. Access them from any PC, Mac or phone. Create and work together on Word, Excel or PowerPoint documents.
 

I have reduced the problem to the most basic trade enterer code and I am still getting about 30+% orders fail ratio. It seems to me a bug in the Strategy Tester - can anyone from MT please comment? Log is attached and the expert used pasted below. 


#property copyright "https://www.mql5.com/en/forum/219144"
#property link      "https://www.mql5.com/en/forum/219144"
#property version   "1.00"
#include "Include/errordescription.mqh" // for things like ErrorDescription

int iOrdersFailed = 0;
int iOrdersSuccess = 0;
int iOrdersTotal = 0;
int OnInit() {  
        return(INIT_SUCCEEDED);
        }

void OnDeinit(const int reason) {
}
  
double OnTester() {
        Print("===" + __FUNCTION__ + "(): DEBUG: `iOrdersTotal=" + iOrdersTotal + "`, `iOrdersFailed=" + iOrdersFailed 
                                + "`, `iOrdersSuccess=" + iOrdersSuccess + "`, % failed=" + NormalizeDouble((iOrdersFailed/(double)iOrdersTotal)*100,2)
                                + "");
        return 0;
}  
  
void OnTick()
  {
        // debug vars
        MqlTick oMqlTick;
        bool bSymbolTickWorked = SymbolInfoTick(Symbol(), oMqlTick);
        string sMarketMode = EnumToString((ENUM_SYMBOL_TRADE_EXECUTION) SymbolInfoInteger(Symbol(), SYMBOL_TRADE_EXEMODE));
        string sTradeAllowed = EnumToString((ENUM_SYMBOL_TRADE_MODE) SymbolInfoInteger(Symbol(), SYMBOL_TRADE_MODE));
        bool sSymbolSynchronized = SymbolIsSynchronized(Symbol());
                
        
        MqlTradeRequest oTradeRequest = { 0 }; // initalize empty - see: https://www.mql5.com/en/docs/constants/structures/mqltraderequest, https://stackoverflow.com/questions/11152160/initializing-a-struct-to-0
        oTradeRequest.action = TRADE_ACTION_DEAL;
        oTradeRequest.symbol = Symbol();
        oTradeRequest.volume = 0.01;
        oTradeRequest.type = ORDER_TYPE_BUY;
        oTradeRequest.type_filling = ORDER_FILLING_RETURN;

        oTradeRequest.deviation = 500 * SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE); //20; // FIXME: strategy tester needs slippage parameter, but we don't seem to for live trading - is using NULL broken but works in live account? someething to do with: https://www.mql5.com/en/forum/31987?
        
        MqlTradeResult oTradeResult = { 0 };
        ResetLastError();
        bool bTradeSuccess = OrderSend(oTradeRequest, oTradeResult);
        iOrdersTotal++;
        if (false == bTradeSuccess) {
                iOrdersFailed++;
                Alert("===" + __FUNCTION__ + "(): ERROR: trade failed `oTradeResult.retcode=" + oTradeResult.retcode + "`, `_LastError ="
                                + _LastError + "`" + "`, `ErrorDescription(_LastError)=" + ErrorDescription(_LastError)
                                + "`");
                Print("===" + __FUNCTION__ + "(): DEBUG: `oMqlTick.ask=" + oMqlTick.ask + "`, `oTradeRequest.price=" + oTradeRequest.price 
                                + "`, `oTradeRequest.deviation=" + oTradeRequest.deviation + "`, 'Market Watch: Ask' just before order sent=XXXX"
                                + "");
                
        }
        else {
                iOrdersSuccess++;
                Alert("===OnTick() trade worked: `oTradeResult.retcode=" + oTradeResult.retcode + "`, `_LastError ="
                                + _LastError + "`" + "`, `ErrorDescription(_LastError)=" + ErrorDescription(_LastError)
                                + "`");
                Print("===" + __FUNCTION__ + "(): DEBUG: `oMqlTick.ask=" + oMqlTick.ask + "`, `oTradeRequest.price=" + oTradeRequest.price 
                                + "`, `oTradeRequest.deviation=" + oTradeRequest.deviation + "`, 'Market Watch: Ask' before order sent=XXXX"
                                + "");
        }
  }
Files:
20171110.log  247 kb
Reason: