Cliente Nativo de Twitter: Parte 2

14 septiembre 2020, 15:55
Soewono Effendi
0
464

Introducción

Como ya prometimos en el primer artículo Cómo escribir un cliente nativo de Twitter para MetaTrader 4 y MetaTrader 5 sin usar DLL, el artículo siguiente trataría de explorar la API de Twitter para enviar tweets con fotos. Para que el presente artículo siga siendo fácil y sencillo de entender, nos centraremos solo en subir imágenes. Al final del artículo, deberíamos obtener un cliente de Twitter listo para usar, sin utilizar ningún archivo DLL externo, que le permitirá twittear mensajes con hasta cuatro fotos. El límite de 4 fotos es establecido por Twitter API, como se explica en el parámetro media_ids.


Subiendo las fotos

Existe un método nuevo, llamado carga fragmentada, que se usa para subir recursos utilizando los mejores métodos de carga de archivos de grandes dimensiones, por ejemplo, vídeos o GIF animados. Para nuestros cometidos, nos centraremos en el método simple, que se limita a cargar solo imágenes.

Por favor, asegúrese de estar familiarizado con las restricciones sobre el tamaño y los tipos de medios de Twitter.

Cargar una foto en Twitter consiste básicamente en realizar una solicitud HTTP multipart/form-data POST simple con autorización OAuth, que explicaremos en el siguiente párrafo. Cada foto cargada retornará un media_id válido solo dentro de un cierto periodo de tiempo, que permitirá que se incluya en un tweet para su publicación.

Para publicar hasta cuatro fotos, todos los media_ids retornados se unen de forma sencilla como una lista separada por comas.

Los pasos para tuitear un mensaje con fotos son los siguientes:

  1. Cargue la foto y recopile su media_id retornado
  2. Repita la carga de las demás fotos, hasta un máximo de 4. Recopile siempre su media_id retornado.
  3. Prepare su mensaje de tweet
  4. Indique los media_ids al enviar su tweet mediante una lista separada por comas con todos los media_ids a incluir.
NOTA:
Para que el código siga siendo simple y fácil de seguir, se omitirá la gestión de errores.


HTTP multipart/form-data

Para cargar fotos en Twitter, estas se pueden cargar como datos binarios sin procesar, o bien como cadena codificada en Base64. Le recomendamos cargar las fotos como datos binarios sin procesar, ya que la cadena codificada en Base64 tendrá un tamaño aproximadamente tres veces mayor.

El método HTTP multipart/form-data está muy bien definido en RFC-2388, pero le resultará más comprensible cuando lea este magnífico turorial de curl. Básicamente, citando el artículo mencionado: "es una solicitud HTTP POST enviada con el cuerpo de la solicitud formateado especialmente como una serie de "partes", separadas por límites MIME".

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--


La implementación en la clase de Twitter se da de la forma que sigue:

   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);
     }

El código anterior añade los datos binarios sin procesar de un archivo de imagen a las "partes" de la publicación HTTP multipart/form-data. El "envoltorio" del POST se implementa en el siguiente código, con el parámetro Twitter Upload-API "media" especificado.

   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"));
     }

Para estudiar y verificar la compilación de HTTP multipart/form-data, la solicitud HTTP se puede guardar como archivo en la carpeta de datos del terminal MT para realizar un análisis más detallado.


Tweet con fotos

Para simplificar la tarea, utilizamos la función simple getTokenValue() para recuperar el media_id retornado por Twitter Upload-API. Quizá el lector quiera considerar el uso de la excelente biblioteca JSON disponible en MQL5.com

El código siguiente muestra una forma muy sencilla de usar la clase de Twitter. La función Screenshots() simplemente hace capturas de pantalla de los gráficos abiertos actualmente y crea un mensaje de tweet sencillo. Se seleccionan hasta cuatro gráficos.
Cada captura de pantalla se guarda como un archivo cuyo nombre es retornado en la matriz de cadenas fnames.

Las capturas de pantalla se cargan una a una, con su media_id retornado, recopilado y reunido como una lista separada por comas.
Especificando el parámetro media_ids con esta lista separada por comas, publicamos el mensaje del tweet con las capturas de pantalla adjuntas al tweet.

Así de simple.

   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);


La clase de Twitter

La clase de Twitter que puede encontrar en Twitter.mqh se ha desarrollado para que sea autónoma e independiente de otros archivos de inclusión. Para enviar un tweet con fotos, todo lo que necesitaremos es ese único archivo.

En primer lugar, deberemos instanciar un objeto de Twitter, indicando su consumidor y token de acceso, con una marca -opcionalmente- detallada que ayude a realizar la depuración durante el desarrollo.

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

Después, podemos tratar de llamar las funciones publc disponibles:

  • verifyCredentials() 
    retorna el Twitter ID de su token de acceso
  • uploadPhoto()
    carga una foto y retorna su media_id
  • tweet()
    enviar un tweet con un media_ids opcional

También tenemos algunas funciones auxiliares:

  • getTokenValue()
    retornar el valor de un token/parámetro de una cadena json.
    NOTA: Este es un análisis de cadenas muy sencillo, no espere una compatibilidad completa json.
  • unquote()
    eliminar comillas de una cadena.


Twitee sus gráficos

Adjuntamos un script MT5 listo para usar que hace capturas de pantalla de hasta cuatro gráficos y crea un mensaje de tweet simple con el símbolo del gráfico y el valor OHLCV.
Se trata de un ejemplo simple para comenzar a desarrollar nuestros propios expertos y/o scripts.
NOTA:

Deberá indicar su propio consumidor, tokens de acceso y secretos.

A continuación, mostraremos varios ejemplos de tweets enviados por el script.

Tweet con fotos enviadas desde MT5

Figura 1. Tweet con fotos enviadas desde MT5


Gráfico MT5 de tamaño completo en Twitter

Figura 2. Gráfico MT5 de tamaño completo en Twitter 


Y, por supuesto, también podrá adjuntar cualquier foto. ;)

Tweet con gatos de la suerte

Figura 3. Tweet con gatos de la suerte


Conclusión

En el presente artículo, le ofrecemos una clase de Twitter simple y fácil de usar en forme de archivo de inclusión autónomo, para que pueda publicar sus gráficos y señales fácilmente. Hemos mostrado los detalles técnicos relevantes con la esperanza de que se puedan entender fácilmente.

Esta clase de Twitter aún no está completa ni mucho menos: hay muchas otras API de Twitter que se le pueden añadir. No dude en publicar sus mejoras en los comentarios en beneficio de la comunidad MQL5.

Espero que disfrute leyendo este artículo tanto como el autor ha disfrutado escribiéndolo.
Esperamos que pueda usar nuestro código para divertirse, y también para obtener ganancias.

Que lo disfrute.


Traducción del inglés realizada por MetaQuotes Software Corp.
Artículo original: https://www.mql5.com/en/articles/8318

Archivos adjuntos |
Twitter.mqh (19.77 KB)
TwitterDemo.mq5 (4.87 KB)
Cómo escribir un cliente nativo de Twitter para MetaTrader 4 y MetaTrader 5 sin usar DLL Cómo escribir un cliente nativo de Twitter para MetaTrader 4 y MetaTrader 5 sin usar DLL

¿Quiere usted recibir tweets o publicar sus señales comerciales en Twitter? Ya no tendrá que buscar soluciones para ello: en esta serie de artículos, analizaremos cómo trabajar con Twitter sin usar DLL. Juntos, implementaremos una Tweeter API con ayuda de MQL. En el primer artículo, hablaremos de las posibilidades de autenticación y autorización a través de Twitter API.

Trabajando con las series temporales en la biblioteca DoEasy (Parte 43): Las clases de los objetos de búferes de indicador Trabajando con las series temporales en la biblioteca DoEasy (Parte 43): Las clases de los objetos de búferes de indicador

En el artículo, analizaremos la creación de las clases de los objetos de búfer de indicador como herederas del objeto de búfer abstracto, simplificando la declaración y el trabajo con los búferes de indicador al crear programas-indicadores propios basados en la biblioteca DoEasy.

Discretización de series temporales con generación aleatoria de "ruidos" Discretización de series temporales con generación aleatoria de "ruidos"

Nos hemos acostumbrado a analizar el mercado con la ayuda de barras o velas que "hacen cortes" en la serie temporal a intervalos regulares de tiempo. Pero, ¿cuánto deforma realmente este método de discretización la estructura real de los movimientos de mercado? Discretizar una señal sonora a intervalos temporales iguales resulta una solución aceptable, porque una función sonora supone una función que cambia con el tiempo. En sí misma, una señal es una amplitud que depende del tiempo, y esta propiedad en ella es fundamental.

Aplicación práctica de las redes neuronales en el trading Aplicación práctica de las redes neuronales en el trading

En el presente artículo, analizaremos los momentos esenciales de la implementación de las redes neuronales y el terminal comercial para crear un robot comercial plenamente funcinal.