Discussing the article: "Using JSON Data API in your MQL projects" - page 2

 
Sara Sabaghi #:

The claims were not to you, of course, but to the content providers. Which for some reason give not binary data, but text data ))))

We cannot change this fact, unfortunately.

 
Edgar Akhmadeev #:

The claims were not to you, of course, but to the content providers. Which for some reason give not binary data, but text data ))))

We cannot change this fact, unfortunately.

because they need compatibility.

 
Sara Sabaghi #:

This article is about API and how to use it. Do you know an API that provides you with binary forex data? Then introduce it.

Next point, you criticise why use a normal computer to play FIFA2024 when a quantum computer is faster. The answer is simple, I don't need that kind of processing power.
So, the answer to this argument is that most of the data exchanged in this area in the API is in the range of a few megabytes, and there is no need for speed. In addition, all Forex data providers use standards such as XML, JSON...

I am not against the use of JSON. I use it myself, but only at the development stage, as you can always see a well readable response in PostMan or WireShark.
I was just pointing out that the article unfairly didn't even mention the binary format. Moreover, the more performant JSON binary (JSONB) is now gaining momentum.
If I have access to a server, I always use binary data in the exchange between server and client. There is only one reason why JSON is used everywhere: readable( for the user, but not for the computer). To have less dumb questions from users.
Even in websockets, where as a rule the transferred data is very small, I think it is reasonable to use binary data. At least because it is a more productive system with less load on the server and client side. And if you use cloud technologies, which is reasonable in today's highly competitive realities, you save a lot of money on their payment. After all, serialisation consumes a lot of resources and saves a lot of traffic.
 
Nikolai Semko #:
I am not against the use of JSON. I use it myself, but only at the development stage, as you can always see a well readable response in PostMan or WireShark.
I was just pointing out that the article unfairly didn't even mention the binary format. Moreover, the more performant JSON binary (JSONB) is now gaining momentum.
If I have access to a server, I always use binary data in the exchange between server and client. There is only one reason why JSON is used everywhere: readable( for the user, but not for the computer). To have less dumb questions from users.
Even in websockets, where as a rule the transferred data is very small, I think it is reasonable to use binary data. At least because it is a more productive system with less load on the server and client side. And if you use cloud technologies, which is reasonable in today's highly competitive realities, you save a lot of money on their payment. After all, serialisation consumes a lot of resources and saves a lot of traffic.

Thank you very much for taking the time to share your thoughts with us. I completely understand your point, and the points you've raised about using binary formats and JSONB are very valid. You are right that JSON, in comparison to binary formats, is not as optimized for system performance, and this is something that many developers are aware of.

In the article we wrote, our primary focus was on JSON because 99% of financial data providers, particularly in the Forex domain, use this standard for data exchange, and many platforms and services provide data in this format. For this reason, we didn't cover other standards.

Once again, thank you for sharing your perspective and for pointing out this important detail.

 
Edgar Akhmadeev #:

The claims were not to you, of course, but to the content providers. Which for some reason give not binary data, but text data ))))

We cannot change this fact, unfortunately.

Yes, I completely understand it. Additionally, we are required to use this standard because nearly all financial data providers use this method.

 
Hello, here it is, so what I asked for is for me to post it in the mql5 community =
 //+------------------------------------------------------------------+
 //|                             ZIWOX API and Technical Strategy.mq5 |
 //|                                        Copyright 2024, ssabbaghi |
 //|                          https://www.mql5.com/en/users/ssabbaghi |
 //+------------------------------------------------------------------+
 #property   copyright    "Sara Sabbaghi"
 #property   link          "https://www.mql5.com/en/users/ssabbaghi"
 #property   version      "1.0"
 #property   strict

 //---- input parameters
 input      string       APIKey         =   "xxxxaquisuakey" ;       // Your unique API key
 input      string       SymbolPrefix   =   "" ;       // Your Broker account symbol Prefix
 input      string       SymbolSuffiex  =   "m" ;       // Your Broker account symbol Suffix
 input      int          shortMAPeriod  =   50 ;       // Slow MA Period
 input      int          longMAPeriod   =   200 ;     // Fast MA Period
 input      double       Lots           =   0.01 ;     // Static Order volume
 input      int          APICallInterval = 300 ;     // Interval between API calls in seconds (5 minutes)

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

 string    OBJPREFIX      =   "ZXAPI" ,
         SymbolRequest  =   "" ,
         APIJSON[];
 bool      APIOK =   false ;
 datetime LastAPICallTime = 0 ; // Armazena o tempo da última chamada à API

 //+------------------------------------------------------------------+
 //| expert initialization function                                   |
 //+------------------------------------------------------------------+
 int OnInit ()
{
   EventSetTimer ( 30 );
   ArrayResize (APIJSON, 15 );
   SymbolRequest = PureSymbol( Symbol (), SymbolSuffiex, SymbolPrefix); // Prepare real symbol name 
   Comment ( "Wait a sec, to Get API data..." );
   return ( INIT_SUCCEEDED );
}

 //+------------------------------------------------------------------+
 //| Expert deinitialization function                                 |
 //+------------------------------------------------------------------+
 void OnDeinit ( const int reason)
{
   Comment ( "" );
   ObjectsDeleteAll ( 0 );
}

 //+------------------------------------------------------------------+
 //| Expert tick function    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 );

       // Check for crossover signals 
       if ( int (APIJSON[ 3 ]) >= 60 ) // if bullish forecast is higher than 60% 
      {
         if (shortMA > longMA)   // BUY trend 
         {
             if ( OrdersTotal () == 0 ) {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // Use TRADE_ACTION_DEAL for buy 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_BUY ; // Use ORDER_BUY for buy 
               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 ) // if bearish forecast is higher than 60% 
      {
         if (shortMA < longMA)   // Sell trend 
         {
             if ( OrdersTotal () == 0 )
            {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // Use TRADE_ACTION_DEAL for sell 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_SELL ; // Use ORDER_SELL for sell 
               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 ());
               }
            }
         }
      }
   }
}

 //+------------------------------------------------------------------+
 //| Expert OnTimer function                                          |
 //+------------------------------------------------------------------+
 void OnTimer ()
{
   // Verifica se o tempo decorrido desde a última chamada à API é maior que o intervalo definido 
   if ( TimeCurrent () - LastAPICallTime >= APICallInterval)
   {
       string APIfilename = SymbolRequest + "_API_Data.json" ; // API store file name 
      APIOK = GetAPI(SymbolRequest, APIKey, APIfilename);   // Get the API data and save it to APIfilename 
       if (APIOK) JsonDataParse(APIfilename, APIJSON);     // read the JSON data and store them into the API_DATA array 
       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 ]
              );

       // Atualiza o tempo da última chamada à API 
      LastAPICallTime = TimeCurrent ();
   }
}

 //+------------------------------------------------------------------+
 //| New candle check function                                        |
 //+------------------------------------------------------------------+
 datetime NewCandleTime = TimeCurrent ();
 bool IsNewCandle()
{
   if (NewCandleTime == iTime ( Symbol (), 0 , 0 ))
       return false ;
   else 
   {
      NewCandleTime = iTime ( Symbol (), 0 , 0 );
       return true ;
   }
}

 //+------------------------------------------------------------------+
 //| Pure symbol function                                             |
 //+------------------------------------------------------------------+
 string PureSymbol( string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "" )
   {
       StringReplace (puresymbol, suffiex, "" );
       StringReplace (puresymbol, prefix, "" );
   }
   return puresymbol;
}

 //+------------------------------------------------------------------+
 //|  Get Fund data from ziwox                                        |
 //+------------------------------------------------------------------+
 datetime LastWebRequest = 0 ; // use this datetime var for limit failed request API
 bool GetAPI( string symbolname, string apikey, string filename)
{
   Print ( "Get API Update" );
   bool NeedToUpdate = false ;

   // Check if the API data file available 
   if ( FileGetInteger (filename, FILE_EXISTS , true ) >= 0 )
   {
       // Check the latest update time from file modify date time 
       if ( TimeLocal () - ( datetime ) FileGetInteger (filename, FILE_MODIFY_DATE , true ) > 900 ) // update data every 15 min 
         NeedToUpdate = true ;
   }
   else 
      NeedToUpdate = true ;

   if (NeedToUpdate && TimeLocal () - LastWebRequest > 300 )   // retry failed API request every 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 ;
         }
         // Store the API data into a common folder file 
         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 ;
}

 //+------------------------------------------------------------------+
 //| JSON Data Parse function                                         |
 //+------------------------------------------------------------------+
 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();
   }
}
 //+------------------------------------------------------------------+

Version for MQL5 METATRADER 5 I made changes to the code so that it would work in Metatrader 5. The changes were also made regarding the coding for better conditions in the current commercial situation. All the changes were to adapt the code to Metatrader 5. It is functional. And just download this file and run it. If necessary, the JAson.mqh library, which is found in the original code of our companion. My name is Ney Borges. I am from Brazil, state of Goiás, city of Caldas Novas, in the middle of the forest of Brazil. It was very difficult to learn alone without anyone to help, but here in the community I learned a lot. Thank you.

Version for MQL5 METATRADER 5 I made changes to the code so that it would work in Metatrader 5. The changes were also made regarding the coding for better conditions in the current commercial situation. All the changes were to adapt the code to Metatrader 5. It is functional. And just download this file and run it. If necessary, the JAson.mqh library, which is found in the original code of our companion. My name is Ney Borges. I am from Brazil, state of Goiás, city of Caldas Novas, in the middle of the forest of Brazil. It was very difficult to learn alone without anyone to help, but here in the community I learned a lot. Thank you.

Brasil - Goiás - Caldas Novas - Ney Borges

Sara Sabaghi
Sara Sabaghi
  • 2025.01.13
  • www.mql5.com
Trader's profile
 
Ney Borges #:
If necessary, you can use the JAson.mqh library, which can be found in the original code of our companion.

What a horrible way for google translator to work.

Without the JAson library, of course, it won't work.

The library is not in his code, it's here, and the author has specified that.

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

Yes, I completely understand it. Additionally, we are required to use this standard because nearly all financial data providers use this method.

Ney Borges #:
Hello, here it is, so what I asked for is for me to post it in the mql5 community =

Version for MQL5 METATRADER 5 I made changes to the code so that it would work in Metatrader 5. The changes were also made regarding the coding for better conditions in the current commercial situation. All the changes were to adapt the code to Metatrader 5. It is functional. And just download this file and run it. If necessary, the JAson.mqh library, which is found in the original code of our companion. My name is Ney Borges. I am from Brazil, state of Goiás, city of Caldas Novas, in the middle of the forest of Brazil. It was very difficult to learn alone without anyone to help, but here in the community I learned a lot. Thank you.

Version for MQL5 METATRADER 5 I made changes to the code so that it would work in Metatrader 5. The changes were also made regarding the coding for better conditions in the current commercial situation. All the changes were to adapt the code to Metatrader 5. It is functional. And just download this file and run it. If necessary, the JAson.mqh library, which is found in the original code of our companion. My name is Ney Borges. I am from Brazil, state of Goiás, city of Caldas Novas, in the middle of the forest of Brazil. It was very difficult to learn alone without anyone to help, but here in the community I learned a lot. Thank you.

Brasil - Goiás - Caldas Novas - Ney Borges

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

//+------------------------------------------------------------------+
//| Ney Borges versão mql5 de ZIWOX API and Technical Strategy.mq5 |
//|                                        Copyright 2024, ssabbaghi |
//|                          https://www.mql5.com/en/users/ssabbaghi |
//+------------------------------------------------------------------+
#property   copyright   "Sara Sabbaghi"
#property   link        "https://www.mql5.com/en/users/ssabbaghi"
#property   version     "1.0"
#property   strict
#property   description "Expert com funções de rede para ZIWOX API"

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

// Propriedades do Expert para permitir funções de rede
//#property script_show_inputs
//#property script_show_confirm

//---- input parameters
input    string      APIKey         =  "sua Key aqui xxxxxxxx";      // Your unique API key
input    string      SymbolPrefix   =  "";      // Your Broker account symbol Prefix
input    string      SymbolSuffiex  =  "m";      // Your Broker account symbol Suffix
input    int         shortMAPeriod  =  50;      // Slow MA Period
input    int         longMAPeriod   =  200;     // Fast MA Period
input    double      Lots           =  0.01;    // Static Order volume
input    double      BullishThreshold = 60.0;   // Threshold for bullish forecast
input    double      BearishThreshold = 60.0;   // Threshold for bearish forecast
input    int         APICallInterval = 300;     // Interval between API calls in seconds (5 minutes)

string   OBJPREFIX      =  "ZXAPI",
         SymbolRequest  =  "",
         APIJSON[];
bool     APIOK          =  false;
datetime LastAPICallTime = 0; // Armazena o tempo da última chamada à API

//+------------------------------------------------------------------+
//| Função para testar conexão 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);
      
      // Se for erro de permissão, mostra mensagem específica
      if(error==4014)
         msg = "Adicione "+url+" em Ferramentas -> Opções -> Expert Advisors -> Permitir WebRequest";
         
      Print("DEBUG: ", msg);
      return(false);
   }
   
   Print("DEBUG: Conexão HTTP testada com sucesso");
   return(true);
}

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   Print("=== Iniciando Expert Advisor ===");
   
   // Verifica configurações básicas
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("AVISO: Algorithmic Trading não está permitido");
      // Continua mesmo assim
   }
   
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
   {
      Print("AVISO: Terminal não está conectado à internet");
      // Continua mesmo assim
   }
   
   // Configura o EA
   EventSetTimer(30);
   ArrayResize(APIJSON, 15);
   SymbolRequest = PureSymbol(Symbol(), SymbolSuffiex, SymbolPrefix);
   
   // Prepara e mostra a URL que será usada
   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("Ferramentas -> Opções -> Expert Advisors -> Permitir WebRequest");
   
   Comment("Iniciando EA...\n",
           "URL que será usada:\n",
           apiUrl,
           "\n\nIMPORTANTE: Configure a URL nas opções do Expert Advisor");
   
   // Testa conexão HTTP, mas não falha se der erro
   if(!TestHTTPConnection())
   {
      Print("AVISO: Teste de conexão HTTP falhou");
      Print("O EA continuará tentando conectar...");
      // Continua mesmo assim
   }
   
   Print("=== Inicialização concluída ===");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
   ObjectsDeleteAll(0);
}

//+------------------------------------------------------------------+
//| Expert tick function    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);

      // Analisando dados JSON para decisões de negociação
      double aiBullishForecast = StringToDouble(APIJSON[3]); // Previsão de alta
      double aiBearishForecast = StringToDouble(APIJSON[4]); // Previsão de baixa

      // Check for crossover signals
      if (aiBullishForecast >= BullishThreshold && shortMA > longMA) // Se a previsão de alta for maior que o limite
      {
         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) // Se a previsão de baixa for maior que o limite
      {
         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());
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Função para verificar se a 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;
}

//+------------------------------------------------------------------+
//| Expert OnTimer function                                          |
//+------------------------------------------------------------------+
void OnTimer()
{
   // Verifica se a URL está permitida antes de fazer a chamada
   if(!IsURLAllowed())
   {
      Print("DEBUG: URL não está permitida. Aguardando configuração...");
      return;
   }

   if (TimeCurrent() - LastAPICallTime >= APICallInterval)
   {
      string APIfilename = SymbolRequest + "_API_Data.json";
      
      // Prepara a URL para mostrar no comentário
      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 atualização: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), "\n",
                 "\nDados recebidos:",
                 "\nSymbol: ", APIJSON[0],
                 "\nÚltimo Preço: ", APIJSON[1],
                 "\nViés Fundamental: ", APIJSON[2],
                 "\nPrevisão de Alta: ", APIJSON[3], "%",
                 "\nPrevisão de Baixa: ", APIJSON[4], "%",
                 "\nPosições Compradas: ", APIJSON[5],
                 "\nPosições 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. Se a URL está permitida em Ferramentas -> Opções -> Expert Advisors -> WebRequest",
                 "\n2. Se sua conexão com 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;
}

//+------------------------------------------------------------------+
//| Pure symbol function                                             |
//+------------------------------------------------------------------+
string PureSymbol(string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "")
   {
      StringReplace(puresymbol, suffiex, "");
      StringReplace(puresymbol, prefix, "");
   }
   return puresymbol;
}

//+------------------------------------------------------------------+
//| Função para verificar configuração do WebRequest                 |
//+------------------------------------------------------------------+
bool CheckWebRequestSettings()
{
   if(!TerminalInfoInteger(TERMINAL_DLLS_ALLOWED))
   {
      Print("ERRO: DLLs não estão permitidas!");
      return false;
   }
   
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("ERRO: Algorithmic Trading não está permitido!");
      return false;
   }
   
   if(!MQLInfoInteger(MQL_DLLS_ALLOWED))
   {
      Print("ERRO: DLLs não estão permitidas para este Expert!");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Função para verificar conexão com o servidor                     |
//+------------------------------------------------------------------+
bool CheckServerConnection()
{
   int socket = SocketCreate();
   
   if(socket != INVALID_HANDLE)
   {
      // Tenta conectar ao servidor da ZIWOX (porta 80 para HTTP)
      if(SocketConnect(socket, "www.ziwox.com", 80, 1000))
      {
         Print("DEBUG: Conexão com servidor testada com sucesso");
         // Verifica se 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;
}

//+------------------------------------------------------------------+
//| Função para obter dados da API                                   |
//+------------------------------------------------------------------+
bool GetAPI(string symbolname, string apikey, string filename)
{
   if(!TestHTTPConnection())
   {
      Print("DEBUG: Falha no teste de conexão HTTP");
      return false;
   }

   string headers = "Content-Type: application/json\r\nAccept: application/json\r\n";
   char post[], result[];
   string cookie=NULL;
   int res;
   
   // Remove o sufixo 'm' do símbolo para a 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: Body da requisição: ", body);
   
   // Tenta fazer a requisição
   Print("DEBUG: Iniciando WebRequest...");
   res = WebRequest("GET", URL, cookie, NULL, 5000, post, 0, result, headers);
   Print("DEBUG: Código de resposta 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);
   
   // Remove a tag <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;
}

//+------------------------------------------------------------------+
//| Função para analisar dados 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); // Debug
         
         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 gentilesa verificasse e retornar, obrigado -  Sara Sabaghi 

Hi dude

Thank you for sharing your code. Yeah, I tested it. It works fine

Ziwox Forex Data API

 
Nikolai Semko #:

Switched to binary. The size of the same data is now 1.2 Mb. Parsing into required arrays of structures now takes 5 milliseconds.

That's a bit too much for you. Here it takes 12 ms, but the data is 80 Mb.