MT4 · code and request checks
MT4 error 136: check the quote before another retry
Your EA can retry and still hit off quotes. My native MT4 run passed three synthetic policy cases with zero order calls. It did not reproduce or fix broker error 136.

Arnold Holm · 2026-10-29
What the error means
An EA is a program that applies your trading rules in MT4. A quote is the current Bid and Ask for one symbol plus its time. Error 136 is an off quotes result. The number alone does not say if the local quote was missing, the wrong price was used, or no usable price was there. James said even 10 to 15 attempts still returned the same error. His helper read the chart symbol price and sent for the passed pair. A reply correctly noted that mix uses the wrong price when symbols differ. James fixed that line but said he currently trades only the chart symbol. So that note does not explain his failures. Without per attempt symbol, prices, quote time and error, the cause stays open. The official MQL4 error table lists 136 as ERR_OFF_QUOTES, Off quotes. RefreshRates refreshes predefined variables and series data for the current symbol. True means data were updated. False can mean the local copy was already current, not broker acceptance. Waiting or refreshing does not promise the next attempt will clear. I ran a small native check in MT4 4.0.0.1491. It compiled with zero errors and zero warnings. It ran in the Strategy Tester on offline EURUSD H4 supplied history with fixed spread 20 points. The policy wants positive ordered Bid and Ask, quote age no more than five seconds, an unexpired signal and fewer than one prior consideration. Zero quote inputs returned NO_RETRY. Expired signal inputs returned NO_RETRY. Fresh inputs returned ELIGIBLE_ONCE, then NO_RETRY with alreadyConsidered at 1. The proof image shows the original tester log in a browser, not an MT4 terminal screenshot. These are three chosen cases, not full coverage. The five second and one consideration limits are illustrative choices, not universal settings. The function does no waiting, no persistence, no network access, no orders and no duplicate checks. Your caller must keep its own count. Eligibility only allows one more review of all execution checks, never a trade by itself. I check the quote and the still-valid signal before considering another attempt.
Three code paths to check
1. The quote is missing or unusable
Bid or Ask is zero, Ask is below Bid, or the quote time is old or ahead of now. My zero price case returned NO_RETRY. Log the request symbol with Bid, Ask and quote time before any further review.
2. The price comes from the wrong symbol
The EA reads one symbol and sends for another. That mismatch can send a price the broker cannot use for the requested symbol. Read Bid and Ask for the exact request symbol and keep that symbol with the prices in one log line.
3. The signal or retry budget has expired
The idea has a limited life and the retry plan has a limited count. My expired signal case returned NO_RETRY with good prices. One more attempt after expiry or a spent count is an EA decision bug around the error, not proof of a broker cause. Record expiry and count and stop when either is spent.
A read-only check before one further review
The code is a small read only check for one review after an off quotes result. It wants positive prices with Ask at or above Bid, quote time no older than five seconds and not ahead of now, an unexpired signal and prior count below one. All four together return true. It does no waiting, no persistence, no network access, no orders and no duplicate checks. Bring the same four facts together for your EA. If any check fails, keep the record and wait for a fresh idea instead of looping on stale inputs.
#property strict
// Read-only policy fixture. No broker calls, orders, retries, or strategy rules.
// All inputs below are chosen test values, not observed market failures.
bool finished=false;
// One eligibility check after a prior off-quotes result. Eligibility alone
// never authorizes an order. A caller would still need all its execution gates.
bool RetryEligible(double bid,double ask,datetime quoteAt,datetime signalExpires,
datetime now,int alreadyConsidered)
{
if(bid<=0 || ask<=0 || ask<bid) return false;
if(quoteAt>now || now-quoteAt>5) return false;
if(signalExpires<=now) return false;
if(alreadyConsidered>=1) return false;
return true;
}
void RunCases()
{
if(finished) return;
finished=true;
datetime now=D'2021.05.03 03:00:00';
bool missing=RetryEligible(0,0,now,now+30,now,0);
bool expired=RetryEligible(1.2000,1.2002,now,now-1,now,0);
bool fresh=RetryEligible(1.2000,1.2002,now,now+30,now,0);
bool second=RetryEligible(1.2000,1.2002,now,now+30,now,1);
Print("FIX27_POLICY CASE missing_zero_quote decision=",missing?"ELIGIBLE":"NO_RETRY"," expected=NO_RETRY pass=",!missing);
Print("FIX27_POLICY CASE stale_signal decision=",expired?"ELIGIBLE":"NO_RETRY"," expected=NO_RETRY pass=",!expired);
Print("FIX27_POLICY CASE fresh_quote_valid_signal decision=",fresh?"ELIGIBLE_ONCE":"NO_RETRY"," second_decision=",second?"ELIGIBLE":"NO_RETRY"," expected=ELIGIBLE_ONCE_then_NO_RETRY pass=",fresh && !second);
Print("FIX27_POLICY RESULT ",(!missing && !expired && fresh && !second)?"PASS":"FAIL"," chosen_cases=3 order_calls=0 target_error136_reproduced=false");
Print("FIX27_POLICY LIMIT synthetic policy inputs; no OrderSend; no server error136 diagnosis or fix; no execution approval");
}
int OnInit()
{
if(!IsTesting()){Print("FIX27_POLICY FAIL tester_only");return INIT_FAILED;}
RunCases();
return INIT_SUCCEEDED;
}
void OnTick(){}
Native MT4 4.0.0.1491 tester, offline EURUSD H4 supplied history, fixed spread 20 points. Three chosen policy cases with zero order calls. Error 136 was not reproduced or fixed. No broker, execution or profit claim.
How you know it is fixed
Log the exact request and quote
On your next off quotes result, write request symbol, Bid and Ask, quote time, signal expiry, captured error 136 and attempt count in one line. Missing or disordered prices mean no further review of that attempt.
Match price symbol to order symbol
Confirm the price read uses the same symbol as the order call. If your EA only trades the chart symbol, note that in the log so a wrong symbol guess does not replace measured facts.
Enforce signal life and one review budget
Compare now with signal expiry and read your kept count. If the signal expired or you used your one review, close the idea and wait for the next fresh signal. Do not loop on stale inputs.
Your own source
Find the next line to check
Start with the free EA-Check. Your code stays in your browser. It highlights patterns with line numbers; it does not prove the broker accepts an order.
Want one small change shown on your own case?
DEMO0: send the problem and try a free compiled demo first. R49: one authorised, reproducible MT4/MT5 defect in readable source up to 500 lines, with three agreed cases. 49 USD fixed. Delivery within 48 hours after source review and funding. The exact case is agreed before funded work.
Send the expected and actual behaviourRelated checks
Common questions
Does this helper fix error 136?
No. It only checks the quote and the still valid signal before one more review. My three cases made zero order calls and did not reproduce or fix error 136.
Will RefreshRates or waiting cure off quotes?
Not by itself. RefreshRates updates local data for the current symbol. False can mean the data were already current. Log a fresh quote for the request symbol and decide from facts.
Why did 10 to 15 retries still fail?
The thread does not establish the cause. The wrong symbol note was correct but James traded only the chart symbol then. Without per attempt symbol, prices, quote time and error, no code or broker cause is proven.
Sources and limits
- Original question about repeated off-quotes attempts
- Official MQL4 error codes
- Official MQL4 RefreshRates reference
These public questions explain the error; use your own EA log to check whether the same cause applies.