Home > Blog > Off quotes / Requote su MT5 — errore 10021

MT5MQL5ErroriRisoluzione problemiEA

Off quotes / Requote su MT5 — errore 10021

Pubblicato: 2026-07-07Lettura: circa 8 min
This article reflects information as of its publish date. EA performance figures (PF, DD, annual return) change with live trading and re-validation — check the latest on the EA pages. See the latest EA results

Off quotes / Requote (MT5/MQL5) risolti definitivamente

Quando si fa girare un EA e nel Journal o nella tab Experts compaiono off quotes (10021) o requote (10004), sembra quasi che il broker abbia rifiutato l'esecuzione, ed è naturale preoccuparsi. In realtà entrambi non sono un problema di margine o di lotti, ma di prezzo: il prezzo che avete inviato e il prezzo che il server aveva in quel momento non coincidevano, punto. Le cause si riducono quasi sempre a una di queste quattro: movimento improvviso del mercato, deviation troppo stretta, tipo di esecuzione, o latenza di connessione.

Questo articolo è pensato sia per chi utilizza EA su MT5 sia per chi sviluppa in MQL5, e riunisce in un'unica guida definitiva la natura, le cause, le soluzioni immediate e le contromisure permanenti a livello di codice per 10021 (TRADE_RETCODE_PRICE_OFF), 10004 (TRADE_RETCODE_REQUOTE) e gli errori 136/138 dell'era MT4. Per l'elenco completo dei codici di errore consultate la Guida completa ai codici di errore MQL5 / MT5.

Questo articolo fa riferimento a MT5 (build serie 4xxx) a luglio 2026. I dettagli del comportamento (se viene restituito un requote oppure l'ordine viene eseguito comunque) variano a seconda del broker e del tipo di esecuzione.


Che differenza c'è tra questi due (+ 136/138 di MT4)?

I rifiuti legati al "prezzo non corrispondente" si dividono in due tipi, a seconda di come risponde il server.

① TRADE_RETCODE_PRICE_OFF = 10021 (nessuna quotazione disponibile per elaborare la richiesta)

È il valore che compare in MqlTradeResult.retcode come risultato di OrderSend(), e indica un rifiuto del tipo "non ci sono quotazioni per elaborare la richiesta" (There are no quotes to process the request). Significa che il server non dispone di un prezzo valido, oppure che il prezzo inviato è troppo distante dalla quotazione corrente per poter essere elaborato.

Significato: nessuna quotazione disponibile per elaborare la richiesta
Costante   : TRADE_RETCODE_PRICE_OFF
Valore     : 10021

② TRADE_RETCODE_REQUOTE = 10004 (requote = nuova proposta di prezzo)

Anche questo è un retcode restituito da OrderSend(), ma qui non si tratta di un semplice rifiuto: è una nuova proposta ("con questo prezzo non si può, ma che ne dite di questo nuovo prezzo?"). I campi bid / ask di MqlTradeResult conterranno il nuovo prezzo proposto dal server.

Significato: requote — nuova proposta di prezzo
Costante   : TRADE_RETCODE_REQUOTE
Valore     : 10004
// Esempio tipico visibile nel log
2026.07.07 21:30:02.118 EA_NAME EURUSD,M5: OrderSend error 10004 (requote)
2026.07.07 21:30:02.310 EA_NAME EURUSD,M5: OrderSend error 10021

③ Gli errori 136 / 138 dell'era MT4

In MQL4 (MT4) lo stesso fenomeno veniva restituito tramite i codici di errore di GetLastError().

Costante MT4ValoreRetcode MT5 corrispondente
ERR_OFF_QUOTES13610021 (TRADE_RETCODE_PRICE_OFF)
ERR_REQUOTE13810004 (TRADE_RETCODE_REQUOTE)

Se in vecchi articoli o nei log di EA per MT4 trovate "error 136" o "error 138", i contenuti di questo articolo si applicano direttamente (in MT4 la prassi era richiamare RefreshRates() per aggiornare il prezzo prima di reinviare l'ordine; il modo di procedere in MT5 è descritto più avanti).

Distinzione pratica:

RetcodeCosa dice il serverAzione che l'EA dovrebbe intraprendere
10004 (requote)"Il prezzo si è mosso, ecco una nuova proposta"Reinviare con il prezzo aggiornato (o rinunciare)
10021 (price off)"Non ci sono quotazioni disponibili per elaborare"Attendere un attimo e reinviare con l'ultimo tick

Entrambi sono errori temporanei (ritentabili): non è possibile eliminarli del tutto con modifiche al codice o alla configurazione, ma la frequenza può essere ridotta in modo significativo.


Una prima diagnosi in 30 secondi

  1. Verificate quando si è verificato l'errore guardando l'orario nel Journal
    • Nel preciso momento di un dato macroeconomico (payroll, FOMC, ecc.) → è un normale movimento improvviso del mercato. Se l'EA ha un filtro news, attivatelo
    • Intorno alla mezzanotte ora server (rollover) o nei gap di inizio settimana → fascia oraria con quotazioni scarse. Rientra nella normalità
    • Frequenza casuale indipendente dall'orario → sospettate la connessione, il VPS o le impostazioni di deviation
  2. Verificate su quale strumento si è verificato
    • Se è concentrato su strumenti a bassa liquidità come coppie minori, esotiche o CFD, la causa è la scarsità di quotazioni dello strumento stesso
  3. Provate a inviare l'ordine manualmente
    • Se l'ordine rapido manuale passa regolarmente ma solo l'EA viene rifiutato, è molto probabile che la deviation (slippage massimo tollerato) dell'EA sia impostata in modo troppo stretto

Da questi tre controlli potrete già intuire se la causa è "il mercato", "lo strumento" o "le impostazioni/l'ambiente", e passare quindi alle soluzioni specifiche per ciascuna causa.


Cause e soluzioni (5 casi)

① Movimento improvviso del mercato / spike su dati macro (il prezzo inviato è diventato obsoleto prima di arrivare)

Sintomo: 10004/10021 concentrati nell'orario di pubblicazione di dati economici, dichiarazioni di banchieri centrali, o nelle prime ore del lunedì.

Causa: l'EA riceve un tick, calcola il prezzo, e nelle decine o centinaia di millisecondi che intercorrono prima che l'ordine raggiunga il server, il prezzo si muove di alcuni pips. Il prezzo inviato non esiste già più, quindi il server restituisce un requote (10004) o un errore di assenza quotazioni (10021). Più che un errore vero e proprio, è un fenomeno del tutto normale in un mercato veloce.

Soluzioni:

  1. Bloccare i nuovi ingressi prima e dopo i dati macro (filtro news). Gli EA distribuiti su questo sito integrano di serie EconomicFilter
  2. Ampliare la deviation (slippage tollerato) a un valore realistico (vedi punto ②)
  3. Implementare una logica di retry (vedi codice più avanti)

② Deviation (slippage tollerato) impostata in modo troppo stretto

Sintomo: l'errore compare a intermittenza anche in mercati tranquilli. L'ordine manuale passa, ma solo l'EA viene rifiutato.

Causa: MqlTradeRequest.deviation dichiara "fino a quanti punti di scostamento dal prezzo inviato sono accettabili". Se questo valore viene impostato tra 0 e pochi punti, anche il normale aggiornamento dei tick può causare un rifiuto. Un errore classico è anche la confusione tra punti (points) e pips (per un broker a 5 cifre, 1 pip = 10 points).

Soluzioni:

  1. Provare partendo da un valore di deviation tra 10 e 30 points (= 1-3 pips). Se non si tratta di uno scalper, 20 points è un buon punto di partenza
  2. Verificare che non ci sia uno scambio di unità, come impostare deviation=5 pensando fossero 0,5 pips
  3. Se la strategia non tollera alcun tipo di slippage, accettare il rifiuto come inevitabile e limitarsi a controllare il numero di retry

③ Differenza nel tipo di esecuzione (il requote è un fenomeno tipico dell'esecuzione instant)

Sintomo: frequente con il broker A, mai visto con il broker B.

Causa: il requote (10004) è un fenomeno tipico della esecuzione instant (instant execution). Con l'esecuzione instant l'ordine dice "eseguimi a questo prezzo", quindi se il prezzo si è mosso il server ripropone un nuovo prezzo (requote). Con l'esecuzione market (market execution), invece, l'ordine dice "eseguimi al prezzo di mercato attuale": in questo caso il requote non può verificarsi per definizione, e al suo posto l'ordine viene semplicemente eseguito al prezzo effettivo (con slippage).

In altre parole, "niente requote" non significa "broker migliore": è un compromesso tra essere rifiutati o subire slippage. Il tipo di esecuzione dello strumento si può verificare nella scheda "Specifica del simbolo" di MT5, alla voce Execution, oppure via codice con SYMBOL_TRADE_EXEMODE.

Soluzioni:

  1. Verificare il tipo di esecuzione del proprio conto (molti conti standard dei broker internazionali usano l'esecuzione market, dove il requote non si presenta affatto)
  2. Se i requote frequenti ostacolano la strategia, valutare un tipo di conto o un broker con esecuzione market
  3. Anche in esecuzione market esistono broker che rispettano la deviation e altri che non lo fanno; se non si tolleri uno slippage eccessivo, verificare lo slippage reale nello storico delle esecuzioni

④ Fasce orarie o strumenti con quotazioni scarse o ferme

Sintomo: il 10021 compare intorno alla mezzanotte ora server (rollover), subito dopo l'apertura di lunedì, nei periodi di bassa liquidità come Natale, o su strumenti minori.

Causa: durante il rollover, il flusso delle quotazioni può interrompersi temporaneamente o lo spread può allargarsi in modo estremo a causa dell'elaborazione degli swap. Subito dopo l'apertura del lunedì o su strumenti a bassa liquidità, le quotazioni disponibili per l'elaborazione sono già di per sé scarse. Se si invia un ordine in queste condizioni, si ottiene 10021 (nessuna quotazione).

Soluzioni:

  1. Evitare nuovi ingressi tra le 23:55 e le 0:05 circa ora server (filtro orario)
  2. Evitare i primi minuti dopo l'apertura del lunedì (impostazioni tipo AvoidMondayOpen)
  3. Inserire un filtro spread (MaxSpread). Nelle fasce orarie con quotazioni scarse lo spread tende ad allargarsi, quindi questo filtro evita automaticamente tali periodi

⑤ Latenza di connessione (il VPS è lontano dal server del broker)

Sintomo: frequenza chiaramente più alta rispetto ad altri ambienti, indipendentemente da orario e strumento. Valore di ping elevato.

Causa: più è lungo il tempo di andata e ritorno (latenza) necessario perché l'ordine raggiunga il server, più aumenta la probabilità che il prezzo si muova nel frattempo. Se si opera da un PC di casa o da un VPS in una regione lontana dalla sede dei server del broker (spesso Londra, New York, ecc.), la frequenza di 10004/10021 aumenta strutturalmente. Il ping mostrato in basso a destra in MT5 è un buon indicatore (alcune centinaia di millisecondi sono chiaramente svantaggiose, mentre valori sotto le decine di millisecondi sono l'ideale).

Soluzioni:

  1. Controllare il valore di ping in basso a destra in MT5: se è costantemente alto, rivedere l'ambiente di esecuzione dell'EA
  2. Spostarsi su un VPS in una regione vicina al server del broker. In tutta onestà, la quota di 10004/10021 dovuta alla latenza non si può ridurre via codice: l'unica soluzione è avvicinarsi fisicamente. Per i criteri di scelta consultate Come scegliere un VPS per EA
  3. L'impatto della latenza è maggiore per gli EA scalper; per EA su timeframe giornaliero o H4 questa causa ha priorità più bassa

Codice MQL5 per ridurre questo errore (per chi sviluppa EA)

L'approccio si basa su tre punti: (1) impostare una deviation realistica, (2) in caso di rifiuto, recuperare l'ultimo tick e reinviare, (3) limitare i retry ai soli retcode legati al prezzo.

Impostare la deviation in modo appropriato, in punti

MqlTradeRequest req; MqlTradeResult res;
ZeroMemory(req); ZeroMemory(res);
req.action    = TRADE_ACTION_DEAL;
req.symbol    = _Symbol;
req.type      = ORDER_TYPE_BUY;
req.volume    = lots;
req.deviation = 20;   // Slippage tollerato: 20 points (a 5 cifre, 2.0 pips)
// impostare anche req.price / req.sl / req.tp / req.magic, ecc.

L'unità di deviation sono i points. Con un broker a 5 (o 3) cifre, 10 points = 1 pip. Un valore pari a 0 o estremamente piccolo aumenta inutilmente la percentuale di rifiuti.

Ritentare solo sui retcode legati al prezzo (reinviando con l'ultimo tick)

Il punto chiave è recuperare il prezzo aggiornato tramite SymbolInfoTick() a ogni tentativo (reinviare con il prezzo vecchio produrrebbe soltanto lo stesso rifiuto), e limitare i retry ai soli 10004/10021. Ritentare meccanicamente anche in caso di margine insufficiente (10019) o richiesta non valida (10013) non ha alcun senso e serve solo a intasare i log.

bool IsRetryableRetcode(uint rc)
{
   return (rc == TRADE_RETCODE_REQUOTE       // 10004
        || rc == TRADE_RETCODE_PRICE_OFF);   // 10021
}

// Reinvia fino a un massimo di 3 volte, aggiornando il prezzo con l'ultimo tick
bool SendWithRetry(MqlTradeRequest &req, MqlTradeResult &res, int maxTries = 3)
{
   for(int attempt = 0; attempt < maxTries; attempt++)
   {
      MqlTick tick;
      if(!SymbolInfoTick(req.symbol, tick))
      {
         Print("SymbolInfoTick failed: ", GetLastError());
         return false;
      }
      req.price = (req.type == ORDER_TYPE_BUY) ? tick.ask : tick.bid;

      if(OrderSend(req, res) && res.retcode == TRADE_RETCODE_DONE)
         return true;                          // Esecuzione riuscita

      if(!IsRetryableRetcode(res.retcode))
      {
         PrintFormat("OrderSend failed (no retry): retcode=%d", res.retcode);
         return false;                         // Non ritentare per retcode non legati al prezzo
      }
      PrintFormat("Retry %d/%d after retcode=%d", attempt + 1, maxTries, res.retcode);
      Sleep(200 + 150 * attempt);              // Attese crescenti: 200ms → 350ms → 500ms
   }
   Print("Order abandoned after retries (price kept moving).");
   return false;
}

L'attesa crescente in Sleep() serve perché, nel momento di uno spike improvviso, inviare ordini a raffica senza alcuna pausa produrrebbe solo lo stesso rifiuto ripetutamente. Attendere troppo, però, allontana il prezzo di ingresso da quanto previsto dalla strategia: è quindi opportuno rinunciare dopo 2-3 tentativi. Da notare che, in caso di ordine pendente (TRADE_ACTION_PENDING), il retcode di successo è TRADE_RETCODE_PLACED (10008).

Usare il prezzo di riproposta del requote (10004)

In caso di 10004, i campi bid / ask di MqlTradeResult contengono il nuovo prezzo proposto dal server. Reinviare con l'ultimo tick come mostrato sopra è già sufficiente nella pratica, ma se si vuole costruire una logica per l'esecuzione instant del tipo "accetta se il nuovo prezzo proposto rientra in un intervallo tollerabile", basta confrontare in points la differenza tra res.ask / res.bid e il prezzo originariamente previsto, prima di decidere se reinviare.

Creare fasce orarie in cui non si invia affatto l'ordine

Il retry via codice è un rimedio sintomatico. Un filtro che blocchi i nuovi ingressi intorno al rollover, ai dati macro o durante l'allargamento dello spread è una soluzione molto più radicale.

// Esempio di filtro spread: rinuncia ai nuovi ingressi quando lo spread è ampio
long spreadPts = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
if(spreadPts > MaxSpreadPoints)
{
   // Rinuncia al nuovo ingresso (evita automaticamente le fasce orarie in cui è probabile il 10021)
   return;
}

Gli EA distribuiti da FXEA365 implementano di serie questo filtro spread, filtro news e retry automatico sui retcode legati al prezzo.


Checklist delle priorità

PrioritàVerificaSoluzione
🚨 Prima cosaÈ concentrato nei momenti di pubblicazione dati / movimenti improvvisi?Attivare il filtro news, oppure accettarlo come normale in quella fascia oraria
🚨 Prima cosaLa deviation è troppo piccola (attenzione, l'unità è points)?Portarla a 10-30 points, verificare eventuali scambi pips/points
⚠️ PoiÈ concentrato su rollover, apertura di lunedì, strumenti poco scambiati?Filtro orario + filtro spread
⚠️ PoiIl tipo di esecuzione è instant?Valutare anche un conto con esecuzione market (compromesso con lo slippage)
⚠️ PoiIl ping è elevato (alcune centinaia di ms)?Spostarsi su un VPS più vicino al server
🛠 SviluppoIl retry è limitato ai retcode legati al prezzo?Aggiornare con SymbolInfoTick e fermarsi dopo 2-3 tentativi

In sintesi

  • 10021 (TRADE_RETCODE_PRICE_OFF) significa "nessuna quotazione disponibile per elaborare la richiesta", 10004 (TRADE_RETCODE_REQUOTE) significa "nuova proposta di prezzo". Appartengono alla stessa famiglia di rifiuti legati al prezzo degli errori 136/138 dell'era MT4, e non sono un problema di margine o di lotti.
  • Le cause si riducono a cinque: movimento improvviso del mercato, deviation troppo piccola, esecuzione instant, fasce orarie/strumenti con quotazioni scarse, latenza di connessione.
  • Il requote è un fenomeno tipico dell'esecuzione instant; con l'esecuzione market si manifesta invece come slippage. "Non comparire" non equivale a "essere migliore": è un compromesso.
  • Chi sviluppa EA dovrebbe adottare come contromisura permanente 2-3 retry limitati a 10004/10021 con aggiornamento dell'ultimo tick, una deviation adeguata, e filtri orari/spread. Solo la quota dovuta alla latenza si può ridurre esclusivamente con una soluzione fisica (VPS vicino al broker).

Per l'elenco completo dei codici di errore consultate la Guida completa ai codici di errore MQL5 / MT5; per gli EA gratuiti che implementano di serie queste contromisure, consultate l'Elenco EA.


FAQ

D: Tra 10004 e 10021, quale dei due è più grave?

Sono entrambi errori temporanei legati al prezzo, senza grandi differenze di gravità. 10004 significa "è stata proposta una nuova quotazione", 10021 significa "non c'erano quotazioni disponibili per elaborare la richiesta". Se si tratta di un episodio isolato non c'è nulla di cui preoccuparsi; solo se si ripete frequentemente in una determinata fascia oraria o su un determinato strumento conviene individuare ed eliminare la causa (dati macro, rollover, deviation, connessione).

D: Un broker su cui non compare mai il requote è migliore?

È molto probabile che si tratti semplicemente di una differenza nel tipo di esecuzione. Nei conti con esecuzione market il requote non può verificarsi per definizione, e se il prezzo si è mosso l'ordine viene semplicemente eseguito al prezzo effettivo (con slippage). È un compromesso tra rifiuto e slippage, quindi conviene verificare lo slippage reale nello storico delle esecuzioni prima di trarre conclusioni.

D: Con un EA per MT4 compaiono gli errori 136 / 138. Vanno bene le stesse soluzioni?

Sì. Il 136 (ERR_OFF_QUOTES) corrisponde al 10021, il 138 (ERR_REQUOTE) corrisponde al 10004: cause e soluzioni sono le stesse. In MQL4 la prassi era richiamare RefreshRates() prima di reinviare per aggiornare Bid / Ask, un approccio identico nel concetto al recupero del prezzo tramite SymbolInfoTick() in MQL5.

D: Nel backtest non compare mai, ma in live sì. Perché?

È normale. Nello Strategy Tester non esiste (o è estremamente semplificato) il "ritardo necessario perché l'ordine raggiunga il server" e la conseguente variazione di prezzo in quell'intervallo, quindi 10004/10021 emergono solo in forward/live. Anche se il backtest dà buoni risultati, in produzione servono comunque un'impostazione adeguata della deviation, un sistema di retry e un ambiente di esecuzione (VPS) ben configurato.

📧 Avvisi prima degli aumenti di prezzo + corso email gratuito di 5 giorni

Tutti gli EA sono a prezzo di lancio e salgono a scatti con le vendite. Ricevi un avviso prima di ogni aumento, più un'email al giorno su trading algoritmico, lettura dei backtest e scelta del broker.

* Privacy rigorosamente protetta. Potete cancellarvi in qualsiasi momento.

Commenti e domande