Échange de données entre deux EAs fonctionnant dans des terminaux différents - page 3

 

Еще можно попробовать забить гвоздь лампочкой. У некоторых получается.

Quel est le problème de cette approche ?

Vous pouvez également régler l'heure du système.

C'est ainsi que l'heure du système est synchronisée :-). Pas par le biais de la mise en scène, mais par la lecture. Il s'agit d'une sorte d'échange de données.

 




Bonjour à tous !

L'une des meilleures façons de connecter des terminaux de manière fiable semble être l'utilisation du réseau 1C.
Deux caractéristiques principales :
1. L'application principale est exécutée sur 1C, les terminaux et leurs programmes MQL4 sont les exécutants,
2. L'application principale est exécutée sur l'un des terminaux, l'application 1C est utilisée comme protocole de liaison.

Avantages :
1. La possibilité de stocker et de traiter l'historique complet des cotations simultanément sur différents serveurs ;
2.

 
Andres >> :

J'ai déjà écrit une petite bibliothèque et mes Expert Advisors changent déjà les informations via le registre. En fait, ils sont modifiés par le registre, je ne vois pas d'opérations de lecture-écriture sur le disque.


Merci de mettre la bibliothèque à disposition ! Je m'occuperai également de la mise en œuvre de cet échange.

Il y a tout de suite une question évidente. Comment avez-vous mis en œuvre la vérification des paramètres de lecture/écriture ? Autrement dit, comment un autre EA peut-il savoir qu'un certain paramètre d'une clé peut déjà être lu ?

Créez-vous une clé d'autorisation de lecture/écriture supplémentaire par un autre EA ou y a-t-il une autre fonctionnalité que vous avez testée ? En d'autres termes, comment fournir un accès unitaire à un paramètre afin que les EA ne travaillent pas en même temps avec le même paramètre clé pour éviter les échecs ?

 

J'ai compris comment fournir un accès unitaire au paramètre clé. Il suffit de vérifier les erreurs à l'aide de la fonction GetErrorString( int ErrorCode).

Et en cas d'erreur, vous devez répéter l'opération. Mais je n'ai pas compris où dans la bibliothèque cette opération répétée est effectuée. Peut-être devrais-je moi-même ajouter quelque chose qui serait nécessaire. Quoi qu'il en soit, merci pour cette belle solution !

 

Il s'agit d'une simple enveloppe au-dessus de l'API Win, avec une sortie d'erreur qui vous permet uniquement de travailler avec des paramètres de clé de type chaîne.

GetErrorString( int ErrorCode ) est plutôt indicatif, de sorte que lorsque des erreurs se produisent, vous savez quoi, où, pourquoi et comment les corriger. Bien sûr, nous pouvons et devons placer la gestion des erreurs au-delà des limites des fonctions des wrappers et des bibliothèques, et y réagir de différentes manières (il existe de nombreux types d'erreurs), en nous basant sur la logique d'utilisation des clés par divers experts. Pendant ce temps, SetStringValue() à chaque tentative échouée peut seulement vous dire que la tentative a échoué. Et GetStringValue(), en cas d'échec, non seulement vous le dira, mais renverra également une chaîne vide. Je pense qu'il n'y a pas besoin d'une clé de permission de lecture/écriture supplémentaire, car ces vérifications sont effectuées par le système d'exploitation. La gestion des erreurs et la réponse appropriée aux erreurs sont suffisantes. Mes EAs pour le test "chaud" sont simplement désynchronisés dans le temps, c'est probablement la raison pour laquelle ils n'ont pas eu de conflits lors de la lecture/écriture d'un champ en même temps. Mais ce n'est pas une solution, bien sûr. Nous devons aller de l'avant. Je l'ai quand même écrit en une nuit, ne le jugez pas trop sévèrement. Une sorte de version "betta", afin de sentir la méthode :-).

 
Andres >> :

J'ai déjà écrit une petite bibliothèque, et mes EA modifient déjà les informations par le biais du registre. En fait, ils sont modifiés par la RAM, pas de lecture-écriture sur le disque que je n'observe pas. Dans le MSDN, il est écrit qu'il est préférable de ne pas insérer des données de plus de quelques centaines de Ko dans le registre.

La bibliothèque est configurée de telle manière que toutes les clés et tous les paramètres sont créés dans la zone de registre temporaire et ne sont pas écrits dans le registre permanent. Après le redémarrage, ces clés ont disparu.

Un MAIS, la bibliothèque ne fonctionne qu'avec des paramètres de type chaîne de caractères, dont la longueur ne dépasse pas 255 caractères (limitation dans MQL). Mais c'est bien suffisant. En général, les paramètres dans le registre peuvent être de différents types, pas seulement des chaînes de caractères, mais pour l'instant, d'autres types ne sont pas nécessaires à mon avis. Pour l'instant, j'ai deux EA échangées via le registre, mais il y en aura peut-être d'autres :-). Une autre bonne chose est que dans Win API il est possible de se connecter au registre du réseau. Si quelqu'un a besoin d'échanger des informations entre des EA fonctionnant sur différents ordinateurs du même réseau, il peut regarder dans cette direction. A mon avis, il est rapide, simple et fiable, et sans aucune dll ni fichier. Entrée d'une chaîne, sortie d'une chaîne.

Andrey, merci !

J'ai légèrement édité et coupé pour moi.

Tu devrais peut-être mettre ça dans ta tirelire? Tout à fait, une solution digne de ce nom !

Dossiers :
reglib.rar  11 kb
 

Un de ces jours, j'intégrerai votre bibliothèque, Andrey, à ma bibliothèque pour gérer les variables graphiques. Cela me donnera un niveau supplémentaire de déclaration de variable.

1. il y aura une GlobalSuperVariable. Une telle variable sera visible au niveau de l'OS.

2. Il y a maintenant GlobalVariable.

3. Il existe également une GlobalChartVariable. Ils ne sont visibles que pour une seule fenêtre.

En général, il devrait produire une bibliothèque pour travailler avec ses structures au niveau du système d'exploitation dans MQL4.

 
Zhunko >> :

1. il y aura une GlobalSuperVariable. Une telle variable sera visible au niveau du système d'exploitation.

Je vous serai extrêmement reconnaissant (et je ne suis probablement pas le seul) si vous téléchargez une telle variable sur la kodobase.

Fatigué d'inventer avec des méthodes artisanales.

 

Question pour Andrew. Ce registre sera-t-il reporté ?

string GetStringValue1 (int    hKey,      // Код ключа реестра.
                        int    lpSize,    // Длина считываемой строки.
                        string ValueName) // Имя параметра ключа.
 {
  int lpType[1];      // Возвращаемый тип параметра.
  int lpcbData[1];    // Размер буфера.
  int i;              // Переменная для подрезки последних пустых строк.
  int lres;           // Результат.
  string lpData = ""; // Буфер для возвращаемой строки.
  //----
  lpcbData[0] = lpSize; // Размер буфера.
  for ( i = 0; i < lpSize; i++) lpData = lpData + "#";
  lres = RegQueryValueExA ( hKey, ValueName, 0, lpType, lpData, lpcbData); // вызов API
  // Теперь в lpcbData[0] размер скопированных байт. Проверяем результат.
  if ( lres != ERROR_SUCCESS)
   {
    Print ("Error in RegQueryValueExA(): ", GetErrorString ( lres));
    return ("");
   }
  if ( lpType[0] == REG_SZ || lpType[0] == REG_EXPAND_SZ) return (StringSubstr ( lpData, 0, lpcbData[0] - 1));
  return ("");
 }
 
Je vais vous expliquer. Le problème est que si vous utilisez une chaîne de caractères s'incrémentant dynamiquement comme tampon, il y aura des erreurs. J'en ai déjà rencontré un par hasard :
InitRegDefines();
hKey = CreateKey( HKEY_CURRENT_USER, "!MT4TestKey" );

// заносим
SetStringValue( hKey, "Param", "Test" );

// вытаскиваем при помощи Вашей функции:
Print( GetStringValue1( hKey, 20, "Param" ) );

Après cela, il s'avère :

2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1 : ####
2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1 : RegCreateKeyExA() : Une partition inexistante a été créée.
2009.05.19 01:22:16 temp a démarré pour les essais

C'est-à-dire que le contenu du tampon ne change pas, bien qu'il n'y ait pas d'erreur lors de l'appel. Et c'est la ligne "Test" dans le registre.

J'ai appris dans les messages du forum que cela se produit à cause d'une étrange transmission de chaînes de l'environnement MQL aux fonctions DLL. Dans l'environnement MQL, les développeurs opèrent avec des chaînes en utilisant leur propre gestionnaire (string pool), et apparemment sur cette frontière, le mauvais tampon est rempli et donc nous ne pouvons pas voir le résultat renvoyé par la fonction API. Mais si nous utilisons des chaînes de caractères initialisées à la longueur maximale totale, alors, pour autant que je sache, il n'y a aucun problème. C'est pourquoi la chaîne de 255 caractères "#" est là. Le caractère "#" a été choisi simplement pour rendre la chaîne visible à l'œil. Cela n'a rien à voir avec l'API Win elle-même, car le contenu du tampon avant l'appel n'a aucune importance. Il s'agit de la limitation de la longueur de la chaîne que j'ai mentionnée précédemment. Vous pouvez passer plus de chaînes de caractères que 255 caractères dans SetStringValue(), mais il n'est pas possible de les lire.

Bien sûr, il est bon de ne pas avoir de limites, mais je ne vois pas en quoi cela constitue un grand inconvénient. Cela pose la question suivante : pourquoi avoir besoin de lire une chaîne de caractères d'une taille donnée ? S'il s'agit de contraintes, vous pouvez les contourner en écrivant une fonction qui divise la chaîne d'entrée en N paramètres de longueur 255 + le paramètre "reste". Et en le lisant, il le récupère. Il n'y a pas d'autre moyen. Si vous avez des difficultés, contactez-moi, je le ferai. Juste les besoins de chacun sont différents, vous ne pouvez pas fournir tout, il est suffisant pour moi que cela, et quelqu'un utilise des variables globales, et même à plusieurs niveaux.

Raison: