C语言如何高效获取股票实时数据?
摘要:
核心思路无论使用哪种方法,核心思路都是:选择一个数据源:免费的(如 Alpha Vantage, Yahoo Finance)、付费的(如 Bloomberg, Reuters)或... 核心思路
无论使用哪种方法,核心思路都是:
- 选择一个数据源:免费的(如 Alpha Vantage, Yahoo Finance)、付费的(如 Bloomberg, Reuters)或自建的行情服务器。
- 选择一个网络库:用于在 C 程序中发送 HTTP 请求或建立 WebSocket 连接。
- 解析返回的数据:数据通常是 JSON 或 CSV 格式,需要用相应的解析库来提取你需要的信息(如股票代码、价格、成交量等)。
使用 cURL + JSON-C (推荐,最通用)
这种方法非常适合从 REST API 获取数据,cURL 是一个强大的命令行工具和库,用于传输数据;JSON-C 是一个用于解析 JSON 数据的 C 语言库。
步骤 1: 安装必要的库
在 Linux (如 Ubuntu/Debian) 上:
sudo apt-get update sudo apt-get install libcurl4-openssl-dev libjson-c-dev
在 macOS (使用 Homebrew) 上:
brew install curl json-c
步骤 2: 编写 C 代码
我们将使用 Alpha Vantage 的免费 API 作为数据源,你需要先在 Alpha Vantage 注册一个免费的 API Key。
get_stock_price.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <json-c/json.h>
// 用于存储从 cURL 接收到的数据的结构体
struct MemoryStruct {
char *memory;
size_t size;
};
// cURL 的回调函数,用于接收数据
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
if(!ptr) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
mem->memory = ptr;
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
int main(void)
{
CURL *curl;
CURLcode res;
// 替换成你自己的 Alpha Vantage API Key
const char *api_key = "YOUR_API_KEY";
const char *symbol = "IBM";
char url[256];
// 构建请求 URL
snprintf(url, sizeof(url), "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=%s&apikey=%s", symbol, api_key);
struct MemoryStruct chunk;
chunk.memory = malloc(1); // 会有 realloc 来扩展
chunk.size = 0;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // 设置超时为10秒
// 执行请求
res = curl_easy_perform(curl);
// 检查错误
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
// 解析 JSON 数据
struct json_object *parsed_json;
struct json_object *json_price;
struct json_object *json_symbol;
struct json_object *json_timestamp;
parsed_json = json_tokener_parse(chunk.memory);
if (parsed_json != NULL) {
// 获取 "Global Quote" 对象
struct json_object *global_quote;
if (json_object_object_get_ex(parsed_json, "Global Quote", &global_quote)) {
// 从 "Global Quote" 中提取字段
if (json_object_object_get_ex(global_quote, "05. price", &json_price) &&
json_object_object_get_ex(global_quote, "01. symbol", &json_symbol) &&
json_object_object_get_ex(global_quote, "07. latest trading day", &json_timestamp)) {
printf("股票代码: %s\n", json_object_get_string(json_symbol));
printf("当前价格: %s\n", json_object_get_string(json_price));
printf("最新交易日: %s\n", json_object_get_string(json_timestamp));
} else {
fprintf(stderr, "无法从 JSON 中找到所需字段,\n");
// 检查是否是 API 错误
struct json_object *json_error;
if (json_object_object_get_ex(parsed_json, "Error Message", &json_error)) {
fprintf(stderr, "API 错误: %s\n", json_object_get_string(json_error));
}
}
} else {
fprintf(stderr, "JSON 中未找到 'Global Quote' 对象,\n");
}
json_object_put(parsed_json); // 释放 JSON 对象
} else {
fprintf(stderr, "JSON 解析失败,\n");
}
}
// 清理
curl_easy_cleanup(curl);
}
free(chunk.memory);
curl_global_cleanup();
return 0;
}
步骤 3: 编译和运行
# 编译时需要链接 cURL 和 JSON-C 库 gcc get_stock_price.c -o get_stock_price -lcurl -ljson-c # 运行程序 (记得替换 YOUR_API_KEY) ./get_stock_price
输出示例:
股票代码: IBM
当前价格: 152.55
最新交易日: 2025-10-27
使用 WebSocket 实现实时推送 (更高级)
对于真正的“实时”数据,轮询 API(如方法一)会有延迟,更好的方式是使用 WebSocket,服务器会在数据更新时主动推送给你,这比客户端不断请求要高效得多。
我们将使用 libwebsockets 库。
步骤 1: 安装 libwebsockets
在 Linux (Ubuntu/Debian) 上:
sudo apt-get install libwebsockets-dev
步骤 2: 编写 C 代码
注意: 免费的 WebSocket 数据源较少且不稳定,这里我们以一个示例性的场景进行演示,实际使用时需要找到可靠的股票 WebSocket 服务。
realtime_stock_ws.c
#include <libwebsockets.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 自定义协议结构体
struct session_data {
int count;
};
// 回调函数,处理 WebSocket 事件
static callback_function(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
struct session_data *data = (struct session_data *)user;
char buf[256];
int n;
switch (reason) {
case LWS_CALLBACK_ESTABLISHED:
// 连接建立
printf("连接到服务器成功!\n");
data->count = 0;
// 可以在这里发送订阅消息
// n = sprintf(buf, "subscribe{\"symbol\":\"AAPL\"}");
// lws_write(wsi, buf, n, LWS_WRITE_TEXT);
break;
case LWS_CALLBACK_RECEIVE:
// 接收到数据
printf("收到数据 (%zu bytes): %.*s\n", len, (int)len, (char *)in);
// 这里可以添加 JSON 解析逻辑来处理实时数据
// 使用 json-c 解析 in 指向的数据
break;
case LWS_CALLBACK_CLOSED:
// 连接关闭
printf("连接已关闭,\n");
break;
default:
break;
}
return 0;
}
// 定义协议
static const struct lws_protocols protocols[] = {
{
"stock-protocol", // 协议名称
callback_function, // 回调函数
sizeof(struct session_data), // 每个会话的大小
},
{ NULL, NULL, 0, 0 } // 结束标记
};
int main(void) {
struct lws_context *context;
struct lws_client *client;
const char *address = "wss://api.example.com/stocks"; // 替换为真实的 WebSocket 地址
int port = 443;
const char *path = "/";
const char *host = address;
const char *origin = "http://localhost";
// 创建 WebSocket 上下文
context = lws_create_context(0, NULL, protocols, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL);
if (!context) {
fprintf(stderr, "lws_create_context failed\n");
return 1;
}
// 创建客户端连接
client = lws_client_connect_via_info(context, address, port, path, host, origin, protocols[0].name, NULL);
if (!client) {
fprintf(stderr, "lws_client_connect_via_info failed\n");
return 1;
}
// 主循环
while (1) {
lws_service(context, 50); // 50ms 超时
// 在这里可以添加其他逻辑,比如定时重连等
}
// 清理
lws_context_destroy(context);
return 0;
}
步骤 3: 编译和运行
# 编译时需要链接 libwebsockets gcc realtime_stock_ws.c -o realtime_stock_ws -lwebsockets # 运行 ./realtime_stock_ws
使用专门的金融数据库 API (如 TWS/IB)
如果你是专业交易者,可能会使用 Interactive Brokers (IB) 的 Trader Workstation (TWS) 或 Gateway,他们提供了 C++ API,但可以通过封装或特定方式在 C 中使用。
特点:
- 极低延迟:专为高频交易设计。
- 功能强大:可以获取几乎所有金融产品的实时数据、下单、管理账户等。
- 复杂度高:需要理解 IB 的协议和 API,设置也相对复杂。
基本流程:
- 下载并安装 TWS 或 IB Gateway。
- 启动它们并启用 API 连接(在设置中配置端口)。
- 在 C 程序中使用 IB 提供的 C++ SDK(需要 C++ 编译器)或通过 socket 编程模拟其协议进行连接,这超出了简单教程的范围,但是一个非常重要的专业方向。
总结与对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| cURL + JSON-C | 简单、通用、易于实现、资料多 | 有延迟(轮询)、非真正的实时 | 学习、个人项目、非高频数据需求 |
| WebSocket | 真正的实时、高效、低延迟 | 找到免费稳定的源较难、库学习曲线稍陡 | 需要实时数据的应用、监控仪表盘 |
| TWS/IB API | 极低延迟、功能全面、专业 | 非常复杂、需要付费账户、设置繁琐 | 专业交易、算法交易、高频交易 |
给初学者的建议: 从 方法一 (cURL + JSON-C) 开始,它能让你完整地走通“获取网络数据 -> 解析数据 -> 使用数据”的整个流程,是学习 C 语言网络编程和数据处理的最佳起点,当你对实时性有更高要求时,再转向 方法二 (WebSocket)。
作者:咔咔本文地址:https://www.jits.cn/content/19904.html发布于 2025-12-04
文章转载或复制请以超链接形式并注明出处杰思科技・AI 股讯



还没有评论,来说两句吧...