C#实战:如何通过API获取实时外汇API数据?完整教程与代码解析。从零开始,用C#对接外汇行情接口(WebSocket + RESTful)
从零开始,用C#对接外汇API行情接口(WebSocket + RESTful)
引言
对于C#开发者而言,无论是开发外汇分析软件、量化交易系统,还是为应用程序添加实时汇率功能,首要解决的都是如何稳定、高效地获取外汇行情数据。本文将以一个真实的API接口为例,手把手带您完成在C#环境中对接实时外汇数据流与历史K线数据的全过程。我们将涵盖WebSocket实时推送和HttpClient请求K线接口两大核心场景,并提供关键的代码示例。
一、 准备工作:环境与授权
-
获取API权限:
-
行情地址:
http://39.107.99.235:1008/market(用于查询外汇产品代码,如fx_eurusd)
-
-
创建C#项目:
创建一个新的.NET Console应用程序。本文将使用.NET 6+的顶级语句风格,但代码同样适用于其他版本的.NET Framework/Core。 -
引入NuGet包:
我们需要两个重要的NuGet包来简化开发。通过Visual Studio的NuGet包管理器或使用CLI命令安装:
dotnet add package Newtonsoft.Json二、 实战一:使用WebSocket获取实时外汇行情
实时数据是交易和即时分析的生命线。以下是实现的核心步骤。
步骤1:建立WebSocket连接并发送心跳
using System; using System.Net.WebSockets; using System.Text; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json.Linq; // 为保持连接稳定,通常会将WebSocket客户端封装在一个长期运行的后台服务中。 class Program { private static ClientWebSocket _webSocket = new ClientWebSocket(); private static readonly Uri _serverUri = new Uri("ws://39.107.99.235/ws"); private static readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); static async Task Main(string[] args) { await ConnectAndListen(); } static async Task ConnectAndListen() { try { // 1. 建立连接 await _webSocket.ConnectAsync(_serverUri, _cancellationTokenSource.Token); Console.WriteLine("WebSocket连接已建立。"); // 2. 启动后台任务发送心跳 _ = Task.Run(async () => await SendHeartbeat(_cancellationTokenSource.Token)); // 3. 订阅外汇产品 (例如:欧元美元、英镑美元) string subscribeMessage = "{\"Key\":\"fx_eurusd,fx_gbpusd\"}"; byte[] subscribeBytes = Encoding.UTF8.GetBytes(subscribeMessage); await _webSocket.SendAsync(new ArraySegment<byte>(subscribeBytes), WebSocketMessageType.Text, true, _cancellationTokenSource.Token); Console.WriteLine($"已发送订阅请求: {subscribeMessage}"); // 4. 启动监听循环,持续接收消息 await StartListening(); } catch (Exception ex) { Console.WriteLine($"发生错误: {ex.Message}"); // 在实际应用中,应在此实现重连逻辑。 } } static async Task SendHeartbeat(CancellationToken token) { while (!token.IsCancellationRequested) { try { // 每隔10秒发送一次心跳 await Task.Delay(10000, token); long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); string heartbeatMessage = $"{{\"ping\":{timestamp}}}"; byte[] heartbeatBytes = Encoding.UTF8.GetBytes(heartbeatMessage); if (_webSocket.State == WebSocketState.Open) { await _webSocket.SendAsync(new ArraySegment<byte>(heartbeatBytes), WebSocketMessageType.Text, true, token); Console.WriteLine($"心跳已发送: {heartbeatMessage}"); } } catch (TaskCanceledException) { break; } } } }步骤2:监听并解析实时数据
将下面的
StartListening方法添加到上述代码中。static async Task StartListening() { byte[] buffer = new byte[4096]; while (_webSocket.State == WebSocketState.Open) { try { var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cancellationTokenSource.Token); if (result.MessageType == WebSocketMessageType.Text) { string receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count); // Console.WriteLine($"收到原始消息: {receivedMessage}"); // 调试用 // 解析JSON消息 ProcessReceivedMessage(receivedMessage); } else if (result.MessageType == WebSocketMessageType.Close) { await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); Console.WriteLine("WebSocket连接已关闭。"); } } catch (Exception ex) { Console.WriteLine($"接收消息时出错: {ex.Message}"); break; } } } static void ProcessReceivedMessage(string jsonMessage) { try { JObject messageObj = JObject.Parse(jsonMessage); // 处理心跳响应 if (messageObj["pong"] != null) { Console.WriteLine($"收到心跳响应: pong - {messageObj["pong"]}"); return; } // 处理行情数据 if (messageObj["body"] != null) { var body = messageObj["body"]; string stockCode = body["StockCode"]?.ToString(); decimal price = body["Price"]?.ToObject<decimal>() ?? 0; Console.WriteLine($"产品: {stockCode}, 最新价: {price}"); // 您可以在这里进一步解析其他字段,如买一价(body["BP1"]), 卖一价(body["SP1"]), 五档深度(body["Depth"])等。 // 并将数据更新到UI或触发交易逻辑。 } } catch (Exception ex) { Console.WriteLine($"解析消息失败: {ex.Message}, 原始消息: {jsonMessage}"); } }三、 实战二:使用HttpClient获取外汇K线历史数据
对于回测或初始化图表,获取历史K线数据至关重要。
using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json.Linq; class HistoricalDataFetcher { private static readonly HttpClient _httpClient = new HttpClient(); static async Task Main(string[] args) // 如果这是独立程序,保留Main方法 { await GetKLineData(); } // 作为一个可调用方法 public static async Task GetKLineData() { try { // 1. 构建请求URL string baseUrl = "http://39.107.99.235:1008/redis.php"; string code = "fx_eurusd"; // 外汇产品代码 string time = "5m"; // 5分钟K线 int rows = 100; // 获取100条 string requestUrl = $"{baseUrl}?code={code}&time={time}&rows={rows}"; // 2. 添加GZIP压缩支持,提升性能 _httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip"); // 3. 发送GET请求 HttpResponseMessage response = await _httpClient.GetAsync(requestUrl); response.EnsureSuccessStatusCode(); // 确保响应成功 // 4. 读取并解析响应内容 string responseContent = await response.Content.ReadAsStringAsync(); JArray klineArray = JArray.Parse(responseContent); Console.WriteLine($"成功获取到 {klineArray.Count} 条K线数据:"); foreach (JArray kline in klineArray) { // 解析数组,格式为:[毫秒时间戳, 开盘价, 最高价, 最低价, 收盘价, 时间字符串, 成交量] long timestamp = (long)kline[0]; decimal open = (decimal)kline[1]; decimal high = (decimal)kline[2]; decimal low = (decimal)kline[3]; decimal close = (decimal)kline[4]; string timeStr = (string)kline[5]; // 注意:外汇数据成交量可能为0或空,请以实际接口返回为准 // decimal volume = (decimal)kline[6]; Console.WriteLine($"时间:{timeStr}, 开:{open}, 高:{high}, 低:{low}, 收:{close}"); } } catch (HttpRequestException ex) { Console.WriteLine($"HTTP请求失败: {ex.Message}"); if (ex.StatusCode.HasValue) { Console.WriteLine($"状态码: {ex.StatusCode}"); } } catch (Exception ex) { Console.WriteLine($"获取K线数据时发生错误: {ex.Message}"); } } }四、 关键注意事项与最佳实践
-
错误处理与重连:生产环境中,必须为WebSocket连接实现完善的断线重连机制,例如在
catch块或关闭事件中延迟后重新调用ConnectAndListen。 -
性能与频率限制:
-
考虑使用单例模式的
HttpClient,而不是每次请求都创建新的实例。
-
-
数据解析安全:始终使用
try-catch包裹JSON解析逻辑,并使用类似?.的安全导航操作符,以防API返回的数据结构意外变化。 -
后台服务化:对于需要长期运行的WebSocket客户端,应将其封装在BackgroundService(在ASP.NET Core中)或Windows Service中。
-
结语
通过本教程,您已经掌握了在C#中使用ClientWebSocket和HttpClient对接外汇行情API的核心技能。从建立实时推送到获取历史数据,这套代码框架可以作为您金融数据项目的坚实起点。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)