Trading

The Rust SDK provides an async TradeClient built on Tokio. Every method returns Result<T, TigerError>. All network calls must be .awaited inside a Tokio runtime.

Quick Start

use tigeropen::config::ClientConfig;
use tigeropen::trade::{TradeClient, Order};
use serde_json::json;

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

    // Build a limit order
    let order = Order {
        account: account.clone(),
        symbol: "AAPL".to_string(),
        sec_type: "STK".to_string(),
        action: "BUY".to_string(),
        order_type: "LMT".to_string(),
        total_quantity: 100,
        limit_price: Some(150.0),
        time_in_force: "DAY".to_string(),
        ..Default::default()
    };

    // Preview before placing
    let preview = tc.preview_order(order.clone()).await?;
    println!("Commission: {:?}", preview.commission);

    // Place the order
    let result = tc.place_order(order).await?;
    println!("Order ID: {}", result.id);

    Ok(())
}

Order Struct

Use the Order struct to represent orders. All optional fields default to None / zero values via Default::default().

Order Fields

FieldTypeDescription
accountStringAccount identifier
symbolStringContract symbol, e.g. "AAPL"
sec_typeStringSecurity type: "STK", "OPT", "FUT", "WAR", "IOPT"
actionStringOrder side: "BUY" or "SELL"
order_typeString"MKT", "LMT", "STP", "STP_LMT", "TRAIL"
total_quantityi64Number of shares/contracts
limit_priceOption<f64>Limit price (required for LMT / STP_LMT)
aux_priceOption<f64>Stop price (required for STP / STP_LMT)
time_in_forceString"DAY", "GTC", "GTD"
outside_rthboolAllow execution outside regular trading hours
expiryOption<String>Option expiry date ("YYYYMMDD")
strikeOption<f64>Option strike price
rightOption<String>Option type: "PUT" or "CALL"

Example Orders

use tigeropen::trade::Order;

// Stock limit buy
let limit_order = Order {
    account: account.clone(),
    symbol: "AAPL".to_string(),
    sec_type: "STK".to_string(),
    action: "BUY".to_string(),
    order_type: "LMT".to_string(),
    total_quantity: 100,
    limit_price: Some(150.0),
    time_in_force: "DAY".to_string(),
    ..Default::default()
};

// Stock market sell
let market_order = Order {
    account: account.clone(),
    symbol: "TSLA".to_string(),
    sec_type: "STK".to_string(),
    action: "SELL".to_string(),
    order_type: "MKT".to_string(),
    total_quantity: 50,
    time_in_force: "DAY".to_string(),
    ..Default::default()
};

// Option limit buy (call)
let option_order = Order {
    account: account.clone(),
    symbol: "AAPL".to_string(),
    sec_type: "OPT".to_string(),
    action: "BUY".to_string(),
    order_type: "LMT".to_string(),
    total_quantity: 1,
    limit_price: Some(5.50),
    time_in_force: "DAY".to_string(),
    expiry: Some("20250117".to_string()),
    strike: Some(150.0),
    right: Some("CALL".to_string()),
    ..Default::default()
};

Contract Query

get_contract

pub async fn get_contract(&self, symbol: &str, sec_type: &str) -> Result<Contract, TigerError>

Returns detailed contract information for a single symbol.

ParameterTypeRequiredDescription
symbol&strYesContract symbol, e.g. "AAPL"
sec_type&strYesSecurity type: "STK", "OPT", "FUT", "WAR", "IOPT"
let contract = tc.contract("AAPL", "STK").await?;
println!("Exchange: {}", contract.exchange);

get_contracts

pub async fn get_contracts(&self, symbols: &[&str], sec_type: &str) -> Result<Vec<Contract>, TigerError>

Returns contract information for multiple symbols in a single request.

ParameterTypeRequiredDescription
symbols&[&str]YesList of symbols
sec_type&strYesSecurity type for all symbols
let contracts = tc.contracts(&["AAPL", "TSLA", "MSFT"], "STK").await?;

get_quote_contract

pub async fn get_quote_contract(&self, symbol: &str, sec_type: &str) -> Result<Contract, TigerError>

Returns derivative contract details (options or warrants) for the given underlying symbol.

ParameterTypeRequiredDescription
symbol&strYesUnderlying symbol
sec_type&strYesDerivative type: "OPT", "WAR", "IOPT"
let quote_contract = tc.quote_contract("AAPL", "OPT").await?;

Order Management

place_order

pub async fn place_order(&self, order: Order) -> Result<PlaceOrderResult, TigerError>

Submits an order to the exchange. Returns the server-assigned order ID on success.

ParameterTypeRequiredDescription
orderOrderYesOrder details
let result = tc.place_order(limit_order).await?;
println!("Order ID: {}", result.id);
// PlaceOrderResult { id: 123456789, status: "Submitted" }

preview_order

pub async fn preview_order(&self, order: Order) -> Result<PreviewResult, TigerError>

Validates an order and returns estimated commission and margin impact without actually placing it.

let preview = tc.preview_order(limit_order.clone()).await?;
println!("Commission: {:?}", preview.commission);
println!("Margin impact: {:?}", preview.margin_impact);

modify_order

pub async fn modify_order(&self, id: i64, order: Order) -> Result<ModifyResult, TigerError>

Modifies the price or quantity of an existing open order.

ParameterTypeRequiredDescription
idi64YesOrder ID to modify
orderOrderYesUpdated order parameters
let mut updated = limit_order.clone();
updated.limit_price = Some(148.0);
let mod_result = tc.modify_order(123456789, updated).await?;

cancel_order

pub async fn cancel_order(&self, id: i64) -> Result<CancelResult, TigerError>

Cancels an open order by ID.

ParameterTypeRequiredDescription
idi64YesOrder ID to cancel
let cancel_result = tc.cancel_order(123456789).await?;

Order Query

get_orders

pub async fn get_orders(&self) -> Result<Vec<OrderInfo>, TigerError>

Returns all orders (pending, filled, and cancelled) for the current trading day.

let orders = tc.orders().await?;
println!("Total orders today: {}", orders.len());

get_active_orders

pub async fn get_active_orders(&self) -> Result<Vec<OrderInfo>, TigerError>

Returns only orders that are currently pending.

let active_orders = tc.active_orders().await?;
println!("Open orders: {}", active_orders.len());

get_inactive_orders

pub async fn get_inactive_orders(&self) -> Result<Vec<OrderInfo>, TigerError>

Returns orders that have been cancelled or have expired.

let inactive_orders = tc.inactive_orders().await?;

get_filled_orders

pub async fn get_filled_orders(&self) -> Result<Vec<OrderInfo>, TigerError>

Returns orders that have been fully or partially filled.

let filled_orders = tc.filled_orders().await?;

Positions and Assets

get_positions

pub async fn get_positions(&self) -> Result<Vec<Position>, TigerError>

Returns all current open positions (symbol, quantity, average cost, market value, unrealized P&L).

let positions = tc.positions().await?;
for p in &positions {
    println!("{}: qty={} unrealized_pnl={:?}", p.symbol, p.quantity, p.unrealized_pnl);
}

get_assets

pub async fn get_assets(&self) -> Result<Assets, TigerError>

Returns account asset summary (net liquidation value, cash balance, buying power, margin usage).

let assets = tc.assets().await?;
println!("Net liquidation: {:?}", assets.net_liquidation);
println!("Buying power: {:?}", assets.buying_power);

get_prime_assets

pub async fn get_prime_assets(&self) -> Result<PrimeAssets, TigerError>

Returns consolidated asset summary for prime (multi-currency) accounts, aggregated across all sub-accounts.

let prime_assets = tc.prime_assets().await?;

get_order_transactions

pub async fn get_order_transactions(&self, id: i64) -> Result<Vec<Transaction>, TigerError>

Returns the individual fill records (executions) associated with a specific order.

ParameterTypeRequiredDescription
idi64YesOrder ID
let transactions = tc.order_transactions(123456789).await?;
for tx in &transactions {
    println!("Fill: price={} qty={}", tx.price, tx.quantity);
}

Generic Raw API Call

When the SDK has not yet wrapped a specific API endpoint, use HttpClient::execute directly:

use tigeropen::config::ClientConfig;
use tigeropen::client::HttpClient;

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

    // Pass the API method name and a raw JSON parameter string
    let resp = http_client
        .execute("market_state", r#"{"market":"US"}"#)
        .await?;
    println!("Raw response: {}", resp);

    Ok(())
}