请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3365979 新帖:0

用 MQL5 连接 EA 交易程序和 ICQ

外汇交易达人发表于:2 月 25 日 00:38回复(1)

简介

ICQ 是一项文本信息即时交换中央服务,具有离线模式,采用 OSCAR 协议。对于交易者而言,ICQ 能够担当一个及时显示信息及控制面板的终端。本文将介绍一个例子,说明如何在一个 EA 交易程序内实施一个具有最少功能集的 ICQ 客户端。

IcqMod 项目的草稿包含一个开源代码,是本文的使用和处理基础。在 DLL 模块 icq_mql5.dll 中实施了与 ICQ 服务器的交换协议。它以 C++ 编写,并且仅使用 Windows 库 winsock2。本文附带了编译后的模块和针对 Visual Studio 2005 的源代码。

辨别此客户端的功能和实施限制:

  • 同时工作的客户端的最大数量在理论上是没有限制的。
  • 传入消息的最大字符数 - 150 个字符。不支持更长消息的接收。
  • Unicode 支持。
  • 仅支持直接连接。不支持通过代理服务器 (HTTP / SOCK4 / SOCK5) 进行的连接。
  • 不处理离线消息。

库函数的说明

dll 模块的常量和函数的说明位于执行文件 icq_mql5.mqh 中。

函数 ICQConnect 用于连接服务器:

uint  ICQConnect (ICQ_CLIENT & cl,  //  用于存储连接数据的变量 
string  host,  // 服务器名称,例如login.icq.com  
ushort  port,  // 服务器端口,例如 5190  
string  login, // 帐号 (UIN)  
string  pass   // 帐户密码

通过 ICQConnect 返回的值的说明:

常量的名称
    值
描述
 ICQ_CONNECT_STATUS_OK
0xFFFFFFFF  已建立连接
 ICQ_CONNECT_STATUS_RECV_ERROR
0xFFFFFFFE
 读取数据错误
 ICQ_CONNECT_STATUS_SEND_ERR
0xFFFFFFFD
 发送数据错误
 ICQ_CONNECT_STATUS_CONNECT_ERROR
0xFFFFFFFC
 服务器连接错误
 ICQ_CONNECT_STATUS_AUTH_ERROR 0xFFFFFFFB  身份验证错误:密码不正确或超过了连接限制

 

有关连接的数据存储结构:

 struct  ICQ_CLIENT (
uchar  status;     // 连接状态码  
ushort  sequence;  // 序列计数器  
uint  sock;        // 套接字  )

 在实践中,为了执行此结构的连接状态的分析,我们使用可变状态,该状态可假定为以下值:

常量的名称
值 
描述
 ICQ_CLIENT_STATUS_CONNECTED 0x01  已建立了到服务器的连接
 ICQ_CLIENT_STATUS_DISCONNECTED
0x02  到服务器的连接失败

 

频率尝试连接服务器会导致暂时封锁对您的帐户的访问。因此,在再次尝试连接到服务器之前必须等待一段时间。

建议的等待时间为 20-30 秒。

函数 ICQClose 用于中止与服务器的连接:

 void  ICQClose (
ICQ_CLIENT & cl  // 存储连接数据的变量)

函数 ICQSendMsg 用于发送文本消息:

 uint  ICQSendMsg (
ICQ_CLIENT & cl,  // 用于存储连接数据的变量。 
string  uin,        // 接收者的账号 
string  msg         // 消息)

如果成功发送消息,则返回值为 0x01,如果出现发送错误,则返回值为 0x00。 

函数 ICQReadMsg 检查传入的消息:

 uint  ICQReadMsg (
ICQ_CLIENT & cl,  // 存储连接数据的变量  
string  & Uin,     // 发送者的账号  
string  & Msg,     // 消息  
uint  & Len        // 消息中接收到的交易品种的编号

如果有传入的消息,则返回值为 0x01,如果没有消息,则返回值为 0x00。 

COscarClient 类

为了便于在 MQL5 的面向对象的环境中使用 ICQ,特意开发了 COscarClient 类。除了上述基本函数以外,它还包含一个机制,在经过特定时间之后,自动重新连接到服务器(当 autocon = true 时)。类的说明包含在附带的文件 icq_mql5.mqh 中,并如下如示: 

//+------------------------------------------------------------------+
class COscarClient
//+------------------------------------------------------------------+
{
private:
  ICQ_CLIENT client;        // 存储连接数据
          uint connect;     // 连接状态标识
      datetime timesave;     // 最近一次连接服务器的时间
      datetime time_in;      // 最近一次读取消息的时间

public:
      string uin;            // 用于存储已收消息中发送方UIN的缓存
      string msg;            // 存储接收到的消息文本的缓存
        uint len;            // 接收到的消息中的交易品种的数量
     
      string login;          // 发送帐户(UIN)的数量
      string password;       // UIN的密码 
      string server;         // 服务器名称
        uint port;           // 网络端口 
        uint timeout;        // 服务器重新连接请求的超时时间(秒)
        bool autocon;        // 自动重新连接
        
           COscarClient();   // 初始化类的变量的构造函数
      bool Connect(void);     // 与服务器建立连接
      void Disconnect(void);  // 断开与服务器的连接
      bool SendMessage(string  UIN, string  msg); // 发送一个消息 
      bool ReadMessage(string &UIN, string &msg, uint &len); // 接收一个消息
};

基于 COscarClient 类的 EA 交易程序

使用 COscarClient 来处理 ICQ 所需的最少 EA 交易程序代码包含在 icq_demo.mq5 文件中,并且如下所示:

#include <icq_mql5.mqh>

COscarClient client;

//+------------------------------------------------------------------+
int OnInit()
//+------------------------------------------------------------------+
  {
   printf("Start ICQ Client");
   
   client.login      = "641848065";     //<- 登录名
   client.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;

   // 读取消息
   while(client.ReadMessage(client.uin,client.msg,client.len))
     printf("Receive: %s, %s, %u", client.uin, client.msg, client.len);

   //每30秒发送一次报价
   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",        //<- 接收者编号 
                                        text)) //<- 消息文本 
         printf("Send: " + text);
     
}
  
}
//+------------------------------------------------------------------+

图 1 说明了 EA 交易程序的工作,该程序允许与 ICQ 客户端交换文本消息。

图 1. MetaTrader5 和 ICQ2Go 之间的文本消息交换

图 1. MetaTrader5 和 ICQ2Go 之间的文本消息交换

能力建立

让我们通过使其更接近实际应用,使任务复杂一些。例如,我们需要管理 EA 交易程序的工作,使用连接到互联网的手机或其它 PC 远程获取必要的信息。为此,我们描述了一组用于控制期货 EA 交易程序的命令。同样,让我们用一个用于对传入的命令进行解码的解析函数来补充交易程序。

适用于所有命令的格式如下所示: 

[? |!] [命令] [参数] [值]

其中,?- 读取命令的符号; !- 写入操作的符号。

下表列出了相关命令:

     
 help  读  显示语法参考和命令列表
 info  读  显示帐户摘要数据
 symb  读  指定货币对的市场价
 ords  读/写  管理未平仓委托
 param  读/写  管理 EA 交易程序的参数
 close  记录  中止 EA 交易程序的工作并关闭客户端
 shdwn  记录  关闭 PC


实施此组命令的处理的 EA 交易程序位于文件 icq_power.mq5 中。

图 2 清晰地说明了 EA 交易程序的工作。通过已安装的 ICQ 客户端从 CCP 接收命令(图 2a),以及通过实施 ICQ 工作的 WAP 服务器 http://wap.ebuddy.com 接收命令(图 2b)。对于不希望在他们的手机上搜索、安装和配置 ICQ 软件的人而言,第二个选项是首选项。

         

图 2. 通过 Pocket PC 版的 ICQ 使用交易程序(图 2a),以及通过 wap.ebuddy.com WAP 网站使用交易程序(图 2b)。

可视化 ICQ 组件

本节将简单地说明一个 icq_visual.mq5 脚本例子,该例子实施一个组件,组件的外观显示在图 3 中。

例如 3. 可视化 ICQ 组件

例如 3. 可视化 ICQ 组件

组件的窗体类似于一个 Windows 窗口,并且由按钮、文本框和文本标签等一组控件构成。

为方便起见,在窗体中实施了一个用于存储帐户和联系人列表的集成控件。通过使用相应的导航按钮从列表选择值。

为了创建 ICQ 6.5 风格的窗口,我们可以用图像标记代替按钮。图 4 显示了在 icq_visual_skin.mq5 脚本中实施的组件的外观。对于那些希望创建自己的组件设计的人而言,开发并替换 skin.bmp 文件就已足够,该文件负责窗口的外观。

图 4. 可视化 ICQ 组件的颜色设计

图 4. 可视化 ICQ 组件的颜色设计

总结

本文说明了通过使用嵌入式编程语言,针对 Metatrader 5 实施一个 ICQ 客户端的最简单的方式之一。

全部回复

0/140

量化课程

    移动端课程