Errori, bug, domande - pagina 2451

 
Un file con un # nel suo nome non può essere aggiunto all'archivio. È un comportamento normale o un bug?
 

Se stiamo parlando di FX, lì i tick non cambiano molto il prezzo (di solito). Ma in altri mercati un ordine può seriamente scivolare con un approccio ticky. Sono ancora a favore di provare tra le zecche - non vedo alcun danno, il beneficio potenziale c'è.

Dobbiamo provare...

 
Isteresi in azione... su un esempio di come funziona un operatore di copia di assegnazione implicita nelle strutture.

#define  PRINT(x) Print(#x, ":", string(x))

struct MyArray{
   uchar data[];
};


void OnStart(){
   MyArray tmp_arr;
   
   MyArray huge_arr;
   ArrayResize(huge_arr.data, 1000);
   ArrayInitialize(huge_arr.data, 0x8);
   
   MyArray small_arr;
   ArrayResize(small_arr.data, 10);
   ArrayInitialize(small_arr.data, 0x1);
   
   
   tmp_arr = small_arr;
   Print("\r\nTest with small_arr");
   PRINT(ArraySize(tmp_arr.data));
   PRINT(tmp_arr.data[0]);
   PRINT(tmp_arr.data[ArraySize(tmp_arr.data)-1]);
   
   tmp_arr = huge_arr;
   Print("\r\nTest with huge_arr");
   PRINT(ArraySize(tmp_arr.data));
   PRINT(tmp_arr.data[0]);
   PRINT(tmp_arr.data[ArraySize(tmp_arr.data)-1]);
   
   tmp_arr = small_arr;
   Print("\r\nTest with small_arr");
   PRINT(ArraySize(tmp_arr.data));
   PRINT(tmp_arr.data[0]);
   PRINT(tmp_arr.data[ArraySize(tmp_arr.data)-1]);
}

Risultato:
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   Test with small_arr
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   ArraySize(tmp_arr.data):10
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[0]:1
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[ArraySize(tmp_arr.data)-1]:1
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   Test with huge_arr
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   ArraySize(tmp_arr.data):1000
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[0]:8
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[ArraySize(tmp_arr.data)-1]:8
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   Test with small_arr
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   ArraySize(tmp_arr.data):1000
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[0]:1
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[ArraySize(tmp_arr.data)-1]:8
 
Sergey Dzyublik:
Isteresi in azione... da un esempio di come funziona un operatore di copia implicita nelle strutture.

Probabilmente, per rilevare una cosa del genere, si doveva raggiungere uno stato interno/stupidità di "non può funzionare niente qui, ma lo controllerò comunque" alla ricerca di un errore nel proprio codice.

 
fxsaber:

Immagino che per rilevare una cosa del genere, tu abbia dovuto raggiungere uno stato interno/stupidità di "niente può andare storto qui, ma lo controllerò comunque" alla ricerca di un bug nel tuo codice.

Il codice stava analizzando il flusso di byte per un particolare protocollo.
I dati spacchettati e non spacchettati (dati per il livello successivo di incapsulamento) non corrispondono.

 
Sergey Dzyublik:

Il codice stava analizzando il flusso di byte per un protocollo specifico.
I dati spacchettati e non spacchettati (dati per il livello successivo di incapsulamento) non corrispondono.

Non è difficile rilevare un tale compito. Fortunato.
 
Sergey Dzyublik:
Isteresi in azione... Un esempio di come funziona un operatore di copia implicita nelle strutture.

Qual è la domanda?

void OnStart()
{
        int a[]; ArrayResize( a, 3 ); ArrayInitialize( a, 3 );
        int b[]; ArrayResize( b, 2 ); ArrayInitialize( b, 2 );

In MQL, una voce condizionale

//                 a = b;

è uguale a

        ArrayCopy( a,  b );

Risultato:

        ArrayPrint( a );
}

2 2 3

 
A100:

Qual è la domanda?


Secondo me, l'operatore di copia di assegnazione dovrebbe copiare non solo gli elementi dell'array stesso, ma anche il loro numero, lasciando valida la quantità di memoria riservata.

E ora è praticamente il seguente:

int size;
size = 4; // size == 4
size = 8; // size == 8
size = 4; //  size == 8



Codice sorgente:

struct MyArray{
   uchar 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 8 8 8 8
}
 
Sergey Dzyublik:


L'operatore di copia dovrebbe copiare non solo gli elementi dell'array stesso, ma il loro numero, lasciando valida la quantità di memoria riservata.

Perché allora

struct MyArray {
        uchar data[];
};
void OnStart()
{
        { uchar   a[], b[]; a = b; } //(1) Error
        { MyArray a,   b;   a = b; } //(2) нормально
}

in (1) l'errore e in (2) va bene? Qual è la differenza?

La differenza è che gli array sono copiati non dalle regole a = b, ma dalle regole ArrayCopy( a, b )

Non secondo le regole a = b, perché non esiste, e se esistesse, l'errore (1) non esisterebbe


 
Igor Zakharov:

Il conteggio di ogni tick richiede molte risorse, specialmente nel tester di strategia. Non sarebbe più corretto ricalcolare solo l'evento Trade, cioè quando qualcosa nella lista delle posizioni aperte cambia effettivamente? Con OnTradeTransaction(), è più facile controllare l'intervento dell'utente nell'EA. (Ci sono alcuni precedenti :)

In questo robot stavo testando la possibilità di chiudere la griglia con lo schema: Perdita + profitto > X , quindi chiudere entrambi (di solito su simboli diversi). Ma si verifica un fallimento, perché anche se sono chiusi, il tester non ne è consapevole, e procede all'iterazione successiva, "accoppiando" erroneamente quelli esistenti con quelli già chiusi. Cioè ho dovuto aggiungere un ricalcolo dopo ogni chiusura.

Ho ricalcolato con il reset del contatore e su tutti quelli aperti prima, non +1 / -1

Sono d'accordo, è stato rischioso usare inizialmente OnTradeTransaction() In realtà, probabilmente mi rifiuterò di usarlo nei casi in cui le mie richieste non sono asincrone - causano solo problemi.

Non è affatto rischioso. L'unico problema è nell'organizzare la sequenza delle azioni e degli eventi. Il consiglio di Fool è corretto: chiudi la coppia e lascia il ciclo fino al prossimo tick. Al prossimo tick, i prezzi non sono necessariamente peggiori di quelli che sono. Forse, sarà meglio chiuderlo un po' più tardi, ma non ci sarà confusione su cosa si è chiuso con cosa.

La seconda variante: disporre il ciclo non per PositionsTotal, ma per l'array creato in precedenza. E quando si chiude una coppia, questi biglietti dovrebbero essere rimossi dall'array. Questo non permetterà di richiudere le posizioni chiuse. In generale, un volo di fantasia e una logica di azioni.