
开发具有 RestAPI 集成的 MQL5 强化学习代理(第 1 部分):如何在 MQL5 中使用 RestAPI
概述
在编程和系统开发中,不同应用程序之间的通信至关重要。API(Application Programming Interfaces,应用程序编程接口)在这种情况下发挥着重要作用,因为它们允许系统有效地通信和交换数据。在本文中,我们将专门讨论 RestAPI,它改变了系统在 Web 上交互的方式。
RestAPI(Representational State Transfer Application Programming Interface,表述性状态转移应用程序编程接口)是一组定义系统如何在互联网上通信的规则。它基于简单且可扩展的体系结构原则,并使用资源和标识符等概念来管理数据。实际上,它是一种通信方法,允许应用程序以有组织的方式请求和发送信息。
REST 体系结构出现在21世纪初,这要归功于 Roy Fielding 的一篇文章,该文章概述了构建可靠和可扩展的 web 系统的原则。从那时起,RestAPI 就广受欢迎。这是因为与 SOAP(Simple Object Access Protocol,简单对象访问协议)等早期协议相比,它们非常简单。
基于 XML 的 SOAP 非常流行,但众所周知它很复杂,并且需要大量数据才能进行简单的事务处理。RestAPI 已成为系统到系统通信的一种更简单、更通用的替代方案,从而极大地改变了游戏规则。
RestAPI 是通用的,广泛用于各种系统和应用程序。它的简单性和对 REST 原则的遵守允许创建可扩展、可集成且易于维护的系统。它们被广泛应用于各个行业,包括金融领域。
如果将它们与 SOAP 协议进行比较,就会清楚地知道为什么 RestAPI 会占据强势地位。SOAP 不灵活且繁琐,而 RestAPI 轻量、易于使用,是需要高效通信的现代系统的理想选择。此外,它们几乎可以用任何编程语言实现,是世界各地开发人员的理想选择。
什么是 API?
在日益数字化的世界中,“API”一词被广泛使用,但它到底是什么意思呢?缩写“API”代表“Application Programming Interface(应用程序编程接口)”。它是软件开发和系统集成的一个基本概念。
本质上,API 是一组允许不同软件之间相互通信的规则和协议。它充当桥梁的作用,允许一个程序使用另一个程序的功能,而无需了解该程序的所有内部细节。API 对于构建应用程序至关重要,因为它们允许开发人员使用第三方资源甚至内部系统。
让我们探索一下 API 的主要方面:
1.应用程序之间的通信:
API 最重要的功能之一是促进不同应用程序或系统之间的通信。想象一下,您正在开发一个天气预报应用程序,并希望在其中包含实时天气预报。您可以使用现有天气服务的API,而不是从头开始构建整个天气预报系统。API 将提供一套指令和方法,您的应用可以使用它们来请求最新的天气数据。
2.复杂性的抽象:
API 允许您抽象系统的底层复杂性。这意味着当使用 API 时,您不需要了解与之交互的系统或服务的所有技术细节。您只需要知道如何使用 API。这使得开发更加高效,并允许开发人员专注于他们的任务,而不是每次都重新发明轮子。
3.API 类型:
如上所述,API 有几种类型。Web API 在互联网上被广泛使用,并且基于 HTTP 等网络协议。本地 API 提供对操作系统或中间件资源的访问。程序 API 用于访问远程程序组件。有几种技术和标准来实现它们,例如 gRPC 和 REST。RESTful API 遵循 REST 原则,而 SOAP API 是基于 XML 的,而且更为复杂。例如,GraphQL API 因其允许客户端查询特定数据的灵活性而闻名。
4.现实世界的例子:
让我们看一些现实世界中的例子来了解 API 是如何使用的。Facebook 或 Twitter 等社交网络提供 API,允许开发人员将内容共享或身份验证功能集成到自己的应用程序中。PayPal 等支付服务提供支持金融交易的 API。甚至一些地图服务,例如 Google 地图,也有允许将交互式地图包含在应用程序中的 API。
5.安全和身份验证:
API 通常包含安全机制,以确保只有授权的应用程序才能访问资源。这可能包括 API 密钥生成、令牌身份验证或其他敏感数据保护方法。
什么是 RestAPI?
在我们进入 RestAPI 的世界之前,软件系统通常通过更严格、更复杂的协议进行通信。系统之间的通信不太顺畅,这使得不同应用程序之间的信息交换成为一项具有挑战性的任务。
然后是 REST 时代,它带来了一种革命性的系统间通信方法。REST 代表 Representational State Transfer(表述性状态转移), 由 Roy Fielding 于 2000 年首次提出。这种创新的软件架构方法成为了 RestAPI 的基础。REST 定义了一组指导系统如何交互的原则,包括使用 URL(Uniform Resource Locators,统一资源定位器)来识别资源和使用 HTTP 方法与它们交互。 RestAPI 在数字时代的应用程序和系统通信方式中发挥着重要作用。它们允许一个系统从另一个系统请求信息或操作,从而使数据交换和操作更加高效和灵活。
让我们考虑一个简单的例子。假设您在我们的智能手机上使用天气预报应用程序。此应用程序应向您显示当前位置的温度和天气状况的最新信息。然而,它并不是单独生成这些信息,而是从远程服务器接收这些信息,该服务器从各种来源收集天气信息。
这就是 RestAPI 有用的地方。当我们打开天气应用程序时,它会通过 RestAPI 向远程服务器发送请求。此请求通常是 GET 请求,查询您所在位置的天气状况信息。服务器处理请求并生成一个响应,通常采用JSON或XML格式,其中包含所请求的天气数据。然后,应用程序使用这些数据将其显示在适当的界面中。RestAPI 的强大之处在于交互的标准化。系统可以可靠地通信:换句话说,它们知道如果遵循 REST 原则,信息将以可靠的方式传输。
使用示例:
在社交媒体应用中,当您将照片上传到您最喜欢的社交平台时,RestAPI 会负责将数据传输到服务器,然后让其他用户可以使用该照片。这种交互基于 RestAPI 的请求和响应。
API 和 REST API 之间的主要区别
API 通过提供现成的代码和信息渠道来简化许多应用程序的集成过程,以帮助开发人员构建强大的数字解决方案。API 充当应用程序之间的中介,促进它们之间的交互。但是,由于应用程序架构不同,API 可以是不同类型的,例如编程式 API、本地 API、Web API 或 REST API。
API 使得连接计算机或计算机程序成为可能。基本上,它是一个软件接口,为其他程序提供服务以增强必要的功能。近年来,API 在市场上越来越受欢迎,因为几乎所有的 Web 应用程序都在使用它们。例如,每当您在智能手机上查看天气或预订旅行票时,API 都会在后台调用。
因为 API 允许公司向外部第三方开发人员开放其应用程序的数据和功能,这最终会产生商业合作伙伴关系,从而增加收入。
API 类型
Web API
- 基于 Web 的架构,基本遵循 REST 风格。
- 通过 HTTP 协议进行通信。
- 它可用于通过互联网提供资源和服务。
本地 API
- 用于访问本地服务或系统资源的特定体系结构。
- 它可以提供对操作系统或中间件资源的访问。
- 它可能适用于不同的操作系统,并不局限于特定的平台。
- 基于远程过程调用(RPC)技术,包括 gRPC、JSON-RPC 等变体。
- 它允许像访问本地软件组件一样访问远程软件组件,从而使分布式系统之间的通信更为方便。
- 实现程序 API 的技术和标准多种多样。
- 基于 REST 原则的 RESTful 架构,包括资源、HTTP方法、数据表示。
- 它使用标准 HTTP 方法(GET、POST、PUT、DELETE)对资源执行操作。
- 通常以 JSON 或 XML 格式返回数据。
- 基于XML并遵循简单对象访问协议(SOAP)。
- 提供具有高级功能(如安全和事务)的高度合规服务。
- 比 RESTful API 更复杂。
GraphQL API
- 使用灵活的查询语言,允许客户端只请求它们需要的数据。
- 它允许客户端指定所需响应的结构,使其在现代应用程序中广受欢迎。
- 它不一定遵循 RESTful 或 SOAP 架构,并且在查询方面更加灵活。
协议和 API 架构
-
XML-RPC:该协议是为了在两个或多个网络之间交换信息而创建的。客户端使用 XML 对其调用和数据传输的 HTTP 请求进行编码,从而执行RPC。
-
JSON-RPC:一种轻量级的 JSON 编码 RPC,类似于 XML-RPC,允许多个通知和服务器调用,并可以异步响应。
-
SOAP:一种用于交换结构化信息的 Web API 协议。它使用 XML 在操作系统上运行的进程之间进行身份验证、授权和通信。由于 HTTP 等 Web 协议在大多数操作系统上运行,SOAP 允许客户端调用 Web 服务并接收响应,而不管所使用的语言和平台如何。
-
REST:一种在互联网上系统之间提供标准的架构风格。因为它不是一个协议、库或工具,所以它使系统之间的通信变得简单。REST 架构使得客户端和服务端的实现各自独立,不影响彼此的功能。
了解 API 的必要性
-
自动化 加速API测试,从而提高效率。API不仅将数字世界与其动态联系起来,还使公司能够通过自动化工作流程变得更加敏捷。
-
可以通过 API 实现平台和应用程序的集成 ,让您能够享受持续通信的优势。如果没有 API,公司就缺乏连接,从而相应降低生产力和效能。系统集成允许您移动数据,使您更容易实现工作流程自动化并改进工作中的协作。
-
随着人为干预的减少,效率 也随之提高。提供对 API 的访问避免了内容的重复,为公司提供了更大的灵活性,使它们能够将时间花在质量创新上。
-
安全性 是一个额外的好处,因为 API 在您的数据和服务器之间增加了一层额外的安全保护。开发人员可以使用令牌、签名和传输层安全性 (TLS) 加密进一步增强安全性。
REST API 概述:
REST API 是一种软件架构模型,它建立了互联网上应用程序和服务之间交互的规则和标准。当 API 严格遵循 REST 架构原则时,它通常被称为 RESTful API。
RESTful API 的主要优点之一是其访问 Web 服务的灵活方法。这是因为它们使用标准 HTTP 协议和方法(例如 GET、POST、PUT 和 DELETE)来对 URL 所表示的资源执行操作。这种简单的设计使得与 Web 服务的交互更加容易,即使在计算资源有限的设备或环境中也是如此。
REST 架构
-
非平稳性:在 REST 范式中运行的系统必须是非平稳的。在客户端和服务器之间通信时,无状态限制使得服务器不受客户端状态的影响,反之亦然。使用资源而不是命令来应用约束。它们是网络名词,描述可以存储/发送到其他资源的任何对象、文档或事物。
-
缓存兼容性。缓存有助于服务器减轻与非静态相关的一些限制。这是提高现代 Web 应用程序性能的关键因素。缓存不仅可以提高客户端的性能,还可以为服务器端带来显著的效益。运行良好的缓存机制将能显著减少我们服务器的平均响应时间。
-
分布式特性。REST 使用分布式方法,其中客户端和服务器应用程序彼此分离。无论请求在何处发起,客户端应用程序所知道的唯一信息是所请求资源的 URI(统一资源标识符)。服务器应用程序应该通过 HTTP 传输请求的数据,但不应尝试修改客户端应用程序。
-
多层次。多层体系使得 REST 架构具有可扩展性。在 RESTful 架构中,客户端和服务器应用程序是分离的,因此 REST API 调用和响应会经过不同的层次。由于 REST API 是多层的,因此它的设计必须确保客户端和服务器都不会识别它们与终端或中间应用程序的交互。
REST API 的主要优点
-
REST API 可以灵活地响应不同类型的调用,例如,返回不同的数据格式,并随着超媒体的正确实现在结构上发生变化。这使得用户可以与客户端和服务器进行双向交互,即使它们位于不同的服务器上。
-
REST API 可适应对数据库中存储的数据所做的任何更改,即使它们位于不同的内部和外部服务器上。由于它在某种程度上依赖于代码,因此它有助于跨不同站点同步数据。
-
数据流使用 HTTP(GET、POST、PUT 或 DELETE)方法进行通信,这些方法是不言自明的。此外,REST 架构允许开发人员在客户端显示信息并在服务器端存储或操作数据,从而有助于提高开发人员的工作效率。
API vs REST API
-
结构。虽然大多数 API 在结构上遵循应用程序到应用程序的格式,但 REST API 严格遵循基于 Web 的客户端和服务器概念。客户端与服务器相互分离,提供了更大的灵活性。
-
设计。API 通常是为有限的设备设计的轻量级架构。相比之下,REST API 在单个系统级别进行交互,这使得其架构更加复杂。
-
协议。API 的主要目的是标准化 Web 服务之间的数据交换,根据 API 的类型,协议的选择会有所不同。另一方面,REST API 是一种用于创建通过 HTTP 进行通信的 Web 服务的架构风格。尽管 REST API 早在 2000 年就由计算机科学家 Roy Fielding 制定,但它仍然是公共 API 的黄金标准。
-
支持。大多数 API 都很容易实现,因为它们不面临无状态问题。反过来,即使用户不知道按特定顺序排列的函数和参数的名称,REST API 也会执行。
-
统一接口。没有多少 API 将客户端和服务器或一个应用程序与另一个应用程序分开。REST API 遵守单一接口的原则,禁止在一个 API 内使用多个或单独的接口。理想情况下,应该使用超媒体连接来分发单一接口。这还应确保类似的数据(例如用户名或电子邮件)只属于一个 URI。因此,无论初始请求是什么,针对相同资源的所有API请求都必须显示为相同。
-
可扩展性。虽然可扩展性是通用 API 的一个问题,但 REST API 具有分层结构,这使其模块化且更灵活地实现可扩展性。
例子:在 MQL5 中使用 WebRequest 函数
现在我们已经进入了 API 和 REST API 的世界,您可能会好奇:“MQL5 与这个故事有什么关系?”因此,现在是我们撸起袖子开始使用 MQL5 中实际示例的时候了。毕竟,没有什么比一个好的实际例子更好的了。
为了使示例更加完整和有趣,我们将与 jsonplaceholder.typicode.com 合作。我们还将从 Coinbase 添加一些端点。
这个想法很简单:让我们从使用 jsonplaceholder 进行基本的 CRUD 操作(C-创建、R-读取、U-更新、D-删除)开始,因为它对于理解基础知识和进行测试非常有用。但随后我们会将其提升到更高的水平,并将这些知识应用到 Coinbase API 更复杂、更具挑战性的场景中。它拥有一切:报价、历史数据甚至进入交易世界的能力。这完全取决于我们访问哪些端点。
让我们从 CRUD 操作开始。
新内容 - POST
int CreateNewPost(string title, string body, int userId) { uchar result[]; string result_headers; string url = "https://jsonplaceholder.typicode.com/posts"; char post_data[]; StringToCharArray(StringFormat("{\"title\": \"%s\", \"body\": \"%s\", \"userId\": %d}", title, body, userId), post_data); string headers = "Content-Type: application/json\r\n"; int timeout = 5000; int res = WebRequest("POST", url, headers, timeout, post_data, result, result_headers); if(res > 0) { Print("Post created successfully."); } else { Print("Error: Failed to create post."); } return -1; }
更新内容 - PUT
bool UpdatePost(int postId, string newTitle, string newBody) { uchar result[]; string result_headers; string url = StringFormat("https://jsonplaceholder.typicode.com/posts/%d", postId); char put_data[]; // Declare post_data as char[] StringToCharArray(StringFormat("{\"title\": \"%s\", \"body\": \"%s\"}", newTitle, newBody), put_data); string headers = "Content-Type: application/json\r\n"; // Declare headers as char[] int timeout = 5000; int res = WebRequest("PUT", url, headers, timeout, put_data, result, result_headers); if(res > 0) { Print("Post updated successfully."); return true; } else { Print("Error: Failed to update post."); return false; } }
删除内容 - DELETE
bool DeletePost(int postId) { char data[]; uchar result[]; string result_headers; string url = StringFormat("https://jsonplaceholder.typicode.com/posts/%d", postId); int timeout = 5000; int res = WebRequest("DELETE", url, NULL, timeout, data, result, result_headers); if(res > 0) { Print("Post deleted successfully."); return true; } else { Print("Error: Failed to delete post."); return false; } }
获取内容 - GET
string GetPostById(int postId) { char data[]; uchar result[]; string result_headers; string url = StringFormat("https://jsonplaceholder.typicode.com/posts/%d", postId); int timeout = 5000; int res = WebRequest("GET", url, NULL, timeout, data, result, result_headers); if(res > 0) { CJAVal jv; if(jv.Deserialize(result)) { string postTitle = jv["title"].ToStr(); Print("Post title: ", postTitle); return postTitle; } else { Print("Error: Unable to parse the response."); } } else { Print("Error: Failed to fetch post."); } return ""; }
现在,想象一下您想查看比特币的当前价格(谁不想呢?)。除了一般价格外,您可能还对 BTC 的买入价(bid)、卖出价(ask)和现货价格(spot price)感兴趣。为了通过 API 获取此信息,我们将使用 MQL5 中的 WebRequest 函数:
string GetBitcoinPrice(string priceType) { char data[]; uchar result[]; string result_headers; string baseURL = "https://api.coinbase.com/v2/prices/"; if(priceType == "buy") baseURL += "buy"; else if(priceType == "sell") baseURL += "sell"; else baseURL += "spot"; string url = baseURL + "?currency=USD"; char headers[]; int timeout = 5000; int res; Print("Fetching Bitcoin price for type: ", priceType); res = WebRequest("GET", url, NULL, NULL, timeout, data, 0, result, result_headers); string price = ""; if(res > 0) { Print("Response received from Coinbase API"); CJAVal jv; if(jv.Deserialize(result)) { price = jv["data"]["amount"].ToStr(); Print("Price fetched: ", price); } else { Print("Error: Unable to parse the response."); } } else { Print("Error: No response from Coinbase API or an error occurred."); } return price; }
我们还可以列出所有货币。
string GetAvailableCurrencies() { char data[]; uchar result[]; string result_headers; string url = "https://api.coinbase.com/v2/currencies"; char headers[]; int timeout = 5000; int res; Print("Fetching list of available currencies from Coinbase API"); res = WebRequest("GET", url, NULL, NULL, timeout, data, 0, result, result_headers); string currencies = ""; if(res > 0) { Print("Response received from Coinbase API"); CJAVal jv; if(jv.Deserialize(result)) { // Considerando que a resposta é uma lista de moedas for(int i = 0; i < jv["data"].Size(); i++) { currencies += "Currency: " + jv["data"][i]["id"].ToStr(); currencies += ", Name: " + jv["data"][i]["name"].ToStr(); currencies += ", Min Size: " + jv["data"][i]["min_size"].ToStr(); currencies += "\n"; } Print(currencies); } else { Print("Error: Unable to parse the response."); } } else { Print("Error: No response from Coinbase API or an error occurred."); } return currencies; }
现在我们已经看到了所有创建好的函数,让我们运行它们并查看结果。
#include "libraries/RESTFunctions.mqh" int OnStart() { //--- CRUD Operations on Posts ---// // 1. Create a new post int userId = 1; // exemplo de userID, você pode ajustar conforme necessário string title = "Exemplo de Título"; string body = "Este é o conteúdo do post para demonstração."; int newPostId = CreateNewPost(title, body, userId); if(newPostId != -1) Print("New Post ID: ", newPostId); // 2. Update the created post string updatedTitle = "Título Atualizado"; string updatedBody = "Conteúdo do post atualizado."; if(UpdatePost(newPostId, updatedTitle, updatedBody)) Print("Post atualizado com sucesso."); // 3. Get the updated post string fetchedTitle = GetPostById(newPostId); if(StringLen(fetchedTitle) > 0) Print("Título do Post Obtido: ", fetchedTitle); // 4. Delete the post if(DeletePost(newPostId)) Print("Post excluído com sucesso."); //--- Coinbase Operations ---// const string buyPrice = GetBitcoinPrice("buy"); const string sellPrice = GetBitcoinPrice("sell"); const string spotPrice = GetBitcoinPrice("spot"); Print("Buy Price: ", buyPrice); Print("Sell Price: ", sellPrice); Print("Spot Price: ", spotPrice); const string currencies = GetAvailableCurrencies(); Print("Available Currencies: ", currencies); //--- return(INIT_SUCCEEDED); }
因此,我们将看到以下内容:
结论:
简而言之,API 在编程和系统开发领域发挥着重要作用,因为它们允许不同的应用程序和系统高效而灵活地相互通信。基于 REST 架构的 RestAPI 已经成为一种流行的选择,因为与 SOAP 等旧协议相比,它们提供了更大的简单性和多功能性。它们被广泛应用于金融等各个领域,因为它们能够创建可扩展、集成且易于维护的系统。
需要 API 来促进不同应用程序之间的通信、抽象底层复杂性并允许开发人员利用第三方资源。API 有 Web API、本地、编程、RESTful、SOAP、GraphQL 等几种类型,每种都有自己的特点和用途。
反过来,REST API 遵循一组架构原则,使其灵活、适应性强且易于理解。REST API 特别适合Web通信,它使用 HTTP 协议对资源进行操作,并经常以 JSON 或 XML 格式返回数据。
如果我们将 API 与 REST API 进行比较,我们会注意到 REST API 具有更严格的结构,将客户端与服务器分开,并且主要在 Web 环境中运行。两者都遵循单一界面,并通过多层次结构提高可扩展性。
最后,通过将这些概念应用到使用 MQL5 的实际示例中,我们可以了解 API 在现实世界中的使用方式,从基本的 CRUD 操作到使用 Coinbase API 读取金融数据。
好吧,伙计们,我们关于 API、REST、MQL5 和其他一切的讨论已经结束了。请注意,这里所说的一切都是我的专业眼光的结果:始终关注细节 - 因为您永远不知道什么时候会突然出现错误!
重要的是要记住,在技术世界中,事情会很快发生变化,因此掌握最新趋势和更新总是一个好主意。当然,检查一下一切是否正常工作也无妨。
我希望本次对话对您有用并且具有指导意义。别忘了,即使有了所有的技术,在编程的世界里,好奇心总是会有很大的帮助。
现在,我希望您能够探索 API 的威力,创建自己的集成,并开发出令人惊叹的系统。请记住,如果事情没有按计划进行,不要担心——这就是我们获取经验的方式。
如果您有任何进一步的问题或需要帮助,请随时与我联系,我愿意尽我所能来帮助你。
回头见,朋友们!
本文由MetaQuotes Ltd译自葡萄牙语
原文地址: https://www.mql5.com/pt/articles/13661



