Austausch von Daten zwischen zwei EAs, die auf verschiedenen Terminals laufen - Seite 3

 

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

Was ist an diesem Ansatz falsch?

Sie können auch die Systemzeit einstellen.

Auf diese Weise wird die Systemzeit synchronisiert :-). Nicht durch das Setting, sondern durch das Lesen. Dies ist eine Art Datenaustausch.

 




Guten Tag zusammen!

Eine der besten Möglichkeiten, Terminals zuverlässig zu verbinden, scheint die Verwendung des Netzwerks 1C zu sein.
Zwei Hauptmerkmale:
1. Die Hauptanwendung wird auf 1C ausgeführt, Terminals und ihre MQL4-Programme sind die Ausführenden,
2. Die Hauptanwendung wird auf einem der Terminals ausgeführt, die 1C-Anwendung wird als Verbindungsprotokoll verwendet.

Vorteile:
1. Die Möglichkeit, die gesamte Kursgeschichte gleichzeitig auf verschiedenen Servern zu speichern und zu verarbeiten;
2.

 
Andres >> :

Ich habe bereits eine kleine Bibliothek geschrieben und meine Expert Advisors ändern bereits Informationen über die Registry. Tatsächlich werden sie über das Register geändert, ich sehe keine Lese- und Schreiboperationen auf der Festplatte.


Vielen Dank für die Bereitstellung der Bibliothek! Ich werde mich auch mit der Umsetzung dieses Austauschs befassen.

Eine Frage drängt sich sofort auf. Wie haben Sie die Überprüfung der Lese-/Schreibparameter implementiert? Das heißt, woher weiß ein anderer EA, dass ein bestimmter Parameter eines Schlüssels bereits gelesen werden kann?

Haben Sie einen zusätzlichen Schlüssel für die Lese-/Schreibberechtigung durch einen anderen EA erstellt oder gibt es eine andere Funktion, die Sie getestet haben? Mit anderen Worten: Wie kann man einen einheitlichen Zugriff auf einen Parameter gewährleisten, so dass die EAs nicht gleichzeitig mit demselben Schlüsselparameter arbeiten, um Fehler zu vermeiden?

 

Ich habe sozusagen herausgefunden, wie man einen einheitlichen Zugriff auf den Schlüsselparameter ermöglicht. Sie können einfach mit der Funktion GetErrorString( int ErrorCode) auf Fehler prüfen.

Und im Falle eines Fehlers müssen Sie den Vorgang wiederholen. Aber ich habe nicht verstanden, wo in der Bibliothek dieser wiederholte Vorgang durchgeführt wird. Vielleicht müsste ich selbst etwas hinzufügen, was erforderlich wäre. Jedenfalls danke für die gute Lösung!

 

Dies ist ein einfacher Wrapper auf der Win-API, mit Fehlerausgabe, der nur die Arbeit mit String-Schlüsselparametern erlaubt.

GetErrorString( int ErrorCode ) ist eher indikativ, so dass Sie beim Auftreten von Fehlern wissen, was, wo, warum und wie Sie es beheben können. Natürlich können und sollten wir die Behandlung von Fehlern über die Grenzen von Wrapper- und Bibliotheksfunktionen hinaus ausdehnen und auf unterschiedliche Weise auf sie reagieren (es gibt viele Arten von Fehlern), basierend auf der Logik der Verwendung von Schlüsseln durch verschiedene Experten. In der Zwischenzeit kann SetStringValue() bei einem fehlgeschlagenen Versuch nur mitteilen, dass der Versuch fehlgeschlagen ist. Und GetStringValue() gibt im Falle eines Fehlers nicht nur einen Hinweis, sondern auch eine leere Zeichenkette zurück. Ich denke, es besteht keine Notwendigkeit für einen zusätzlichen Schlüssel für Lese- und Schreibrechte, da solche Überprüfungen vom Betriebssystem durchgeführt werden. Fehlerbehandlung und angemessene Fehlerreaktionen sind ausreichend. Meine EAs für den "heißen" Test sind einfach zeitlich desynchronisiert, deshalb gab es wahrscheinlich keine Konflikte beim gleichzeitigen Lesen/Schreiben eines Feldes. Aber das ist natürlich keine Lösung. Wir müssen weitergehen. Trotzdem habe ich es in einer Nacht geschrieben, also urteilen Sie nicht zu streng. Eine Art "betta"-Version, um die Methode zu spüren :-).

 
Andres >> :

Ich habe bereits eine kleine Bibliothek geschrieben, und meine EAs ändern bereits Informationen über die Registrierung. In der Tat, sie sind durch den RAM geändert, keine Lese-Schreib auf der Festplatte ich nicht beobachten. In MSDN steht geschrieben, dass es besser ist, keine Daten mit mehr als ein paar hundert Kb in die Registrierung zu schieben.

Die Bibliothek ist so konfiguriert, dass alle Schlüssel und Parameter im temporären Registrierungsbereich erstellt und nicht in die permanente Registrierung geschrieben werden. Nach einem Neustart sind diese Tasten verschwunden.

Ein ABER, die Bibliothek arbeitet nur mit String-Parametern, die nicht mehr als 255 Zeichen lang sind (Einschränkung in MQL). Aber das ist völlig ausreichend. Im Allgemeinen können die Parameter in der Registrierung von verschiedenen Typen sein, nicht nur von Strings, aber im Moment sind andere Typen meiner Meinung nach nicht erforderlich. Im Moment habe ich zwei EAs, die über die Registrierung ausgetauscht werden, aber vielleicht werden noch mehr benötigt :-). Eine weitere gute Sache ist, dass es in Win API möglich ist, eine Verbindung zur Netzwerkregistrierung herzustellen. Wenn jemand Informationen zwischen EAs austauschen muss, die auf verschiedenen Computern im selben Netzwerk laufen, kann er in diese Richtung schauen. Meiner Meinung nach ist es schnell, einfach und zuverlässig, und das ganz ohne Dlls und Dateien. Eingabe einer Zeichenkette, Ausgabe einer Zeichenkette.

Andrey, vielen Dank!

Er wurde für mich leicht bearbeitet und gekürzt.

Vielleicht sollten Sie das in Ihr Sparschwein stecken? Durchaus, eine würdige Lösung!

Dateien:
reglib.rar  11 kb
 

Eines Tages werde ich deine Bibliothek, Andrey, in meine Bibliothek integrieren , um grafische Variablen zu behandeln. Dadurch erhalte ich eine weitere Ebene der Variablendeklaration.

1. Es wird eine GlobalSuperVariable geben. Eine solche Variable wird auf der Ebene des Betriebssystems sichtbar sein.

2. Jetzt gibt es GlobalVariable.

3. Es gibt auch GlobalChartVariable. Sie sind nur für ein Fenster sichtbar.

Im Allgemeinen sollte sie eine Bibliothek für die Arbeit mit ihren Strukturen auf der Betriebssystemebene in MQL4 erstellen.

 
Zhunko >> :

1. Es wird eine GlobalSuperVariable geben. Diese Variable wird auf Betriebssystemebene sichtbar sein.

Ich wäre Ihnen sehr dankbar (und wahrscheinlich bin ich nicht der Einzige), wenn Sie eine solche Variable in die kodobase hochladen würden.

Ich habe es satt, mit selbstgebastelten Methoden zu arbeiten.

 

Frage an Andrew. Wird diese Registrierung übernommen?

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 ("");
 }
 
Ich werde es erklären. Die Sache ist die, wenn Sie einen dynamisch inkrementierenden String als Puffer verwenden, wird es einige Fehler geben. Ich bin selbst schon einmal über einen solchen gestolpert:
InitRegDefines();
hKey = CreateKey( HKEY_CURRENT_USER, "!MT4TestKey" );

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

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

Danach stellt es sich heraus:

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(): Eine nicht existierende Partition wurde erstellt.
2009.05.19 01:22:16 Zeitarbeit zum Testen gestartet

Das heißt, der Inhalt des Puffers ändert sich nicht, obwohl es beim Aufruf keine Fehler gibt. Und es ist die Zeile "Test" in der Registrierung.

Ich habe aus Forenbeiträgen gelernt, dass es wegen einiger seltsamer Zeichenfolgenübergabe von MQL-Umgebung zu DLL-Funktionen passiert. In MQL-Umgebung arbeiten die Entwickler mit Strings mit ihren eigenen Manager (String-Pool), und anscheinend auf dieser Grenze der falsche Puffer gefüllt ist und daher können wir nicht sehen, das Ergebnis von API-Funktion zurückgegeben. Aber wenn wir Zeichenketten verwenden, die auf die gesamte Maximallänge initialisiert sind, dann gibt es, soweit ich sehen kann, kein Problem. Aus diesem Grund gibt es die 255 Zeichen lange Zeichenfolge "#". Das Zeichen "#" wurde gewählt, um die Zeichenfolge für das Auge sichtbar zu machen. Es hat nichts mit der Win-API selbst zu tun, denn es spielt keine Rolle, womit der Puffer vor dem Aufruf gefüllt ist. Dies ist die bereits erwähnte Begrenzung der Zeichenfolgenlänge. Sie können Strings, die länger als 255 Zeichen sind, an SetStringValue() übergeben, aber es ist nicht möglich, sie zu lesen.

Natürlich ist es gut, wenn es keine Einschränkungen gibt, aber ich sehe nicht, dass dies eine große Unannehmlichkeit darstellt. Das wirft die Frage auf: Warum müssen Sie eine Zeichenkette mit einer bestimmten Größe lesen? Wenn es um Einschränkungen geht, können Sie diese umgehen, indem Sie eine Funktion schreiben, die die Eingabezeichenfolge in N Parameter mit einer Länge von 255 + "Rest"-Parameter zerlegt. Und beim Lesen sammelt er sie wieder ein. Es gibt keinen anderen Weg. Wenn Sie Schwierigkeiten haben, kontaktieren Sie mich bitte, ich werde es tun. Nur jeder die Bedürfnisse sind unterschiedlich, können Sie nicht alles, es ist genug für mich nur diese, und jemand verwendet globale Variablen, und sogar auf mehreren Ebenen.