2 releases

0.1.1 Apr 22, 2025
0.1.0 Apr 22, 2025

#486 in WebSocket

Download history 113/week @ 2025-04-16 108/week @ 2025-04-23

221 downloads per month

MIT license

175KB
3.5K SLoC

webull-rs

A Rust client for the Webull trading API.

Crates.io Documentation License: MIT

Overview

webull-rs is a Rust crate that provides a robust, type-safe, and idiomatic interface to the Webull trading API. It enables developers to build trading applications, algorithms, and bots in Rust.

Features

  • Type-safe API client for Webull trading platform
  • Comprehensive error handling with detailed error types
  • Async/await support with Tokio
  • Authentication with support for multi-factor authentication and token refresh
  • Account management for retrieving account information, positions, and balances
  • Market data for quotes, bars, option chains, and more
  • Trading operations for placing, modifying, and canceling orders (including options trading)
  • Streaming data via WebSockets for real-time updates
  • Rate limiting with configurable strategies to avoid API rate limit violations
  • Response caching for improved performance
  • Secure credential storage with encryption
  • Strongly-typed models for all API entities

Installation

Add this to your Cargo.toml:

[dependencies]
webull-rs = "0.1.0"
tokio = { version = "1", features = ["full"] }

Quick Start

use webull_rs::{WebullClient, OrderSide, OrderType, TimeInForce, OrderRequest};
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a client
    let client = WebullClient::builder()
        .with_api_key("your-api-key")
        .with_api_secret("your-api-secret")
        .with_timeout(Duration::from_secs(30))
        .build()?;

    // Login to Webull
    client.login("username", "password").await?;

    // Get account information
    let accounts = client.accounts().get_accounts().await?;
    println!("Found {} accounts", accounts.len());

    // Get real-time quote
    let quote = client.market_data().get_quote("AAPL").await?;
    println!("AAPL current price: ${}", quote.last_price);

    // Place an order
    let order_request = OrderRequest::market()
        .symbol("AAPL")
        .side(OrderSide::Buy)
        .quantity(1.0)
        .time_in_force(TimeInForce::Day);

    let order = client.orders().place_order(order_request).await?;
    println!("Order placed: {}", order.id);

    // Logout
    client.logout().await?;

    Ok(())
}

Examples

The crate includes several examples to help you get started:

To run an example:

cargo run --example account

Architecture

The crate is organized into several modules:

  • client: The main WebullClient and builder
  • auth: Authentication and token management
  • endpoints: API endpoints for different domains
  • models: Data models for API requests and responses
  • streaming: WebSocket client for streaming data
  • utils: Utility functions and helpers

Advanced Usage

Secure Credential Storage

use webull_rs::{WebullClient, WebullError};
use webull_rs::utils::credentials::EncryptedCredentialStore;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a credential store
    let credential_store = EncryptedCredentialStore::new(
        "credentials.json".to_string(),
        "token.json".to_string(),
        "my-secret-key".to_string(),
    );

    // Create a client with the credential store
    let client = WebullClient::builder()
        .with_api_key("your-api-key")
        .with_api_secret("your-api-secret")
        .with_credential_store(credential_store)
        .build()?;

    // Login to Webull
    client.login("username", "password").await?;

    // Credentials are now securely stored
    // ...

    Ok(())
}

Streaming Data

use webull_rs::{WebullClient, WebullError};
use webull_rs::streaming::events::EventType;
use webull_rs::streaming::subscription::SubscriptionRequest;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a client
    let client = WebullClient::builder()
        .with_api_key("your-api-key")
        .with_api_secret("your-api-secret")
        .build()?;

    // Login to Webull
    client.login("username", "password").await?;

    // Create a WebSocket client
    let mut ws_client = client.streaming();

    // Connect to the WebSocket server
    ws_client.connect().await?;

    // Subscribe to quote updates for AAPL
    let subscription = SubscriptionRequest::new()
        .add_symbol("AAPL")
        .add_event_type(EventType::QuoteUpdate);

    ws_client.subscribe(subscription).await?;

    // Listen for events
    while let Some(event) = ws_client.next_event().await {
        println!("Received event: {:?}", event);
    }

    // Disconnect
    ws_client.disconnect().await?;

    Ok(())
}

Documentation

For detailed documentation, see docs.rs/webull-rs.

For a comprehensive getting started guide, see GETTING_STARTED.md.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

Security

Please see SECURITY.md for security policies and best practices.

Changelog

See CHANGELOG.md for a list of changes in each release.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Dependencies

~9–23MB
~322K SLoC