Erreurs, bugs, questions - page 2963
![MQL5 - Langage des stratégies de trading intégré au terminal client MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Vous manquez des opportunités de trading :
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Inscription
Se connecter
Vous acceptez la politique du site Web et les conditions d'utilisation
Si vous n'avez pas de compte, veuillez vous inscrire
Pourquoi auraient-ils besoin de se synchroniser ? user32.dll le fera pour eux.
Essayez de l'écrire. Peut-être que vous ne comprenez pas bien la tâche.
Pourquoi n'aimez-vous pas les ressources ? Je pense que c'est optimal dans les limites d'un seul terminal. La variante que j'ai suggérée en utilisant user32.dll (j'ai mis en œuvre cette variante il y a environ 10 ans, lorsque je m'adonnais à l'arbitrage dans ma jeunesse) a un temps d'accès et d'analyse d'environ 50 microsecondes (je pense qu'il peut être accéléré de 1,5 à 2 fois). Est-il plus lent avec les ressources ?
La lecture prend 100 microsecondes sur une machine domestique dans des conditions idéales. Un conseiller expert sur un seul tick peut provoquer la lecture d'une centaine de fois. C'est lent.
Dans des conditions idéales, GlobalVariableGet sera exécuté en 10 microsecondes. Mais ce n'est pas un indicateur, car c'est un frein horrible dans des conditions de combat nouvelles pour moi.
C'est HistoryTicks - la capture de tous les ticks pour les EAs. Par conséquent, EventChartCustom n'est pas adapté, il possède sa propre file d'attente. Il en va de même pour le tampon.
Je l'ai fait fonctionner sur EventChartCustom. 99,8% des ticks sont reçus dans un délai de 0,15 ms.
Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie
EventChartCustom => l'indicateur est trop lent
Andrey Khatimlianskii, 2019.12.12 09:27
Voici les statistiques pour 9 heures de travail avec 5 symboles :
Le conseiller expert était sur GBPUSD, donc le OnTick natif fonctionnait pour lui.
Il n'y a pas eu d'erreur "l'indicateur est trop lent".
En revanche, le pourcentage de ticks manqués et la latence moyenne sont beaucoup plus élevés sur le VPS de MQ (je posterai les statistiques plus tard).
Et il y a beaucoup d'erreurs "l'indicateur est trop lent".
Je ne comprends pas la nature du débordement de la file d'attente, car le conseiller expert traite immédiatement les événements accumulés (il ne fait que revenir).
Est-ce que quelqu'un d'autre le traite ?
Je l'ai fait fonctionner surEventChartCustom. 99,8% des ticks sont reçus dans un délai de 0,15 ms.
J'envoie les ticks de l'indicateur via ceci : sparam contient MqlTick, lparam - numéro de tick.
Le conseiller expert dans OnChartEvent capte ces ticks. Et il doit comprendre si le tick actuel est le plus actuel ou non ? C'est-à-dire, y a-t-il une file d'attente de ticks ou est-elle vide ?
Pour cela, il lit le numéro (la tâche est de lire ce numéro) du dernier tick envoyé par l'indicateur. Si le tick a le même numéro - la file d'attente est vide, et il est possible de commencer à travailler avec les ticks.
Et pendant l'opération de OnTick, après OrderSend il est nécessaire de vérifier si l'indicateur a envoyé plus de ticks. Pour cela, nous devons à nouveau lire le nombre à partir de l'indicateur. Et il peut y avoir plus d'une centaine de ces vérifications pendant un OnTick. C'est pourquoi nous devons lire rapidement.
Dans un terminal, le winapi le plus rapide sera l'allocation de mémoire (globale au sein d'un processus) et les fonctions verrouillées comme https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange.
Celles-ci sont non bloquantes, atomiques et essentiellement exécutées en quelques instructions asm.
Dans un terminal, le winapi le plus rapide sera l'allocation de mémoire (globale au sein d'un processus) et les fonctions verrouillées comme https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange.
Celles-ci sont non bloquantes, atomiques et essentiellement exécutées en quelques instructions asm.
Pas sans un exemple.
Pour ce faire, il lit le numéro (la tâche est de lire ce numéro) du dernier tick envoyé par l'indicateur. Si le tick reçu a le même numéro - la file d'attente est vide, et vous pouvez commencer à travailler avec un paquet de ticks.
Et pendant l'opération de OnTick, après OrderSend il est nécessaire de vérifier si l'indicateur a envoyé plus de ticks. Pour ce faire, nous devons à nouveau lire le numéro de l'indicateur. Et il peut y avoir plus d'une centaine de ces vérifications pendant un OnTick. Par conséquent, nous devons le lire rapidement.
Initialisation.
1. Dans le premier thread (très probablement, le thread d'écriture), allouez de la mémoire de quelque manière que ce soit pour la variable de la taille requise.
2. Dans les threads nécessaires (threads de lecture), envoyez l'adresse de cette mémoire.
Travail de base.
3. Le fil d'écriture initie InterlockedExchange ou InterlockedExchange64 selon la taille de la variable pour y écrire.
4. Le fil de lecture tire par exemple InterlockedCompareExchange pour lire.
Achèvement.
5. Libérer la mémoire allouée, de préférence dans le même thread qui l'a allouée.
Si nécessaire, elle peut être répétée pour la création de plusieurs compteurs. En revanche, vous aurez besoin de la connexion WinAPI. Des caractéristiques de la mémoire allouée l'adresse devrait être alignée, mais par défaut elle l'est généralement.
Le travail se fera au sein d'un processus, la mémoire est partagée pour les threads d'un processus. Si nécessaire, il existe d'autres fonctions verrouillées comme InterlockedDecrement, InterlockedAdd, etc.
Les fonctions sont non bloquantes, n'attendent rien, automates, elles sont exécutées en quelques instructions asm.
P.S. Autant que je me souvienne, les opérations régulières de lecture et d'écriture via mov en assembleur sont de toute façon atomiques. Et si le compilateur ne fait pas de dégâts (il ne devrait pas en théorie), nous pouvons essayer de lire et d'écrire dans la variable dans la mémoire allouée et ce sera atomique.
Si elle convient à la tâche, il est peu probable qu'elle soit plus rapide en un seul processus. Pour l'interprocessus, le plus rapide sera similaire, mais avec la mémoire partagée, dans ce cas vous ne pouvez pas vous passer de WinAPI.
Ce système ne semble pas fonctionner. Montrez un exemple élémentaire, s'il vous plaît.
Pourquoi pas ? C'est comme ça que je le vois. Le principe du getter setter.
Obtenir la valeur d'une variable cachée par le biais de la fonction.
Si vous passez la structure MqlTick, définissez votre structure avec les champs définis comme MqlTick, et ajoutez votre champ compteur à la structure.
Et renvoyer cette structure à partir de la fonction d'exportation.
Un exemple élémentaire pour l'indicateur. Ne faites pas attention à l'exemple dans le script.
Dans Expert Advisor, vous appelez GetTickStruct et obtenez la structure entière avec votre compteur.
Dans Expert Advisor vous appelez GetTickStruct, vous obtenez la structure entière, avec son compteur.
Veuillez écrire un transfert élémentaire de numéros de l'indicateur à l'EA.
Un transfert de nombre élémentaire de l'indicateur à l'EA, veuillez écrire.
Remplacer la structure par une variable ))
Remplacer la structure par une seule variable ;))
Non transférable.