文章 "在您的 MQL 项目中使用 JSON 数据 API" - 页 2 123 新评论 Edgar Akhmadeev 2025.01.17 13:56 #11 Sara Sabaghi #: 当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某种原因,它们提供的不是二进制数据,而是文本数据 )))) 遗憾的是,我们无法改变这一事实。 Maxim Kuznetsov 2025.01.17 14:34 #12 Edgar Akhmadeev #:当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某些原因,提供的不是二进制数据,而是文本数据 ))))遗憾的是,我们无法改变这一事实。 因为他们需要兼容性。 Nikolai Semko 2025.01.17 14:49 #13 Sara Sabaghi #:本文介绍 API 及其使用方法。您知道可以为您提供二元外汇数据的 API 吗?那就介绍一下吧。下一点,你批评说,量子计算机速度更快,为什么还要用普通计算机玩《FIFA2024》?答案很简单,我不需要那样的处理能力。 因此,对这一论点的回答是,API 在这一领域交换的大部分数据都在几兆字节范围内,不需要速度。此外,所有外汇数据提供商都使用 XML、JSON 等标准... 我并不反对使用 JSON。我自己也使用 JSON,但仅限于开发阶段,因为你总能在 PostMan 或 WireShark 中看到可读性良好的响应。我只是想指出,这篇文章甚至没有提到二进制格式,这是不公平的。此外,性能更强的 JSON 二进制格式(JSONB)现在正逐渐流行起来。如果我能访问服务器,我总是在服务器和客户端之间使用二进制数据进行交换。到处使用 JSON 的原因只有一个:可读性(对用户而言,但对计算机而言并非如此)。为了减少用户提出的愚蠢问题。即使在 websockets(通常传输的数据量很小)中,我认为使用二进制数据也是合理的。至少因为这样的系统效率更高,服务器和客户端的负担更轻。而且,如果使用云技术(这在当今竞争激烈的现实情况下是合理的),还能节省大量的支付费用。毕竟,序列化会消耗大量资源,节省大量流量。 Sara Sabaghi 2025.01.17 22:53 #14 Nikolai Semko #: 我并不反对使用 JSON。我自己也使用 JSON,但仅限于开发阶段,因为你总能在 PostMan 或 WireShark 中看到可读的响应。 我只是想指出,这篇文章甚至没有提到二进制格式,这是不公平的。此外,性能更强的 JSON 二进制格式(JSONB)现在正逐渐流行起来。 如果我能访问服务器,我总是在服务器和客户端之间使用二进制数据进行交换。到处使用 JSON 的原因只有一个:可读性(对用户而言,但对计算机而言并非如此)。减少用户提出的愚蠢问题。 即使在 websockets(通常传输的数据量很小)中,我认为使用二进制数据也是合理的。至少因为这样的系统效率更高,服务器和客户端的负担更轻。而且,如果使用云技术(这在当今竞争激烈的现实情况下是合理的),还能节省大量的支付费用。毕竟,序列化会消耗大量资源,节省大量流量。 非常感谢您抽出时间与我们分享您的想法。我完全理解您的观点,您提出的关于使用二进制格式和 JSONB 的观点非常有道理。您说得没错,与二进制格式相比,JSON 在系统性能方面没有那么优化,这一点很多开发人员都意识到了。 在我们撰写的这篇文章中,我们主要关注的是 JSON,因为 99% 的金融数据提供商(尤其是在外汇领域)都使用这种标准进行数据交换,而且许多平台和服务都以这种格式提供数据。因此,我们没有涉及其他标准。 再次感谢您分享您的观点并指出这一重要细节。 Sara Sabaghi 2025.01.17 22:56 #15 Edgar Akhmadeev #:当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某些原因,提供的不是二进制数据,而是文本数据 ))))遗憾的是,我们无法改变这一事实。 是的,我完全理解。此外,我们必须使用这一标准,因为几乎所有的金融数据提供商都使用这种方法。 Ney Borges 2025.01.21 12:35 #16 你好,就是它了,所以我的要求是让我把它发布到 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&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 2025.01.13www.mql5.com Trader's profile Edgar Akhmadeev 2025.01.21 13:18 #17 Ney Borges #: 如果有必要, 您可以使用 JAson.mqh 库,它可以在我们同伴的原始代码中 找到。 谷歌翻译器的工作方式真可怕。 没有 JAson 库,它当然就无法工作。 该库不在他的代码中,而是在这里,作者已经说明了这一点。 JSON Serialization and Deserialization (native MQL) www.mql5.com Сериализация и десериализация JSON протокола. Портированный код со скоростной библиотеки С++. Ney Borges 2025.01.21 19:24 #18 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&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&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" 2025.01.17Edgar Akhmadeevwww.mql5.com Check out the new article: Using JSON Data API in your MQL projects . Author: Sara Sabaghi... Sara Sabaghi 2025.01.21 20:33 #19 Ney Borges #:我对 MQL5 的代码进行了一些修改,希望您能核实并返回,谢谢 -Sara Sabaghi 你好,伙计 感谢您分享代码。是的,我测试过了。运行正常 fxsaber 2025.01.22 15:58 #20 Nikolai Semko #:转为二进制。现在相同数据的大小为1.2 Mb。 解析为所需的结构数组现在需要5 毫秒。 这对你来说有点太多了。这里 需要 12 毫秒,但数据是 80 Mb。 123 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某种原因,它们提供的不是二进制数据,而是文本数据 ))))
遗憾的是,我们无法改变这一事实。
当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某些原因,提供的不是二进制数据,而是文本数据 ))))
遗憾的是,我们无法改变这一事实。
因为他们需要兼容性。
本文介绍 API 及其使用方法。您知道可以为您提供二元外汇数据的 API 吗?那就介绍一下吧。
下一点,你批评说,量子计算机速度更快,为什么还要用普通计算机玩《FIFA2024》?答案很简单,我不需要那样的处理能力。
因此,对这一论点的回答是,API 在这一领域交换的大部分数据都在几兆字节范围内,不需要速度。此外,所有外汇数据提供商都使用 XML、JSON 等标准...
我并不反对使用 JSON。我自己也使用 JSON,但仅限于开发阶段,因为你总能在 PostMan 或 WireShark 中看到可读的响应。
非常感谢您抽出时间与我们分享您的想法。我完全理解您的观点,您提出的关于使用二进制格式和 JSONB 的观点非常有道理。您说得没错,与二进制格式相比,JSON 在系统性能方面没有那么优化,这一点很多开发人员都意识到了。
在我们撰写的这篇文章中,我们主要关注的是 JSON,因为 99% 的金融数据提供商(尤其是在外汇领域)都使用这种标准进行数据交换,而且许多平台和服务都以这种格式提供数据。因此,我们没有涉及其他标准。
再次感谢您分享您的观点并指出这一重要细节。
当然,这不是对您提出的要求,而是对内容提供商提出的要求。由于某些原因,提供的不是二进制数据,而是文本数据 ))))
遗憾的是,我们无法改变这一事实。
是的,我完全理解。此外,我们必须使用这一标准,因为几乎所有的金融数据提供商都使用这种方法。
MQL5 METATRADER 5 版本 我对代码进行了修改,使其可以在 Metatrader 5 中运行。为了更好地适应当前的商业环境,我还对代码进行了修改。所有改动都是为了使代码适应 Metatrader 5。它是实用的。只需下载此文件并运行即可。如有必要,可使用 JAson.mqh 库,该库可在我们同伴的原始代码中找到。我叫 Ney Borges。我来自巴西戈亚斯州的卡尔达斯诺瓦斯市,在巴西的森林之中。在没有人帮助的情况下独自学习是非常困难的,但在社区里我学到了很多。谢谢你们
MQL5 METATRADER 5 版本 我修改了代码,使其可以在 Metatrader 5 中运行。为了更好地适应当前的商业环境,我还对代码进行了修改。所有改动都是为了使代码适应 Metatrader 5。它是实用的。只需下载此文件并运行即可。如有必要,可使用 JAson.mqh 库,该库可在我们同伴的原始代码中找到。我叫 Ney Borges。我来自巴西戈亚斯州的卡尔达斯诺瓦斯市,在巴西的森林之中。在没有人帮助的情况下独自学习是非常困难的,但在社区里我学到了很多。谢谢你们
巴西 - 戈亚斯州 - 卡尔达斯诺瓦斯 - 内伊-博尔赫斯
如果有必要, 您可以使用 JAson.mqh 库,它可以在我们同伴的原始代码中 找到。
谷歌翻译器的工作方式真可怕。
没有 JAson 库,它当然就无法工作。
该库不在他的代码中,而是在这里,作者已经说明了这一点。
是的,我完全理解。此外,我们必须使用这一标准,因为几乎所有的财务数据提供商都使用这种方法。
你好,就是这个,所以我的要求是让我把它发布到 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
我对 MQL5 的代码进行了一些修改,希望您能核实并返回,谢谢 -Sara Sabaghi
你好,伙计
感谢您分享代码。是的,我测试过了。运行正常
转为二进制。现在相同数据的大小为1.2 Mb。 解析为所需的结构数组现在需要5 毫秒。
这对你来说有点太多了。这里 需要 12 毫秒,但数据是 80 Mb。