Errori, bug, domande - pagina 2452

 
A100:

Quello che copia gli array non è secondo le regole a = b, ma secondo le regole diArrayCopy( a, b )

L'hai inventato tu o è scritto da qualche parte?
Lasciate che vi ricordi che questo è un operatore di assegnazione implicita per strutture con array dinamici.

 
Sergey Dzyublik:

L'hanno inventato loro stessi o è scritto da qualche parte?
Vi ricordo che è il lavoro dell'operatore di assegnazione implicita per strutture con array dinamici.

Non è stata una mia idea, ma degli sviluppatori.

        uchar a[], b[]; a = b; //Error: invalid array access
Perché c'è un errore? L'hai avvolto in una struttura e l'errore è scomparso? E perché? Cosa è cambiato fondamentalmente? Le mie risposte sopra
 
Alexey Viktorov:

Si tratta solo di organizzare la sequenza delle azioni e degli eventi.

Lei stesso ha citato il manuale, che dice che la coerenza non è garantita. Ecco perché è rischioso.

Ho già iniziato a riscrivere il codice secondo i consigli di Vladimir, ma sono inciampato in un caso in cui la chiusura è più lunga di un tick - doppio conteggio di nuovo (il nodo filtro nel conteggio è molto pesante). Finora non ho trovato niente di meglio che fermarsi prima della chiusura completa per un compromesso con la velocità di ottimizzazione.

È venerdì :) Forse dopo un po' di riposo mi verrà in mente qualcosa.

In ogni caso, grazie per le idee - non andranno perse!

 
A100:

Non è stata una mia idea, ma degli sviluppatori.

Non ho mai capito dove è stato scritto, ma non importa...
Grazie per il cholivar.

L'ha sostenuto con una stampella e ha continuato a correre:

struct MyArray{
   uchar data[];
   
   void operator=(MyArray &bytes){
      ArrayCopy(this.data, bytes.data);
      ArrayResize(this.data, ArraySize(bytes.data));
   }
};


MyArray GetArray(int i){
   MyArray arr;
   
   if (i%2 == 0){
      ArrayResize(arr.data, 8);
      ArrayInitialize(arr.data, 0x8);
   }else{
      ArrayResize(arr.data, 4);
      ArrayInitialize(arr.data, 0x4);
   }
   return arr;
}


void OnStart(){
   MyArray arr_1 = GetArray(1);
   ArrayPrint(arr_1.data);        // 4 4 4 4
   
   MyArray arr_2 = GetArray(2);
   ArrayPrint(arr_2.data);        // 8 8 8 8 8 8 8 8
   
   arr_2 = arr_1;
   ArrayPrint(arr_2.data);        // 4 4 4 4            
}
 
Igor Zakharov:

Lei stesso ha citato il manuale, che dice che la coerenza non è garantita. Ecco perché è rischioso.

Ho già iniziato a riscrivere il codice secondo i consigli di Vladimir, ma sono inciampato in un caso in cui la chiusura è più lunga di un tick - doppio conteggio di nuovo (il nodo filtro nel conteggio è molto pesante). Finora non ho trovato niente di meglio che fermarsi prima della chiusura completa per un compromesso con la velocità di ottimizzazione.

È venerdì :) Forse dopo un po' di riposo mi verrà in mente qualcosa.

Comunque, grazie per le idee - non andranno sprecate!

Stavo parlando della mia coerenza.

Secondo le mie osservazioni, risulta che dopo OnTick, quando si verifica la transazione, l'esecuzione del codice viene passata alla funzione OnTradeTransaction senza aspettare il prossimo tick. Pertanto, non c'è differenza se la chiusura viene elaborata dalle proprie funzioni o da OnTradeTransaction. Ma preferisco lavorare con OnTradeTransaction. La cosa principale è organizzare correttamente la sequenza delle operazioni senza dipendere dalla sequenza delle transazioni provenienti dal server. Ed è importante capire correttamente questa sequenza. Di nuovo, secondo le mie osservazioni, la sequenza può essere spezzata nel tipo di transazione. Cioè TRADE_TRANSACTION_DEAL_ADD può essere eseguito prima , e poi TRADE_TRANSACTION_HISTORY_ADD, mentre logicamente un ordine dovrebbe essere prima aggiunto alla storia e poi una transazione.

ps; Poi, come ho detto, vagliando la transazione TRADE_TRANSACTION_DEAL_ADD potete vagliare per apertura di posizione e per chiusura di posizione. Dopo tutto, stiamo parlando di un Expert Advisor per il mercato forex e di un conto, giusto? Pertanto, non c'è bisogno di ricalcolare tutte le posizioni ad ogni starnuto. È sufficiente aggiungerne uno se è stato aperto, o cancellarne uno da quelli contati se è stato chiuso.
 
Alexey Viktorov:

del mercato forex e del conto, giusto?

Griglia :) Sì.

La logica attuale è la seguente: c'è una struttura che memorizza tutte le informazioni su ogni griglia: simbolo-numero di posizioni-cum-profitto e poche altre cose poco importanti... Il profitto viene ricalcolato dal timer, se ci sono ordini (robot multisimbolo). Ma i lotti e la quantità sono stati ricalcolati in OnTradeTransaction (nel caso in cui l'utente abbia "aiutato").

Volevo controllare un caso in cui una griglia, per esempio, è in profitto di 100$, e l'altra è in perdita di 50$ - per chiudere entrambe con un profitto di 50$ per evitare che cresca.

Al momento l'ho fatto:

void  OnTradeTransaction(
   const MqlTradeTransaction&    trans,     // trade transaction structure 
   const MqlTradeRequest&        reqst,     // request structure 
   const MqlTradeResult&         reslt      // response structure 
    )
{
 int index=-1;
 for(index=0;index<symbols_total;index++)
  if(ARRAY[index].symbol==trans.symbol) break; //нашли индекс символа по которому прошла трансакция в массиве структур
 
 if(index>=0) CountOrders(index); //пересчитали элемент
}

Finora ho aggiuntoCountOrders()dopo aver chiuso un paio di griglie. Per un tester di strategia, funziona. Per un conto reale userò lo schema di Vladimir (con un array di biglietti chiusi).

A proposito, la chiusura della coppia non si è giustificata - il drawdown non diminuisce considerevolmente, mentre il profitto si riduce decentemente.

 
Vladimir Karputov:

Rinuncerei a TUTTO mentre, Sleep e OnTimer per il compito di chiudere le posizioni. Io farei così: spara ordini di chiusura - uscita OnTick, sul prossimo tick controlla: se le posizioni con i ticket necessari sono ancora vive - spara ordini di chiusura di nuovo e così via in un cerchio attraverso entrata/uscita a OnTick.

La logica è la seguente: la chiusura di una posizione è la prima priorità, quindi il ciclo di chiusura è all'inizio di OnTick. E la formazione di array di biglietti di chiusura può essere in qualsiasi luogo di OnTick - anche alla fine.

Prima o poi ti ritroverai con quanto segue: hai bisogno di chiudere una posizione, viene inviato un ordine di chiusura (MQL5), cioè viene inviato un ordine di tipo opposto, poiché non stai tracciando le azioni di trading nel gestore appropriato (o non stai salvando lo stato della posizione nel tuo EA) e al prossimo tick un ordine di chiusura potrebbe essere in procinto di essere inviato e tu invierai un altro ordine. Il risultato è una posizione nella direzione opposta.

 
Alexey Kozitsyn:

Prima o poi, vi ritroverete con quanto segue: avete bisogno di chiudere una posizione, inviate un ordine di chiusura (MQL5), cioè, inviate un ordine di tipo opposto, poiché non tracciate le azioni di trading nel gestore corrispondente (o non salvate lo stato della posizione nel vostro EA) e al prossimo tick un ordine di chiusura potrebbe essere in procinto di essere inviato, ma voi inviate un altro ordine. Il risultato è una posizione nella direzione opposta.

Per un caso del genere abbiamo:

10036

TRADE_RETCODE_POSITION_CLOSED

Laposizione con il POSITION_IDENTIFIERspecificato è già stata chiusa

La posizione di chiusura viene inviata con il ticket della posizione da chiudere, quindi è improbabile che la tua descrizione avvenga.

 
Sergey Dzyublik:

Non ho mai capito dove è scritto, ma non importa...
Grazie per il cholivar.

L'ha sostenuto con una stampella e ha continuato a correre:

Beh, è strano come vengono copiati gli array, ma ad alcuni piace persino...

Ho fatto un wrap più o meno adeguato su un array e non ho problemi.

https://www.mql5.com/ru/forum/221917/page26#comment_11233214

 
A100:

Non è stata una mia idea, ma degli sviluppatori.

Non ricordo che l'abbiano mai detto.

L'operatore di assegnazione è destinato a creare una copia identica di un oggetto. Questo è il suo scopo. Quando si equipara qualcosa a qualcosa, si dovrebbe ovviamente ottenere una copia completa sul lato sinistro, non qualcos'altro. Quindi c'è ovviamente un bug qui.