Discusión sobre el artículo "Cómo usar la API de datos JSON en sus proyectos MQL" - página 2

 
Sara Sabaghi #:

Las reclamaciones no eran a usted, por supuesto, sino a los proveedores de contenidos. Que por alguna razón no dan datos binarios, sino datos de texto ))))

No podemos cambiar este hecho, por desgracia.

 
Edgar Akhmadeev #:

Las reclamaciones no eran a usted, por supuesto, sino a los proveedores de contenidos. Que por alguna razón no dan datos binarios, sino datos de texto ))))

No podemos cambiar este hecho, por desgracia.

porque necesitan compatibilidad.

 
Sara Sabaghi #:

Este artículo trata sobre la API y cómo utilizarla. ¿Conoce una API que le proporcione datos binarios de Forex? Entonces preséntala.

Siguiente punto, criticas por qué usar un ordenador normal para jugar al FIFA2024 cuando un ordenador cuántico es más rápido. La respuesta es simple, no necesito esa potencia de procesamiento.
Así que la respuesta a este argumento es que la mayoría de los datos que se intercambian en este ámbito en la API están en el rango de unos pocos megabytes, y no hay necesidad de velocidad. Además, todos los proveedores de datos Forex utilizan estándares como XML, JSON...

No estoy en contra del uso de JSON. Yo mismo lo utilizo, pero sólo en la fase de desarrollo, ya que siempre se puede ver una respuesta bien legible en PostMan o WireShark.
Sólo señalaba que el artículo injustamente ni siquiera mencionaba el formato binario. Además, el binario JSON (JSONB), más eficaz, está ganando terreno.
Si tengo acceso a un servidor, siempre utilizo datos binarios en el intercambio entre servidor y cliente. Sólo hay una razón por la que JSON se utiliza en todas partes: legible (para el usuario, pero no para el ordenador). Para tener menos preguntas tontas de los usuarios.
Incluso en websockets, donde por regla general los datos transferidos son muy pequeños, creo que es razonable utilizar datos binarios. Al menos porque es un sistema más productivo y con menos carga en el lado del servidor y del cliente. Y si utilizas tecnologías en la nube, lo cual es razonable en las realidades altamente competitivas de hoy en día, ahorras mucho dinero en su pago. Al fin y al cabo, la serialización consume muchos recursos y ahorra mucho tráfico.
 
Nikolai Semko #:
No estoy en contra del uso de JSON. Yo mismo lo uso, pero sólo en la fase de desarrollo, ya que siempre se puede ver una respuesta bien legible en PostMan o WireShark.
Sólo señalaba que el artículo injustamente ni siquiera mencionaba el formato binario. Además, el binario JSON (JSONB), más eficaz, está ganando terreno.
Si tengo acceso a un servidor, siempre utilizo datos binarios en el intercambio entre servidor y cliente. Sólo hay una razón por la que JSON se utiliza en todas partes: legible (para el usuario, pero no para el ordenador). Para tener menos preguntas tontas de los usuarios.
Incluso en websockets, donde por regla general los datos transferidos son muy pequeños, creo que es razonable utilizar datos binarios. Al menos porque es un sistema más productivo y con menos carga en el lado del servidor y del cliente. Y si utilizas tecnologías en la nube, lo cual es razonable en las realidades altamente competitivas de hoy en día, ahorras mucho dinero en su pago. Al fin y al cabo, la serialización consume muchos recursos y ahorra mucho tráfico.

Muchas gracias por tomarse el tiempo de compartir sus pensamientos con nosotros. Entiendo perfectamente tu punto de vista, y los puntos que has planteado sobre el uso de formatos binarios y JSONB son muy válidos. Tienes razón en que JSON, en comparación con los formatos binarios, no está tan optimizado para el rendimiento del sistema, y esto es algo de lo que muchos desarrolladores son conscientes.

En el artículo que escribimos, nos centramos principalmente en JSON porque el 99% de los proveedores de datos financieros, especialmente en el ámbito Forex, utilizan este estándar para el intercambio de datos, y muchas plataformas y servicios proporcionan datos en este formato. Por esta razón, no cubrimos otros estándares.

Una vez más, gracias por compartir su perspectiva y por señalar este importante detalle.

 
Edgar Akhmadeev #:

Las reclamaciones no eran a usted, por supuesto, sino a los proveedores de contenidos. Que por alguna razón no dan datos binarios, sino datos de texto ))))

No podemos cambiar este hecho, por desgracia.

Sí, lo entiendo perfectamente. Además, estamos obligados a utilizar esta norma porque casi todos los proveedores de datos financieros utilizan este método.

 
Hola, aquí está, así que lo que pedí es que lo publique en la comunidad mql5 =
 //+------------------------------------------------------------------+
 //|ZIWOX API y Estrategia Técnica.mq5
 //|Copyright 2024, ssabbaghi |
 //| https://www.mql5.com/es/users/ssabbaghi |
 //+------------------------------------------------------------------+
 #property   copyright    "Sara Sabbaghi"
 #property   link          "https://www.mql5.com/es/users/ssabbaghi"
 #property   version      "1.0"
 #property   strict

 //---- parámetros de entrada
 input      string       APIKey         =   "xxxxaquisuakey" ;       // Su clave API única
 input      string       SymbolPrefix   =   "" ;       // Prefijo del símbolo de su cuenta
 input      string       SymbolSuffiex  =   "m" ;       // Símbolo de su cuenta de Broker Sufijo
 input      int          shortMAPeriod  =   50 ;       // Periodo MA lento
 input      int          longMAPeriod   =   200 ;     // Periodo MA rápido
 input      double       Lots           =   0.01 ;     // Volumen de pedido estático
 input      int          APICallInterval = 300 ;     // Intervalo entre llamadas a la API en segundos (5 minutos)

 // Bibliotecas CatBoost
 #include <JAson.mqh>
CJAVal JsonValue;

 string    OBJPREFIX      =   "ZXAPI" ,
         SymbolRequest  =   "" ,
         APIJSON[];
 bool      APIOK =   false ;
 datetime LastAPICallTime = 0 ; // Calcula el tiempo de la última llamada a la API

 //+------------------------------------------------------------------+
 //| función de inicialización de expertos|
 //+------------------------------------------------------------------+
 int OnInit ()
{
   EventSetTimer ( 30 );
   ArrayResize (APIJSON, 15 );
   SymbolRequest = PureSymbol( Symbol (), SymbolSuffiex, SymbolPrefix); // Preparar el nombre real del símbolo 
   Comment ( "Wait a sec, to Get API data..." );
   return ( INIT_SUCCEEDED );
}

 //+------------------------------------------------------------------+
 //| Función de desinicialización experta|
 //+------------------------------------------------------------------+
 void OnDeinit ( const int reason)
{
   Comment ( "" );
   ObjectsDeleteAll ( 0 );
}

 //+------------------------------------------------------------------+
 //| Función tick experto OnTick()|
 //+------------------------------------------------------------------+
 void OnTick ()
{
   if (!APIOK) return ;

   double shortMA, longMA;
   long ticket = - 1 ;

   if (IsNewCandle())
   {
      shortMA = iMA ( Symbol (), PERIOD_CURRENT , shortMAPeriod, 0 , MODE_SMA , PRICE_CLOSE );
      longMA = iMA ( Symbol (), PERIOD_CURRENT , longMAPeriod, 0 , MODE_SMA , PRICE_CLOSE );

       // Comprobar señales de cruce 
       if ( int (APIJSON[ 3 ]) >= 60 ) // si la previsión alcista es superior al 60% 
      {
         if (shortMA > longMA)   // COMPRAR tendencia 
         {
             if ( OrdersTotal () == 0 ) {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // Usar TRADE_ACTION_DEAL para comprar 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_BUY ; // Usar ORDER_BUY para comprar 
               request.price = SymbolInfoDouble ( Symbol (), SYMBOL_ASK );
               request.sl = 0 ;
               request.tp = 0 ;
               request.deviation = 3 ;
               request.comment = "Buy Order" ;
               if (! OrderSend (request, result)) {
                   Print ( "Error opening buy order: " , GetLastError ());
               }
            }
         }
      }
       if ( int (APIJSON[ 4 ]) >= 60 ) // si la previsión bajista es superior al 60% 
      {
         if (shortMA < longMA)   // Tendencia de venta 
         {
             if ( OrdersTotal () == 0 )
            {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // Usar TRADE_ACTION_DEAL para vender 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_SELL ; // Utilizar ORDER_SELL para vender 
               request.price = SymbolInfoDouble ( Symbol (), SYMBOL_BID );
               request.sl = 0 ;
               request.tp = 0 ;
               request.deviation = 3 ;
               request.comment = "Sell Order" ;
               if (! OrderSend (request, result)) {
                   Print ( "Error opening sell order: " , GetLastError ());
               }
            }
         }
      }
   }
}

 //+------------------------------------------------------------------+
 //| Función experta OnTimer|
 //+------------------------------------------------------------------+
 void OnTimer ()
{
   // Comprueba si el tiempo transcurrido desde la última llamada a la API es mayor que el intervalo definido 
   if ( TimeCurrent () - LastAPICallTime >= APICallInterval)
   {
       string APIfilename = SymbolRequest + "_API_Data.json" ; // Nombre del archivo de almacenamiento API 
      APIOK = GetAPI(SymbolRequest, APIKey, APIfilename);   // Obtener los datos de la API y guardarlos en APIfilename 
       if (APIOK) JsonDataParse(APIfilename, APIJSON);     // leer los datos JSON y almacenarlos en el array API_DATA 
       Comment ((APIOK ? "API OK" : "API FAILED" ),
               "\nAPI:\n" ,
               "\nBullish Forecast: " , APIJSON[ 3 ],
               "\nBearish Forecast: " , APIJSON[ 4 ],
               "\nRetail traders Long: " , APIJSON[ 5 ],
               "\nRetail traders Short: " , APIJSON[ 6 ],
               "\nMarket Sentiment: " , APIJSON[ 14 ]
              );

       // Actualiza la hora de la última llamada a la API 
      LastAPICallTime = TimeCurrent ();
   }
}

 //+------------------------------------------------------------------+
 //| Nueva función de comprobación de velas|
 //+------------------------------------------------------------------+
 datetime NewCandleTime = TimeCurrent ();
 bool IsNewCandle()
{
   if (NewCandleTime == iTime ( Symbol (), 0 , 0 ))
       return false ;
   else 
   {
      NewCandleTime = iTime ( Symbol (), 0 , 0 );
       return true ;
   }
}

 //+------------------------------------------------------------------+
 //| Función de símbolo puro|
 //+------------------------------------------------------------------+
 string PureSymbol( string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "" )
   {
       StringReplace (puresymbol, suffiex, "" );
       StringReplace (puresymbol, prefix, "" );
   }
   return puresymbol;
}

 //+------------------------------------------------------------------+
 //| Obtener datos del Fondo de ziwox|
 //+------------------------------------------------------------------+
 datetime LastWebRequest = 0 ; // usa esta var datetime para limitar peticiones fallidas API
 bool GetAPI( string symbolname, string apikey, string filename)
{
   Print ( "Get API Update" );
   bool NeedToUpdate = false ;

   // Comprobar si el archivo de datos API está disponible 
   if ( FileGetInteger (filename, FILE_EXISTS , true ) >= 0 )
   {
       // Comprueba la última hora de actualización a partir de la hora de modificación del archivo 
       if ( TimeLocal () - ( datetime ) FileGetInteger (filename, FILE_MODIFY_DATE , true ) > 900 ) // actualizar datos cada 15 min 
         NeedToUpdate = true ;
   }
   else 
      NeedToUpdate = true ;

   if (NeedToUpdate && TimeLocal () - LastWebRequest > 300 )   // reintentar petición API fallida cada 5 min 
   {
       string cookie = NULL , headers;
       char post[], result[];
       int res;
       string URL = "https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=" + apikey + "&apitype=json&pair=" + symbolname;
       ResetLastError ();
       int timeout = 5000 ;
      res = WebRequest ( "GET" , URL, cookie, NULL , timeout, post, 0 , result, headers);
       if (res == - 1 )
      {
         LastWebRequest = TimeLocal ();
         int error = GetLastError ();
         if (error == 4060 )
             Print ( "API data Webrequest Error " , error, " Check your webrequest on Metatrader Expert option." );
         else if (error == 5203 )
             Print ( "HTTP request for " + symbolname + " Data failed!" );
         else 
             Print ( "Unknown HTTP request error(" + string (error) + ")! " + symbolname + " Data" );
         return false ;
      }
       else if (res == 200 )
      {
         LastWebRequest = TimeLocal ();
         string HTTPString = CharArrayToString (result, 0 , 0 , CP_UTF8 );
         Print ( "HTTP request for " + symbolname + " Data successful!" );
         Print (HTTPString);
         if ( StringFind (HTTPString, "invalid api key" , 0 ) != - 1 ) {
             Alert ( "Invalid API key" );
             return false ;
         }
         // Almacenar los datos de la API en un archivo de carpeta común 
         int filehandle = FileOpen (filename, FILE_READ | FILE_SHARE_READ | FILE_WRITE | FILE_SHARE_WRITE | FILE_BIN | FILE_COMMON );
         if (filehandle != INVALID_HANDLE )
         {
             FileWriteArray (filehandle, result, 0 , ArraySize (result));
             FileClose (filehandle);
         }
      }
   }
   return true ;
}

 //+------------------------------------------------------------------+
 //| Función de análisis de datos JSON|
 //+------------------------------------------------------------------+
 void JsonDataParse( string filename, string &_APIJSON[])
{
   for ( int arraIn = 0 ; arraIn < ArraySize (APIJSON); arraIn++) APIJSON[arraIn] = "" ;

   if ( FileGetInteger (filename, FILE_EXISTS , true ) >= 0 )
   {
       int FileHandle = FileOpen (filename, FILE_READ | FILE_SHARE_READ | FILE_WRITE | FILE_SHARE_WRITE | FILE_BIN | FILE_COMMON );
       char jsonarray[];
       FileReadArray (FileHandle, jsonarray);
       FileClose (FileHandle);

      JsonValue.Clear();
      JsonValue.Deserialize( CharArrayToString (jsonarray, 0 , 0 , CP_UTF8 ));

      _APIJSON[ 0 ] = JsonValue[ 0 ][ "Symbol" ].ToStr();
      _APIJSON[ 1 ] = JsonValue[ 0 ][ "Fundamental Bias" ].ToStr();
      _APIJSON[ 2 ] = JsonValue[ 0 ][ "Fundamental Power" ].ToStr();
      _APIJSON[ 3 ] = JsonValue[ 0 ][ "AI Bullish Forecast" ].ToStr();
      _APIJSON[ 4 ] = JsonValue[ 0 ][ "AI Bearish Forecast" ].ToStr();
      _APIJSON[ 5 ] = JsonValue[ 0 ][ "Retail Long Ratio" ].ToStr();
      _APIJSON[ 6 ] = JsonValue[ 0 ][ "Retail Short Ratio" ].ToStr();
      _APIJSON[ 7 ] = JsonValue[ 0 ][ "Retail Short Lot" ].ToStr();
      _APIJSON[ 8 ] = JsonValue[ 0 ][ "Retail Short pos" ].ToStr();
      _APIJSON[ 9 ] = JsonValue[ 0 ][ "Base COT NET" ].ToStr();
      _APIJSON[ 10 ] = JsonValue[ 0 ][ "Base COT change" ].ToStr();
      _APIJSON[ 11 ] = JsonValue[ 0 ][ "Quote COT NET" ].ToStr();
      _APIJSON[ 12 ] = JsonValue[ 0 ][ "Quote COT change" ].ToStr();
      _APIJSON[ 13 ] = JsonValue[ 0 ][ "COT chng Ratio" ].ToStr();
      _APIJSON[ 14 ] = JsonValue[ 0 ][ "Risk Sentiment" ].ToStr();
   }
}
 //+------------------------------------------------------------------+

Versión para MQL5 METATRADER 5 He realizado cambios en el código para que funcione en Metatrader 5. Los cambios también se hicieron en cuanto a la codificación para mejores condiciones en la situación comercial actual. Todos los cambios fueron para adaptar el código a Metatrader 5. Es funcional. Sólo tiene que descargar este archivo y ejecutarlo. Si es necesario, la biblioteca JAson.mqh, que se encuentra en el código original de nuestro compañero. Mi nombre es Ney Borges. Soy de Brasil, estado de Goiás, ciudad de Caldas Novas, en medio de la selva de Brasil. Fue muy difícil aprender solo sin nadie que me ayudara, pero aquí en la comunidad aprendí mucho. Muchas gracias.

Versión para MQL5 METATRADER 5 Hice cambios en el código para que funcionara en Metatrader 5. Los cambios también se hicieron en cuanto a la codificación para mejores condiciones en la situación comercial actual. Todos los cambios fueron para adaptar el código a Metatrader 5. Es funcional. Sólo tiene que descargar este archivo y ejecutarlo. Si es necesario, la biblioteca JAson.mqh, que se encuentra en el código original de nuestro compañero. Mi nombre es Ney Borges. Soy de Brasil, estado de Goiás, ciudad de Caldas Novas, en medio de la selva de Brasil. Fue muy difícil aprender solo sin nadie que me ayudara, pero aquí en la comunidad aprendí mucho. Muchas gracias.

Brasil - Goiás - Caldas Novas - Ney Borges

Sara Sabaghi
Sara Sabaghi
  • 2025.01.13
  • www.mql5.com
Trader's profile
 
Ney Borges #:
Si es necesario, puede utilizar la biblioteca JAson.mqh, que se puede encontrar en el código original de nuestro compañero.

Que manera tan horrible de trabajar para el traductor de google.

Sin la librería JAson, por supuesto, no funcionará.

La librería no está en su código, está aquí, y el autor lo ha especificado.

JSON Serialization and Deserialization (native MQL)
JSON Serialization and Deserialization (native MQL)
  • www.mql5.com
Сериализация и десериализация JSON протокола. Портированный код со скоростной библиотеки С++.
 
Sara Sabaghi #:

Sí, lo entiendo perfectamente. Además, estamos obligados a utilizar esta norma porque casi todos los proveedores de datos financieros utilizan este método.

Ney Borges #:
Hola, aquí está, así que lo que pedí es que lo publique en la comunidad mql5 =

Versión para MQL5 METATRADER 5 Hice cambios en el código para que funcionara en Metatrader 5. Los cambios también se hicieron en cuanto a la codificación para mejores condiciones en la situación comercial actual. Todos los cambios fueron para adaptar el código a Metatrader 5. Es funcional. Sólo tiene que descargar este archivo y ejecutarlo. Si es necesario, la biblioteca JAson.mqh, que se encuentra en el código original de nuestro compañero. Mi nombre es Ney Borges. Soy de Brasil, estado de Goiás, ciudad de Caldas Novas, en medio de la selva de Brasil. Fue muy difícil aprender solo sin nadie que me ayudara, pero aquí en la comunidad aprendí mucho. Muchas gracias.

Versión para MQL5 METATRADER 5 Hice cambios en el código para que funcionara en Metatrader 5. Los cambios también se hicieron en cuanto a la codificación para mejores condiciones en la situación comercial actual. Todos los cambios fueron para adaptar el código a Metatrader 5. Es funcional. Sólo tiene que descargar este archivo y ejecutarlo. Si es necesario, la biblioteca JAson.mqh, que se encuentra en el código original de nuestro compañero. Mi nombre es Ney Borges. Soy de Brasil, estado de Goiás, ciudad de Caldas Novas, en medio de la selva de Brasil. Fue muy difícil aprender solo sin nadie que me ayudara, pero aquí en la comunidad aprendí mucho. Muchas gracias.

Brasil - Goiás - Caldas Novas - Ney Borges

Fiz algumas correçoes ao codigo para funcionar no MQL5 gostaria que por gentil verificasse e retornar, obrigado - Sara Sabaghi

//+------------------------------------------------------------------+
//| Ney Borges versão mql5 de ZIWOX API y Estrategia Técnica.mq5 |||
//|Copyright 2024, ssabbaghi |
//| https://www.mql5.com/es/users/ssabbaghi |
//+------------------------------------------------------------------+
#property   copyright   "Sara Sabbaghi"
#property   link        "https://www.mql5.com/es/users/ssabbaghi"
#property   version     "1.0"
#property   strict
#property   description "Experto en funciones de red para ZIWOX API"

// Bibliotecas
#include <JAson.mqh>
CJAVal JsonValue;

// Características de Expert para permitir funciones de red
//#property script_show_inputs
//#property script_show_confirm

//---- parámetros de entrada
input    string      APIKey         =  "sua Key aqui xxxxxxxx";      // Su clave API única
input    string      SymbolPrefix   =  "";      // Prefijo del símbolo de su cuenta
input    string      SymbolSuffiex  =  "m";      // Símbolo de su cuenta de Broker Sufijo
input    int         shortMAPeriod  =  50;      // Periodo MA lento
input    int         longMAPeriod   =  200;     // Periodo MA rápido
input    double      Lots           =  0.01;    // Volumen de pedido estático
input    double      BullishThreshold = 60.0;   // Umbral de previsión alcista
input    double      BearishThreshold = 60.0;   // Umbral de previsión bajista
input    int         APICallInterval = 300;     // Intervalo entre llamadas a la API en segundos (5 minutos)

string   OBJPREFIX      =  "ZXAPI",
         SymbolRequest  =  "",
         APIJSON[];
bool     APIOK          =  false;
datetime LastAPICallTime = 0; // Calcula el tiempo de la última llamada a la API

//+------------------------------------------------------------------+
//| Función para probar la conexión HTTP|
//+------------------------------------------------------------------+
bool TestHTTPConnection()
{
   string cookie=NULL,headers;
   char post[],result[];
   string url="https://www.ziwox.com";
   
   ResetLastError();
   int timeout=5000; 
   
   int res=WebRequest("GET",url,cookie,NULL,timeout,post,0,result,headers);
   
   if(res==-1)
   { 
      int error=GetLastError();
      string msg = "Falha ao conectar, erro "+IntegerToString(error);
      
      // En caso de error, envíe un mensaje específico.
      if(error==4014)
         msg = "Adicione "+url+" en Herramientas -> Opciones -> Asesores Expertos -> Permitir WebRequest";
         
      Print("DEBUG: ", msg);
      return(false);
   }
   
   Print("DEBUG: Conexión HTTP probada con éxito");
   return(true);
}

//+------------------------------------------------------------------+
//| función de inicialización de expertos|
//+------------------------------------------------------------------+
int OnInit()
{
   Print("=== Iniciando Expert Advisor ===");
   
   // Verificar configuraciones básicas
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("AVISO: El trading algorítmico no está permitido");
      // Continúa igual
   }
   
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
   {
      Print("AVISO: El terminal no está conectado a Internet");
      // Continúa igual
   }
   
   // Configura o EA
   EventSetTimer(30);
   ArrayResize(APIJSON, 15);
   SymbolRequest = PureSymbol(Symbol(), SymbolSuffiex, SymbolPrefix);
   
   // Prepara y muestra la URL que se utilizará
   string cleanSymbol = SymbolRequest;
   StringReplace(cleanSymbol, "m", "");
   string apiUrl = StringFormat("https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=%s&apitype=json&pair=%s", 
                              APIKey, cleanSymbol);
   
   Print("URL configurada: ", apiUrl);
   Print("IMPORTANTE: Adicione a URL https://www.ziwox.com em:");
   Print("Herramientas -> Opciones -> Asesores Expertos -> Permitir WebRequest");
   
   Comment("Iniciando EA...\n",
           "URL que será usada:\n",
           apiUrl,
           "IMPORTANTE: Configurar la URL en las opciones del Asesor Experto");
   
   // Prueba la conexión HTTP, pero no falla si hay un error
   if(!TestHTTPConnection())
   {
      Print("AVISO: Fallo en la prueba de conexión HTTP");
      Print("O EA continuará tentando conectar...");
      // Continúa igual
   }
   
   Print("=== Inicialización concluida ===");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Función de desinicialización experta|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
   ObjectsDeleteAll(0);
}

//+------------------------------------------------------------------+
//| Función tick experto OnTick()|
//+------------------------------------------------------------------+
void OnTick()
{
   if (!APIOK) return;
   
   double shortMA, longMA;
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   if (IsNewCandle())
   {
      shortMA = iMA(Symbol(),PERIOD_CURRENT, shortMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
      longMA = iMA(Symbol(),PERIOD_CURRENT, longMAPeriod, 0, MODE_SMA, PRICE_CLOSE);

      // Análisis de datos JSON para la toma de decisiones comerciales
      double aiBullishForecast = StringToDouble(APIJSON[3]); // Previsão de alta
      double aiBearishForecast = StringToDouble(APIJSON[4]); // Previsión de baja

      // Comprobar señales de cruce
      if (aiBullishForecast >= BullishThreshold && shortMA > longMA) // Si la previsión de alta para mayor que el límite
      {
         if (OrdersTotal() == 0) {
            request.action = TRADE_ACTION_DEAL;
            request.symbol = _Symbol;
            request.volume = Lots;
            request.type = ORDER_TYPE_BUY;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            request.deviation = 3;
            request.magic = 123456;
            request.comment = "Buy Order";
            request.type_filling = ORDER_FILLING_FOK;
            
            if(!OrderSend(request, result))
               Print("Error opening buy order: ", GetLastError());
         }
      }
      if (aiBearishForecast >= BearishThreshold && shortMA < longMA) // Si la previsión de baja para mayor que el límite
      {
         if (OrdersTotal() == 0) {
            request.action = TRADE_ACTION_DEAL;
            request.symbol = _Symbol;
            request.volume = Lots;
            request.type = ORDER_TYPE_SELL;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            request.deviation = 3;
            request.magic = 123456;
            request.comment = "Sell Order";
            request.type_filling = ORDER_FILLING_FOK;
            
            if(!OrderSend(request, result))
               Print("Error opening sell order: ", GetLastError());
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Función para comprobar si la URL está permitida.
//+------------------------------------------------------------------+
bool IsURLAllowed()
{
   string url = "https://www.ziwox.com";
   string cookie=NULL, headers;
   char post[], result[];
   ResetLastError();
   
   int res = WebRequest("GET", url, cookie, NULL, 5000, post, 0, result, headers);
   
   if(res == -1)
   {
      int error = GetLastError();
      if(error == 4014)
      {
         Comment("ATENÇÃO: URL não permitida\n",
                 "1. Vá em Ferramentas -> Opções -> Expert Advisors\n",
                 "2. Marque 'Permitir WebRequest para as URLs listadas abaixo'\n",
                 "3. Adicione a URL: ", url, "\n",
                 "4. Clique em OK");
         return false;
      }
   }
   return true;
}

//+------------------------------------------------------------------+
//| Función experta OnTimer|
//+------------------------------------------------------------------+
void OnTimer()
{
   // Compruebe si la URL está permitida antes de realizar la llamada
   if(!IsURLAllowed())
   {
      Print("DEBUG: URL não está permitida. Aguardando configuración...");
      return;
   }

   if (TimeCurrent() - LastAPICallTime >= APICallInterval)
   {
      string APIfilename = SymbolRequest + "_API_Data.json";
      
      // Prepara la URL para mostrar en el comentario
      string cleanSymbol = SymbolRequest;
      StringReplace(cleanSymbol, "m", "");
      string apiUrl = StringFormat("https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=%s&apitype=json&pair=%s", 
                                 APIKey, cleanSymbol);
      
      // Mostra que está fazendo a chamada
      Comment("Fazendo chamada à API...\n",
              "URL: ", apiUrl,
              "\n\nAguarde...");
      
      APIOK = GetAPI(SymbolRequest, APIKey, APIfilename);
      
      if (APIOK) {
         JsonDataParse(APIfilename, APIJSON);
         Comment("=== API OK ===\n",
                 "URL: ", apiUrl, "\n",
                 " Última actualización: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), "\n",
                 "\nDados recebidos:",
                 "\nSymbol: ", APIJSON[0],
                 "\nÚltimo Preço: ", APIJSON[1],
                 "\nViés Fundamental: ", APIJSON[2],
                 "\nPrevisión de Alta: ", APIJSON[3], "%",
                 "\nPrevisão de Baixa: ", APIJSON[4], "%",
                 "Posiciones Compradas: ", APIJSON[5],
                 "Posiciones Vendidas: ", APIJSON[6],
                 "\nTendência D1: ", APIJSON[7],
                 "\nRSI D1: ", APIJSON[8],
                 "\nPermitido Operar: ", APIJSON[9]
                 );
      } else {
         Comment("=== FALHA NA API ===\n",
                 "URL tentada: ", apiUrl, "\n",
                 "Hora: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), "\n",
                 "\nVerifique:",
                 "\n1. Si la URL está permitida en Herramientas -> Opciones -> Asesores Expertos -> WebRequest",
                 "\n2. Su conexión a Internet está funcionando".,
                 "\n3. Se o símbolo está correto"
                 );
      }

      LastAPICallTime = TimeCurrent();
   }
}

//+------------------------------------------------------------------+
//| Função para verificar se é um novo candle ||
//+------------------------------------------------------------------+
bool IsNewCandle()
{
   static datetime lastCandleTime = 0;
   datetime currentCandleTime = iTime(Symbol(), 0, 0);
   if (currentCandleTime != lastCandleTime)
   {
      lastCandleTime = currentCandleTime;
      return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| Función de símbolo puro|
//+------------------------------------------------------------------+
string PureSymbol(string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "")
   {
      StringReplace(puresymbol, suffiex, "");
      StringReplace(puresymbol, prefix, "");
   }
   return puresymbol;
}

//+------------------------------------------------------------------+
//| Función para verificar la configuración de WebRequest.
//+------------------------------------------------------------------+
bool CheckWebRequestSettings()
{
   if(!TerminalInfoInteger(TERMINAL_DLLS_ALLOWED))
   {
      Print("ERRO: ¡Las DLL no están permitidas!");
      return false;
   }
   
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("ERRO: ¡El trading algorítmico no está permitido!");
      return false;
   }
   
   if(!MQLInfoInteger(MQL_DLLS_ALLOWED))
   {
      Print("ERRO: DLLs não estão permitidas para este Expert!");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Función para verificar la conexión con el servidor.
//+------------------------------------------------------------------+
bool CheckServerConnection()
{
   int socket = SocketCreate();
   
   if(socket != INVALID_HANDLE)
   {
      // Conéctese al servidor de ZIWOX (puerto 80 para HTTP)
      if(SocketConnect(socket, "www.ziwox.com", 80, 1000))
      {
         Print("DEBUG: Conexão com servidor testada com sucesso");
         // Verifica si está realmente conectado
         if(SocketIsConnected(socket))
         {
            SocketClose(socket);
            return true;
         }
      }
      else
      {
         Print("DEBUG: Falha ao conectar com o servidor: ", GetLastError());
      }
      SocketClose(socket);
   }
   else
   {
      Print("DEBUG: Falha ao criar socket: ", GetLastError());
   }
   return false;
}

//+------------------------------------------------------------------+
//| Función para obtener datos de la API|
//+------------------------------------------------------------------+
bool GetAPI(string symbolname, string apikey, string filename)
{
   if(!TestHTTPConnection())
   {
      Print("DEBUG: Fallo en la prueba de conexión HTTP");
      return false;
   }

   string headers = "Content-Type: application/json\r\nAccept: application/json\r\n";
   char post[], result[];
   string cookie=NULL;
   int res;
   
   // Elimina el sufijo 'm' del símbolo para la API
   string cleanSymbol = symbolname;
   StringReplace(cleanSymbol, "m", "");
   
   string URL = "https://www.ziwox.com/terminal/services/API/V1/fulldata.php";
   string params = StringFormat("?expn=ziwoxuser&apikey=%s&apitype=json&pair=%s", 
                              apikey, cleanSymbol);
   
   Print("DEBUG: Preparando requisição...");
   Print("DEBUG: URL completa: ", URL + params);
   
   URL = URL + params;
   
   string body = StringFormat("{\"apikey\":\"%s\",\"pair\":\"%s\"}", apikey, cleanSymbol);
   StringToCharArray(body, post, 0, WHOLE_ARRAY, CP_UTF8);
   
   Print("DEBUG: Cuerpo de la solicitud: ", body);
   
   // Haga su solicitud
   Print("DEBUG: Iniciando WebRequest...");
   res = WebRequest("GET", URL, cookie, NULL, 5000, post, 0, result, headers);
   Print("DEBUG: Código de respuesta WebRequest: ", res);
   
   if(res == -1)
   {
      int error = GetLastError();
      Print("DEBUG: GetLastError retornou: ", error);
      return false;
   }
   
   if(res != 200)
   {
      Print("DEBUG: Resposta HTTP diferente de 200: ", res);
      return false;
   }
   
   string response = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);
   
   // Eliminar una etiqueta <pre> da resposta
   StringReplace(response, "<pre>", "");
   StringReplace(response, "</pre>", "");
   
   Print("DEBUG: Resposta recebida (primeiros 500 caracteres): ", StringSubstr(response, 0, 500));
   Print("DEBUG: Tamanho total da resposta: ", StringLen(response));
   
   if(StringFind(response, "invalid api key") >= 0)
   {
      Print("DEBUG: API Key inválida encontrada na resposta");
      Alert("Invalid API key");
      return false;
   }
   
   // Tenta salvar a resposta
   Print("DEBUG: Tentando salvar resposta no arquivo: ", filename);
   int filehandle = FileOpen(filename, FILE_WRITE|FILE_BIN|FILE_COMMON);
   if(filehandle != INVALID_HANDLE)
   {
      // Converte a resposta para array de caracteres
      char responseArray[];
      StringToCharArray(response, responseArray, 0, StringLen(response));
      
      // Salva no arquivo
      FileWriteArray(filehandle, responseArray);
      FileClose(filehandle);
      Print("DEBUG: Arquivo salvo com sucesso");
      return true;
   }
   
   Print("DEBUG: Falha ao salvar arquivo");
   return false;
}

//+------------------------------------------------------------------+
//| Función de análisis de datos JSON|
//+------------------------------------------------------------------+
void JsonDataParse(string filename, string &_APIJSON[])
{
   for (int arraIn = 0; arraIn < ArraySize(APIJSON); arraIn++) 
      APIJSON[arraIn] = "";

   if (FileGetInteger(filename, FILE_EXISTS, true) >= 0)
   {
      int FileHandle = FileOpen(filename, FILE_READ|FILE_BIN|FILE_COMMON);
      if(FileHandle != INVALID_HANDLE)
      {
         char jsonarray[];
         FileReadArray(FileHandle, jsonarray);
         FileClose(FileHandle);

         JsonValue.Clear();
         string jsonString = CharArrayToString(jsonarray, 0, WHOLE_ARRAY, CP_UTF8);
         Print("JSON Recebido: ", jsonString); // Depurar
         
         if(JsonValue.Deserialize(jsonString))
         {
            _APIJSON[0] = JsonValue[0]["Symbol"].ToStr();
            _APIJSON[1] = JsonValue[0]["Last Price"].ToStr();
            _APIJSON[2] = JsonValue[0]["Base Fundamental Bias"].ToStr();
            _APIJSON[3] = JsonValue[0]["AI Bullish Forecast"].ToStr();
            _APIJSON[4] = JsonValue[0]["AI Bearish Forecast"].ToStr();
            _APIJSON[5] = JsonValue[0]["Retail Long Ratio"].ToStr();
            _APIJSON[6] = JsonValue[0]["Retail Short Ratio"].ToStr();
            _APIJSON[7] = JsonValue[0]["D1 Trend"].ToStr();
            _APIJSON[8] = JsonValue[0]["D1 RSI"].ToStr();
            _APIJSON[9] = JsonValue[0]["Allow To Trade"].ToStr();
            
            Print("Dados processados:");
            Print("Symbol: ", _APIJSON[0]);
            Print("Last Price: ", _APIJSON[1]);
Discussing the article: "Using JSON Data API in your MQL projects"
Discussing the article: "Using JSON Data API in your MQL projects"
  • 2025.01.17
  • Edgar Akhmadeev
  • www.mql5.com
Check out the new article: Using JSON Data API in your MQL projects . Author: Sara Sabaghi...
 
Ney Borges #:

Fiz algumas correçoes ao codigo para funcionar no MQL5 gostaria que por gentil verificasse e retornar, obrigado - Sara Sabaghi

Hola amigo

Gracias por compartir tu código. Sí, lo he probado. Funciona bien

API de datos Forex de Ziwox

 
Nikolai Semko #:

Cambiado a binario. El tamaño de los mismos datos es ahora de 1,2 Mb. El análisis sintáctico en las matrices de estructuras requeridas tarda ahora 5 milisegundos.

Eso es demasiado para ti. Aquí tarda 12 ms, pero los datos son de 80 Mb.