实时推送

Rust SDK 通过 PushClient 提供基于 WebSocket 的实时推送服务,支持行情推送和账户推送,内置自动重连和心跳保活机制。Rust SDK 使用 PushClientOptions 结构体配置回调,并通过 add_subscription / add_account_sub 管理订阅。以下为完整可运行示例:

use tigeropen::config::ClientConfig;
use tigeropen::push::{PushClient, PushClientOptions, SubjectType};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ClientConfig::from_properties_file("tiger_openapi_config.properties")?;

    // 配置回调函数
    let options = PushClientOptions {
        on_connect: Some(Box::new(|| {
            println!("[推送] 连接成功");
        })),
        on_disconnect: Some(Box::new(|| {
            println!("[推送] 连接断开,等待自动重连...");
        })),
        on_error: Some(Box::new(|err| {
            eprintln!("[推送] 发生错误: {:?}", err);
        })),
        on_quote: Some(Box::new(|data| {
            println!("[行情] {} 最新价: {}", data.symbol, data.latest_price);
        })),
        on_tick: Some(Box::new(|data| {
            println!("[逐笔] {} 成交价: {} 数量: {}", data.symbol, data.price, data.volume);
        })),
        on_order: Some(Box::new(|data| {
            println!("[订单] {} 状态变更: {}", data.symbol, data.status);
        })),
        on_asset: Some(Box::new(|_data| {
            println!("[资产] 账户资产变动");
        })),
        on_position: Some(Box::new(|data| {
            println!("[持仓] {} 数量变更", data.symbol);
        })),
        on_transaction: Some(Box::new(|data| {
            println!("[成交] {} 成交价: {}", data.symbol, data.filled_price);
        })),
        ..Default::default()
    };

    let mut client = PushClient::new(config.clone(), Some(options));

    // 订阅行情
    client.add_subscription(SubjectType::Quote, &["AAPL".to_string(), "TSLA".to_string()]);
    client.add_subscription(SubjectType::Tick, &["AAPL".to_string()]);

    // 订阅账户推送
    client.add_account_sub(SubjectType::Asset);
    client.add_account_sub(SubjectType::Order);
    client.add_account_sub(SubjectType::Position);
    client.add_account_sub(SubjectType::Transaction);

    // 启动推送(阻塞直到断开)
    client.connect().await?;

    Ok(())
}

初始化

PushClient::new 创建推送客户端

PushClient::new(config: ClientConfig, options: Option<PushClientOptions>) -> PushClient

说明

创建 PushClient 实例,通过 PushClientOptions 配置所有回调和客户端行为。

参数

参数名类型是否必填描述
configClientConfig客户端配置对象
optionsOption<PushClientOptions>推送选项,包含所有回调函数配置

示例

let config = ClientConfig::from_properties_file("tiger_openapi_config.properties")?;
let client = PushClient::new(config, None);

PushClientOptions 回调配置

PushClientOptions 结构体用于配置所有推送回调,所有字段均为 Option 类型:

字段类型描述
on_connectOption<Box<dyn Fn() + Send + Sync>>连接成功时触发
on_disconnectOption<Box<dyn Fn() + Send + Sync>>连接断开时触发
on_errorOption<Box<dyn Fn(TigerError) + Send + Sync>>发生错误时触发
on_kickoutOption<Box<dyn Fn(String) + Send + Sync>>账户被踢出时触发
on_quoteOption<Box<dyn Fn(QuoteData) + Send + Sync>>收到行情推送时触发
on_tickOption<Box<dyn Fn(TickData) + Send + Sync>>收到逐笔成交时触发
on_depthOption<Box<dyn Fn(DepthData) + Send + Sync>>收到深度行情更新时触发
on_optionOption<Box<dyn Fn(OptionData) + Send + Sync>>收到期权行情推送时触发
on_futureOption<Box<dyn Fn(FutureData) + Send + Sync>>收到期货行情推送时触发
on_klineOption<Box<dyn Fn(KlineData) + Send + Sync>>收到 K 线数据推送时触发
on_assetOption<Box<dyn Fn(AssetData) + Send + Sync>>收到账户资产变动时触发
on_positionOption<Box<dyn Fn(PositionData) + Send + Sync>>收到持仓变动时触发
on_orderOption<Box<dyn Fn(OrderData) + Send + Sync>>收到订单状态变更时触发
on_transactionOption<Box<dyn Fn(TransactionData) + Send + Sync>>收到成交明细时触发

示例

let options = PushClientOptions {
    on_connect: Some(Box::new(|| println!("连接成功"))),
    on_quote: Some(Box::new(|data| {
        println!("{}: {}", data.symbol, data.latest_price);
    })),
    ..Default::default()
};

连接管理

connect 连接推送服务

client.connect() -> Result<(), TigerError>

说明

建立 WebSocket 连接并启动推送接收循环。此方法会阻塞直到连接断开。通常应在单独的 tokio 任务中调用,或作为主循环运行。

自动重连机制

当网络中断时,SDK 会自动尝试重连,重连成功后会自动恢复之前的订阅。每次断开和重连成功时分别触发 on_disconnecton_connect 回调。

示例

// 在后台任务中运行
let handle = tokio::spawn(async move {
    if let Err(e) = client.connect().await {
        eprintln!("推送连接错误: {:?}", e);
    }
});

// 等待一段时间后可以取消
// handle.abort();

行情推送订阅

add_subscription 添加行情订阅

client.add_subscription(subject: SubjectType, symbols: &[String])

说明

添加行情类型的订阅。Rust SDK 使用统一的 add_subscription 方法替代 Go/TypeScript 中各独立的 subscribe* 方法。需在调用 connect 之前完成订阅配置。

参数

参数名类型描述
subjectSubjectType订阅类型,见下方枚举值
symbols&[String]标的代码切片

SubjectType 行情类型枚举值:

描述
SubjectType::Quote实时行情
SubjectType::Tick逐笔成交
SubjectType::Depth深度行情
SubjectType::Option期权行情
SubjectType::Future期货行情
SubjectType::KlineK 线数据

示例

// 订阅股票行情
client.add_subscription(SubjectType::Quote, &[
    "AAPL".to_string(),
    "TSLA".to_string(),
]);

// 订阅逐笔成交
client.add_subscription(SubjectType::Tick, &["AAPL".to_string()]);

// 订阅深度行情
client.add_subscription(SubjectType::Depth, &["AAPL".to_string()]);

// 订阅期权行情(注意双空格格式)
client.add_subscription(SubjectType::Option, &[
    "AAPL  250117C00150000".to_string(),
]);

// 订阅期货行情
client.add_subscription(SubjectType::Future, &[
    "ES2506".to_string(),
    "NQ2506".to_string(),
]);

// 订阅 K 线
client.add_subscription(SubjectType::Kline, &["AAPL".to_string()]);

remove_subscription 移除行情订阅

client.remove_subscription(subject: SubjectType, symbols: &[String])

说明

移除指定标的的行情订阅。

参数

参数名类型描述
subjectSubjectType订阅类型
symbols&[String]要退订的标的代码切片

示例

// 退订 TSLA 的行情
client.remove_subscription(SubjectType::Quote, &["TSLA".to_string()]);

账户推送订阅

add_account_sub 添加账户订阅

client.add_account_sub(subject: SubjectType)

说明

添加账户类推送订阅(资产、持仓、订单、成交明细)。账户推送无需指定标的,直接按账户推送。

参数

参数名类型描述
subjectSubjectType账户订阅类型,见下方枚举值

SubjectType 账户类型枚举值:

描述
SubjectType::Asset账户资产变动
SubjectType::Position持仓变动
SubjectType::Order订单状态变更
SubjectType::Transaction成交明细

示例

// 订阅所有账户推送类型
client.add_account_sub(SubjectType::Asset);
client.add_account_sub(SubjectType::Position);
client.add_account_sub(SubjectType::Order);
client.add_account_sub(SubjectType::Transaction);

remove_account_sub 移除账户订阅

client.remove_account_sub(subject: SubjectType)

说明

移除指定类型的账户推送订阅。

参数

参数名类型描述
subjectSubjectType要移除的账户订阅类型

示例

// 取消订阅持仓变动
client.remove_account_sub(SubjectType::Position);

完整示例(带并发处理)

以下示例展示如何使用 Rust 的并发特性,在推送连接运行的同时执行其他操作:

use tigeropen::config::ClientConfig;
use tigeropen::push::{PushClient, PushClientOptions, SubjectType};
use std::sync::Arc;
use tokio::sync::Mutex;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ClientConfig::from_properties_file("tiger_openapi_config.properties")?;

    let options = PushClientOptions {
        on_connect: Some(Box::new(|| println!("[推送] 已连接"))),
        on_quote: Some(Box::new(|data| {
            println!("[行情] {}: {:.2} ({:+.2}%)",
                data.symbol, data.latest_price, data.change_percentage);
        })),
        on_order: Some(Box::new(|data| {
            println!("[订单] id={} {} {} 状态: {}",
                data.order_id, data.symbol, data.action, data.status);
        })),
        ..Default::default()
    };

    let mut client = PushClient::new(config, Some(options));

    // 配置订阅
    client.add_subscription(SubjectType::Quote, &[
        "AAPL".to_string(), "TSLA".to_string(), "MSFT".to_string(),
    ]);
    client.add_account_sub(SubjectType::Order);
    client.add_account_sub(SubjectType::Asset);

    println!("推送服务启动中...");

    // 启动推送(阻塞当前线程)
    client.connect().await?;

    Ok(())
}