文章 "在您的 MQL 项目中使用 JSON 数据 API" - 页 2

 
Sara Sabaghi #:

当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某种原因,它们提供的不是二进制数据,而是文本数据 ))))

遗憾的是,我们无法改变这一事实。

 
Edgar Akhmadeev #:

当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某些原因,提供的不是二进制数据,而是文本数据 ))))

遗憾的是,我们无法改变这一事实。

因为他们需要兼容性。

 
Sara Sabaghi #:

本文介绍 API 及其使用方法。您知道可以为您提供二元外汇数据的 API 吗?那就介绍一下吧。

下一点,你批评说,量子计算机速度更快,为什么还要用普通计算机玩《FIFA2024》?答案很简单,我不需要那样的处理能力。
因此,对这一论点的回答是,API 在这一领域交换的大部分数据都在几兆字节范围内,不需要速度。此外,所有外汇数据提供商都使用 XML、JSON 等标准...

我并不反对使用 JSON。我自己也使用 JSON,但仅限于开发阶段,因为你总能在 PostMan 或 WireShark 中看到可读性良好的响应。
我只是想指出,这篇文章甚至没有提到二进制格式,这是不公平的。此外,性能更强的 JSON 二进制格式(JSONB)现在正逐渐流行起来。
如果我能访问服务器,我总是在服务器和客户端之间使用二进制数据进行交换。到处使用 JSON 的原因只有一个:可读性(对用户而言,但对计算机而言并非如此)。为了减少用户提出的愚蠢问题。
即使在 websockets(通常传输的数据量很小)中,我认为使用二进制数据也是合理的。至少因为这样的系统效率更高,服务器和客户端的负担更轻。而且,如果使用云技术(这在当今竞争激烈的现实情况下是合理的),还能节省大量的支付费用。毕竟,序列化会消耗大量资源,节省大量流量。
 
Nikolai Semko #:
我并不反对使用 JSON。我自己也使用 JSON,但仅限于开发阶段,因为你总能在 PostMan 或 WireShark 中看到可读的响应。
我只是想指出,这篇文章甚至没有提到二进制格式,这是不公平的。此外,性能更强的 JSON 二进制格式(JSONB)现在正逐渐流行起来。
如果我能访问服务器,我总是在服务器和客户端之间使用二进制数据进行交换。到处使用 JSON 的原因只有一个:可读性(对用户而言,但对计算机而言并非如此)。减少用户提出的愚蠢问题。
即使在 websockets(通常传输的数据量很小)中,我认为使用二进制数据也是合理的。至少因为这样的系统效率更高,服务器和客户端的负担更轻。而且,如果使用云技术(这在当今竞争激烈的现实情况下是合理的),还能节省大量的支付费用。毕竟,序列化会消耗大量资源,节省大量流量。

非常感谢您抽出时间与我们分享您的想法。我完全理解您的观点,您提出的关于使用二进制格式和 JSONB 的观点非常有道理。您说得没错,与二进制格式相比,JSON 在系统性能方面没有那么优化,这一点很多开发人员都意识到了。

在我们撰写的这篇文章中,我们主要关注的是 JSON,因为 99% 的金融数据提供商(尤其是在外汇领域)都使用这种标准进行数据交换,而且许多平台和服务都以这种格式提供数据。因此,我们没有涉及其他标准。

再次感谢您分享您的观点并指出这一重要细节。

 
Edgar Akhmadeev #:

当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某些原因,提供的不是二进制数据,而是文本数据 ))))

遗憾的是,我们无法改变这一事实。

是的,我完全理解。此外,我们必须使用这一标准,因为几乎所有的金融数据提供商都使用这种方法。

 
你好,就是它了,所以我的要求是让我把它发布到 mql5 社区 =。
 //+------------------------------------------------------------------+
 //|ZIWOX API 和技术策略。mq5
 //|Copyright 2024, ssabbaghi | |
 //|https://www.mql5.com/zh/users/ssabbaghi| |.
 //+------------------------------------------------------------------+
 #property   copyright    "Sara Sabbaghi"
 #property   link          "https://www.mql5.com/zh/users/ssabbaghi"
 #property   version      "1.0"
 #property   strict

 //---- 输入参数
 input      string       APIKey         =   "xxxxaquisuakey" ;       // 您唯一的应用程序接口密钥
 input      string       SymbolPrefix   =   "" ;       // 您的经纪商账户符号前缀
 input      string       SymbolSuffiex  =   "m" ;       // 您的经纪商账户符号后缀
 input      int          shortMAPeriod  =   50 ;       // 慢速 MA 周期
 input      int          longMAPeriod   =   200 ;     // 快速 MA 周期
 input      double       Lots           =   0.01 ;     // 静态订单量
 input      int          APICallInterval = 300 ;     // 以秒为单位的 API 调用间隔(5 分钟)

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

 string    OBJPREFIX      =   "ZXAPI" ,
         SymbolRequest  =   "" ,
         APIJSON[];
 bool      APIOK =   false ;
 datetime LastAPICallTime = 0 ; // 查看应用程序接口的最新页面时间

 //+------------------------------------------------------------------+
 //| 专家初始化函数|
 //+------------------------------------------------------------------+
 int OnInit ()
{
   EventSetTimer ( 30 );
   ArrayResize (APIJSON, 15 );
   SymbolRequest = PureSymbol( Symbol (), SymbolSuffiex, SymbolPrefix); // 准备真正的符号名称 
   Comment ( "Wait a sec, to Get API data..." );
   return ( INIT_SUCCEEDED );
}

 //+------------------------------------------------------------------+
 //| 专家去初始化函数|
 //+------------------------------------------------------------------+
 void OnDeinit ( const int reason)
{
   Comment ( "" );
   ObjectsDeleteAll ( 0 );
}

 //+------------------------------------------------------------------+
 //| 专家勾选函数 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 );

       // 检查交叉信号 
       if ( int (APIJSON[ 3 ]) >= 60 ) // 如果看涨预测高于 60% 时 
      {
         if (shortMA > longMA)   // 购买趋势 
         {
             if ( OrdersTotal () == 0 ) {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // 买入时使用 TRADE_ACTION_DEAL 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_BUY ; // 使用 ORDER_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 ) // 如果看跌预测高于 60 
      {
         if (shortMA < longMA)   // 卖出趋势 
         {
             if ( OrdersTotal () == 0 )
            {
               MqlTradeRequest request;
               MqlTradeResult result;
               request.action = TRADE_ACTION_DEAL ; // 使用 TRADE_ACTION_DEAL 进行卖出 
               request.symbol = Symbol ();
               request.volume = Lots;
               request.type = ORDER_TYPE_SELL ; // 使用 ORDER_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 ());
               }
            }
         }
      }
   }
}

 //+------------------------------------------------------------------+
 //| 专家 OnTimer 函数|
 //+------------------------------------------------------------------+
 void OnTimer ()
{
   // 核实从最后一次通话到 API 的时间间隔是否大于所定义的时间间隔 
   if ( TimeCurrent () - LastAPICallTime >= APICallInterval)
   {
       string APIfilename = SymbolRequest + "_API_Data.json" ; // 应用程序接口存储文件名 
      APIOK = GetAPI(SymbolRequest, APIKey, APIfilename);   // 获取 API 数据并将其保存到 APIfilename 中 
       if (APIOK) JsonDataParse(APIfilename, APIJSON);     // 读取 JSON 数据并将其存储到 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 ]
              );

       // 更新应用程序接口的最新章节时间 
      LastAPICallTime = TimeCurrent ();
   }
}

 //+------------------------------------------------------------------+
 //| 新增蜡烛检查功能|
 //+------------------------------------------------------------------+
 datetime NewCandleTime = TimeCurrent ();
 bool IsNewCandle()
{
   if (NewCandleTime == iTime ( Symbol (), 0 , 0 ))
       return false ;
   else 
   {
      NewCandleTime = iTime ( Symbol (), 0 , 0 );
       return true ;
   }
}

 //+------------------------------------------------------------------+
 //| 纯符号函数|
 //+------------------------------------------------------------------+
 string PureSymbol( string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "" )
   {
       StringReplace (puresymbol, suffiex, "" );
       StringReplace (puresymbol, prefix, "" );
   }
   return puresymbol;
}

 //+------------------------------------------------------------------+
 //| 从 ziwox 获取基金数据|
 //+------------------------------------------------------------------+
 datetime LastWebRequest = 0 ; // 使用此日期时间变量来限制失败请求的 API
 bool GetAPI( string symbolname, string apikey, string filename)
{
   Print ( "Get API Update" );
   bool NeedToUpdate = false ;

   // 检查应用程序接口数据文件是否可用 
   if ( FileGetInteger (filename, FILE_EXISTS , true ) >= 0 )
   {
       // 从文件修改日期时间检查最新更新时间 
       if ( TimeLocal () - ( datetime ) FileGetInteger (filename, FILE_MODIFY_DATE , true ) > 900 ) // 每 15 分钟更新一次数据 
         NeedToUpdate = true ;
   }
   else 
      NeedToUpdate = true ;

   if (NeedToUpdate && TimeLocal () - LastWebRequest > 300 )   // 每 5 分钟重试一次失败的 API 请求 
   {
       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 ;
         }
         // 将应用程序接口数据存储到通用文件夹文件中 
         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 数据解析函数|
 //+------------------------------------------------------------------+
 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 库,该库可在我们同伴的原始代码中找到。我叫 Ney Borges。我来自巴西戈亚斯州的卡尔达斯诺瓦斯市,在巴西的森林之中。在没有人帮助的情况下独自学习是非常困难的,但在社区里我学到了很多。谢谢你们

MQL5 METATRADER 5 版本 我修改了代码,使其可以在 Metatrader 5 中运行。为了更好地适应当前的商业环境,我还对代码进行了修改。所有改动都是为了使代码适应 Metatrader 5。它是实用的。只需下载此文件并运行即可。如有必要,可使用 JAson.mqh 库,该库可在我们同伴的原始代码中找到。我叫 Ney Borges。我来自巴西戈亚斯州的卡尔达斯诺瓦斯市,在巴西的森林之中。在没有人帮助的情况下独自学习是非常困难的,但在社区里我学到了很多。谢谢你们

巴西 - 戈亚斯州 - 卡尔达斯诺瓦斯 - 内伊-博尔赫斯

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 库。我叫 Ney Borges。我来自巴西戈亚斯州的卡尔达斯诺瓦斯市,在巴西的森林之中。在没有人帮助的情况下独自学习是非常困难的,但在社区里我学到了很多。谢谢你们

MQL5 METATRADER 5 版本 我修改了代码,使其可以在 Metatrader 5 中运行。为了更好地适应当前的商业环境,我还对代码进行了修改。所有改动都是为了使代码适应 Metatrader 5。它是实用的。只需下载此文件并运行即可。如有必要,可在我们同伴的原始代码中找到 JAson.mqh 库。我叫 Ney Borges。我来自巴西戈亚斯州的卡尔达斯诺瓦斯市,在巴西的森林之中。在没有人帮助的情况下独自学习是非常困难的,但在社区里我学到了很多。谢谢你们

巴西 - 戈亚斯州 - 卡尔达斯诺瓦斯 - 内伊-博尔赫斯

我在 MQL5 中输入了一些代码,但不知道如何运行,希望您能核实并返回,谢谢 -Sara Sabaghi

//+------------------------------------------------------------------+
//| Ney Borges versão mql5 de ZIWOX API and Technical Strategy.mq5 | | ZIWOX 应用程序接口和技术策略.mql5
//|Copyright 2024, ssabbaghi | |
//|https://www.mql5.com/zh/users/ssabbaghi| |.
//+------------------------------------------------------------------+
#property   copyright   "Sara Sabbaghi"
#property   link        "https://www.mql5.com/zh/users/ssabbaghi"
#property   version     "1.0"
#property   strict
#property   description "ZIWOX应用程序接口功能专家"

// 图书馆
#include <JAson.mqh>
CJAVal JsonValue;

// 专家为实现赎回功能所做的工作
//#perty script_show_inputs
//#property script_show_confirm

//---- 输入参数
input    string      APIKey         =  "sua Key aqui xxxxxxxx";      // 您唯一的应用程序接口密钥
input    string      SymbolPrefix   =  "";      // 您的经纪商账户符号前缀
input    string      SymbolSuffiex  =  "m";      // 您的经纪商账户符号后缀
input    int         shortMAPeriod  =  50;      // 慢速 MA 周期
input    int         longMAPeriod   =  200;     // 快速 MA 周期
input    double      Lots           =  0.01;    // 静态订单量
input    double      BullishThreshold = 60.0;   // 预测看涨的阈值
input    double      BearishThreshold = 60.0;   // 预测看跌的阈值
input    int         APICallInterval = 300;     // 以秒为单位的 API 调用间隔(5 分钟)

string   OBJPREFIX      =  "ZXAPI",
         SymbolRequest  =  "",
         APIJSON[];
bool     APIOK          =  false;
datetime LastAPICallTime = 0; // 查看应用程序接口的最新页面时间

//+------------------------------------------------------------------+
//} 测试 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:HTTP 连接测试成功");
   return(true);
}

//+------------------------------------------------------------------+
//| 专家初始化函数|
//+------------------------------------------------------------------+
int OnInit()
{
   Print("=== Iniciando Expert Advisor ===");
   
   // 验证基本配置
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("AVISO: 不允许算法交易");
      // Continueua mesmo assim
   }
   
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
   {
      Print("AVISO: 终端未连接互联网");
      // Continueua mesmo assim
   }
   
   // 配置 EA
   EventSetTimer(30);
   ArrayResize(APIJSON, 15);
   SymbolRequest = PureSymbol(Symbol(), SymbolSuffiex, SymbolPrefix);
   
   // 准备并显示要使用的 URL
   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/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 继续尝试连接......");
      // Continueua mesmo assim
   }
   
   Print("=== Inicialização concluída ===");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 专家去初始化函数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
   ObjectsDeleteAll(0);
}

//+------------------------------------------------------------------+
//| 专家勾选函数 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);

      // 分析 JSON 数据以做出商业决策
      double aiBullishForecast = StringToDouble(APIJSON[3]); // 高级预测
      double aiBearishForecast = StringToDouble(APIJSON[4]); // 下期预测

      // 检查交叉信号
      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());
         }
      }
   }
}

//+------------------------------------------------------------------+
//} 验证 URL 是否被允许的功能。
//+------------------------------------------------------------------+
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;
}

//+------------------------------------------------------------------+
//| 专家 OnTimer 函数|
//+------------------------------------------------------------------+
void OnTimer()
{
   // 验证是否允许输入 URL
   if(!IsURLAllowed())
   {
      Print("DEBUG:URL não está permitida.等待配置...");
      return;
   }

   if (TimeCurrent() - LastAPICallTime >= APICallInterval)
   {
      string APIfilename = SymbolRequest + "_API_Data.json";
      
      // 准备用于在评论中显示的 URL
      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);
      
      // 正在举办的展览
      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",
                 "最新更新:", 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" (允许的URL),
                 "\n2.Se sua conexão com a internet está funcionando",
                 "\n3.Se o símbolo está correto"
                 );
      }

      LastAPICallTime = TimeCurrent();
   }
}

//+------------------------------------------------------------------+
//| 验证是否是新蜡烛的功能
//+------------------------------------------------------------------+
bool IsNewCandle()
{
   static datetime lastCandleTime = 0;
   datetime currentCandleTime = iTime(Symbol(), 0, 0);
   if (currentCandleTime != lastCandleTime)
   {
      lastCandleTime = currentCandleTime;
      return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| 纯符号函数|
//+------------------------------------------------------------------+
string PureSymbol(string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "")
   {
      StringReplace(puresymbol, suffiex, "");
      StringReplace(puresymbol, prefix, "");
   }
   return puresymbol;
}

//+------------------------------------------------------------------+
//| 验证 WebRequest 配置的功能
//+------------------------------------------------------------------+
bool CheckWebRequestSettings()
{
   if(!TerminalInfoInteger(TERMINAL_DLLS_ALLOWED))
   {
      Print("错误:不允许使用动态链接库!");
      return false;
   }
   
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("ERRO:不允许算法交易!");
      return false;
   }
   
   if(!MQLInfoInteger(MQL_DLLS_ALLOWED))
   {
      Print("ERRO: DLLs não estão permitidas para este Expert!" "ERRO: DLLs não estão permitidas para este Expert!);
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| 验证与服务器连接的功能
//+------------------------------------------------------------------+
bool CheckServerConnection()
{
   int socket = SocketCreate();
   
   if(socket != INVALID_HANDLE)
   {
      // 连接 ZIWOX 服务器(HTTP 端口为 80)
      if(SocketConnect(socket, "www.ziwox.com", 80, 1000))
      {
         Print("DEBUG:与服务器的连接测试成功");
         // 验证是否已真正连接
         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;
}

//+------------------------------------------------------------------+
//| 获取 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;
   
   // 移除应用程序接口的符号 "m"。
   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);
   
   // 删除标签 <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)
   {
      // 将响应转换为特征数组
      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;
}

//+------------------------------------------------------------------+
//| 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); // 调试
         
         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 #:

我对 MQL5 的代码进行了一些修改,希望您能核实并返回,谢谢 -Sara Sabaghi

你好,伙计

感谢您分享代码。是的,我测试过了。运行正常

Ziwox 外汇数据 API

 
Nikolai Semko #:

转为二进制。现在相同数据的大小为1.2 Mb。 解析为所需的结构数组现在需要5 毫秒

这对你来说有点太多了。这里 需要 12 毫秒,但数据是 80 Mb。