Il mio EA fa una doppia entrata - pagina 4

 
doshur:

posso chiedere se PositionSelect() controlla il lato client o il lato sever?

Ho la forte sensazione che il problema sia causato dal ritardo in cui il server (lato broker) sta elaborando la richiesta e non ha aggiornato il lato client, ecco perché PositionSelect() funziona di nuovo

Ho la forte sensazione che non ci sia alcuna differenza quando usiamo il modo cTrade vs MqlTradeRequest e la funzione Sleep dovrebbe aiutare a ritardare tutto per far sì che il nostro lato client venga "aggiornato" prima che PositionSelect() venga eseguito nuovamente causando una doppia entrata. Controllando dalla mia scheda giornale, >2013.12.20 08:35:00 Trades '800****': exchange buy 0.01 EURUSD at market placed for execution in 313 ms <

mettere sonno più di 400 dovrebbe essere sicuro??

Cosa ne pensi?


"Ho la forte sensazione che il problema sia causato dal ritardo in cui il server (lato broker) sta elaborando la richiesta e non ha aggiornato il lato client, ecco perché PositionSelect() viene eseguito di nuovo"

Penso anche che questa sia la causa del doppio inserimento. Nel mio codice è teoricamente impossibile inviare un nuovo ordine se la dimensione della posizione corrente è uguale o superiore alla dimensione massima della posizione consentita, quindi quando la PositionSelect() non riceve in tempo lo stato della posizione corrente, il mio EA invierà nuovamente un nuovo ordine.


"Mettere in sleep più di 400 dovrebbe essere sicuro???"

Più grande è l'intervallo di tempo e meglio è, ma c'è un problema. Se girate la vostra posizione, in due passi (LONG a SHORT o SHORT a LONG), questo ritardo extra può essere la causa di un cattivo prezzo di esecuzione, specialmente durante eventi macro economici.

 
snelle_moda:


"Ho la forte sensazione che il problema sia causato dal ritardo in cui il server (lato broker) sta elaborando la richiesta e non ha aggiornato il lato client, ecco perché PositionSelect() gira di nuovo"

Penso anche che questa sia la causa del doppio inserimento. Nel mio codice è teoricamente impossibile inviare un nuovo ordine se la dimensione della posizione corrente è uguale o superiore alla dimensione massima della posizione consentita, quindi quando la PositionSelect() non riceve in tempo lo stato della posizione corrente, il mio EA invierà nuovamente un nuovo ordine.


"Mettere uno sleep più di 400 dovrebbe essere sicuro???"

Più grande è l'intervallo di tempo e meglio è, ma c'è un problema. Se girate la vostra posizione, in due passi (LONG a SHORT o SHORT a LONG), questo ritardo extra può essere la causa di un cattivo prezzo di esecuzione, specialmente durante eventi macro economici.

Penso che non dovrebbe essere un problema. Il mio EA non inverte immediatamente quando ho appena inviato una richiesta di acquisto/vendita. Sto mettendo il mio sleep a 800ms in modo che il mio EA abbia tutto il tempo per aspettare gli aggiornamenti del broker. Speriamo che Sleep possa risolvere questo problema qui.
 
doshur:
Non so se il broker gioca a parte qui, ma sembra che il nostro broker sia lo stesso. Alpari.

Pls rimuovere il nome del broker se necessario.
Sì, il broker è lo stesso.
 
snelle_moda:


Ho avuto 1 altro doppio ingresso dal 03-10-2013. Uso entrambi i metodi per inviare il mio ordine. Vedi il mio post precedente.

ah huh... proprio come mi aspettavo...
 

Questo è quello che ho appena implementato. si spera che possa risolvere il problema

if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0))
            {
               Sleep(800);

               if(m_Trade.ResultRetcode() == 10009)
               {
                  Print("Position opened in ", Symbol());

                  return;
               }
               else
               {
                  Print("Error opening position in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
               }
            }
            else
            {
               Print("Error with PositionOpen in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
            }
 
doshur:

Questo è quello che ho appena implementato. si spera che possa risolvere il problema

Per quanto ne so, un codice di risultato = 10008 indica anche che un trade è ben piazzato.
 

Penso che sia molto importante trovare la ragione dietro questo problema, naturalmente è anche importante avere un workaround (Sleep ?) fino a quando non possiamo capire completamente cosa sta succedendo. Quindi provo a riprendere la situazione:

  • Quando si utilizza il metodo PositionOpen della classe CTrade, almeno 3 utenti hanno ottenuto, in un certo momento, 2 operazioni nella stessa direzione invece di 1, con il risultato di una posizione con un volume raddoppiato rispetto a quello previsto.
  • Il codice postato inizialmente da doshur, può spiegare perché può vedere nel suo log "Position opened in..." mentre nessun trade è stato aperto. Questo perché, anche se PositionOpen() ritorna true, non significa che un trade sia stato piazzato. Vedere la documentazione. Ma non può spiegare perché un trade "doppio" è stato piazzato.
  • Posso vedere solo 2 spiegazioni per questo trade "doppio":
  1. PositionSelect() non sempre restituisce la vera situazione della posizione. Una posizione è aperta ma PositionSelect restituisce false. Bug in PositionSelect allora.
  2. Un trade viene piazzato ma, quando PositionSelect() viene chiamato al prossimo tick, la posizione non esiste ancora. Per capire se è possibile, dobbiamo conoscere il flusso delle operazioni quando viene piazzato un trade.
  • Questo problema sembra verificarsi sullo stesso broker, con un simbolo dove Depth of Market è attivato (gli interessati possono confermarlo per favore).
  • Questo problema si verifica con l'ordine sincrono, l'ordine asincrono non è stato utilizzato (si prega di confermare).
  • Il problema si verifica in modo casuale.
  • Klammeraffe riferisce di non averepiù il problema, ma non vedo come il codice che ha postato possa spiegarlo. Questo codice viene eseguito ad ogni tick? Questo codice viene eseguito dopo l'uso di PositionSelect()? Quindi forse ha rimosso la causa dell'errore o è solo casuale.
  • Dopo aver controllato il codice, non vedo alcuna differenza tra l'uso della classe CTrade o MqlTradeRequest con OrderSend direttamente.

Sono d'accordo con snella_moda che la migliore spiegazione è:

I think the problem is the (to slow) execution of the PositionSelect(Symbol()) function. Maybe, the new ticks come in so fast, the EA sends in a new order before it receives a response of the PositionSelect(Symbol()). So the current position size is not calculated properly. In my code, its theoretically impossible to send in a new/double order if the current position size is equal or greater than the max allowed position size, see code. 

Ma è difficile da controllare.

Penso che la cosa migliore da fare sia chiedere consiglio a Metaquotes. Ci proverò.

 
angevoyageur:
  • Klammeraffe riferisce di non averepiù il problema, ma non vedo come il codice che ha postato possa spiegarlo. Questo codice viene eseguito ad ogni tick? Questo codice viene eseguito dopo l'uso di PositionSelect()? Quindi forse ha rimosso la causa dell'errore o è solo casuale.

La linea riguardante "ogni tick" potrebbe essere il motivo per cui non succede più.

La funzione viene eseguita solo quando appare una nuova barra. Quindi, molto probabilmente, solo il primo tick di una barra può eseguire un trade. Dopo la prima barra, il codice ottiene un 'ritorno' finché non appare una nuova barra. Forse questo mi ha risolto il problema.

Penso che questo pezzo di codice provenga dagli articoli:

//-------------------------------------------------- Check for new bar     
         static datetime OldTime;
         datetime NewTime[1];
         bool newBar=false;
         
         int copied=CopyTime(Symbol(),Period(),0,1,NewTime);
         if (copied>0)
           {
             if (OldTime != NewTime[0])
               {  
                 newBar=true;
                 OldTime=NewTime[0];
               }
           }
         else
           {
            Print("Error in copying historical times data, error =",GetLastError());
            ResetLastError();
            return;
           }  
         if(newBar==false) return;      
//-------------------------------------------------- Check for new bar
 
Klammeraffe:

La linea riguardante "ogni tick" potrebbe essere il motivo per cui non succede più.

La funzione viene eseguita solo quando appare una nuova barra. Quindi, molto probabilmente, solo il primo tick di una barra può eseguire un trade. Dopo la prima barra, il codice ottiene un 'ritorno' finché non appare una nuova barra. Forse questo mi ha risolto il problema.

Penso che questo pezzo di codice provenga dagli articoli:

Sì, penso di sì. Grazie.
 
  • Il codice postato inizialmente da doshur, può spiegare perché può vedere nel suo log "Position opened in..." mentre nessun trade è stato aperto. Questo perché, anche se PositionOpen() ritorna true, non significa che sia stata piazzata una negoziazione,vedi documentazione. Ma non può spiegare perché è stato piazzato un trade "doppio".

correzione. C'è un doppio"Posizione aperta in..." e sono state aperte 2 operazioni.

  • Questo problema sembra verificarsi sullo stesso broker, con un simbolo in cui è attivata la Profondità di mercato (gli interessati possono confermarlo per favore).
Non sono sicuro degli altri, ma il mio ha DOM

  • Questo problema si verifica con l'ordine sincrono, l'ordine asincrono non è stato utilizzato (si prega di confermare).
Sto usando le impostazioni predefinite di cTrade.

  • Il problema si verifica in modo casuale.
sì, casualmente