La fonction qui indique la nécessité d'un emballage est marquée en rouge. Son problème est décrit ici. Certains se souviendront peut-être qu'il s'agit d'un ancien problème de réouverture de position, qui dans les temps anciens était résolu par le Sleep, en attendant que la position s'ouvre après l'OrderSend. Mais en fait, ce problème n'a rien à voir avec OrderSend. Vous devez être capable de lire correctement l'environnement commercial.
Le droit est un exemple simple.
La liste des ordres, comme la liste des positions, n'est pas mise à jour instantanément. Je pense qu'on ne peut pas se passer de Sleep-crutch.
Le plus correct est probablement OnTradeTransaction
La liste des ordres, comme la liste des positions, n'est pas mise à jour instantanément. imho, on ne peut pas se passer de Sleep-crutch.
Il serait probablement préférable d'utiliser OnTradeTransaction.
Si un problème se pose en attendant la mise à jour de l'environnement, comment Sleep peut-il aider ? Cela aidera ou pas.
Il faut donc adopter l'approche inverse : après avoir envoyé un ordre d'ouverture de position ou un ordre en attente, il faut attendre le résultat et ne plus envoyer d'autres ordres d'ouverture ou d'ordre. Nous avons donc besoin d'un drapeau que nous gérons nous-mêmes au lieu de faire confiance au sommeil qui ne fait que retarder l'exécution du programme mais ne vérifie pas le résultat d'une demande de transaction envoyée par le programme lui-même qui doit savoir ce qu'il faut faire ensuite - mettre un drapeau et travailler selon la logique des résultats en attente. Après avoir attendu le résultat, le drapeau est retiré.
Question : Que se passera-t-il si, après avoir envoyé un ordre de transaction jusqu'au prochain tick, l'ordre de marché n'est pas placé par le serveur ?
Ce sera exactement la même chose que sur MT4 - s'il n'y a rien, cela ne sera pas compté.
Il peut y avoir plusieurs raisons pour un tel ordre commercial
OrderSend ou OrderSendAsync de tiers - ne provenant pas du programme dans lequel nous lisons l'environnement commercial. Il peut même ne pas provenir du terminal dans lequel le programme est exécuté. Dans ce cas, rien ne peut être fait. Dans de telles situations, tout est identique à ce qui se passe dans MT4.
OrderSend ou OrderSendAsync - sont lancés à partir du programme dans lequel l'environnement commercial est lu. Dans le cas de OrderSend, tout est clair, car OrderSend terminera son exécution avec un résultat clair. Dans le cas de OrderSendAsync nous pouvons faire deux choses - passer les données aux événements suivants selon le premier paradigme, ou faire OrdersAsyncWait() (je n'ai pas le code), comme cela est fait dans une simulation régulière de transfert de données asynchrones dans MT4 (implémentation de plusieurs threads).
Je devrais probablement dire quelques mots sur OrderSendAsync dans MT4. À n'importe quel stade de l'exécution du programme, il est possible de voir à quel point un thread commercial correspondant est occupé et ce qu'il fait exactement. En ce sens, l'asynchronie personnalisée dans MT4 nous offre beaucoup plus de possibilités que celle de MT5. Mais dans MT4, elle est implémentée en exécutant des "clients" sur chaque graphique, ce qui est coûteux. Dans MT5, il est possible d'écrire la même fonctionnalité et même sans beaucoup de graphiques - en exécutant le script sur un objet OBJ_CHART, mais il y aura toujours un léger retard. C'est-à-dire que OrderSendAsyncCustom sera légèrement plus lent que OrderSendAsync, mais il sera toujours beaucoup plus rapide que OrderSend + tous les avantages de l'implémentation personnalisée.
La liste des ordres, comme la liste des positions, n'est pas mise à jour instantanément. imho, on ne peut pas se passer de Sleep-crutch.
Probablement, il serait plus correct d'utiliser OnTradeTransaction
MqlTradeTransaction peut être nécessaire uniquement lors du choix du paradigme approprié pour travailler avec OrderSendAsync. Dans d'autres cas, OnTradeTransaction == OnTrade dans le sens et ne joue pas plus de rôle que OnTick ou OnTimer.
Il existe deux paradigmes de travail avec l'environnement de trading, l'écriture d'EAs.
Les entrées d'événements (OnTick, OnTimer, etc.) dépendent les unes des autres. Il y a des informations qui DOIVENT se trouver entre les événements (pas pour la vitesse, comme le cache, mais pour la convivialité). Par exemple, nous devons sauvegarder le résultat de OrderSendAsync et l'utiliser dans OnTradeTransaction. Les caches ne sont PAS des informations obligatoires et ne sont utilisés que pour accélérer le processus. C'est pourquoi nous ne les considérons pas tout de suite.
Les entrées d'événements (OnTick, OnTimer, etc.) ne sont PAS dépendantes les unes des autres. Chaque entrée est faite à partir de zéro. En gros, c'est comme un script que vous exécutez vous-même à chaque événement.
Le surlignage indique que le même code commercial est exécuté dans chaque fonction On. Le code non commercial correspondant complète le reste.
Ce sera exactement la même chose que sur MT4 - s'il n'y a rien, cela ne sera pas compté.
C'est-à-dire qu'au prochain tic, le programme envoie une nouvelle demande d'ouverture. Par conséquent, nous avons le même problème - des ouvertures multiples.
Le conseiller expert doit avoir la logique suivante :
C'est-à-dire qu'au prochain tick, le logiciel envoie une nouvelle demande d'ouverture. Par conséquent, nous avons le même problème - des ouvertures multiples.
Vérifiez le nombre d'ordres/positions, s'il n'y a pas de signal pour ouvrir une nouvelle position - sortez (au point 1).
Vérifier le drapeau d'attente de réponse du serveur:
Le drapeau est levé - sortie (à l'étape 1)
Drapeau omis - continuer
Si le drapeau est omis, envoyez un ordre de transaction (le nombre de tentatives est limité) et vérifiez le code de retour.
L'ordre a été exécuté - activez le drapeau d'attente.
Ordre non exécuté - appeler la fonction corriger l'ordre commercial et passer au point 4
Le drapeau d'attente est levé - vérifiez le changement d'environnement commercial.
L'environnement commercial n'a pas changé - quittez (à l'étape 1).
L'environnement a changé - un ordre en attente est placé ou une position est ouverte - supprimez le drapeau d'attente et sortez (à l'étape 1).
L'indicateur d'attente n'est disponible que pour le deuxième cas et OrderSendAsync. Pour OrderSend, le drapeau d'attente n'est pas du tout nécessaire. OrderSendAsync sans drapeau d'attente est OrdersAsyncWait().
Vous pouvez vérifier toute théorie dans la pratique.
Le drapeau d'attente n'est possible que pour le deuxième cas et OrderSendAsync. Pour OrderSend, le drapeau d'attente n'est pas du tout nécessaire. OrderSendAsync sans drapeau d'attente est OrdersAsyncWait().
Toute théorie peut être testée en pratique
Je suis guidé par les résultats pratiques.
Eh bien, j'ai écrit pour le mode asynchrone. Avec le mode synchrone, vous n'avez pas besoin d'attendre - le résultat est déjà là dans la réponse à la requête.
Je n'ai vu aucune étape pour contourner l'erreur de découverte multiple. Seulement des "paradigmes" généraux ;)
C'est pourquoi j'ai décrit la logique approximative, qui est redondante - le drapeau est vérifié dans une fonction (wrapper) qui ouvre des positions / définit des ordres en attente. Ou peut-être aussi dans la fonction de suivi du signal.
Vous devez réfléchir à la meilleure façon de procéder.
le drapeau est vérifié dans la fonction (wrapper) d'ouverture des positions/placement des ordres en attente. Ou peut-être aussi dans la fonction de suivi du signal.
Je préfère de loin la solution via OrdersAsyncWait(), lorsque la sortie de la fonction On est toujours effectuée sans suspendre l'état. La prochaine lecture de l'environnement commercial avec une ardoise propre est alors aussi pertinente que possible.
L'utilisation de OrderSendAsync devrait toujours être appropriée. La seule situation où il serait approprié d'envoyer plusieurs (> 1) ordres de transaction, indépendants les uns des autres, sur un seul signal. Par conséquent, le truc OrderSendAsync n'a jamais de sens dans tous les autres cas.
SZZY Il y a un sujet distinct où OrderSendAsync est très pertinent - multi-conseillers : plusieurs TS indépendants dans un conseiller expert. L'OrderSend y est rarement adapté et même l'OrderAsyncWait( const string Symb) n'est pas bon puisque aucun Sleep n'est en principe autorisé.
fxsaber:
La fonction qui indique la nécessité d'un emballage est marquée en rouge. Son problème est décrit ici. Certains se souviendront peut-être qu'il s'agit d'un ancien problème de réouverture de position, qui dans les temps anciens était résolu par le Sleep, en attendant que la position s'ouvre après l'OrderSend. Mais en fait, ce problème n'a rien à voir avec OrderSend. Vous devez être capable de lire correctement l'environnement commercial.
Le droit est un exemple simple.
La liste des ordres, comme la liste des positions, n'est pas mise à jour instantanément. Je pense qu'on ne peut pas se passer de Sleep-crutch.
Le plus correct est probablement OnTradeTransaction
La liste des ordres, comme la liste des positions, n'est pas mise à jour instantanément. imho, on ne peut pas se passer de Sleep-crutch.
Il serait probablement préférable d'utiliser OnTradeTransaction.
Si un problème se pose en attendant la mise à jour de l'environnement, comment Sleep peut-il aider ? Cela aidera ou pas.
Il faut donc adopter l'approche inverse : après avoir envoyé un ordre d'ouverture de position ou un ordre en attente, il faut attendre le résultat et ne plus envoyer d'autres ordres d'ouverture ou d'ordre. Nous avons donc besoin d'un drapeau que nous gérons nous-mêmes au lieu de faire confiance au sommeil qui ne fait que retarder l'exécution du programme mais ne vérifie pas le résultat d'une demande de transaction envoyée par le programme lui-même qui doit savoir ce qu'il faut faire ensuite - mettre un drapeau et travailler selon la logique des résultats en attente. Après avoir attendu le résultat, le drapeau est retiré.
Question : Que se passera-t-il si, après avoir envoyé un ordre de transaction jusqu'au prochain tick, l'ordre de marché n'est pas placé par le serveur ?
Ce sera exactement la même chose que sur MT4 - s'il n'y a rien, cela ne sera pas compté.
Il peut y avoir plusieurs raisons pour un tel ordre commercial
- OrderSend ou OrderSendAsync de tiers - ne provenant pas du programme dans lequel nous lisons l'environnement commercial. Il peut même ne pas provenir du terminal dans lequel le programme est exécuté. Dans ce cas, rien ne peut être fait. Dans de telles situations, tout est identique à ce qui se passe dans MT4.
- OrderSend ou OrderSendAsync - sont lancés à partir du programme dans lequel l'environnement commercial est lu. Dans le cas de OrderSend, tout est clair, car OrderSend terminera son exécution avec un résultat clair. Dans le cas de OrderSendAsync nous pouvons faire deux choses - passer les données aux événements suivants selon le premier paradigme, ou faire OrdersAsyncWait() (je n'ai pas le code), comme cela est fait dans une simulation régulière de transfert de données asynchrones dans MT4 (implémentation de plusieurs threads).
Je devrais probablement dire quelques mots sur OrderSendAsync dans MT4. À n'importe quel stade de l'exécution du programme, il est possible de voir à quel point un thread commercial correspondant est occupé et ce qu'il fait exactement. En ce sens, l'asynchronie personnalisée dans MT4 nous offre beaucoup plus de possibilités que celle de MT5. Mais dans MT4, elle est implémentée en exécutant des "clients" sur chaque graphique, ce qui est coûteux. Dans MT5, il est possible d'écrire la même fonctionnalité et même sans beaucoup de graphiques - en exécutant le script sur un objet OBJ_CHART, mais il y aura toujours un léger retard. C'est-à-dire que OrderSendAsyncCustom sera légèrement plus lent que OrderSendAsync, mais il sera toujours beaucoup plus rapide que OrderSend + tous les avantages de l'implémentation personnalisée.La liste des ordres, comme la liste des positions, n'est pas mise à jour instantanément. imho, on ne peut pas se passer de Sleep-crutch.
Probablement, il serait plus correct d'utiliser OnTradeTransaction
MqlTradeTransaction peut être nécessaire uniquement lors du choix du paradigme approprié pour travailler avec OrderSendAsync. Dans d'autres cas, OnTradeTransaction == OnTrade dans le sens et ne joue pas plus de rôle que OnTick ou OnTimer.
Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie
Les erreurs typiques et la façon de les corriger lorsqu'on travaille dans un environnement de négociation
fxsaber, 2018.02.19 22:36
Il existe deux paradigmes de travail avec l'environnement de trading, l'écriture d'EAs.
Le surlignage indique que le même code commercial est exécuté dans chaque fonction On. Le code non commercial correspondant complète le reste.
Ce sera exactement la même chose que sur MT4 - s'il n'y a rien, cela ne sera pas compté.
C'est-à-dire qu'au prochain tic, le programme envoie une nouvelle demande d'ouverture. Par conséquent, nous avons le même problème - des ouvertures multiples.
Le conseiller expert doit avoir la logique suivante :
C'est-à-dire qu'au prochain tick, le logiciel envoie une nouvelle demande d'ouverture. Par conséquent, nous avons le même problème - des ouvertures multiples.
Il serait bon de lire l'intégralité du message.
L'EE doit avoir la logique suivante :
L'indicateur d'attente n'est disponible que pour le deuxième cas et OrderSendAsync. Pour OrderSend, le drapeau d'attente n'est pas du tout nécessaire. OrderSendAsync sans drapeau d'attente est OrdersAsyncWait().
Vous pouvez vérifier toute théorie dans la pratique.
Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading
Les erreurs typiques et la façon de les corriger lorsqu'on travaille dans un environnement de négociation
fxsaber, 2018.02.20 00:01
ZZY Insérez ce code ici et vérifiez le résultat sur le serveur de démonstration.
Il est bon de lire le post dans son intégralité.
Le drapeau d'attente n'est possible que pour le deuxième cas et OrderSendAsync. Pour OrderSend, le drapeau d'attente n'est pas du tout nécessaire. OrderSendAsync sans drapeau d'attente est OrdersAsyncWait().
Toute théorie peut être testée en pratique
Je suis guidé par les résultats pratiques.Eh bien, j'ai écrit pour le mode asynchrone. Avec le mode synchrone, vous n'avez pas besoin d'attendre - le résultat est déjà là dans la réponse à la requête.
J'ai écrit pour le mode asynchrone.
Une réponse détaillée a été donnée dès le début.
Une réponse étendue a été donnée dès le début.
Je dois l'avoir mal lu :)
Je n'ai vu aucune étape pour contourner l'erreur de découverte multiple. Seulement des "paradigmes" généraux ;)
C'est pourquoi j'ai décrit la logique approximative, qui est redondante - le drapeau est vérifié dans une fonction (wrapper) qui ouvre des positions / définit des ordres en attente. Ou peut-être aussi dans la fonction de suivi du signal.
Vous devez réfléchir à la meilleure façon de procéder.
le drapeau est vérifié dans la fonction (wrapper) d'ouverture des positions/placement des ordres en attente. Ou peut-être aussi dans la fonction de suivi du signal.
Je préfère de loin la solution via OrdersAsyncWait(), lorsque la sortie de la fonction On est toujours effectuée sans suspendre l'état. La prochaine lecture de l'environnement commercial avec une ardoise propre est alors aussi pertinente que possible.
L'utilisation de OrderSendAsync devrait toujours être appropriée. La seule situation où il serait approprié d'envoyer plusieurs (> 1) ordres de transaction, indépendants les uns des autres, sur un seul signal. Par conséquent, le truc OrderSendAsync n'a jamais de sens dans tous les autres cas.
SZZY Il y a un sujet distinct où OrderSendAsync est très pertinent - multi-conseillers : plusieurs TS indépendants dans un conseiller expert. L'OrderSend y est rarement adapté et même l'OrderAsyncWait( const string Symb) n'est pas bon puisque aucun Sleep n'est en principe autorisé.