Problema di ordini multipli - pagina 2

 

Ciao Raptor;

Mentre in Tester tutti gli ordini vengono chiusi quando il TrailingStop si chiude, su Demo si chiude solo l'ordine chiuso con il TrailingStop, qualsiasi ordine che è aperto rimane aperto.

Usando il seguente codice sopra quello da te consigliato la logica è;

"Trova qual è la condizione dell'ultimo ordine, se era una chiusura allora esegui il codice per iniziare a chiudere tutti i rimanenti ordini aperti".

Qualche indizio sul perché questo accada?

Cordiali saluti

Luis

int OrdType, GLError;
   double OrderClosed;
   RefreshRates();
   
    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--) 
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)
        && OrderMagicNumber()== MagicNumber
        && OrderSymbol()== Symbol())
        {//29
        OrderClosed = OrderCloseTime();
        if(OrderClosed!=0)
           {//30                                  
   for(int OrderPos = OrdersTotal()-1; OrderPos >= 0; OrderPos--)       
      if(OrderSelect(OrderPos, SELECT_BY_POS, MODE_TRADES)
         && OrderMagicNumber()== MagicNumber 
         && OrderSymbol()== Symbol())                                       
         {//31
         OrdType = OrderType();
         if(OrdType == OP_BUY || OrdType==OP_SELL)
           {//32
           if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),RealSlippage, Yellow))
               GLError = GetLastError();
           }//32                                         
          }//31
       }//30
     }//29 
    
  if(GLError > 0) Print("Error Closing/Deleting Order, error # ", GLError, " for ticket: ", OrderTicket());           
  return(0);
  }//0 
 
luisneves:

Ciao Raptor;

Mentre in Tester tutti gli ordini vengono chiusi alla chiusura del TrailingStop, su Demo si chiude solo l'ordine chiuso con il TrailingStop, qualsiasi ordine aperto rimane aperto.

Usando il seguente codice sopra quello da te consigliato la logica è;

"Trova qual è la condizione dell'ultimo ordine, se era una chiusura allora esegui il codice per iniziare a chiudere tutti i rimanenti ordini aperti".

Qualche idea sul perché questo accada?

Non si può fare questo. . .

    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--)    // OrdersTotal is the total of open orders
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)        //  this is looping through the closed orders

. . . non ha senso usare il numero di ordini aperti come condizione iniziale del ciclo per poi passare agli ordini chiusi. Forse volevi usareOrdersHistoryTotal()? ma OrderCloseTime() di un ordine chiuso non sarà mai == 0

 
luisneves:

.....

Sto usando BuyTicket e SellTicket nel codice per evitare l'apertura di ordini multipli ma sembra che non sia il metodo giusto...

.....

Il problema arriva quando arriva una condizione per aprire un terzo ordine e così via. Qui, tuttavia, le condizioni di apertura ci sono e il codice ha affrontato bene la seconda apertura, perché il codice non funziona qui?

Capisco che hai cambiato leggermente l'argomento iniziale e forse il primo problema è stato discusso fino alla fine (per me va bene)
Se vuoi ancora dare un seguito al tema iniziale, devi spiegarlo un po' meglio, perché non capisco bene cosa stai cercando.

Il primo frammento che ho modificato impedisce al codice di aprire più ordini. Sembravi non essere contento, quindi l'hai rimosso (o semplicemente non aggiunto), ma facendo la cosa simile usando BuyTicket e SellTicket.
Poi parli di un terzo ordine... Cercate qualcosa del genere?

Acquisto->Vendita->Acquisto->Vendita->Acquisto
ma impedisci
Compra->Compra->Vendi->Compra->Compra

In altre parole, se l'ultimo ordine aperto è un ordine di acquisto, il prossimo deve essere di vendita e viceversa?

Oppure qual è la quantità massima di ordini che il tuo EA dovrebbe aprire? Sono 2, una vendita e se la condizione per un ordine opposto è soddisfatta, un acquisto, ma non più una vendita se rimbalza di nuovo dal trigger di acquisto?
Se questo è vero, qual era il problema con il contatore OpenOpposite che ho aggiunto al tuo codice iniziale?

modifica:

La terza opzione che posso immaginare è che tu voglia aprire un altro ordine opposto se il primo ordine opposto è stato fermato?
Quindi come questo:

Buy->Sell->se Sell è stato fermato->Sell->se Sell è stato fermato->Sell

 
kronin:

Ho capito che hai cambiato leggermente l'argomento iniziale e forse il primo problema è stato discusso fino alla fine (per me va bene)
Se vuoi ancora seguire il tema iniziale, devi spiegarlo un po' meglio, perché non capisco bene cosa stai cercando.

Il primo frammento che ho modificato impedisce al codice di aprire più ordini. Sembravi non essere contento, quindi l'hai rimosso (o semplicemente non aggiunto), ma facendo la cosa simile usando BuyTicket e SellTicket.
Poi parli di un terzo ordine... Cercate qualcosa del genere?

Acquisto->Vendita->Acquisto->Vendita->Acquisto
ma impedisci
Compra->Compra->Vendi->Compra->Compra

In altre parole, se l'ultimo ordine aperto è un ordine di acquisto, il prossimo deve essere di vendita e viceversa?

Oppure qual è la quantità massima di ordini che il tuo EA dovrebbe aprire? Sono 2, una vendita e se la condizione per un ordine opposto è soddisfatta, un acquisto, ma non più una vendita se rimbalza di nuovo dal trigger di acquisto?
Se questo è vero, qual era il problema con il contatore OpenOpposite che ho aggiunto al tuo codice iniziale?

modifica:

La terza opzione che posso immaginare è che tu voglia aprire un altro ordine opposto se il primo ordine opposto è stato fermato?
Quindi come questo:

Comprare->Vendere->se Vendere è stato fermato->Vendere->se Vendere è stato fermato->Vendere


Ciao Kronin,

Ti ringrazio in anticipo per il tempo che mi dedicherai in questo problema.

La strategia osserva questa logica;

Diciamo che il primo ordine da aprire è un acquisto e poi cerca di chiudere in base al TrailingStop, ma se il Bid rimbalza in basso di qualche pip sotto l'OrderOpenPrice(ReturnDistance), si aprirà un Sell e cercherà di chiudere in base al TrailingStop e ancora se l'Ask rimbalza in alto di qualche pip sopra l'OrderOpenPrice allora si aprirà un buy. Questo processo di ping pong terminerà quando l'ultimo ordine aperto chiuderà in base al TrailingStop o raggiungerà il numero massimo di ordini impostati, che è 7 (si può regolare questo per via esterna).

Il problema con le aperture multiple si verifica quando il prezzo sale e scende attraversando l'OrderOpenPrice. Quindi, se abbiamo un acquisto il prossimo ordine può essere una vendita e così via.

Per quanto riguarda il vostro aiuto precedente, forse non ho spiegato bene quale fosse il mio problema. Qualsiasi aiuto fornito ha per me il massimo del valore.

Cordiali saluti

Luis

 

Luis, ho passato un bel po' di tempo sul tuo codice, ma onestamente non sono davvero sicuro che faccia quello che vuoi.

Vedi allegato. Finalizzalo/modificalo, testalo, capiscilo.... e dimmi almeno che funziona vicino, simile o completo, a quello che stai cercando. Non sono ancora sicuro della strategia.
Per favore non aggiungere ancora nuove funzioni (non riaggiungere la martingala). Il codice è abbastanza grande e hai ancora molto lavoro davanti a te per renderlo affidabile.
Devo dire che il codice non è molto più chiaro. Non ho voluto cambiare le tue parti in esecuzione (anche tu hai bisogno di una migliore gestione degli errori). Ho commentato parti e spostato parti, ma è ancora tutto lì...


Buon divertimento...

 
kronin:

Luis, ho passato un bel po' di tempo sul tuo codice, ma onestamente non sono davvero sicuro di fare quello che vuoi.

Vedi allegato. Finalizzalo/modificalo, testalo, capiscilo.... e dimmi almeno che funziona vicino, simile o completo, a quello che stai cercando. Non sono ancora sicuro della strategia.
Per favore non aggiungere ancora nuove funzioni (non riaggiungere la martingala). Il codice è abbastanza grande e hai ancora molto lavoro davanti a te per renderlo affidabile.
Devo dire che il codice non è molto più chiaro. Non ho voluto cambiare le tue parti in esecuzione (anche tu hai bisogno di una migliore gestione degli errori). Ho commentato parti e spostato parti, ma è ancora tutto lì...


Buon divertimento...


Ciao Kronin,

Prima di tutto il mio su più ti ringrazio per il tempo speso a sostegno dei miei problemi.

Mentre credo che hai fatto del tuo meglio per capire la strategia alcune cose non sono abbastanza rispondere (a causa naturalmente della mia mancanza di comprensione in questa materia).

Ho fatto alcune modifiche comprare il tuo consiglio, ma non sono sicuro se fatto correttamente.

Due problemi;

1 - L'idea è che una volta che il trade è stato chiuso con il TrailingStop tutti gli ordini aperti rimanenti dovrebbero chiudersi. Gli ordini non devono essere chiusi sul TakeProfit (il TakeProfit è lì solo perché voglio essere sicuro che sia messo nella Freeze Zone). Così ho pensato di farlo usando la chiusura dell'ultimo ordine per eseguire la funzione CloseAll (vengono fuori delle cose stupide per provare a farlo...). Tu stai usando Last Closed Ticket per eseguire la chiusura degli ordini aperti al ribasso, ma non capisco se questo succede quando il trade si chiude per mezzo di TrailingStop...

2 - Il "ping pong" non funziona, almeno in Tester.

In allegato c'è il file dove sono state fatte le modifiche per quanto ho capito.

Grazie in anticipo per la vostra pazienza e il tempo speso. (più in messaggio privato)

Cordiali saluti

Luis

 

Ok, ho cambiato l'algoritmo per chiudere tutti gli ordini su SL invece che su TP. (Il cambiamento è stato '<' sostituito da '>' - dovresti scoprire dove)

Il ping pong funziona per me e l'ho fatto funzionare solo nel tester in modalità visiva. Ma ho regolato i tuoi parametri di input in modo che non tutti gli ordini si aprano più o meno nello stesso momento. Forse devi verificare i parametri di default.

Inizia con l'ordine iniziale (ho modificato la dichiarazione print()) e poi fa gli ordini opposti.

EURUSD,M1: aperto #1 compra 0.01 EURUSD a 1.43310 ok
EURUSD,M1: ordine di acquisto iniziale piazzato # 1
EURUSD,M1: modificare #1 acquistare 0,01 EURUSD a 1,43310 sl: 1,42810 tp: 1,43510 ok
EURUSD,M1: aprire #2 vendere 0.01 EURUSD a 1.43200 ok
EURUSD,M1: Ordine di vendita opposto piazzato # 2
EURUSD,M1: modificare #2 vendere 0,01 EURUSD a 1,43200 sl: 1,43700 tp: 1,43000 ok
EURUSD,M1: aprire #3 comprare 0,01 EURUSD a 1,43300 ok
EURUSD,M1: Ordine di acquisto opposto piazzato # 3
EURUSD,M1: modificare #3 comprare 0,01 EURUSD a 1,43300 sl: 1,42800 tp: 1,43500 ok

Ho aggiunto return a OpenOppositeOrder() quando ho aperto un ordine. Insieme alle impostazioni era possibile aprire un ordine di acquisto e nello stesso tick un ordine di vendita. Questo porta a MaxOrder non è affidabile.
Forse un approccio migliore è quello di dividerlo in 2 funzioni o dare alla funzione un parametro per eseguire solo gli ordini di vendita o gli ordini di acquisto.

btw. il codice che hai caricato non ha fatto trading! Tutti i trade sono falliti a causa di 'invalid LotSize'....

 

Ciao Kronin,

Grazie per il tempo speso nel supportarmi.

Per quanto riguarda il problema "il codice che hai caricato non ha fatto trading! Tutti i trade sono falliti a causa di 'invalid LotSize'.... ", questo è successo dopo aver spostato il codice MM alla fine del file. Ho fatto la chiamata della funzione usando MM(); all'inizio del codice, sembra che questo tipo di azione non funzioni, ma l'ultimo codice che hai inviato funziona e la funzione MM() è ancora allo stesso posto e funziona, quindi qui mi sono perso....

Riguardo all'ordine che si apre allo stesso tick;

Quando l'EA entra nel grafico deve fare in modo che il prezzo sia più (o meno) del prezzo in quel momento, il che significa che quando il prezzo sale (o scende) l'OpenDistance un ordine di acquisto (o vendita) ha luogo. Da qui la prossima apertura può avvenire solo quando il prezzo rimbalza verso il basso (se l'ultimo ordine è un acquisto) da OrderOpenPrice meno ReturnDistance. Forse un limite deve essere posto per evitare qualsiasi apertura di ordine fuori da questa logica.

Cordiali saluti

Luis

 
//mine
LotSize = (RiskAmount / StopLoss) / TickValue;              //Phil: LotSize is defined in global scope

//yours
double LotSize = (RiskAmount / StopLoss) / TickValue;


Hai definito LotSize in ambito globale e l'hai inizializzato con 0. Nella funzione void MM() calcoli un LotSize valido solo in quella funzione. Ho solo rimosso l'inizializzazione, quindi la variabile in ambito globale viene aggiornata.

Potresti commentare per ognuno di questi valori, il valore in Pips, per favore?

extern double StopLoss       =  50;
extern double TakeProfit     =  20;
extern double TrailingStop   =   2;
extern int    MinimumProfit  =   3;
extern int    Slippage       =   3;
extern double OpenDistance   =   2;
extern double ReturnDist     =   1;
extern double MinStop        =   1;

Qual è lo spread per il simbolo che si desidera eseguire l'EA?

Ma ho regolato i tuoi params di input in modo che non tutti gli ordini si aprano più o meno nello stesso momento.Forse devi verificare i parametri di default.

Prova a fare lo stesso e fallo girare nel tester in modalità visiva.

 
kronin:


Hai definito LotSize in ambito globale e l'hai inizializzato con 0. Nella funzione void MM() calcoli un LotSize valido solo in quella funzione. Ho solo rimosso l'inizializzazione, quindi la variabile in ambito globale viene aggiornata.

Potresti commentare per ognuno di questi valori, il valore in Pips, per favore?

Qual è lo spread per il simbolo che si desidera eseguire l'EA?

Ma ho regolato i tuoi params di input in modo che non tutti gli ordini si aprano più o meno nello stesso momento.Forse devi verificare i parametri di default.

Prova a fare lo stesso e fallo girare nel tester in modalità visiva.


Ciao Kronin,

Sì, ho molto da imparare....Ora capisco che quando c'è la necessità di accedere a un valore dall'esterno di una funzione che deve essere a globale.

I valori che sono all'esterno sono moltiplicati per 10 perché l'EA deve funzionare anche su broker a 5 cifre. Sto usando questo blocco di codice per ottenere ciò automaticamente, ma ricevo un consiglio da WHRoeder che non è compatibile con i metalli.

int init ()// Adjust for 4 or 5 digits.
   {
   if (Digits == 2 || Digits == 4) <------- not compatible with metals
      {
      pt = Point;
      RealSlippage = Slippage;
      }    
   if (Digits == 3 || Digits == 5) 
      {
      pt = Point * 10;
      RealSlippage = Slippage * 10;
      }

Lo spread di coppia potrebbe essere variabile. Ecco perché sto usando il codice per uscire dal livello di stop.

Riguardo a questo problema "Ma ho regolato i tuoi params di input in modo che non tutti gli ordini si aprano più o meno nello stesso momento. Forse devi verificare i params di default".

Per quanto posso vedere (scusate se non lo sono...), OpenDistance mantiene come 2 pip e ReturnDistance è ora con 2 pure. Quello che vedo ora è che l'ordine si apre ma non a 2 pip di differenza. Questo sta funzionando con un tester da una piattaforma di un broker ECN (IC Markets). Questo potrebbe avere qualche importanza?

In effetti gli ordini non si aprono allo stesso tempo ma sembra che Open Distance e ReturnDist non siano presi in considerazione per ottenere la giusta distanza per aprire gli ordini.

Nel codice c'è scritto che;

OTLastTick=OTCurrentTick;                      //shift OrderTotal
  OTCurrentTick=OrdersTotal();                   //reinit OrderTotal
  if(OTCurrentTick>0)Trail();                    //Trail
  if(OTLastTick>=2                               //if OrderTotal has changed
     &&OTCurrentTick<OTLastTick
     &&OTCurrentTick>0){CloseAllOnSL();return;}  //Check order closed on SL level
  if(OTCurrentTick>=MaxOrders)return;            //Dont open more orders. Trail and return.
                                                 //Actually we have nothing more to do.
                                                 //Only call opposite if the initial order of the serie is open
  if(OTCurrentTick>0)OpenOppositeOrder(); //<--------------------- include this line to call function (not sure if this the right method to do it...)
  MM();                //<--------------------- include this line to call function (not sure if this the right method to do it...)
                        
  if(OTCurrentTick==0){//init serie
     BuyAllowed=true;
     SellAllowed=true; 

Ho incluso la linea in grassetto per chiamare la funzione OpenOppositeOrder e qui non sono sicuro che questo sia giusto. Dall'altra parte non riesco a vedere dove sia il confronto del tick attuale con l'ultimo tick che è avvenuto 2 pip prima (OpenDistance).

Scusate se inizio ad annoiarvi con i miei problemi.

Cordiali saluti

Luis

Motivazione: