Erreurs, bugs, questions - page 2451

 

Si nous parlons du marché des changes, les ticks ne modifient pas beaucoup le prix (généralement). Mais sur d'autres marchés, un ordre peut sérieusement déraper avec une approche tatillonne. Je suis toujours en faveur de l'essai entre les ticks - je ne vois pas de mal, le bénéfice potentiel est là.

Nous devons essayer...

 
L'hystérésis en action... sur un exemple de fonctionnement d'un opérateur de copie d' affectation implicite dans les structures.

#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]);
}

Résultat :
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:
L'hystérésis en action... par un exemple du fonctionnement d'un opérateur de copie implicite dans les structures.

Probablement, pour détecter une telle chose, il fallait atteindre un état interne/stupidité de "rien ne peut fonctionner ici, mais je vais quand même le vérifier" à la recherche d'une erreur dans son code.

 
fxsaber:

Je suppose que pour détecter une telle chose, vous avez dû atteindre un état interne/stupidité de "rien ne peut aller mal ici, mais je vais quand même le vérifier" à la recherche d'un bug dans votre code.

Le code analysait le flux d'octets pour un protocole particulier.
Les données déballées et non déballées (données pour le niveau d'encapsulation suivant) ne correspondaient pas.

 
Sergey Dzyublik:

Le code analysait le flux d'octets pour un protocole spécifique.
Les données déballées et non déballées (données pour le niveau d'encapsulation suivant) ne correspondaient pas.

Il n'est pas difficile de détecter une telle tâche. Chanceux.
 
Sergey Dzyublik:
L'hystérésis en action... Un exemple du fonctionnement d'un opérateur de copie implicite dans les structures.

Quelle est la question ?

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

Dans MQL, une entrée conditionnelle

//                 a = b;

est égal à

        ArrayCopy( a,  b );

Résultat :

        ArrayPrint( a );
}

2 2 3

 
A100:

Quelle est la question ?


À mon avis, l'opérateur de copie d' affectation devrait copier non seulement les éléments du tableau eux-mêmes, mais aussi leur nombre, en laissant la quantité de mémoire réservée valide.

Et maintenant, c'est pratiquement le suivant :

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



Code source :

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'opérateur de copie doit copier non seulement les éléments du tableau eux-mêmes, mais aussi leur nombre, en laissant valide la quantité de mémoire réservée.

Pourquoi alors

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

dans (1) l'erreur et dans (2) c'est bon !? Quelle est la différence ?

La différence est que les tableaux sont copiés non pas par la règle a = b, mais par la règle ArrayCopy( a, b )

Pas par la règle a = b, parce qu'elle n'existe pas, et si elle existait, l'erreur (1) n'existerait pas.


 
Igor Zakharov:

Compter sur chaque tic est gourmand en ressources, surtout pour le testeur de stratégie. Ne serait-il pas plus correct de recalculer uniquement l'événement Trade, c'est-à-dire lorsque quelque chose dans la liste des positions ouvertes change réellement ? Avec OnTradeTransaction(), il est plus facile de contrôler l'intervention de l'utilisateur dans l'EA. (Il y a des précédents :)

Dans ce robot, je testais la possibilité de fermer la grille par le schéma : Perte + profit > X , puis de fermer les deux (généralement sur des symboles différents). Mais un échec se produit, car même s'ils sont fermés, le testeur n'en est pas conscient et passe à l'itération suivante, en "jumelant" par erreur les existants avec ceux déjà fermés. C'est-à-dire que j'ai dû ajouter un nouveau calcul après chaque fermeture.

J'ai un recalcul avec remise à zéro du compteur et sur tous les ouverts d'abord, pas +1 / -1

Je suis d'accord, il était risqué d'utiliser OnTradeTransaction() en premier lieu. En fait, je vais probablement refuser de l'utiliser dans les cas où les requêtes ne sont pas asynchrones - elles ne causent que des problèmes.

Ce n'est pas du tout risqué. La question est seulement d'organiser la séquence des actions et des événements. Le conseil de Fool est correct - fermez la paire et laissez la boucle jusqu'au prochain tick. Au tic-tac suivant, les prix ne sont pas nécessairement plus mauvais qu'ils ne le sont. Il sera peut-être préférable de le fermer un peu plus tard, mais il n'y aura pas de confusion sur ce qui a été fermé avec quoi.

La deuxième variante : organiser la boucle non pas en fonction de PositionsTotal, mais en fonction du tableau créé au préalable. Et lors de la fermeture d'une paire, ces tickets doivent être retirés du tableau. Cela ne permettra pas de refermer les positions fermées. En général, une fuite en avant et une logique d'actions.

 
A100:

Celui qui copie les tableaux ne l'est pas par les règles a = b, mais par les règles deArrayCopy( a, b )

Vous l'avez inventé vous-même ou c'est écrit quelque part ?
Je vous rappelle qu'il s'agit d'un opérateur d'affectation implicite pour les structures avec des tableaux dynamiques.

Raison: