Skip to content

tigerfintech/openapi-rust-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tiger OpenAPI Rust SDK

Rust SDK for Tiger Brokers OpenAPI. Provides market data queries, order execution, account management, and real-time push notifications.

Crates.io License: MIT

Installation

Add to your Cargo.toml:

[dependencies]
tigeropen = "0.1.0"
tokio = { version = "1", features = ["full"] }

Requires Rust 1.70 or later.

Quick Start

use tigeropen::config::ClientConfig;
use tigeropen::client::http_client::HttpClient;
use tigeropen::quote::QuoteClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Load config from properties file
    let config = ClientConfig::builder()
        .properties_file("tiger_openapi_config.properties")
        .build()?;

    // 2. Create HTTP client
    let http = HttpClient::new(config);

    // 3. Query market data
    let qc = QuoteClient::new(&http);
    let states = qc.market_state("US").await?;
    println!("US market state: {:?}", states);

    Ok(())
}

Configuration

The SDK supports multiple configuration methods. Priority: environment variables > builder setters (incl. properties file) > auto-discovered config file > defaults.

Method 1: Properties File

The most common approach. Create a tiger_openapi_config.properties file:

tiger_id=your_developer_id
private_key=your_rsa_private_key
account=your_trading_account

Load it explicitly:

let config = ClientConfig::builder()
    .properties_file("tiger_openapi_config.properties")
    .build()?;

Method 2: Auto-Discovery

If you call build() without setting tiger_id or private_key, the builder automatically searches for a config file in this order:

  1. ./tiger_openapi_config.properties (current directory)
  2. ~/.tigeropen/tiger_openapi_config.properties (home directory)

This means you can simply do:

let config = ClientConfig::builder().build()?; // auto-discovers config

Place your config file at ~/.tigeropen/tiger_openapi_config.properties and it will be picked up automatically across all your projects.

Method 3: Builder

Set values programmatically:

let config = ClientConfig::builder()
    .tiger_id("your_developer_id")
    .private_key("your_rsa_private_key")
    .account("your_trading_account")
    .build()?;

Method 4: Environment Variables

export TIGEROPEN_TIGER_ID=your_developer_id
export TIGEROPEN_PRIVATE_KEY=your_rsa_private_key
export TIGEROPEN_ACCOUNT=your_trading_account

Environment variables have the highest priority and override all other methods.

Configuration Reference

Field Description Required Default
tiger_id Developer ID Yes -
private_key RSA private key Yes -
account Trading account No -
language Language (ZhCn/EnUs) No ZhCn
timeout Request timeout No 15s

Market Data

use tigeropen::client::http_client::HttpClient;
use tigeropen::quote::QuoteClient;

let http = HttpClient::new(config);
let qc = QuoteClient::new(&http);

// Market state
let states = qc.market_state("US").await?;

// Real-time quotes
let quotes = qc.quote_real_time(&["AAPL", "TSLA"]).await?;

// K-line data
let klines = qc.kline("AAPL", "day").await?;

// Timeline
let timeline = qc.timeline(&["AAPL"]).await?;

// Depth quotes
let depth = qc.quote_depth("AAPL").await?;

// Option expiration dates
let expiry = qc.option_expiration("AAPL").await?;

// Option chain
let chain = qc.option_chain("AAPL", "2024-01-19").await?;

// Futures exchange list
let exchanges = qc.future_exchange().await?;

Trading

use tigeropen::client::http_client::HttpClient;
use tigeropen::trade::TradeClient;
use serde_json::json;

let http = HttpClient::new(config);
let tc = TradeClient::new(&http, "your_account");

// Place a limit order
let order = json!({
    "symbol": "AAPL",
    "secType": "STK",
    "action": "BUY",
    "orderType": "LMT",
    "totalQuantity": 100,
    "limitPrice": 150.0,
    "timeInForce": "DAY",
});
let result = tc.place_order(order).await?;

// Preview order (no actual execution)
let preview = tc.preview_order(order).await?;

// Modify order
tc.modify_order(order_id, json!({"limitPrice": 155.0})).await?;

// Cancel order
tc.cancel_order(order_id).await?;

// Query orders, positions, assets
let orders = tc.orders().await?;
let positions = tc.positions().await?;
let assets = tc.assets().await?;

Generic API Call (execute)

When the SDK hasn't wrapped a specific API yet, use HttpClient::execute directly:

let http = HttpClient::new(config);
let resp = http.execute("market_state", r#"{"market":"US"}"#).await?;
println!("Raw response: {}", resp);

Real-Time Push

The push client uses a TCP + TLS + Protobuf persistent connection for real-time market data and account notifications. It supports automatic reconnection and heartbeat keep-alive.

Callback parameters use Protobuf-generated types (pb::QuoteData, pb::OrderStatusData, pb::AssetData, etc.).

use std::sync::Arc;
use tigeropen::config::ClientConfig;
use tigeropen::push::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ClientConfig::builder().build()?; // auto-discovers config
    let account = config.account.clone();

    let pc = Arc::new(PushClient::new(config, None));

    // Set callbacks (parameters are pb::* Protobuf types)
    pc.set_callbacks(Callbacks {
        on_quote: Some(Arc::new(|data: pb::QuoteData| {
            println!("[Quote] {} price={:?} vol={:?}", data.symbol, data.latest_price, data.volume);
        })),
        on_order: Some(Arc::new(|data: pb::OrderStatusData| {
            println!("[Order] {:?}", data);
        })),
        on_asset: Some(Arc::new(|data: pb::AssetData| {
            println!("[Asset] {:?}", data);
        })),
        on_position: Some(Arc::new(|data: pb::PositionData| {
            println!("[Position] {:?}", data);
        })),
        on_connect: Some(Arc::new(|| println!("Connected"))),
        on_disconnect: Some(Arc::new(|| println!("Disconnected"))),
        on_error: Some(Arc::new(|msg| eprintln!("Error: {}", msg))),
        ..Default::default()
    });

    // Connect using the free function push::connect()
    connect(&pc).await.map_err(|e| format!("connect failed: {}", e))?;

    // Subscribe to market data
    pc.subscribe(&SubjectType::Quote, Some("AAPL,TSLA"), None, None);

    // Subscribe to account push
    pc.subscribe(&SubjectType::Asset, None, Some(&account), None);
    pc.subscribe(&SubjectType::Order, None, Some(&account), None);

    println!("Subscribed. Press Ctrl+C to exit.");
    tokio::signal::ctrl_c().await?;
    pc.disconnect();
    Ok(())
}

Project Structure

openapi-rust-sdk/
├── src/
│   ├── config/    # Configuration (ClientConfig builder, config parser, dynamic domain)
│   ├── signer/    # RSA signing
│   ├── client/    # HTTP client (request/response, retry, execute)
│   ├── model/     # Data models (Order, Contract, Position, enums)
│   ├── quote/     # Market data query client
│   ├── trade/     # Trading client
│   ├── push/      # TCP+TLS push client (Protobuf binary protocol)
│   ├── error.rs   # Error types
│   ├── logger.rs  # Logging
│   └── lib.rs     # Public exports
├── examples/      # Example code
└── tests/         # Tests

API Reference

License

MIT License


Tiger OpenAPI Rust SDK(中文)

老虎证券 OpenAPI 的 Rust SDK,提供行情查询、交易下单、账户管理和实时推送等功能。

Crates.io License: MIT

安装

Cargo.toml 中添加依赖:

[dependencies]
tigeropen = "0.1.0"
tokio = { version = "1", features = ["full"] }

要求 Rust 1.70 或更高版本。

快速开始

use tigeropen::config::ClientConfig;
use tigeropen::client::http_client::HttpClient;
use tigeropen::quote::QuoteClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 从 properties 文件加载配置
    let config = ClientConfig::builder()
        .properties_file("tiger_openapi_config.properties")
        .build()?;

    // 2. 创建 HTTP 客户端
    let http = HttpClient::new(config);

    // 3. 查询行情
    let qc = QuoteClient::new(&http);
    let states = qc.market_state("US").await?;
    println!("美股市场状态: {:?}", states);

    Ok(())
}

配置

SDK 支持多种配置方式,优先级:环境变量 > Builder 设置(含配置文件) > 自动发现的配置文件 > 默认值

方式一:Properties 配置文件

最常用的方式。创建 tiger_openapi_config.properties 文件:

tiger_id=你的开发者ID
private_key=你的RSA私钥
account=你的交易账户

显式加载:

let config = ClientConfig::builder()
    .properties_file("tiger_openapi_config.properties")
    .build()?;

方式二:自动发现

如果调用 build() 时未设置 tiger_idprivate_key,Builder 会按以下顺序自动搜索配置文件:

  1. ./tiger_openapi_config.properties(当前目录)
  2. ~/.tigeropen/tiger_openapi_config.properties(用户主目录)

因此你可以直接:

let config = ClientConfig::builder().build()?; // 自动发现配置

将配置文件放在 ~/.tigeropen/tiger_openapi_config.properties,所有项目都能自动加载。

方式三:Builder 模式

通过代码设置:

let config = ClientConfig::builder()
    .tiger_id("你的开发者ID")
    .private_key("你的RSA私钥")
    .account("你的交易账户")
    .build()?;

方式四:环境变量

export TIGEROPEN_TIGER_ID=你的开发者ID
export TIGEROPEN_PRIVATE_KEY=你的RSA私钥
export TIGEROPEN_ACCOUNT=你的交易账户

环境变量优先级最高,会覆盖所有其他配置方式。

配置项说明

配置项 说明 必填 默认值
tiger_id 开发者 ID -
private_key RSA 私钥 -
account 交易账户 -
language 语言(ZhCn/EnUs) ZhCn
timeout 请求超时 15s

行情查询

use tigeropen::client::http_client::HttpClient;
use tigeropen::quote::QuoteClient;

let http = HttpClient::new(config);
let qc = QuoteClient::new(&http);

// 市场状态
let states = qc.market_state("US").await?;

// 实时报价
let quotes = qc.quote_real_time(&["AAPL", "TSLA"]).await?;

// K 线数据
let klines = qc.kline("AAPL", "day").await?;

// 分时数据
let timeline = qc.timeline(&["AAPL"]).await?;

// 深度行情
let depth = qc.quote_depth("AAPL").await?;

// 期权到期日
let expiry = qc.option_expiration("AAPL").await?;

// 期权链
let chain = qc.option_chain("AAPL", "2024-01-19").await?;

// 期货交易所列表
let exchanges = qc.future_exchange().await?;

交易操作

use tigeropen::client::http_client::HttpClient;
use tigeropen::trade::TradeClient;
use serde_json::json;

let http = HttpClient::new(config);
let tc = TradeClient::new(&http, "你的账户");

// 下限价单
let order = json!({
    "symbol": "AAPL",
    "secType": "STK",
    "action": "BUY",
    "orderType": "LMT",
    "totalQuantity": 100,
    "limitPrice": 150.0,
    "timeInForce": "DAY",
});
let result = tc.place_order(order).await?;

// 预览订单(不实际下单)
let preview = tc.preview_order(order).await?;

// 修改订单
tc.modify_order(order_id, json!({"limitPrice": 155.0})).await?;

// 取消订单
tc.cancel_order(order_id).await?;

// 查询订单、持仓、资产
let orders = tc.orders().await?;
let positions = tc.positions().await?;
let assets = tc.assets().await?;

通用方法(execute)

当 SDK 尚未封装某个 API 时,可以使用 HttpClient::execute 直接调用:

let http = HttpClient::new(config);
let resp = http.execute("market_state", r#"{"market":"US"}"#).await?;
println!("原始响应: {}", resp);

实时推送

推送客户端使用 TCP + TLS + Protobuf 长连接接收实时行情和账户推送通知,支持自动重连和心跳保活。

回调参数使用 Protobuf 生成的类型(pb::QuoteDatapb::OrderStatusDatapb::AssetData 等)。

use std::sync::Arc;
use tigeropen::config::ClientConfig;
use tigeropen::push::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ClientConfig::builder().build()?; // 自动发现配置
    let account = config.account.clone();

    let pc = Arc::new(PushClient::new(config, None));

    // 设置回调(参数为 pb::* Protobuf 类型)
    pc.set_callbacks(Callbacks {
        on_quote: Some(Arc::new(|data: pb::QuoteData| {
            println!("[行情] {} 最新价={:?} 成交量={:?}", data.symbol, data.latest_price, data.volume);
        })),
        on_order: Some(Arc::new(|data: pb::OrderStatusData| {
            println!("[订单] {:?}", data);
        })),
        on_asset: Some(Arc::new(|data: pb::AssetData| {
            println!("[资产] {:?}", data);
        })),
        on_position: Some(Arc::new(|data: pb::PositionData| {
            println!("[持仓] {:?}", data);
        })),
        on_connect: Some(Arc::new(|| println!("推送连接成功"))),
        on_disconnect: Some(Arc::new(|| println!("推送连接断开"))),
        on_error: Some(Arc::new(|msg| eprintln!("推送错误: {}", msg))),
        ..Default::default()
    });

    // 使用 push::connect() 自由函数连接
    connect(&pc).await.map_err(|e| format!("连接失败: {}", e))?;

    // 订阅行情
    pc.subscribe(&SubjectType::Quote, Some("AAPL,TSLA"), None, None);

    // 订阅账户推送
    pc.subscribe(&SubjectType::Asset, None, Some(&account), None);
    pc.subscribe(&SubjectType::Order, None, Some(&account), None);

    println!("已订阅,按 Ctrl+C 退出");
    tokio::signal::ctrl_c().await?;
    pc.disconnect();
    Ok(())
}

项目结构

openapi-rust-sdk/
├── src/
│   ├── config/    # 配置管理(ClientConfig Builder、ConfigParser、动态域名)
│   ├── signer/    # RSA 签名
│   ├── client/    # HTTP 客户端(请求/响应、重试策略、execute)
│   ├── model/     # 数据模型(Order、Contract、Position、枚举)
│   ├── quote/     # 行情查询客户端
│   ├── trade/     # 交易客户端
│   ├── push/      # TCP+TLS 推送客户端(Protobuf 二进制协议)
│   ├── error.rs   # 错误类型
│   ├── logger.rs  # 日志模块
│   └── lib.rs     # 统一导出
├── examples/      # 示例代码
└── tests/         # 测试

API 参考

许可证

MIT License

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages