schwabdev Python Wrapper

repository·main·Indexed 19 days ago

https://github.com/tylerebowers/schwabdev

A lightweight Python wrapper for the Charles Schwab API (version 3.0.5) designed to simplify authentication, token lifecycle management, and real-time data streaming. It supports both synchronous and asynchronous programming patterns, providing tools for order management, account positions, market quotes, and option chains. Key features include automatic token refreshes, optional token database encryption, and a streaming API with customizable response handlers.

Tokens
23K
Snippets
79
Records
122
Agent score
74%

What's inside schwabdev

  1. Overview of Schwabdev capabilities

    main

    Schwabdev is a lightweight Python wrapper for the Charles Schwab API. It is designed to simplify authentication and data access while handling complex tasks like token lifecycle management.

    Key features include:

    • Automatic Token Management: Handles authentication and automatic token refreshes.
    • Flexible Programming Models: Supports both Synchronous and Asynchronous programming patterns.
    • Real-time Data Streaming: Provides streaming capabilities with customizable response handlers and automatic restarts if the streamer crashes.
    • Order Management: Capabilities to place orders and retrieve order details.
    • Security: Supports optional encryption for the token database.
    • Market Awareness: Optional automatic starting/stopping of the streamer based on market open/close times.
  2. Understand Account Activity event types

    main

    The Account Activity stream emits several key event types within the content[n]['2'] field. These events track the lifecycle of an order:

    • OrderCreated: The initial creation of an order.
    • OrderAccepted: The order has been accepted by the system.
    • ExecutionRequested: The order is being routed for execution.
    • ExecutionRequestCreated: The routing request has been initialized.
    • ExecutionRequestCompleted: The routing request has finished (e.g., RouteStatus: RouteVenueAccepted).
    • OrderFillCompleted: The order has been fully or partially filled.
  3. Important Usage Notes and Limits

    main

    Concurrency and Threading

    • Multiple clients can run simultaneously if they share the same tokens_db file, but only one streamer can be active at a time.
    • Clients are not guaranteed to be thread-safe. Use a threading lock if accessing a client from multiple threads.

    API Requirements and Limits

    • Required Scopes: You must have both Accounts and Trading Production and Market Data Production added to your Schwab app.
    • Rate Limits (Exceeding these results in HTTP 429):
      • 120 API requests per minute.
      • 4000 order-related API calls per day.
      • 500 concurrently streamed tickers.

    Logging

    Schwabdev uses the standard Python logging module. Configure it using: logging.basicConfig(level=logging.INFO)

  4. Stream data delivery models by product type

    main

    Different Schwab products deliver streaming data using different logic. Understanding this is critical for maintaining accurate local state:

    • Changes (Delta updates): LEVELONE_EQUITIES, LEVELONE_OPTIONS, LEVELONE_FUTURES, LEVELONE_FUTURES_OPTIONS, and LEVELONE_FOREX. These services only stream the fields that have changed. You must merge incoming updates into your existing local data object to maintain a complete view.
    • Whole Data: NYSE_BOOK, NASDAQ_BOOK, OPTIONS_BOOK, SCREENER_EQUITY, and SCREENER_OPTION. These services stream all fields for the subscribed symbols in every update.
    • All-Sequence Data: CHART_EQUITY, CHART_FUTURES, and ACCT_ACTIVITY. These provide a sequence number with each response (e.g., the i'th sequence number represents the i'th candle of the day).
  5. Fix SSL Certificate verification failures on macOS

    main

    If you encounter SSL: CERTIFICATE_VERIFY_FAILED - self-signed certificate in certificate chain, you must install the Python certificates for your macOS installation.

    Fix: Run the following command in your terminal (adjust the version number if necessary): open /Applications/Python\ 3.12/Install\ Certificates.command

    open /Applications/Python\ 3.12/Install\ Certificates.command
  6. Set up your Schwab developer account and app

    main

    To use schwabdev, you must first configure your credentials through the Schwab Developer portal:

    1. Create Account: Create a Schwab developer account using the same email as your Schwab brokerage account.
    2. Request API Access: Request access to the Trader API - Individual product.
    3. Create Developer App: In the Schwab dashboard, create a new individual developer app with the following settings:
      • Callback URL: Set to https://127.0.0.1. You can add multiple URLs separated by commas (e.g., https://127.0.0.1,https://127.0.0.1:7777). URLs must be https or localhost addresses.
      • API Products: You must add both Accounts and Trading Production and Market Data Production to the app for full functionality.
    4. Wait for Approval: Wait until the app status is "Ready for use". Note that "Approved - Pending" will not work.
    5. Enable TOS: Enable Thinkorswim (TOS) for your Schwab account (e.g., by logging into a TOS platform) to allow orders and other API calls.
  7. Use the interactive playground for testing snippets

    main

    You can use a Python interactive session to quickly test code snippets. The repository provides two versions:

    1. Standard Playground: Run python -i playground.py for a synchronous interactive session.
    2. Asynchronous Playground: Run python -i async_playground.py for an asynchronous interactive session.
    python -i playground.py
    # OR
    python -i async_playground.py
  8. Authenticate with Schwab

    main

    The first time you run your code, you must perform an interactive login:

    1. Run your script. A link will be generated in the terminal.
    2. Open the link and sign in to your Schwab account.
    3. Agree to the terms and select your account(s).
    4. Copy the URL from your browser's address bar after the redirect and paste it back into the terminal.
  9. Manage credentials using a .env file

    main

    To avoid hardcoding sensitive credentials in your scripts, use a .env file located in the same directory as your script. This file should store your app_key, app_secret, and callback_url.

    Security Warning: Always add your .env file to your .gitignore to prevent leaking credentials when pushing code to version control systems like GitHub.

    # .env file content
    app_key = "Your app key"
    app_secret = "Your app secret"
    callback_url = "https://127.0.0.1"
  10. Initialize the Schwabdev Async Client

    main

    For concurrent API calls, use schwabdev.ClientAsync. This client is designed to be used with asyncio.

    In addition to the standard parameters available to the synchronous client, ClientAsync includes a parsed option to control whether API responses are automatically converted into Python dictionaries/lists.

    import schwabdev
    
    client = schwabdev.ClientAsync(
        app_key, 
        app_secret, 
        callback_url="https://127.0.0.1",
        tokens_db="~/.schwabdev/tokens.db",
        encryption=None,
        timeout=10,
        call_on_auth=None,
        parsed=False
    )