Caractéristiques du langage mql5, subtilités et techniques - page 157

 
Andrey Khatimlianskii:

Salut !

L'analogue des graphiques hors ligne de MT4 sont les instruments castum. Vous pouvez remplir n'importe quel historique, y compris en faisant en sorte que 1 barre = 1 tick.

Mais, comme dans MT4, chaque barre doit être différente d'au moins une minute de la précédente, il n'y aura donc pas d'échelle de temps normale.

ps : il y a un indicateur prêt à l'emploi ici - https://www.mql5.com/en/blogs/post/719145

Dans MT4, il suffit que le temps d'une barre soit plus long que celui de la barre précédente pour que MT4 affiche la barre, c'est-à-dire que dans MT4, vous pouvez dessiner des barres sur des graphiques hors ligne avec une précision de quelques secondes, j'ai posté un graphique en secondes dans QB.

Mais avec MT5, cela ne fonctionnera pas, si vous essayez d'envoyer au symbole personnalisé 2 barres avec le même temps d'ouverture, sans tenir compte des secondes, alors une seule barre sera affichée, c'est-à-dire que la précision de moins de M1 sur les graphiques personnalisés de MT5 ne fonctionnera pas.

 
fxsaber:

Il y a un schémaici. Ça marche.

Sans déplacer le TA ? Est-ce que ça marche à chaque fois ? Pas plus que de la chance.


fxsaber:

Où se situe la limite de la perfection qui peut/doit être tolérée ? Quel est le rapport entre les régressions et les requêtes qui surviennent occasionnellement et le testeur ?

Les rejets n'ont rien à voir avec ça.

Un ordre à cours limité ne doit pas nécessairement être exécuté au dernier prix connu, que ce soit dans le testeur ou en temps réel. Le prix peut aller n'importe où pendant son envoi.

Par ailleurs, en mode de délai nul (exécution idéale), le testeur peut prétendre que l'ordre a été envoyé au courtier et exécuté immédiatement, mais je n'y vois aucun bénéfice, car, une fois encore, il est inutile de procéder à des tests idéaux si le contraire se produit de toute façon dans la situation réelle.

 
Igor Makanu:

Dans MT4, le temps de la barre doit simplement être plus long que la barre précédente et MT4 affichera la barre, c'est-à-dire que dans MT4, vous pouvez dessiner des barres sur des graphiques hors ligne à la seconde près, j'ai posté un graphique des secondes dans KB.

Merci pour l'édition, j'avais déjà oublié. Il fut un temps où il y avait certainement des erreurs si l'heure n'était pas un multiple de minutes, puis cela semblait fonctionner de cette façon aussi.

Vous ne pouvez certainement pas le faire de cette façon en 5.

 
Andrey Khatimlianskii:

Salut !

L'analogue des graphiques hors ligne de MT4 sont les instruments castum. Vous pouvez remplir n'importe quel historique, y compris en faisant en sorte que 1 barre = 1 tick.

Mais, comme dans MT4, chaque barre doit être différente d'au moins une minute de la précédente, de sorte qu'il n'y aura pas de chronologie normale.

ps : il y a un indicateur prêt à l'emploi ici - https://www.mql5.com/en/blogs/post/719145

Oh, les symboles personnalisés sont exactement ce qu'il faut ! Et le temps de tic n'a pas d'importance pour moi. Merci, c'est une impulsion dans la bonne direction. )))

 
Andrey Khatimlianskii:

Sans déplacer le TA ? Est-ce que ça marche bien à chaque fois ? Pas plus que de la chance.

Non, bien sûr que non. C'est pourquoi le cycle.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Caractéristiques du langage mql4, subtilités et astuces

fxsaber, 2019.12.13 00:27

Schématiquement, la fermeture urgente d'un poste se fait de la manière suivante
const double ClosePrice = OrderType() ? MathMin(OrderClosePrice(), Bid + MaxSpread * _Point) 
                                      : MathMax(OrderClosePrice(), Ask - MaxSpread * _Point);
    
OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), ClosePrice, 0); // StopLoss оставлен для истории
Dans la boucle, bien sûr. Avez-vous d'autres options ?

Les règlements n'ont rien à voir avec cela.

Le limiteur ne doit pas être déclenché au dernier prix connu, que ce soit dans le testeur ou dans la vie réelle. Le prix peut varier pendant la durée de l'envoi.

Un autre point est que dans le mode de délai 0 (exécution idéale), le testeur peut prétendre que l'ordre a été envoyé au courtier et exécuté instantanément, mais je n'y vois aucun bénéfice, car, encore une fois, il n'y a aucun sens à effectuer des tests idéaux si le contraire se produit de toute façon dans le monde réel.

En réalité, il s'agira soit d'une exécution complète (ou partielle) au prix actuel (ou meilleur), soit d'une réfutation. C'est-à-dire que l'exécution peut être parfaite ou non.

Ainsi, le Testeur fonctionne toujours parfaitement pour un marché, alors qu'il échoue toujours pour un ordre à cours limité.

 
fxsaber:

Cela signifie que le testeur fonctionne toujours parfaitement pour un marché, mais pas pour un limiteur.

Je préfère faire le prochain tic pour un marché. Il serait préférable que le testeur montre une perte plutôt qu'une perte réelle. Et il est peu probable que le Graal soit perdu de ce fait.

 
Andrey Khatimlianskii:

Ici, je préfère faire l'exécution du prochain tick pour les marchés. Il vaut mieux qu'un testeur montre une chute qu'une vraie chute. Et il est peu probable que le Graal soit perdu de ce fait.

Le tick suivant n'est pas correct, votre marché doit générer un tick, et être exécuté au bid ou ask le plus proche, en tenant compte du volume de la transaction.
Les limites doivent également être remplies à un prix garanti en fonction du volume.
Tous les autres algorithmes qui sont faits maintenant, seulement trompeur, obtenir des résultats réels.
C'est pourquoi je n'utilise pas du tout le testeur. Il n'y a pas de sens, quand sur les bases mêmes, il y a une substitution d'exécution.

 
Roman:

Le tick suivant n'est pas correct, votre marché devrait donner lieu à un tick, et sera exécuté au bid ou ask le plus proche, en tenant compte du volume de la transaction.
L'ordre à cours limité doit également être exécuté à un prix garanti en fonction du volume.
Tous les autres algorithmes qui sont faits maintenant, seulement trompeur, obtenir des résultats réels.
C'est pourquoi je n'utilise pas du tout le testeur. Il n'y a pas de sens, quand sur les bases mêmes, il y a une substitution d'exécution.

Pour cela, vous avez besoin de l'historique de la coupe ou au moins des volumes de l'offre et de la demande extrêmes. Et il n'y en a pas.

Et un marché ne doit pas générer de tick dans le testeur, sinon l'historique dépendrait de la stratégie testée.

 
Andrey Khatimlianskii:

Pour cela, vous avez besoin de l'historique de la coupe ou au moins des volumes de l'offre et de la demande extrêmes. Et il n'y en a pas.

Et le marché ne doit pas générer de tick dans le testeur, sinon l'historique dépendrait de la stratégie testée.

Comme l'a dit l'un des modérateurs, mt5 a été développé pour les marchés boursiers,
mais en regardant l'implémentation du testeur, son développement a été réduit au même principe d'exécution des transactions, même sur des ticks réels.

Comment faites-vous les tests alors ? Sur quelles données historiques ?
Et ensuite, faites-vous confiance aux tests sur de telles citations historiques ?
:))

Bien sûr, il faut un historique des tiques et des tests sur de vraies tiques.
Le problème de l'utilisateur est de savoir où se procurer l'historique des tiques. Vous pouvez le collecter vous-même, l'acheter, le prendre à quelqu'un qui le possède, etc.

Oui, je suis d'accord pour dire que les volumes pour l'enchère asc ne sont pas sauvegardés maintenant, mais qu'est-ce qui empêche les développeurs d'ajouter trois colonnes!

  1. Colonne de volume Demande
  2. Colonne de volume Bid
  3. Colonne Dernier sens de la transaction, achat ou vente


Alors tous les problèmes concernant la justesse des tests sur des ticks réels disparaîtront automatiquement.
L'exécution des ordres d'échange dans le testeur se fera comme il se doit.

Oui, le tick générateur, pas si je voulais dire que le marché dans le testeur devrait être exécuté aux Bid Asks les plus proches, en collectant la liquidité au niveau des prix.
C'est-à-dire que si nous envoyons un BuyMarket avec un volume de 25, le prix d'exécution rassemblera deux niveaux, 10 et 15, et fera automatiquement la moyenne du prix net de la position.

182.13 Demande1 15
182.12 Ask0 10
--------------------
182,11 Bid0 5
182,10 Bid1 8

Pour les ordres à cours limité, le volume de la dernière transaction doit remplir le volume de votre ordre à cours limité au prix garanti auquel l'ordre à cours limité est placé.
C'est-à-dire que votre ordre à cours limité doit être partiellement exécuté. Si votre ordre limite est placé avec un volume de 25, alors la dernière transaction avec un volume de 5 prendra 5 de votre ordre limite.
Votre ordre limite a maintenant un volume de 20, la dernière transaction suivante est passée avec un volume de 10, votre ordre limite a maintenant un volume de 10,
une autre Dernière transaction passée avec un volume de 10, votre ordre limite est entièrement rempli.
Si le prix s'est inversé et que vous n'avez pas exécuté la totalité du volume de votre ordre à cours limité, c'est la situation réelle, l'exécution réelle.
Et le volume restant de votre ordre à cours limité continue d'attendre jusqu'à ce que Last s'en occupe à nouveau, ou que vous retiriez vous-même cet ordre.

Par conséquent, la manière dont l'algorithme est mis en œuvre dans le testeur n'a rien à voir avec la réalité.
C'est comme un jouet qui lave les yeux.


 

Je ne vais pas modifier mes structures POD pour ouvrir un format. Il existe de nombreux domaines dans les structures. Certaines structures sont héritées, d'autres ont des champs privés.


Quoi qu'il en soit, la tâche de mettre à zéro ces structures afin d'éditer le format étudié s'est présentée. Et rien ne sort vraiment. En conséquence, j'ai décidé d'utiliser cette variante.

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

// Обнуление переменной.
template <typename T>
void ToNull( T &Value )
{
  uchar Bytes[sizeof(T)];
  ArrayInitialize(Bytes, 0);
  
  _W(Value) = Bytes;
}


Application.

struct A
{
private:
  int i;
  
public:
  int j;  
};

void OnStart()
{
//  A a = {0};     // 'a' - cannot be initialized with initializer list
//  ZeroMemory(a); // 'a' - not allowed for objects with protected members or inheritance
  
  ToNull(a);
}


Une alternative est la bienvenue.

Raison: