首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >贵金属行情API的调用方法

贵金属行情API的调用方法

原创
作者头像
Always_Somewhere
修改2025-09-12 11:34:59
修改2025-09-12 11:34:59
1260
举报

在本文中,我们将通过C++接入Infoway API的贵金属实时行情数据接口,帮助你获取黄金和白银等贵金属的K线数据。我们会使用 libcurl 库进行HTTP请求,并处理API返回的数据。

一、API请求地址

贵金属的实时行情通过如下API获取:

代码语言:txt
复制
https://data.infoway.io/common/batch_kline/{klineType}/{klineNum}/{codes}

入参说明:

{klineType} 是K线的时间周期,传入不同的值代表不同周期的K线:

ID

K线周期

1

1分钟k线

2

5分钟k线

3

15分钟k线

4

30分钟k线

5

1小时k线

6

2小时k线

7

4小时k线

8

1日k线

9

1周k线

10

1月k线

11

1季k线

12

1年k线

{klineNum} 是需要的K线数量,这个接口支持能查询最近的500根K线。

{codes} 是资产代码,比如黄金是XAUUSD

二、代码示例

假设我们需要查询黄金和白银的1分钟K线,请求地址是:

代码语言:txt
复制
https://data.infoway.io/common/batch_kline/1/2/XAUUSD%2CXAGUSD
// 这个地址能返回黄金和白银最近的2根1分钟K线

完整代码如下:

代码语言:txt
复制
#include <iostream>
#include <string>
#include <curl/curl.h>

// 回调函数,用来接收HTTP响应的数据
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* out) {
    size_t total_size = size * nmemb;
    out->append((char*)contents, total_size);
    return total_size;
}

int main() {
    CURL* curl;
    CURLcode res;
    
    // 设置 API URL 和请求头
    // 申请API Key: www.infoway.io
    const std::string api_url = "https://data.infoway.io/common/batch_kline/1/2/XAUUSD%2CXAGUSD";
    
    // 初始化 libcurl
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    
    if (curl) {
        // 设置 URL
        curl_easy_setopt(curl, CURLOPT_URL, api_url.c_str());
        
        // 设置请求头
        struct curl_slist* headers = NULL;
        headers = curl_slist_append(headers, "User-Agent: Mozilla/5.0");
        headers = curl_slist_append(headers, "Accept: application/json");
        headers = curl_slist_append(headers, "apiKey: yourApikey");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        
        // 存储响应结果
        std::string response_string;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
        
        // 发送 GET 请求
        res = curl_easy_perform(curl);
        
        if (res != CURLE_OK) {
            std::cerr << "Curl request failed: " << curl_easy_strerror(res) << std::endl;
        } else {
            // 输出 HTTP 状态码
            long http_code = 0;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
            std::cout << "HTTP code: " << http_code << std::endl;
            std::cout << "Message: " << response_string << std::endl;
        }
        
        // 清理请求头
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }
    
    // 清理 libcurl
    curl_global_cleanup();
    
    return 0;
}

三、返回示例

代码语言:txt
复制
{
  "ret": 200,
  "msg": "success",
  "traceId": "43fe7163-abb2-4a59-b6b2-2af4dc8c4141",
  "data": [
    {
      "s": "XAUUSD",
      "respList": [
        {
          "t": "1750177320",
          "h": "1950.07400",
          "o": "1949.17600",
          "l": "1948.17600",
          "c": "1950.07400",
          "v": "15.0",
          "vw": "1950.7220",
          "pc": "0.12%",
          "pca": "2.78600"
        },
        {
          "t": "1750177260",
          "h": "1949.41400",
          "o": "1948.28800",
          "l": "1948.28800",
          "c": "1949.41400",
          "v": "10.0",
          "vw": "1949.1220",
          "pc": "0.03%",
          "pca": "0.52400"
        }
      ]
    },
    {
      "s": "XAGUSD",
      "respList": [
        {
          "t": "1750177320",
          "h": "25.07400",
          "o": "25.17600",
          "l": "25.17600",
          "c": "25.07400",
          "v": "30.0",
          "vw": "25.7220",
          "pc": "0.10%",
          "pca": "0.78600"
        },
        {
          "t": "1750177260",
          "h": "25.01400",
          "o": "25.04800",
          "l": "25.04800",
          "c": "25.01400",
          "v": "20.0",
          "vw": "25.3220",
          "pc": "0.02%",
          "pca": "0.52400"
        }
      ]
    }
  ]
}

字段说明:

返回的字段包含周期内的高开低收数据,比如我们查询的是1分钟K线,那么返回的数据就是1分钟内的高开低收。

字段名

类型

必填

描述

示例值

t

String

成交时间

1747382898892

h

String

最高价

18.01

o

String

开盘价

18.01

l

String

最低价

18.01

c

String

收盘价

18.01

v

String

成交量

18000

vm

String

成交额

20000

pc

String

涨跌幅

0.12%

pca

String

涨跌额

0.11

常见问题

1. 如何优化 libcurl 请求以处理高频 K 线数据(如 1 分钟 K 线)在高并发场景下的性能?

在高频 K 线数据请求场景下,建议以下优化措施:

连接复用:使用 curl_easy_init()curl_easy_cleanup() 创建的 CURL 句柄可以通过设置 CURLOPT_TCP_KEEPALIVECURLOPT_KEEPALIVE 启用 TCP 连接复用,减少每次请求的连接建立开销。

示例代码:

代码语言:txt
复制
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(curl, CURLOPT_KEEPALIVE_TIME, 60L);

异步请求:对于高并发场景,建议使用 libcurl 的多接口(multi interface)结合 curl_multi_perform 实现异步请求,允许多个请求并行处理。

批量请求:将多个资产代码(如 XAUUSD、XAGUSD)合并到单次请求中,减少 API 调用次数,降低服务器压力。

错误重试机制:实现指数退避重试策略,处理因网络波动或 API 限频导致的失败(如 HTTP 429 错误)。可以使用 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code) 检查状态码并设置重试逻辑。

2. API 返回的成交时间(t)字段是 Unix 时间戳,如何确保时间戳与本地时区的同步?

API 返回的 t 字段为 Unix 时间戳。为确保与本地时区同步:

时间戳单位:t 是毫秒(如 1747382898892),需除以 1000 转换为秒。

使用 C++ 的 chrono 库或 gmtime/localtime 函数将时间戳转换为本地时间。例如:

代码语言:txt
复制
#include <chrono>
#include <iomanip>
#include <sstream>

std::string timestampToLocalTime(const std::string& timestamp) {
    auto ts = std::stoll(timestamp) / 1000; // 假设毫秒
    auto time = std::chrono::system_clock::from_time_t(ts);
    auto local_time = std::chrono::system_clock::to_time_t(time);
    std::stringstream ss;
    ss << std::put_time(std::localtime(&local_time), "%Y-%m-%d %H:%M:%S");
    return ss.str();
}
3. 如何处理 API 返回数据中可能出现的缺失 K 线(如非交易时段的空数据)?

贵金属市场(如 XAUUSD)在周末或节假日可能存在非交易时段,导致 K 线数据缺失。处理方式包括:

预检查时间范围:在请求前,排除非交易时段(如周六、周日或特定市场假期)。可通过查询 API 文档或历史数据确定交易时间窗口。

数据补全逻辑:对于缺失的 K 线,可用前一根 K 线的收盘价c补全缺失数据的 ohlc 字段,设置成交量 v 为 0。示例:

代码语言:txt
复制
if (kline_data.empty()) {
    // 假设 last_kline 是前一根 K 线数据
    kline_data.o = last_kline.c;
    kline_data.h = last_kline.c;
    kline_data.l = last_kline.c;
    kline_data.c = last_kline.c;
    kline_data.v = "0";
}

WebSocket 订阅:相比 HTTP 轮询,WebSocket 可实时检测市场状态变化,减少对空数据的处理需求。参考 Infoway API 官网的 WebSocket 文档。

4. 如何在多线程环境中安全地复用 libcurl 句柄以提高吞吐量?

libcurl 本身是线程安全的,但需注意以下事项:

每个线程独立句柄:为每个线程创建独立的 CURL* 句柄,避免共享同一句柄导致竞争条件。不要在多线程间共享 curl_easy_init() 返回的句柄。

全局初始化线程安全:调用 curl_global_init(CURL_GLOBAL_ALL) 时确保只调用一次,通常在程序启动时完成,且使用互斥锁保护:

代码语言:txt
复制
#include <mutex>
static std::once_flag curl_init_flag;
std::call_once(curl_init_flag, []() { curl_global_init(CURL_GLOBAL_ALL); });

连接池管理:使用 libcurl 的 curl_share_init创建共享对象,共享 DNS 缓存、连接池等资源,减少开销。示例:

代码语言:txt
复制
CURLSH* share = curl_share_init();
curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_easy_setopt(curl, CURLOPT_SHARE, share);

清理资源:确保每个线程在完成请求后调用 curl_easy_cleanup,程序退出时调用 curl_global_cleanup

5. API 返回的成交量(v)和成交额(vm)字段如何用于计算市场活跃度?

成交量v和成交额vm可用于分析市场活跃度和流动性:

成交量加权价格(VWAP):通过 vw 字段(成交量加权平均价)直接获取周期内的 VWAP,或手动计算:VWAP = vm / v。VWAP 可用于评估市场价格趋势的稳定性。

活跃度指标:比较多周期的成交量(如 1 分钟 vs. 5 分钟 K 线),若短周期成交量激增,可能表示市场短期活跃或突发事件。

异常检测:设置阈值(如 v 超过历史均值的 2 倍标准差),检测异常交易活动。示例:

代码语言:txt
复制
double calculateActivity(const std::string& volume, double avg_volume, double stddev_volume) {
    double v = std::stod(volume);
    return (v - avg_volume) / stddev_volume; // Z 分数
}
6. 如何通过 WebSocket 订阅降低延迟并处理断线重连?

WebSocket 订阅可显著降低数据获取延迟,适合实时交易场景:

订阅实现:参考 API 官网 WebSocket 文档,使用库如 libwebsocketcpprestsdk 建立连接,订阅特定资产和 K 线类型(如 wss://data.infoway.io/ws/kline/1/XAUUSD)。

断线重连:实现心跳机制(如每 30 秒发送 PING 消息),检测连接状态。若断线,设置指数退避重试(初始 1 秒,最大 60 秒)。示例:

代码语言:txt
复制
void reconnectWebSocket() {
    int retry_delay = 1;
    while (!connect()) {
        std::this_thread::sleep_for(std::chrono::seconds(retry_delay));
        retry_delay = std::min(retry_delay * 2, 60); // 指数退避
    }
}

数据一致性:断线后重新订阅时,需通过 HTTP API 拉取断线期间的 K 线数据,合并到本地数据流,确保数据连续性。

更多详细接入步骤,可以参考Github

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、API请求地址
  • 二、代码示例
  • 三、返回示例
    • 字段说明:
  • 常见问题
    • 1. 如何优化 libcurl 请求以处理高频 K 线数据(如 1 分钟 K 线)在高并发场景下的性能?
    • 2. API 返回的成交时间(t)字段是 Unix 时间戳,如何确保时间戳与本地时区的同步?
    • 3. 如何处理 API 返回数据中可能出现的缺失 K 线(如非交易时段的空数据)?
    • 4. 如何在多线程环境中安全地复用 libcurl 句柄以提高吞吐量?
    • 5. API 返回的成交量(v)和成交额(vm)字段如何用于计算市场活跃度?
    • 6. 如何通过 WebSocket 订阅降低延迟并处理断线重连?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档