Sở hữu ngay máy chủ VPS Robot Forex khi giao dịch tại HotForex

Mục lục:

  1. Giới thiệu
  2. Telegram BOT là gì
  3. Cách thức hoạt động BOT Telegram
  4. BOT Telegram hoạt động với MQL4, MQL5 như thế nào
  5. Một vài ví dụ
  6. Kết luận
  7. Tải về source code

1. Giới thiệu

Trong hội nghị F8 được tổ chức tại San Francisco vào ngày 12 tháng 4 năm 2016, Facebook đã công bố việc tích hợp API cho bot vào Messenger. Cùng ngày, một bản cập nhật lớn cho Nền tảng Bot Telegram đã được phát hành. Phiên bản 2.0 đã gây ngạc nhiên với chức năng của nó. Có vẻ như các bot đã từng rất phổ biến trong kỷ nguyên ICQ hiện đang có sự trở lại. Ở giai đoạn mới của các bot phát triển đã được cung cấp một chức năng chu đáo, giao diện mở để lập trình và hỗ trợ đa phương tiện. Về cơ bản, họ có tất cả các điều kiện để trở nên không thể thay thế khi bạn muốn tìm, xem hoặc mua một cái gì đó.

Bài viết này sẽ hướng dẫn từng bước để tạo bot cho Telegram trong MQL5 MQL4.

Vậy ‘bot’ là gì? Bot (rút ngắn từ ‘robot’) là một tài khoản đặc biệt trong Telegram để trao đổi tin nhắn. Các bot hoạt động ở máy khách của bạn và tương tác với máy chủ Telegram bằng cách sử dụng một bộ lệnh đặc biệt là một phần của Bot API. Trước khi chúng ta tiến hành tạo bot, vui lòng tải xuống Telegram và đăng nhập vào nó. Việc đăng ký được liên kết với số điện thoại, nhưng bạn cũng có thể tìm kiếm theo @username. Bây giờ là lúc để làm quen với một thư mục của tất cả các bot.

2. Đăng ký BOT với Telegram

Một bot đặc biệt @BotFather chịu trách nhiệm đăng ký và thiết lập các chức năng của bot. Chúng ta sẽ tìm thấy nó thông qua các công cụ tìm kiếm. Sau khi thêm nó vào danh sách các liên hệ, chúng ta sẽ bắt đầu liên lạc với nó bằng lệnh /start. Như một phản hồi, nó sẽ gửi cho bạn một danh sách tất cả các lệnh có sẵn, như trong Hình 1.

Với lệnh /newbot, chúng ta bắt đầu đăng ký bot mới. BotFather sẽ hỏi bạn tên và tên người dùng, sau đó tạo mã thông báo ủy quyền cho bot mới của bạn. Tên bot của bạn được hiển thị trong chi tiết liên lạc và các nơi khác. Tên người dùng là một tên ngắn, được sử dụng trong đề cập và liên kết t.me. Tên người dùng dài 5-32 ký tự và không phân biệt chữ hoa chữ thường, nhưng chỉ có thể bao gồm các ký tự Latinh, số và dấu gạch dưới. Tên người dùng bot của bạn phải kết thúc bằng ‘bot, ví dụ: Tetris_bot, hoặc ‘TetrisBot.

Token là một chuỗi dọc theo dòng 110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw được yêu cầu để ủy quyền cho bot và gửi yêu cầu tới API Bot. Giữ token của bạn an toàn và lưu trữ an toàn, bất kỳ ai cũng có thể sử dụng nó để kiểm soát bot của bạn.

Kết quả là chúng ta có được mã thông báo token – khóa truy cập để hoạt động với bot thông qua API. Ví dụ về đăng ký được hiển thị trong Hình 2.

Nếu bạn muốn, một vài thông số có thể được sửa đổi. Khuyến nghị các tuỳ chọn mặc định được giữ nguyên.

  • /setcommands – thiết lập danh sách các lệnh được hỗ trợ. Danh sách này sẽ xuất hiện cho người dùng dưới dạng một chú giải công cụ khi nhập ký hiệu ‘/’ trong cửa sổ trò chuyện.
  • /setuserpic – thiết lập hình ảnh hồ sơ..
  • /setdescription – văn bản được hiển thị dưới dạng lời chào khi bot được thêm vào Messenger. Thông thường, có vài câu để mô tả mục đích của bot.

Như vậy việc tạo 1 bot diễn ra dễ dàng phải không nào. Lưu ý quan trọng hãy lưu token khi BotFather trả về nhé.

An toàn & bảo mật vốn đầu tư tại HotForex

Tạo mã Token ủy quyền:

Nếu mã token hiện tại của bạn bị xâm phạm hoặc vì lý do nào đó, bạn đã sử dụng lệnh /token để tạo mã token mới.

3. Các chế đô hoạt động của BOT Telegram

Telegram có ba sơ đồ tương tác giữa bot và người dùng. Đầu tiên – trò chuyện riêng tư. Mọi người dùng giao tiếp với một bot độc lập với nhau, như thể hiện trong Hình 3, bằng cách đưa ra yêu cầu và nhận phản hồi.

Người dùng gửi tin nhắn đến bot. Chúng được lưu trữ trên máy chủ không quá 24 giờ và được gỡ bỏ sau đó. Một bot có thời gian để yêu cầu những tin nhắn này và trả lời chúng. Đây là chế độ chính mà các bot của chúng ta sẽ hoạt động.

Chế độ thứ hai, liên quan đến các cuộc trò chuyện nhóm. Trong trường hợp này, toàn bộ nhóm gửi tin nhắn đều có thể được gửi bởi bất kỳ thành viên nào trong nhóm (Hình 4).

Ngoài ra, bạn có thể cho phép chúng tham gia các nhóm bằng cách sử dụng lệnh /setjoingroups. Nếu một bot được thêm vào một nhóm, thì bằng cách sử dụng lệnh /setprivacy, bạn có thể đặt tùy chọn để nhận tất cả các tin nhắn, hoặc chỉ những tin nhắn bắt đầu bằng một dấu hiệu của nhóm.

Chế độ thứ ba tập trung vào hoạt động trên một kênh. Các kênh Telegram là tài khoản để truyền tin nhắn cho nhiều đối tượng hỗ trợ số lượng người đăng ký không giới hạn, hay còn gọi chức năng này như là quảng bá tín hiệu. Tính năng quan trọng của các kênh là người dùng không thể để lại nhận xét và lượt thích trên nguồn cấp tin tức (kết nối một chiều). Chỉ quản trị viên kênh mới có thể tạo tin nhắn ở đó (Hình 5).

Các bot cũng có thể được thêm vào danh sách quản trị viên. Điều này làm cho một kênh trở thành một công cụ lý tưởng để cung cấp tín hiệu giao dịch. Một lát sau chúng ta sẽ viết một bot đơn giản xuất bản các tín hiệu từ chỉ báo MACD. Một kênh public mới có thể được tạo thông qua trình đơn tạo Kênh mới của Messenger. Đừng quên thêm bot của bạn vào danh sách quản trị viên của kênh. Bot toàn quyền thì mới gửi tin được nhé 😀

4. Xử lý dữ liệu luồng tin nhắn

Bài viết này chúng ta nhắm tới mục tiêu là tạo ra một lớp sẽ xử lý các thông điệp và cho phép tập trung vào logic của bot. Để làm được việc này, ban đầu chúng ta đã tạo nên 1 thư viện mới với lớp CCustomBot thực hiện chức năng liên quan đến API Telegram.

Để giao tiếp với máy chủ Telegram chúng ta cần thông qua các yêu cầu POST bằng chức năng WebRequest . Mỗi lệnh có URL riêng dạng:

https://api.telegram.org/bot<TOKEN>/METHOD_NAME

trong đó TOKEN là mã của bot đã đăng ký; METHOD_NAME – danh sách các phương thức được hỗ trợ.

Phản hồi từ máy chủ đến định dạng JSON, do đó cần có trình phân tích cú pháp JSON tốt. Chúng ta hãy áp dụng một trình phân tích cú pháp và tuần tự hóa JSON được sưu tầm trên diễn đàn mql5 nhé. Ngoài ra, ứng dụng bảng điều khiển để hiển thị một số thông số cũng được áp dụng. Lớp CComment lấy từ Codebase mql5 phù hợp cho nhiệm vụ này.

Các phương thức METHOD_NAME mà chúng ta dùng để quản lý, thực hiện trong lớp được liệt kê dưới đây:

  • GetMe
  • GetUpdates
  • GendMessage
  • SendPhoto
  • SendChatAction

Để hiểu cách sử dụng các chức năng này, chúng ta sẽ đi sâu hơn vào lập trình.

GetMe

Chức năng GetMe để kiểm tra độ tin cậy của bot trước khi xử lý tiếp. Vì vậy chúng ta nên thực hiện kiểm tra này khi bắt đầu EA và thông báo cho người dùng trong trường hợp thất bại.

int GetMe()
//Returned value   error code

Nếu thành công, GetMe trả về 0 và bạn có thể tìm ra tên người dùng bot thông qua phương thức Name(). Tên này không được sử dụng trong quá trình giao dịch hay thông báo. Tuy nhiên, nó sẽ được hiển thị trên bảng điều khiển cho mục đích thông tin. Địa chỉ như telegram.me/botname cho phép sử dụng phiên bản Web của Messenger và sẽ đóng vai trò là liên kết để quảng cáo bot của bạn. EA kiểm tra mã thông báo trong OnInit sẽ như sau:

//+------------------------------------------------------------------+
//|                                               Telegram_GetMe.mq5 |
//|                                   Copyright 2019, Forex365 Corp. |
//|                                              https://forex365.vn |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Forex365 Corp."
#property link      "https://forex365.vn"
#property version   "1.00"
#property strict

#include <Telegram.mqh>

input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token

CCustomBot bot;
int getme_result;
//+------------------------------------------------------------------+
//|   OnInit                                                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set token
   bot.Token(InpToken);
//--- check token
   getme_result=bot.GetMe();
//--- run timer
   EventSetTimer(3);
   OnTimer();
//--- done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|   OnDeinit                                                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|   OnTimer                                                        |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- show error message end exit
   if(getme_result!=0)
     {
      Comment("Error: ",GetErrorDescription(getme_result));
      return;
     }
//--- show bot name
   Comment("Bot name: ",bot.Name());

//---{ insert your code here }
  }
//+------------------------------------------------------------------+

GetUpdates

Chức năng chính GetUpdates là đọc một mảng các tin nhắn được lưu trữ trên máy chủ. Nó cần được gọi bởi bộ đếm thời gian định trước. Không nên đặt thời gian cập nhật bộ hẹn giờ dưới 1 giây để tránh quá tải máy chủ hoặc thiết bị đầu cuối MetaTrader.

int GetUpdate()
//Returned value   error code

Chúng ta hãy xem có gì bên trong chức năng này. Khi được gọi, việc đọc và phân tích tất cả các tin nhắn chưa đọc nhận được từ người dùng được thực hiện. Ví dụ về một trong những thông điệp được cung cấp dưới đây:

{ 
   "ok":true,
   "result":[ 
      { 
         "update_id":349778698,
         "message":{ 
            "message_id":2,
            "from":{ 
               "id":198289825,
               "first_name":"Andriy",
               "last_name":"Voitenko",
               "username":"avaticks"
            },
            "chat":{ 
               "id":198289825,
               "first_name":"Andriy",
               "last_name":"Voitenko",
               "username":"avaticks",
               "type":"private"
            },
            "date":1459775817,
            "text":"\/start"
         }
      }
   ]
}

Một người dùng có tên người dùng avaticks đã gửi lệnh /start đến bot. Vấn đề là chúng cần lưu các tin nhắn như vậy và trả lời chúng trong tương lai. Số trò chuyện trò chuyện [id] là một định danh duy nhất. Cùng một người dùng giao tiếp với bot thông qua các thiết bị khác nhau sẽ có các số nhận dạng cuộc trò chuyện khác nhau. Tham số này phù hợp làm khóa duy nhất để tạo danh sách trò chuyện. Trong khi vận hành, các bot sẽ tích lũy mảng trò chuyện và chỉ cập nhật tin nhắn nhận được cuối cùng mà bot nhận được. Nếu chúng ta đã trả lời thì thông báo này đã được xử lý và chúng ta hoàn toàn có thể đặt cờ cho bot hiểu. Điều này áp dụng cho các loại trò chuyện, có thể là nội dung chat riêng tư, hoặc nhóm.

Để viết bot của riêng bạn, chỉ cần thừa kế từ CCustomBot và xác định lại hàm ảo ProcessMessage trong lớp đó. Một bot đầy đủ, theo tài liệu của Telegram, cần biết cách trả lời hai lệnh: ‘/start’ và ‘/help’.

Bot đầu tiên của chúng ta sẽ như sau

//+------------------------------------------------------------------+
//|                                          Telegram_GetUpdates.mq5 |
//|                                   Copyright 2019, Forex365 Corp. |
//|                                              https://forex365.vn |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Forex365 Corp."
#property link      "https://forex365.vn"
#property version   "1.00"
#property strict

#include <Telegram.mqh>
//+------------------------------------------------------------------+
//|   CMyBot                                                         |
//+------------------------------------------------------------------+
class CMyBot: public CCustomBot
  {
public:
   void ProcessMessages(void)
     {
      for(int i=0; i<m_chats.Total(); i++)
        {
         CCustomChat *chat=m_chats.GetNodeAtIndex(i);
         //--- if the message is not processed
         if(!chat.m_new_one.done)
           {
            chat.m_new_one.done=true;
            string text=chat.m_new_one.message_text;

            //--- start
            if(text=="/start")
               SendMessage(chat.m_id,"Hello, world! I am bot. \xF680");

            //--- help
            if(text=="/help")
               SendMessage(chat.m_id,"My commands list: \n/start-start chatting with me \n/help-get help");
           }
        }
     }
  };

//---
input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token
//---
CMyBot bot;
int getme_result;
//+------------------------------------------------------------------+
//|   OnInit                                                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set token
   bot.Token(InpToken);
//--- check token
   getme_result=bot.GetMe();
//--- run timer
   EventSetTimer(3);
   OnTimer();
//--- done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|   OnDeinit                                                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|   OnTimer                                                        |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- show error message end exit
   if(getme_result!=0)
     {
      Comment("Error: ",GetErrorDescription(getme_result));
      return;
     }
//--- show bot name
   Comment("Bot name: ",bot.Name());
//--- reading messages
   bot.GetUpdates();
//--- processing messages
   bot.ProcessMessages();
  }
//+------------------------------------------------------------------+

Kết quả đạt được được thể hiện trong hình 6.

Làm việc với bàn phím

Để bot có thể giao tiếp tương tác với người dùng, các nhà phát triển đã đưa ra ý tưởng về một bàn phím Tiếng Đức (loại bàn phím cục gạch nhé). Một bộ phím được chọn trước sẽ được hiển thị và khi nhấn một phím, người dùng sẽ gửi một tin nhắn với một văn bản được chỉ định trên đó. Bằng cách này, sự tương tác giữa bot và người dùng được đơn giản hóa đáng kể.

Lớp này có ba chức năng để làm việc với bàn phím. Các chức năng đầu tiên tạo ra đối tượng của bàn phím.

string ReplyKeyboardMarkup(const string keyboard,
                           const bool resize,
                           const bool one_time)
keyboard
Chuỗi đặt vị trí của các phím
 resizeQuyền thay đổi kích thước bàn phím
 one_timeĐể hiển thị bàn phím chỉ một lần. Bàn phím biến mất
Sau khi nhấn phím.
 Returned valueChuỗi (đối tượng JSON) cần được truyền đi
Làm tham số reply_markup khi gửi tin nhắn
Với SendMessage

Chức năng ẩn bàn phím:

string ReplyKeyboardHide()
//Returned value: Chuỗi (đối tượng JSON) cần được truyền dưới dạng tham số reply_markup khi gửi tin nhắn bằng SendMessage

Chức năng thứ ba cho phép gửi một bảng điều khiển nhỏ có loại cho biết bot mong đợi câu trả lời từ bạn dưới dạng văn bản (bàn phím không được hiển thị).

string ForceReply()
//Returned value: Chuỗi (đối tượng JSON) cần được truyền dưới dạng tham số reply_markup khi gửi tin nhắn bằng SendMessage

Bây giờ chúng ta tiến hành phân tích làm thế nào các chức năng này được sử dụng.

SendMessage

Bàn phím không thể được hiển thị hoặc ẩn bởi chính nó. Bởi vậy các hành động cần được gửi bằng một tin nhắn. Chức năng SendMessage để gửi tin nhắn đến trò chuyện như sau:

int SendMessage(const long chat_id,
                const string text,
                const string reply_markup=NULL)
//chat_id: chat number
//text: message text
//reply markup: keyboard (JSON object)
//Returned value: error code

Bàn phím là tùy chọn thêm cho những coder nào muốn EA của mình chuyên nghiệp hơn. Tuy nhiên chúng ta có thể gửi tin nhắn văn bản đơn giản từ các chương trình MQL của Meta Trader. Theo mình chức năng này thú vị hơn là SendNotification thuần tuý. Đầu tiên, chúng ta có thể gửi tin nhắn thường xuyên hơn (khoảng mỗi giây). Ngoài ra, nó hỗ trợ định dạng HTML và cả Emoji nữa nhé, cái này rất xịn xò 😀 .

Тelegram hỗ trợ rất nhiều ký tự Emoji, bạn có thể được xem tại đây. Như bạn có thể thấy, đa số các mã Emoji là trong khoảng 1F300 – 1F700. Độ bit của chúng vượt xa mã chuỗi hai byte được chấp nhận trong MQL5/MQL4. Nếu bạn loại bỏ các chữ số cao hơn để chỉ còn lại một số hai chữ số, thì phạm vi thu được (F300 – F700) nằm trong khu vực (E000, F8FF) mà trong bảng Unicode dành riêng cho một mục đích sử dụng nhất định. Bằng cách này, không có gì ngăn chúng ta sử dụng 2 lần cắt để gửi Emoji. Thông điệp chuỗi với một Emoji cổ điển với một mã U+1F642 như sau:

string text="Have a nice day.\xF642";//message text with Emoji U+1F642

Giờ đây việc sử dụng Emoji kết hợp các chuỗi string khác thật dễ dàng.

Tiếp theo, hãy đi vào viết 1 ví dụ hiển thị ba phím với trình xử lý sự kiện.

//+------------------------------------------------------------------+
//|                                         Telegram_SendMessage.mq5 |
//|                                   Copyright 2019, Forex365 Corp. |
//|                                              https://forex365.vn |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Forex365 Corp."
#property link      "https://forex365.vn"
#property version   "1.00"
#property strict

#include <Telegram.mqh>
//+------------------------------------------------------------------+
//|   CMyBot                                                         |
//+------------------------------------------------------------------+
class CMyBot: public CCustomBot
  {
private:
   string            m_button[3];
public:
   //+------------------------------------------------------------------+
   void CMyBot::CMyBot(void)
     {
      m_button[0]="Button #1";
      m_button[1]="Button #2";
      m_button[2]="Button #3";
     }

   //+------------------------------------------------------------------+
   string GetKeyboard()
     {
      return("[[\""+m_button[0]+"\"],[\""+m_button[1]+"\"],[\""+m_button[2]+"\"]]");
     }

   //+------------------------------------------------------------------+
   void ProcessMessages(void)
     {
      for(int i=0;i<m_chats.Total();i++)
        {
         CCustomChat *chat=m_chats.GetNodeAtIndex(i);
         if(!chat.m_new_one.done)
           {
            chat.m_new_one.done=true;
            string text=chat.m_new_one.message_text;

            //--- start or help commands
            if(text=="/start" || text=="/help")
               bot.SendMessage(chat.m_id,"Click on the buttons",bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));

            //--- on click event
            int total=ArraySize(m_button);
            for(int k=0;k<total;k++)
              {
               if(text==m_button[k])
                  bot.SendMessage(chat.m_id,m_button[k],bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));
              }
           }
        }
     }
  };

input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token

CMyBot bot;
int getme_result;
//+------------------------------------------------------------------+
//|   OnInit                                                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set token
   bot.Token(InpToken);
//--- check token
   getme_result=bot.GetMe();
//--- run timer
   EventSetTimer(1);
   OnTimer();
//--- done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|   OnDeinit                                                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|   OnTimer                                                        |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- show error message end exit
   if(getme_result!=0)
     {
      Comment("Error: ",GetErrorDescription(getme_result));
      return;
     }
//--- show bot name
   Comment("Bot name: ",bot.Name());
//--- reading messages
   bot.GetUpdates();
//--- processing messages
   bot.ProcessMessages();
  }
//+------------------------------------------------------------------+

Kết quả là chúng ta sẽ nhận được một thông báo bằng bàn phím như được hiển thị trong Hình 7.

Ngoài Button ra, chúng ta còn có các Object khác như: RadioButton và CheckBox. Ví dụ: chúng ta phải chọn một trong ba tùy chọn và cũng có thể bật hoặc tắt một tùy chọn nhất định. Các thay đổi sẽ chỉ ảnh hưởng đến lớp, do đó mã EA còn lại từ ví dụ trước sẽ giữ nguyên.

//+------------------------------------------------------------------+
//|                                         Telegram_SendMessage.mq5 |
//|                                   Copyright 2019, Forex365 Corp. |
//|                                              https://forex365.vn |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Forex365 Corp."
#property link      "https://forex365.vn"
#property version   "1.00"
#property strict

#include <Telegram.mqh>

#define MUTE_TEXT       "Mute"
#define UNMUTE_TEXT     "Unmute"

#define LOCK_TEXT       "Lock"
#define UNLOCK_TEXT     "Unlock"

#define RADIO_SELECT    "\xF518"
#define RADIO_EMPTY     "\x26AA"

#define MUTE_CODE       "\xF515"
#define UNMUTE_CODE     "\xF514"

#define LOCK_CODE       "\xF512"
#define UNLOCK_CODE     "\xF513"
//+------------------------------------------------------------------+
//|   CMyBot                                                         |
//+------------------------------------------------------------------+
class CMyBot: public CCustomBot
  {
private:
   string            m_radio_button[3];
   int               m_radio_index;
   bool              m_lock_state;
   bool              m_mute_state;

public:
   //+------------------------------------------------------------------+
   void CMyBot::CMyBot(void)
     {
      m_radio_button[0]="Radio Button #1";
      m_radio_button[1]="Radio Button #2";
      m_radio_button[2]="Radio Button #3";
      m_radio_index=0;
      m_lock_state=false;
      m_mute_state=true;
     }

   //+------------------------------------------------------------------+
   string GetKeyboard()
     {
      //---
      string radio_code[3]={RADIO_EMPTY,RADIO_EMPTY,RADIO_EMPTY};
      if(m_radio_index>=0 && m_radio_index<=2)
         radio_code[m_radio_index]=RADIO_SELECT;
      //---
      string mute_text=UNMUTE_TEXT;
      string mute_code=UNMUTE_CODE;
      if(m_mute_state)
        {
         mute_text=MUTE_TEXT;
         mute_code=MUTE_CODE;
        }
      //---
      string lock_text=UNLOCK_TEXT;
      string lock_code=UNLOCK_CODE;
      if(m_lock_state)
        {
         lock_text=LOCK_TEXT;
         lock_code=LOCK_CODE;
        }
      //---
      //Print(m_lock.GetKey());
      return(StringFormat("[[\"%s %s\"],[\"%s %s\"],[\"%s %s\"],[\"%s %s\",\"%s %s\"]]",
             radio_code[0],m_radio_button[0],
             radio_code[1],m_radio_button[1],
             radio_code[2],m_radio_button[2],
             lock_code,lock_text,
             mute_code,mute_text));
     }

   //+------------------------------------------------------------------+
   void ProcessMessages(void)
     {
      for(int i=0;i<m_chats.Total();i++)
        {
         CCustomChat *chat=m_chats.GetNodeAtIndex(i);
         if(!chat.m_new_one.done)
           {
            chat.m_new_one.done=true;
            string text=chat.m_new_one.message_text;

            //--- start
            if(text=="/start" || text=="/help")
              {
               bot.SendMessage(chat.m_id,"Click on the buttons",bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));
              }

            //--- Click on a RadioButton
            int total=ArraySize(m_radio_button);
            for(int k=0;k<total;k++)
              {
               if(text==RADIO_EMPTY+" "+m_radio_button[k])
                 {
                  m_radio_index=k;
                  bot.SendMessage(chat.m_id,m_radio_button[k],bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));
                 }
              }

            //--- Unlock
            if(text==LOCK_CODE+" "+LOCK_TEXT)
              {
               m_lock_state=false;
               bot.SendMessage(chat.m_id,UNLOCK_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));
              }

            //--- Lock
            if(text==UNLOCK_CODE+" "+UNLOCK_TEXT)
              {
               m_lock_state=true;
               bot.SendMessage(chat.m_id,LOCK_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));
              }

            //--- Unmute
            if(text==MUTE_CODE+" "+MUTE_TEXT)
              {
               m_mute_state=false;
               bot.SendMessage(chat.m_id,UNMUTE_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));
              }

            //--- Mute
            if(text==UNMUTE_CODE+" "+UNMUTE_TEXT)
              {
               m_mute_state=true;
               bot.SendMessage(chat.m_id,MUTE_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false));
              }
           }
        }
     }
  };

Kết quả là chúng ta có được cửa sổ sau (hình 8).

Có thể thấy ở đây, Emoji được sử dụng với khả năng hiển thị bắt mắt hơn nhiều. Ngoài các nút điều khiển, chúng ta sẽ có thể dễ dàng thực hiện nhiều sub-menu trong mỗi menu chính. Mọi thứ sẽ phụ thuộc vào chức năng mà bạn sẽ đưa ra và quyết định thực hiện như thế nào.

Trong trường hợp bạn cần gửi thông điệp lên 1 kênh nhất định, có một tùy chọn thứ hai – SendMessage.

int SendMessage(const string channel_name,
                const string text)
// channel_name: channel name as @name
// text: message text. HTML tags are supported.
// Returned value: error code

Làm việc với đa phương tiện

Bots có thể trao đổi hình ảnh, tập tin âm thanh, video và tin nhắn thoại, nhãn dán và tọa độ vị trí. Tại thời điểm viết bài viết này, Bot API 2.0 với chức năng trao đổi dữ liệu liên lạc và lời mời chào đã được tung ra. Chúng ta hãy đi vào thử chức năng gửi ảnh qua API này nhé!

Bot API các version cao hơn luôn được cập nhật và có sẵn các chức năng xịn xò hơn cho dân lập trình. Cập nhật và theo dõi tại trang chủ https://core.telegram.org/bots/api

SendPhoto

Với 2 cách gửi ảnh như sau:

int SendPhoto(const long   chat_id,
              const string local_path,
              string       &photo_id,
              const string caption=NULL,
              const bool   common_flag=false,
              const int    timeout=10000)
// chat_id   chat number
// local_path  đường dẫn thư mục <data folder>\MQL5\Files
// photo_id  định danh ảnh để upload lên server
// caption   mô tả cho ảnh
// common_flag   Cờ vị trí tệp: \Terminal\Common\Files
// timeout   thời gian timeout tính bằng milisecons

Ví dụ:

CCustomBot bot;

string token = "208375865:AAFnuOjlZ3Wsdan6PAjeqqUtBybe0Di1or8";

bot.Token(token);

string photo_id;
int result=bot.SendPhoto(198289825,"EURUSD1.gif",photo_id,"screenshot");
if(result==0)
   Print("Photo ID: ",photo_id);
else
   Print("Error: ",GetErrorDescription(result));

Trường hợp bạn muốn gửi ảnh cho nhiều người dùng hoặc gửi cùng một ảnh nhiều lần thì sao? Trong trường hợp này, việc tải lên ảnh một lần sẽ hợp lý hơn và áp dụng định danh photo_id. Cách thứ 2 để gửi ảnh:

int SendPhoto(const long chat_id,
              const string photo_id,
              const string caption=NULL)

// chat_id   chat number
// photo_id  identifier of the photo uploaded to the server
// caption   signature text below photo

SendChartAction:

Hãy tưởng tượng rằng bạn xử lý phản hồi của người dùng và gần như sẵn sàng cung cấp cho anh ta kết quả. Vì có thể mất vài giây để tạo phản hồi, sẽ rất lịch sự khi thông báo cho người dùng rằng bạn đang trong quá trình xử lý. Và đây là những gì các sự kiện được sử dụng cho vấn đề này. Ví dụ: trong khi ảnh chụp màn hình biểu đồ được lưu để gửi cho người dùng, bạn có thể gửi sự kiện gửi ảnh trong thời gian này.

Thông qua SendChatAction.

int SendChatAction(const long chat_id,
                   const ENUM_CHAT_ACTION actiona)

// chat_id   chat number
// action  event identifier

Hãy đến với 3 ví dụ sau đây để hiểu hơn về bài viết này nhé:

5. Ví dụ về Telegram BOT

Bot đầu tiên, Telegram_Bot_EA cho phép lấy thông tin về số dư tài khoản, báo giá và ảnh chụp màn hình biểu đồ. Cách thức hoạt động được hiển thị trong video này.

Bot thứ hai, Telegram_Search_EA gửi kết quả tìm kiếm đến MQL5.com. Hãy xem làm thế nào nó hoạt động nhé:

Bot thứ ba, Telegram_Signal_EA xuất các tín hiệu từ chỉ báo tiêu chuẩn MACD trên kênh. Bạn có thể dễ dàng thay đổi MACD thành chỉ số yêu thích của bạn và sử dụng mã này cho mục đích của bạn.

//+------------------------------------------------------------------+
//|                                        Telegram_Signal_EA_v1.mq4 |
//|                                   Copyright 2019, Forex365 Corp. |
//|                                              https://forex365.vn |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Forex365 Corp."
#property link      "https://forex365.vn"
#property version   "1.00"

//+------------------------------------------------------------------+
//|   Includes                                                       |
//+------------------------------------------------------------------+
#include <Telegram.mqh>

//--- Input parameters
input string InpChannelName="@forexsignalchannel";//Channel Name
input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token

//--- Global variables
CCustomBot bot;
int macd_handle;
datetime time_signal=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   time_signal=0;

//--- set token
   bot.Token(InpToken);

//--- get an indicator handle
   macd_handle=iMACD(NULL,0,12,26,9,PRICE_CLOSE);
   if(macd_handle==INVALID_HANDLE)
      return(INIT_FAILED);

//--- done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get time
   datetime time[1];
   if(CopyTime(NULL,0,0,1,time)!=1)
      return;

//--- check the signal on each bar
   if(time_signal!=time[0])
     {
      //--- first calc
      if(time_signal==0)
        {
         time_signal=time[0];
         return;
        }

      double macd[2]={0.0};
      double signal[2]={0.0};

      if(CopyBuffer(macd_handle,0,0,2,macd)!=2)
         return;
      if(CopyBuffer(macd_handle,1,0,2,signal)!=2)
         return;

      time_signal=time[0];

      //--- Send signal BUY
      if(macd[1]>signal[1] && 
         macd[0]<=signal[0])
        {
         string msg=StringFormat("Name: MACD Signal\nSymbol: %s\nTimeframe: %s\nType: Buy\nPrice: %s\nTime: %s",
                                 _Symbol,
                                 StringSubstr(EnumToString(_Period),7),
                                 DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits),
                                 TimeToString(time[0]));
         int res=bot.SendMessage(InpChannelName,msg);
         if(res!=0)
            Print("Error: ",GetErrorDescription(res));
        }

      //--- Send signal SELL
      if(macd[1]<signal[1] && 
         macd[0]>=signal[0])
        {
         string msg=StringFormat("Name: MACD Signal\nSymbol: %s\nTimeframe: %s\nType: Sell\nPrice: %s\nTime: %s",
                                 _Symbol,
                                 StringSubstr(EnumToString(_Period),7),
                                 DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits),
                                 TimeToString(time[0]));
         int res=bot.SendMessage(InpChannelName,msg);
         if(res!=0)
            Print("Error: ",GetErrorDescription(res));
        }
     }
  }
//+------------------------------------------------------------------+

Kết quả sẽ nhận được các thông báo như trong Hình 9.

6. Kết luận

Nếu như bạn muốn kết nối phân tích với cơ sở Yandex.AppMetrika cho bot của họ, bạn có thể sử dụng nguồn Botan. Ý tưởng của dịch vụ là gửi cho họ tin nhắn nhận được từ người dùng và yêu cầu các chỉ số như segmentation, tracking, cohort analysis ,v.v. Không cần phải thoát Messenger, bởi vì số liệu thống kê sẽ được gửi bởi bot đặc biệt dưới dạng biểu đồ, và một báo cáo chi tiết hơn sẽ có sẵn trên trang web.

Tôi hy vọng rằng bài viết này đã truyền cảm hứng cho bạn để áp dụng Telegram trong giao dịch Forex. Mục tiêu của bài viết này không phải là bao gồm hết tất cả các chi tiết, vì chúng đã được cung cấp trong tài liệu về Bot API. Các mã được đính kèm trong bài viết này được điều chỉnh để giao dịch trên cả hai nền tảng – MetaTrader 4 và MetaTrader 5.

HotForex tặng thưởng 100% và miễn phí nạp rút tiền

13 BÌNH LUẬN

    • Hi, mình ko làm video nhé. Bạn có thể tải source code về rồi chỉnh sửa theo ý. Cơ bản mọi tính năng mình đã hướng dẫn trong bài viết này rồi. Thanks!

    • Bạn đã làm theo các bước trên chưa:
      – Tạo Bot bằng BotFather của Telegram –> có token bot API
      – Add Bot vào chanel hoặc Group
      – Điền thông tin vào EA MQL4 hoặc MQL5

  1. Hi bạn trước hết cảm ơn bạn đã chia sẽ, bài này thật sự rất dễ hiểu và clear. Cơ mà có một chỗ mình vẫn k hiểu nó là như thế nào, đó là cái cách mình deploy code như thế nào nhỉ? Làm sao để mớ code đó áp dụng cho BOT của mình trong Telegram nhỉ? Mình cảm ơn trước nha 😀

    • Hi bạn,

      Mình có code sample bạn có thể tải về xem. Tuy nhiên phần tạo bot ở Telegram là 1 phần quan trọng. Bạn cần lấy được token và chart id (thao tác với telegram) để MT4/MT5 thực thi gọi API Telegram nhé

      • Vậy là mỗi lần người dùng sử dụng 1 câu lệnh ví dụ /caulenh gì đó là câu lệnh đó sẽ request đến API của Telegram hả? Mình không hiểu phần này lắm. Ý mình là liệu có cần server để Deploy code mình code trên đó không?

  2. Thank bạn đã chia sẻ, bài viết rất hữu ích, dễ hiểu và clear. Mình có cái này muốn hỏi là không biết sau khi code xong thì làm thế nào để Deploy code mình viết để chạy con BOT trên telegram nhỉ? Có phải mình cần 1 server không? Giúp mình với. Mình cảm ơn trước nhé!

    • Bạn chỉ cần Server để chạy Robot thôi, phần còn lại gọi API đến Telegram thì đã được hỗ trợ rồi. Nếu bạn đã đang sử dụng các hệ thống server khác thì không cần bổ sung thêm gì cả nhé.

BÌNH LUẬN

Vui lòng nhập bình luận của bạn
Vui lòng nhập tên của bạn ở đây

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.