Verbindung eines Expert-Systems mit ICQ in MQL5

Andriy Voitenko | 4 März, 2016

Einleitung

ICQ ist ein zentraler Dienst zum sofortigen und rechnerunabhängigen Austausch von Textmitteilungen unter Verwendung des OSCAR-Protokolls. Ein Händler kann ICQ einerseits zur Anzeige aktueller Informationen sowie als Steuerpult nutzen. In diesem Beitrag wird ein Beispiel für die Ausführung einer ICQ-Instanz mit einem Minimum an Funktionen in einem Expert-System vorgestellt.

Als Grundlage wurde ein IcqMod-Entwurf mit offenem Quellcode verwendet und modifiziert. Das Protokoll für den Austausch mit dem ICQ-Server wird in dem DLL-Modul icq_mql5.dll bereitgestellt. Es ist in C++ geschrieben und verwendet ausschließlich die Bibliothek Winsock2 von Windows. Das kompilierte Modul und der Quellcode für Visual Studio 2005 befinden sich in der Anlage zu diesem Beitrag.

Besonderheiten und Beschränkungen dieser Umsetzung der Instanz sind:

Darstellung der Funktionen der Bibliothek

Eine Beschreibung der Konstanten und Funktionen des dll-Moduls befindet sich in der Datei icq_mql5.mqh in der Anlage zu diesem Beitrag.

Die Herstellung der Verbindung zum Server erfolgt mithilfe der Funktion ICQConnect:

uint  ICQConnect (ICQ_CLIENT & cl,  // Variable for storing data about the connection  
string  host,  // Server name, such as login.icq.com  
ushort  port,  // Server port, eg 5190  
string  login, // Account Number (UIN)  
string  pass   // Account password for)

Vorstellung der Ausgabewerte der Funktion ICQConnect:

Bezeichnung der Konstanten
    Wert
Beschreibung
 ICQ_CONNECT_STATUS_OK
0xFFFFFFFF  Verbindung hergestellt
 ICQ_CONNECT_STATUS_RECV_ERROR
0xFFFFFFFE
 Fehler beim Lesen der Daten
 ICQ_CONNECT_STATUS_SEND_ERR
0xFFFFFFFD
 Fehler beim Versenden der Daten
 ICQ_CONNECT_STATUS_CONNECT_ERROR
0xFFFFFFFC
 Fehler bei der Verbindung mit dem Server
 ICQ_CONNECT_STATUS_AUTH_ERROR 0xFFFFFFFB  Zugang verweigert: Ungültiges Passwort oder Überschreitung der Verbindungsobergrenze

 

Gerüst für die Speicherung der Verbindungsdaten:

 struct  ICQ_CLIENT (
uchar  status;     // connection status code  
ushort  sequence;  // sequence meter  
uint  sock;        // socket number  )

 In der Praxis kommt zur Analyse des Verbindungszustands in diesem Gerüst nur die Variable „Status“ zum Einsatz, sie kann folgende Werte annehmen:

Bezeichnung der Konstanten
Wert 
Beschreibung
 ICQ_CLIENT_STATUS_CONNECTED 0x01  Es ist eine Verbindung zum Server vorhanden
 ICQ_CLIENT_STATUS_DISCONNECTED
0x02  Es ist keine Verbindung zum Server vorhanden

Häufige Versuche zur Herstellung einer Verbindung mit dem Server können zu einer vorübergehenden Sperrung des Zugriffs auf die Berechnungsaufzeichnungen führen. In Anbetracht dessen muss zwischen den einzelnen Verbindungsversuchen eine Sperrzeit eingehalten werden.

Die empfohlene Sperrzeit beträgt 20 - 30 Sekunden.

Für den Abbruch der Verbindung mit dem Server sorgt die Funktion ICQClose:

 void  ICQClose (
ICQ_CLIENT & cl  // Variable for storing connection data)

Die Funktion ICQ sendMsg wird verwendet, um Textmitteilungen zu senden:

 uint  ICQSendMsg (
ICQ_CLIENT & cl,  // Variable to store data about the connection.  
string  uin,        // Account number of the recipient  
string  msg         // Message)

Wenn die Mitteilung erfolgreich verschickt wurde, ist der ausgegebene Wert 0x01, wenn ein Fehler vorliegt, dagegen 0x00. 

Zur Prüfung des Vorhandenseins eingehender Nachrichten dient die Funktion ICQReadMsg:

 uint  ICQReadMsg (
ICQ_CLIENT & cl,  // Variable for storing connection data  
string  & Uin,     // Account number of the sender  
string  & Msg,     // Message  
uint  & Len        // Number of received symbols in the message

Bei Vorliegen eingehender Nachrichten lautet der ausgegebene Wert 0x01, wenn keine Nachrichten vorhanden sind, 0x00.


Die Klasse COscarClient

Zur Erleichterung der Arbeit mit ICQ in einer objektorientierten MQL5-Umgebung wurde die Klasse COscarClient entwickelt. Sie beinhaltet neben den oben dargestellten grundlegenden Funktionen einen Mechanismus zur automatischen Neuverbindung mit dem Server (wenn autocon = true) bei einem Abbruch der Verbindung nach Ablauf einer vorgegebenen Sperrzeit (die Variable „timeout“). Die Beschreibung der Klasse befindet sich in der Datei icq_mql5.mqh in der Anlage zu diesem Beitrag und folgt hier: 

//+------------------------------------------------------------------+
class COscarClient
//+------------------------------------------------------------------+
{
private:
  ICQ_CLIENT client;        // storing connection data
          uint connect;     // flag of status connection
      datetime timesave;     // the time of last connection to the server
      datetime time_in;      // the time of last reading of messages

public:
      string uin;            // buffer for the storage of the uin of the sender for a received message
      string msg;            // buffer for the storage of text for a received message
        uint len;            // the number of symbols in the received message
     
      string login;          // number of the sender's account (UIN)
      string password;       // password for UIN 
      string server;         // name of the server
        uint port;           // network port  
        uint timeout;        // timeout tasks (in seconds) between attempts to reconnect to the server
        bool autocon;        // automatic connection resume
        
           COscarClient();   // constructor for initialization of variable classes
      bool Connect(void);     // establishment of a connection with a server
      void Disconnect(void);  // breaking a connection with a server
      bool SendMessage(string  UIN, string  msg); // sending a message 
      bool ReadMessage(string &UIN, string &msg, uint &len); // receiving a message
};

Ein Expert-System auf der Grundlage der Klasse COscarClient

Der Mindestcode für ein Expert-System zur Arbeit mit ICQ mithilfe der Klasse COscarClient befindet sich in der Datei icq_demo.mq5 und hier:

#include <icq_mql5.mqh>

COscarClient client;

//+------------------------------------------------------------------+
int OnInit()
//+------------------------------------------------------------------+
  {
   printf("Start ICQ Client");
   
   client.login      = "641848065";     //<- login
   client.password   = "password";      //<- password
   client.server     = "login.icq.com";
   client.port       = 5190;
   client.Connect();
   
   return(0);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
//+------------------------------------------------------------------+
  {
   client.Disconnect();
   printf("Stop ICQ Client");
  }
//+------------------------------------------------------------------+
void OnTick()
//+------------------------------------------------------------------+
  {
   string text;
   static datetime time_out;
   MqlTick last_tick;

   // reading the messages
   while(client.ReadMessage(client.uin,client.msg,client.len))
     printf("Receive: %s, %s, %u", client.uin, client.msg, client.len);

   // transmission of quotes every 30 seconds
   if((TimeCurrent()-time_out)>=30)
     {
      time_out = TimeCurrent();
      SymbolInfoTick(Symbol(), last_tick);
      
      text = Symbol()+" BID:"+DoubleToString(last_tick.bid, Digits())+
                  " ASK:"+DoubleToString(last_tick.ask, Digits()); 
      
      if (client.SendMessage("266690424",        //<- number of the recipient 
                                        text)) //<- message text 
         printf("Send: " + text);
     }
  }
//+------------------------------------------------------------------+

Zur Veranschaulichung der Funktionsweise eines Expert-Systems, das den Austausch von Textmitteilungen mit einer ICQ-Instanz ermöglicht, dient Abbildung 1.

Abbildung 1. Austausch von Textmitteilungen zwischen MetaTrader5 und ICQ2Go

Abbildung 1. Austausch von Textmitteilungen zwischen MetaTrader5 und ICQ2Go

Erweiterung der Möglichkeiten

Wir machen es etwas schwieriger, indem wir sie der praktischen Anwendung annähern. Nehmen wir beispielsweise an, wir müssten die Arbeit unseres Expert-Systems aus der Ferne überwachen und die benötigten Informationen auf unserem Mobiltelefon oder einem fremden PC mit Internetverbindung empfangen. Dazu legen wir einen Satz von Befehlen zur Steuerung des zukünftigen Expert-Systems fest. Außerdem erweitern wir das Expert-System um eine Zergliederungsfunktion („Parsing“) zur Entschlüsselung der eingehenden Befehle.

Das allen Befehlen gemeinsame Format sieht folgendermaßen aus: 

[? |!] [command] [parameter] [value],

mit ? als Hinweis auf einen Lesevorgang; und ! als Hinweis auf einen Schreibvorgang.

Eine Übersicht über die Befehle bietet folgende Tabelle:

     
 help  Lesen  Ausgabe der Informationen zur Syntax und zum Verzeichnis der Befehle
 info  Lesen  Ausgabe der Angaben zum Kontostand
 symb  Lesen  Ausgabe des Marktpreises für das angegeben Währungspaar
 ords  Lesen/Schreiben  Verwaltung eröffneter Aufträge
 param  Lesen/Schreiben  Verwaltung der Parameter des Expert-Systems
 close  Schreiben  Beendigung der Arbeit des Expert-Systems und Schließen des Programms
 shdwn  Schreiben  Herunterfahren des Rechners

Das Expert-System zur Umsetzung der Verarbeitung dieser Befehle befindet sich in der Datei icq_power.mq5.

Abbildung 2 bietet eine anschauliche Darstellung seiner Arbeit. Die Steuerungsbefehle kommen von einem PDA mit installierter ICQ-Instanz (Abbildung 2a) sowie über den sicheren WAP-Server http://wap.ebuddy.com, über den die Arbeit mit ICQ abgewickelt wird (Abbildung 2b). Die zweite Möglichkeit ist besser für diejenigen geeignet, die sich nicht mit der Suche, Installation und Einrichtung der Programme für die Arbeit mit ICQ auf ihren Mobiltelefonen herumschlagen möchten.

         

Abbildung 2. Arbeiten mit einem Expert-System über eine ICQ-Instanz auf einem PDA (Abb. 2a) sowie über die WAP-Seite wap.ebuddy.com (Abb. 2b).

Die visuelle Komponente von ICQ

In diesem Abschnitt befassen wir uns kurz mit dem Skriptbeispielicq_visual.mq5, das den Teil umsetzt, dessen Erscheinungsbild in Abbildung 3 zu sehen ist.

Abbildung 3. Die visuelle Komponente von ICQ

Abbildung 3. Die visuelle Komponente von ICQ

Die Musterkomponente erinnert an die Fenster in Windows, sie besteht aus Datenfeldern mit Steuerelementen, wie Schaltflächen, Eingabefeldern und Beschriftungen.

Der Einfachheit halber wurde ein Steuerungselement zur Speicherung der Listen mit den Berechnungsaufzeichnungen und den Kontakten das Muster eingearbeitet. Die Auswahl der jeweiligen Listenwerte erfolgt über die entsprechenden Navigationsschaltflächen.

Zur Erstellung eines Fensters im Stil von ICQ 6.5 werden die Schaltflächen durch grafische Elemente ersetzt. Abbildung 4 zeigt das in dem Skript icq_visual_skin.mq5 angelegte Aussehen der Komponente. Wer eine eigene Komponente gestalten möchte, muss lediglich die für das Aussehen des Fensters verantwortliche Datei skin.bmp durch eine selbst entwickelte ersetzen.

Abbildung 4. Farbliche Gestaltung der visuellen Komponente von ICQ

Abbildung 4. Farbliche Gestaltung der visuellen Komponente von ICQ


Fazit

In diesem Beitrag wurde eines der einfachsten Verfahren zum Anlegen einer ICQ-Instanz für MetaTrader 5 mit den Mitteln der integrierten Programmiersprache vorgestellt.