Il grande e terribile MT4 per sempre (o come strategizzare una transizione) - pagina 13

 
JRandomTrader:

Ecco dalla documentazione:

"l'ordine in cui queste transazioni arrivano nel terminale non è garantito, quindi non potete basare il vostro algoritmo di trading sull'attesa che alcune transazioni commerciali arrivino dopo che altre sono arrivate. " https://www.mql5.com/ru/docs/event_handlers/ontradetransaction

E per esperienza, le transazioni TRADE_TRANSACTION_ORDER_DELETE, TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_HISTORY_ADD possono arrivare in qualsiasi ordine.

Quindi abbiamo situazioni in cui non c'è ancora un accordo e un ordine nella storia, ma l'ordine esiste già. O viceversa, l'ordine è ancora lì, ma l'affare è già stato eseguito. Ma la situazione in cui l'ordine è presente nell'attivo, così come nella storia, è difficilmente possibile.

Non catturo gli eventi, guardo il quadro completo su una nuova zecca.


JRandomTrader:

Infatti, questo è il motivo per cui ho rifiutato di usare la classe CTrade - sta calpestando tutte queste insidie.

Ho una soluzione - ogni EA tiene una lista dei suoi ordini e monitora il loro stato. Questo include stati 'non standard' - 'ordine inviato ma non ancora presente negli ordini attivi' (questo è dove potrebbero raddoppiare), 'ordine cancellato ma non presente nella storia'. Questo aiuta anche con il lavoro simultaneo sullo stesso simbolo durante il netting.

Fino a poco tempo fa usavo una stampella universale che controllava gli ordini mancanti. Ma ad un certo punto ha iniziato a fallire.

Ho aggiunto un'altra stampella personale all'Expert Advisor che ora controlla i propri ordini separatamente.

Sono un sacco di stampelle...

 
Andrey Khatimlianskii:

Sono un sacco di stampelle...

Studiare il problema. Mi imbatto anche in questo: OrderSend market order true, poi PositionsTotal= 0, OrdersTotal = 0, tabelle storiche invariate.

Sembra essere riuscito a scrivere IsSynchronized(). Il codice è un po' pesante. Non ho ancora deciso in quale forma pubblicarla.

 
// Демонстрация открытия дубля позиции в MT5.

#include <Trade\Trade.mqh>

void OnStart()
{
  CTrade Trade;
  
  while (!IsStopped() && (PositionsTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (PositionsTotal() == 1)
      Trade.PositionClose(PositionGetTicket(0)); // Если есть позиция - закрываем.
    else if (!OrdersTotal())
      Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
}

Esegui questo codice su un conto demo vuoto e vedi se due posizioni si aprono dopo pochi secondi.


La stessa logica su MT4 si presenta così.

void OnStart()
{
  while (!IsStopped() && (OrdersTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0) // Если есть позиция - закрываем.
    else
      OrderSend(_Symbol, OP_BUY, 0.01, Ask, 0, 0, 0) // Если нет позиции и ордера - открываем позицию.
}

È chiaro che tale codice su MT4 non causerà l'inversione di posizione. Ma non su MT5.

 
fxsaber:

Esegui questo codice su un conto demo vuoto e vedi se due posizioni si aprono dopo pochi secondi.


La stessa logica su MT4 si presenta così.

È chiaro che tale codice su MT4 non causerà l'inversione di posizione. Ma non su MT5.

Infine, l'hai appena scoperto? Questo problema è vecchio come il terminale stesso. Ma alla fine gli utenti del terminale l'hanno notato... dopo un decennio.

Quando si eseguono azioni commerciali da soli, il problema può essere risolto in modo semplice - inserire Sleep() per un secondo dopo l'esecuzione dell'azione. Ma quando l'EA usa stoploss/stackprofit e chiusura del mercato, c'è il pericolo di incontrare questo problema, e in questo caso non c'è soluzione.

 
Dmitry Fedoseev:

Finalmente, l'hai appena scoperto? Questo problema è vecchio come il terminale stesso. Ma gli utenti del terminale lo hanno finalmente notato... dopo un decennio.

Il problema è stato discusso per molto tempo. Quasi tutti l'hanno incontrato. È la prima volta che un codice che lo riproduce costantemente.

Quando si eseguono azioni commerciali da soli, è possibile risolvere il problema in modo semplice - inserire Sleep() per un secondo dopo che l'azione è stata eseguita. Ma quando Stop Loss/StackProfit e la chiusura del mercato sono usati in un EA, c'è il pericolo di incontrare il problema, e non c'è soluzione in questo caso.

La soluzione è stata trovata.

 
fxsaber:

Esegui questo codice su un conto demo vuoto e vedi se due posizioni si aprono dopo pochi secondi.

Strano. Non si riproduce. Controllato su demo da MQ, build 2900, EURUSD, zero spread. Ho aspettato circa cinque minuti.

Forse devo usare qualche server specifico di un vero DC/broker e non il server MQ?

 
Ihor Herasko:

Strano. Non si riproduce. Controllato su demo da MQ, build 2900, EURUSD, zero spread. Ho aspettato circa cinque minuti.

Forse devo usare qualche server specifico di un vero DC/broker e non il server MQ?

ForexTimeFXTM-Demo01

 
fxsaber:

ForexTimeFXTM-Demo01

Sì, ora lo script si ferma. Ma c'è ancora un posto libero. Immagino che il secondo abbia il tempo di chiudersi?

 
Ihor Herasko:

Sì, ora lo script si ferma. Ma c'è ancora una posizione libera. Il secondo deve avere il tempo di chiudere?

Me ne restano sempre due. Se ne rimane uno, è ancora di più un bug:

  1. PositionsTotal = 1 - invia un ordine di chiusura.
  2. Allora PositionsTotal = 2 e l'ordine dal punto 1 è chiuso.
 
fxsaber:

Me ne restano sempre due. Se ne rimane uno, è un bug ancora più grande:

  1. PositionsTotal = 1 - invia un ordine di chiusura.
  2. Allora PositionsTotal = 2 e l'ordine dal punto 1 è chiuso.

Sì, è quello che voglio dire. Si scopre che lo script riesce a chiudere una delle posizioni quando in realtà ce ne sono due, ma PositionsTotal() restituisce 1. E poi, dopo la chiusura, la condizione della terminazione del ciclo è soddisfatta, cioè PositionsTotal() restituisce 2.

Motivazione: