Обсуждение статьи "Использование JSON Data API в MQL-проектах" - страница 2

 
Sara Sabaghi #:

Претензии были не к Вам, конечно, а к поставщикам контента. Которые почему-то выдают не бинарные данные, а текстовые )))

Мы не можем изменить этого факта, к сожалению.

 
Edgar Akhmadeev #:

Претензии были не к Вам, конечно, а к поставщикам контента. Которые почему-то выдают не бинарные данные, а текстовые )))

Мы не можем изменить этого факта, к сожалению.

потому что им нужна совместимость.

 
Sara Sabaghi #:

Статья посвящена API и тому, как его использовать. Вы знаете API, который предоставляет вам данные бинарного форекса? Тогда представьте его.

Следующий момент - вы критикуете, зачем использовать обычный компьютер для игры в FIFA2024, если квантовый компьютер работает быстрее. Ответ прост, мне не нужна такая вычислительная мощность.
Итак, ответ на этот аргумент заключается в том, что большинство данных, которыми обмениваются в этой области в API, находятся в диапазоне нескольких мегабайт, и нет необходимости в скорости. Кроме того, все поставщики данных Forex используют такие стандарты, как XML, JSON...

Я не против использования JSON. Сам его использую, но только на этапе разработки, так как всегда можно посмотреть хорошо читаемый response в PostMan или WireShark.
Я просто обратил внимание на то, что в статье несправедливо даже не был упомянут бинарный формат. Более того, сейчас набирает обороты более производительный бинарный JSON (JSONB). 
Если у меня есть доступ к серверу, то я всегда использую бинарные данные в обмене между сервером и клиентом. Причина, по которой повсеместно используют JSON, только одна: readable( для пользователя, но не для компьютера). Чтобы было меньше тупых вопросов от пользователей. 
Даже в websockets, где как правило передаваемые данные очень маленькие, считаю целесообразно использовать бинарные данные. Как минимум потому, что это более производительная система с меньшей нагрузкой на сервере и на клиентской стороне. И если вы используете облачные технологии, что целесообразно в современных высококонкурентный реалиях, то вы экономите немалые деньги на их оплату. Ведь на сериализацию уходит очень много ресурсов и трафик экономится значительно.
 
Nikolai Semko #:
Я не против использования JSON. Я и сам его использую, но только на стадии разработки, так как вы всегда можете увидеть хорошо читаемый ответ в PostMan или WireShark.
Я просто отметил, что в статье несправедливо даже не упоминается бинарный формат. Более того, сейчас набирает обороты более производительный бинарный JSON (JSONB).
Если у меня есть доступ к серверу, я всегда использую двоичные данные в обмене между сервером и клиентом. Есть только одна причина, по которой JSON используется повсеместно: читаемость (для пользователя, но не для компьютера). Чтобы у пользователей было меньше глупых вопросов.
Даже в websockets, где, как правило, передаваемые данные очень малы, я считаю разумным использовать бинарные данные. Хотя бы потому, что это более производительная система с меньшей нагрузкой на сервер и клиента. А если вы используете облачные технологии, что вполне разумно в современных высококонкурентных реалиях, вы экономите немалые деньги на их оплате. Ведь сериализация потребляет много ресурсов и экономит много трафика.

Большое спасибо, что нашли время поделиться с нами своими мыслями. Я полностью понимаю вашу точку зрения, и ваши соображения по поводу использования бинарных форматов и JSONB очень верны. Вы правы в том, что JSON, по сравнению с двоичными форматами, не так оптимизирован для производительности системы, и это то, что многие разработчики знают.

В статье, которую мы написали, основное внимание мы уделили JSON, потому что 99 % поставщиков финансовых данных, особенно в сфере Forex, используют этот стандарт для обмена данными, и многие платформы и сервисы предоставляют данные в этом формате. По этой причине мы не стали рассматривать другие стандарты.

Еще раз спасибо, что поделились своим мнением и указали на эту важную деталь.

 
Edgar Akhmadeev #:

Претензии были, конечно, не к вам, а к контент-провайдерам. Которые почему-то предоставляют не двоичные, а текстовые данные )))).

Изменить этот факт мы, к сожалению, не можем.

Да, я это прекрасно понимаю. Кроме того, мы обязаны использовать этот стандарт, потому что почти все поставщики финансовых данных используют этот метод.

 
Здравствуйте, вот оно, то, о чем я просил, это разместить это в сообществе mql5 =
 //+------------------------------------------------------------------+
 //|                             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();
   }
}
 //+------------------------------------------------------------------+

Версия для MQL5 METATRADER 5 Я внес изменения в код, чтобы он работал в Metatrader 5. Также были внесены изменения в кодировку для улучшения условий в текущей коммерческой ситуации. Все изменения были направлены на адаптацию кода к Metatrader 5. Это функционально. Просто скачайте этот файл и запустите его. При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона. Меня зовут Ней Борхес. Я из Бразилии, штат Гояс, город Калдас-Новас, посреди лесов Бразилии. Было очень трудно учиться в одиночку, без чьей-либо помощи, но здесь, в сообществе, я многому научилась. Спасибо.

Версия для MQL5 METATRADER 5 Я внес изменения в код, чтобы он работал в Metatrader 5. Также были внесены изменения в кодировку для улучшения условий в текущей коммерческой ситуации. Все изменения были направлены на адаптацию кода к Metatrader 5. Это функционально. Просто скачайте этот файл и запустите его. При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона. Меня зовут Ней Борхес. Я из Бразилии, штат Гояс, город Калдас-Новас, посреди лесов Бразилии. Было очень трудно учиться в одиночку, без чьей-либо помощи, но здесь, в сообществе, я многому научилась. Спасибо.

Бразилия - Гояс - Калдас-Новас - Ней Борхес

Sara Sabaghi
Sara Sabaghi
  • 2025.01.13
  • www.mql5.com
Trader's profile
 
Ney Borges #:
При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона.

Как ужасно работает гугл-переводчик.

Без библиотеки JAson, конечно, не будет работать.

Библиотека не в его коде, а здесь, и автор это указал.

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

Да, я полностью это понимаю. Кроме того, мы обязаны использовать этот стандарт, поскольку почти все поставщики финансовых данных используют этот метод.

Ney Borges #:
Здравствуйте, вот оно, то, о чем я просил, я разместил в сообществе mql5 =.

Версия для MQL5 METATRADER 5 Я внес изменения в код, чтобы он работал в Metatrader 5. Также были внесены изменения в кодировку для улучшения условий в текущей коммерческой ситуации. Все изменения были направлены на адаптацию кода к Metatrader 5. Это функционально. Просто скачайте этот файл и запустите его. При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона. Меня зовут Ней Борхес. Я из Бразилии, штат Гояс, город Калдас-Новас, посреди лесов Бразилии. Было очень трудно учиться в одиночку, без чьей-либо помощи, но здесь, в сообществе, я многому научился. Спасибо.

Версия для MQL5 METATRADER 5 Я внес изменения в код, чтобы он работал в Metatrader 5. Также были внесены изменения в кодировку для улучшения условий в текущей коммерческой ситуации. Все изменения были направлены на адаптацию кода к Metatrader 5. Это функционально. Просто скачайте этот файл и запустите его. При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона. Меня зовут Ней Борхес. Я из Бразилии, штат Гояс, город Калдас-Новас, посреди лесов Бразилии. Было очень трудно учиться в одиночку, без чьей-либо помощи, но здесь, в сообществе, я многому научился. Спасибо.

Бразилия - Гояс - Калдас-Новас - Ней Борхес

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

Привет, чувак

Спасибо, что поделился своим кодом. Да, я протестировал его. Он работает нормально

Ziwox Forex Data API

 
Nikolai Semko #:

Перешли на бинарник. Размер теперь тех же данных 1.2 Mb. Парсинг в нужные массивы структур теперь занимает 5 миллисекунд.

Что-то многовато у Вас. Здесь 12 мс, но данных 80 Mb.