English 中文 Español Deutsch 日本語 Português
Пишем Twitter-клиент для MetaTrader: Часть 2

Пишем Twitter-клиент для MetaTrader: Часть 2

MetaTrader 5Примеры | 16 сентября 2020, 08:29
2 562 0
Soewono Effendi
Soewono Effendi

Введение

Как я и обещал в первой статье "Пишем Twitter-клиент для MetaTrader 4 и MetaTrader 5 без использования DLL", во второй части мы попытаемся изучить возможности Twitter API для отправки твитов с картинками. Чтобы не загружать статью лишними деталями, сосредоточимся только на публикации изображений. К концу этой статьи у нас должен получиться работающий Твиттер-клиент без использования какой-либо внешней библиотеки DLL, который позволит публиковать твиты, содержащие до четырех картинок. Четыре изображения — это максимально разрешенное количество в Twitter API, согласно параметру media_ids.


Загрузка изображений

В API добавили новый метод chunked upload для загрузки мультимедиа, который позволяет более эффективно заливать большие файлы, например видео или анимированные GIF-файлы. Для наших же целей подойдет простой метод, поскольку мы будем загружать только изображения.

Перед началом работы обязательно ознакомьтесь с требованиями и ограничениями по типам и размерам медиафайлов в Twitter.

По факту загрузка фото в Твиттер это простой POST-запрос multipart/form-data с OAuth-авторизацией. Поговорим об этом в следующем параграфе. Для каждого загруженного изображения возвращается идентификатор media_id, который действителен только в течение определенного периода времени — его то и нужно включать в публикуемый твит.

При публикации четырех изображений вы просто прописываете все возвращенные идентификаторы media_id через запятую.

Для публикации сообщения с изображениями нужно выполнить следующие действия:

  1. Загрузите изображение и заберите возвращенный идентификатор media_id
  2. Повторите загрузку изображений - до 4 картинок. Всегда забирайте возвращенный media_id
  3. Подготовьте сообщение
  4. При отправке сообщения вставки изображений укажите список их идентификаторов media_id через запятую
Примечание: чтобы не усложнять код, я опустил здесь обработку ошибок.


HTTP multipart/form-data

При публикации твита изображения можно загружать как необработанные бинарные данные или строку в кодировке Base64. Все же рекомендуется использовать формат необработанных бинарных данных, поскольку Base64-строка будет примерно в три раза больше по размеру.

Метод HTTP multipart/form-data определен в RFC-2388, но может быть проще понять этот метод из отличного материала по curl. Согласно этим материалам, это "HTTP POST-запрос, отправляемый вместе с телом запроса в виде отформатированного набора частей с MIME boundaries".

POST /submit.cgi HTTP/1.1
Host: example.com
User-Agent: curl/7.46.0
Accept: */*
Content-Length: 313
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------d74496d66958873e

--------------------------d74496d66958873e
Content-Disposition: form-data; name="person"

anonymous
--------------------------d74496d66958873e
Content-Disposition: form-data; name="secret"; filename="file.txt"
Content-Type: text/plain

contents of the file
--------------------------d74496d66958873e--


Реализация в классе Twitter:

   void              appendPhoto(string filename, string hash, uchar &data[],
                                 bool common_flag=false)
     {
      int flags=FILE_READ|FILE_BIN|FILE_SHARE_WRITE|FILE_SHARE_READ;
      if(common_flag)
         flags|=FILE_COMMON;
      //---
      int handle=FileOpen(filename,flags);
      if(handle==INVALID_HANDLE)
         return;
      //---
      int size=(int)FileSize(handle);
      uchar img[];
      ArrayResize(img,size);
      FileReadArray(handle,img,0,size);
      FileClose(handle);
      int pos = ArraySize(data);
      int offset = pos + size;
      int hlen = StringLen(hash)+6;
      int newlen = offset + hlen;
      ArrayResize(data, newlen);
      ArrayCopy(data, img, pos);
      StringToCharArray("\r\n--"+hash+"\r\n", data, offset, hlen);
     }

В этом коде сырой бинарный файл изображения добавляется в "части" HTTP-запроса POST multipart/form-data. Далее в коде показан конверт POST-запроса с указанием параметра Twitter Upload-API media.

   string              uploadPhoto(string filename)
     {
      // POST multipart/form-data
      string url = "https://upload.twitter.com/1.1/media/upload.json";
      //string url = "https://httpbin.org/anything";
      string params[][2];
      string query = oauthRequest(params, url, "POST");
      string o = getOauth(params);
      string custom_headers = "Content-Type: multipart/form-data;"
                              " boundary=";
      string boundary = getNonce();
      StringAdd(custom_headers, boundary); // use nonce as boundary string
      StringAdd(custom_headers, "\r\n");
      string headers = getHeaders(o, custom_headers, "upload.twitter.com");

      //string query = getQuery(params, url);
      //Print(query);
      uchar data[];
      string part = "\r\n--";
      StringAdd(part, boundary);
      StringAdd(part, "\r\nContent-Disposition: form-data;"
                " name=\"media\"\r\n\r\n");
      StringToCharArray(part, data, 0, StringLen(part));
      appendPhoto(filename, boundary, data);
      string resp = SendRequest("POST", url, data, headers);;
      if(m_verbose)
        {
         SaveToFile(filename + "_post.txt", data);
         Print(resp);
        }
      return (getTokenValue(resp, "media_id"));
     }

Чтобы проверить работу multipart/form-data HTTP, сохраним HTTP-запрос в файл в папке данных терминала MetaTrader.


Твит с картинками

Здесь я использую простейшую функцию getTokenValue() для получения media_id, возвращенного интерфейсом Twitter Upload-API. Вы можете воспользоваться отличной MQL5-библиотекой для работы с JSON-протоколом

Далее показан простой пример использования класса Twitter. Функция Screenshots() делает скриншоты текущих открытых графиков и составляет простой твит. Выбрать можно до четырех графиков. Каждый скриншот сохраняется в файл, а название файла возвращается в строковом массиве fnames.

Скриншоты загружаются по-одному, возвращенные идентификаторы media_id собираются вместе в виде списка, разделенного запятыми. Благодаря указанию идентификаторов media_id в таком списке мы публикуем сообщение в твиттере с нашими скриншотами.

Все просто.

   CTwitter tw(consumer_key, consumer_secret,
               access_token, access_secret, verbose);

   // Gather information
   string fnames[4];
   string msg;
   Screenshots(fnames, msg);

   // Upload screenshots
   int n = ArraySize(fnames);
   int i = n - 1;
   // create comma separated media_ids
   string medias = tw.uploadPhoto(fnames[i]);
   for(i= n - 2; i>=0; i--)
   {
      StringAdd(medias, ",");
      StringAdd(medias, tw.uploadPhoto(fnames[i]));
   }
   
   // Send Tweet with photos' ids
   string resp = tw.tweet(msg, medias);
   Print(resp);


Класс Twitter

Класс Twitter в Twitter.mqh — это самостоятельный файл, не зависимый от других include-файлов. То есть для публикации графиков в твиттере вам нужен только один файл.

Сначала нужно инстанциировать объект Twitter, указав токен клиента и доступа, также можно указать флаг "verbose", который поможет провести отладку.

   CTwitter tw(consumer_key, consumer_secret,
               access_token, access_secret, verbose);

Затем можете попробовать вызвать доступные public-функции:

  • verifyCredentials() 
    Возвращает Twitter ID для вашего токена доступа.
  • uploadPhoto()
    Загружает картинку и возвращает ее идентификатор media_id.
  • tweet()
    Отправляет твит с идентификаторами media_id.

Есть несколько вспомогательных функций:

  • getTokenValue()
    Возвращает значение токена/параметра из строки json.
    Примечание: это очень простой пример, не стоит ожидать полной совместимости с json.
  • unquote()
    Удаляет кавычки из строки.


Публикация графиков в Твиттере

К статье прикреплен рабочий MT5-скрипт, который делает до четырех скриншотов графиков и составляет простое сообщение с названием символа и значением OHLCV.

На основе этого простого примера вы можете начать разрабатывать свои собственные скрипты и эксперты.

Примечание: в своем коде указывайте свои токены и секретные ключи.

Далее показаны примеры твитов, опубликованных скриптом.

Твит с картинками, отправленный из МТ5

Рис 1. Твит с картинками, отправленный из МТ5


Твит с графиком из MetaTrader 5 в полном размере

Рис. 2. Твит с графиком из MetaTrader 5 в полном размере 


Ну и конечно, можно публиковать любые картинки.



Твит с кошками Далай-Ламы

Рис. 3. Твит с кошками Далай-Ламы


Заключение

Итак, мы создали простой класс Twitter в виде отдельного подключаемого файла. Он позволяет публиковать твиты с графиками и сигналами. Надеюсь, представленные технические детали будет несложно понять.

Это далеко не полный класс, можно еще много чего добавить из других интерфейсов Twitter API. Делитесь своими идеями в комментариях.

Надеюсь, вам понравилось читать эту статью так же, как мне понравилось ее писать. Пусть твиты приносят удовольствие и прибыль.

Приятного использования!


Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/8318

Прикрепленные файлы |
Twitter.mqh (19.77 KB)
TwitterDemo.mq5 (4.87 KB)
Сетка и мартингейл: что это такое и как их использовать? Сетка и мартингейл: что это такое и как их использовать?
В данной статье я постараюсь подробно объяснить, что такое сетка и мартингейл, а также что в них общего. Ну и попытаться проанализировать, насколько эти стратегии жизнеспособны в реальности. Будет математическая часть и практическая.
Работа с таймсериями в библиотеке DoEasy (Часть 52): Кроссплатформенность мультипериодных мультисимвольных однобуферных стандартных индикаторов Работа с таймсериями в библиотеке DoEasy (Часть 52): Кроссплатформенность мультипериодных мультисимвольных однобуферных стандартных индикаторов
В статье рассмотрим создание мультисимвольного мультипериодного стандартного индикатора Accumulation/Distribution. Чтобы программы, написанные под устаревшую платформу MetaTrader 4, основанные на данной библиотеке, могли нормально работать при переходе на MetaTrader 5, мы немного доработаем классы библиотеки касаемо индикаторов.
Нейросети — это просто (Часть 5): Многопоточные вычисления в OpenCL Нейросети — это просто (Часть 5): Многопоточные вычисления в OpenCL
Мы уже познакомились с некоторыми типами реализации нейронных сетей. Легко заметить, что для каждого нейрона сети повторяются те же самые операции. И тут возникает желание воспользоваться возможностями многопоточных вычислений современной техники для ускорения процесса обучения нейронной сети. Об одном из вариантов такой реализации пойдет речь в данной статье.
Брутфорс-подход к поиску закономерностей Брутфорс-подход к поиску закономерностей
В данной статье мы будем искать закономерности на рынке, создавать советников на их основе и проверять, как долго эти закономерности сохраняют работоспособность и вообще, сохраняют ли они ее.