1 个不稳定版本
0.1.1 | 2024 年 3 月 29 日 |
---|
第 72 位 金融
210KB
3.5K SLoC
XTB-Client
XTB-Client 库提供了对 XTB 证券商 API 的类型化和简单易用的连接器实现。
- 编程风格: 异步
- 框架: tokio
- XTB API 版本: 2.5
- 请求/响应 API: 支持
- 流 API: 支持
警告
此库仍在开发中。库 API 可能会更改,代码中可能存在一些错误。
如何使用
XTB 接口由实现 XtbApi
和 XtbStreamApi
特性的 XtbClient
结构体提供。可以通过 XtbClientBuilder
结构体创建该结构体,并在创建时自动连接到服务器并执行 login
命令。如果两者都成功,则返回 XtbClient
实例。
配置
XtbClient
由 XtbClientBuilder
配置。构建器有三个初始化方法
new(api_url: &str, stream_api_url: &str)
- 创建具有自定义 URL 的新实例。new_real()
- 创建具有预设真实账户服务器的实例。new_demo()
- 创建具有预设演示账户服务器的实例。new_bare()
- 创建没有设置任何值的实例。
可以使用前缀为 with_
的设置器(选项平铺到底层类型)和未前缀的获取器来覆盖以下属性
api_url: Option<String>
- 请求/响应 API 服务器的 URL。stream_api_url: Option<String>
- 流 API 服务器的 URL。app_id: Option<String>
- 可选的应用程序 ID(官方文档中已标记为过时)。app_name: Option<String>
- 可选的应用程序名称(官方文档中已标记为过时)。ping_period: Option<u64>
- ping 请求之间的时间间隔(默认为 30 秒)
当配置了构建器实例时,可以调用 build
方法。该方法接受两个 &str
参数:用户名和密码。
当调用该方法时,会创建服务器连接,用户登录,并启动 ping tokio 绿色线程。
use xtb_client::XtbClientBuilder;
#[tokio::main]
fn main() {
let real_builder = XtbClientBuilder::new_real();
let demo_builder = XtbClientBuilder::new_demo();
let custom_builder = XtbClientBuilder::new("wss://my-server.com/api", "wss://my-server.com/apiStream").with_ping_period(20u64);
let bare_builder = XtbClientBuilder::new_bare().with_api_url("wss://my-server.com/api").with_stream_api_url("wss://my-server.com/apiStream");
let client = custom_builder.build("12345", "reallySecretPassword");
}
请求/响应 API
与服务器通信的最简单方法是请求/响应 API。此 API 总是对请求返回一个响应。
方法名称与命令名称转换为 snake_case 相对应。示例
getAllSymbols
->get_all_symbols
getCalendar
->get_calendar
getVersion
->get_version
一些命令在特质的公共接口中没有实现
login
- 由XtbClient
创建过程自动执行logout
- 当XtbClient
实例被丢弃时自动执行ping
- 由XtbClient
实例每 30 秒定期执行(可以配置)
流 API
流 API 通过 DataStream
结构传递的消息流向消费者提供数据。当 DataStream
实例被丢弃时,订阅会自动取消。
流 API 实现使用内部订阅计数器,因此如果有两个订阅者订阅了相同的信息(例如 USDEUR 的 tick 价格),第一个订阅者的取消订阅不会切断第二个订阅者与信息的连接。
方法名称与命令名称转换为 snake_case 相对应,并使用 subscribe_
前缀代替 get_
前缀。示例
getCandles
->subscribe_candles
getTrades
->subscribe_trades
getProfits
->subscribe_profits
一些命令在特质的公共接口中没有实现
ping
- 由XtbClient
实例每 30 秒定期执行(可以配置)
低级接口
库还公开了低级连接。
请求/响应连接
XtbConnection
特质及其实现者 BasicXtbConnection
为请求-响应命令提供了对 XTB 服务器的低级连接。
该特性提供了send_command
方法。此方法接受命令名称(例如getNews
)和用作命令参数的有效负载。如果没有参数,则传递None
。
调用方法后,将返回ResponsePromise
结构体实例。它是可等待的,可以返回来自服务器的响应。如果命令成功,结果为Ok(Response)
;如果命令失败,则结果为Err(ErrorResponse)
。
流连接
XtbStreamConnection
特性和其实现者BasicStreamConnection
提供了对XTB流服务器的低级连接,用于数据流。
该特性提供了subscribe
、unsubscribe
和make_message_stream
方法。
subscribe
方法接受命令名称和可选参数作为参数。参数必须是None
或Some(serde_json::Value::Null)
,用于无参数的命令,以及Some(serde_json::Value::Object)
,用于带参数的命令。当命令发送成功时,服务器应流式传输请求的数据。
unsubscribe
方法与subscribe
类似,但其效果是停止数据流。
make_message_stream
为从XTB服务器传递的消息创建本地订阅。它接受DataMessageFilter
枚举作为参数,并使用它通过给定的谓词过滤传入的消息。可用的过滤器如下
Always
(默认)- 将所有消息传递给消费者Never
- 不传递任何消息给消费者Command(String)
- 根据从服务器接收到的数据消息的command
字段过滤消息FieldValue { name: String, value: serde_json::Value }
- 根据从服务器接收到的数据消息的data
字段的字段名过滤消息。如果data
包含类型为serde_json::Value::Object
的对象,并且该对象具有名为name
的键,且该字段包含与value
相同的值,则过滤器匹配。Custom(Box<dyn Fn(&StreamDataMessage) -> bool + Send + Sync>)
- 自定义过滤器函数All(Vec<DataMessageFilter>)
- 用于存储零个、一个或多个谓词的容器。当且仅当所有谓词匹配时匹配。如果谓词列表为空,则返回true
。Any(Vec<DataMessageFilter>)
- 用于存储零个、一个或多个谓词的容器。如果任何谓词匹配则匹配。如果谓词列表为空,则返回false
。
注意:尚未实现 Not
,但可以使用 Custom
变体来创建它。
make_message_stream
返回 MessageStream
特质的实现。此特质提供了返回匹配过滤器的传入消息的 next()
方法。
示例
示例 1
简单 API 调用来获取所有可用的符号。
use tracing::Level;
use xtb_client::RequestResponseApi;
use xtb_client::schema::GetAllSymbolsRequest;
#[tokio::main]
async fn main() {
dotenvy::dotenv().unwrap_or_default();
let subscriber = tracing_subscriber::fmt().with_max_level(Level::DEBUG).finish();
tracing::subscriber::set_global_default(subscriber).unwrap();
let username = dotenvy::var("XTB_USERNAME").unwrap();
let password = dotenvy::var("XTB_PASSWORD").unwrap();
let api_server = dotenvy::var("XTB_API_SERVER").unwrap();
let stream_server = dotenvy::var("XTB_STREAM_SERVER").unwrap();
let mut client = xtb_client::XtbClientBuilder::new(&api_server, &stream_server).build(&username, &password).await.unwrap();
let symbols = client.get_all_symbols(GetAllSymbolsRequest::default()).await.unwrap();
println!("{}", serde_json::to_string_pretty(&symbols).unwrap())
}
示例 2
订阅 keppAlive
消息。
use tracing::Level;
use xtb_client::{StreamApi};
use xtb_client::schema::{StreamGetKeepAliveSubscribe};
#[tokio::main]
async fn main() {
dotenvy::dotenv().unwrap_or_default();
let subscriber = tracing_subscriber::fmt().with_max_level(Level::DEBUG).finish();
tracing::subscriber::set_global_default(subscriber).unwrap();
let username = dotenvy::var("XTB_USERNAME").unwrap();
let password = dotenvy::var("XTB_PASSWORD").unwrap();
let api_server = dotenvy::var("XTB_API_SERVER").unwrap();
let stream_server = dotenvy::var("XTB_STREAM_SERVER").unwrap();
let mut client = xtb_client::XtbClientBuilder::new(&api_server, &stream_server).build(&username, &password).await.unwrap();
let mut listener = client.subscribe_keep_alive(StreamGetKeepAliveSubscribe::default()).await.unwrap();
while let Some(item) = listener.next().await.unwrap() {
println!("Keep alive received: {}", item.timestamp);
}
println!("Stream closed");
}
TODO
该库处于开发状态(版本号以 0 开头),直到以下步骤完成。
- tests - 缺少主要功能的测试
- dummy implementations - 创建连接和客户端特质的示例实现。这些实现可用于测试或演示示例。
- 未知的枚举变体 - 值为
104
的MarginMode
变体和值为 5 和 6 的QuoteId
变体在官方文档中没有提及。在库稳定之前必须知道这些变体的含义。
请买我一杯 咖啡 啤酒
如果您喜欢这个库,或者您想支持其开发,请通过一杯冰冷的 啤酒 支持我。啤酒味道很好,富含维生素 :-)
依赖项
~7–17MB
~235K SLoC