### Install Schwab API Ruby Gem Source: https://github.com/wakproductions/schwab-api-ruby/blob/master/README.md To install the Schwab API Ruby gem, add the following line to your Gemfile. This will pull the latest version directly from the GitHub repository. ```ruby gem 'schwab-api-ruby', git: 'https://github.com/wakproductions/schwab-api-ruby.git' ``` -------------------------------- ### Initialize Schwab API Client with Environment Variables Source: https://github.com/wakproductions/schwab-api-ruby/blob/master/README.md A more robust way to initialize the Schwab API client is by fetching credentials from environment variables. This example also shows how to include access token, refresh token, and their expiration times. ```ruby client = Schwab::Client.new( client_id: ENV.fetch('SCHWAB_CLIENT_ID'), secret: ENV.fetch('SCHWAB_SECRET'), redirect_uri: ENV.fetch('SCHWAB_REDIRECT_URI'), access_token: '', refresh_token: '', access_token_expires_at:, refresh_token_expires_at: ) ``` -------------------------------- ### Get Accounts with Positions Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieve detailed account information, including balances, positions, and portfolio holdings. This endpoint provides a comprehensive view of the user's accounts. ```APIDOC ## Get Accounts with Positions ### Description Retrieve detailed account information including balances, positions, and portfolio holdings. ### Method GET ### Endpoint `/accounts` (Implicitly handled by the gem, defaults to fetching positions) ### Parameters #### Path Parameters None #### Query Parameters - **fields** (string) - Optional - Specifies which account details to retrieve. For example, 'positions' for holdings, 'orders' for recent orders, ' 0' for all fields (default). #### Request Body None ### Request Example ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Get all accounts with position details (default field) accounts = client.get_accounts # To get specific fields, e.g., only balances: # balances_only = client.get_accounts(fields: 'balance') ``` ### Response #### Success Response (200) - An array of account objects, each containing detailed information such as: - **accountNumber** (string) - **currentBalances** (object) - Contains various balance types (e.g., cash, equity). - **securitiesAccount** (object) - Contains details about holdings and positions. - ... and other relevant account data depending on the `fields` parameter. #### Response Example ```json [ { "accountNumber": "123456789", "type": "MARGIN", "primaryBalance": { "accruedInterest": 0.0, "availableFunds": 5000.0, // ... other balance details }, "currentBalances": { "cashBalance": 10000.0, // ... other balance details }, "securitiesAccount": { "type": "MARGIN", "accountId": "123456789", "roundTrips": 0, "cashAvailableForTrading": 5000.0, "patternDayTrader": false, "tradingDaysRemaining": 0, "buyingPower": 20000.0, "dayTradingBuyingPower": 20000.0, "maintenanceRequirement": 5000.0, "netLiquidation": 50000.0, // ... position details } } // ... other accounts ] ``` ``` -------------------------------- ### Get Accounts with Positions (Ruby) Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieves detailed information for all accounts, including balances and positions. This method uses the default fields for fetching account details. It requires valid authentication credentials. ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Get all accounts with position details (default field) accounts = client.get_accounts ``` -------------------------------- ### Get Account Numbers Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieve a list of all account numbers associated with the authenticated user. This is useful for identifying which accounts to query for further details. ```APIDOC ## Get Account Numbers ### Description Retrieve a list of all account numbers associated with the authenticated user. ### Method GET ### Endpoint `/accounts` (Implicitly handled by the gem) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Fetch account numbers account_numbers = client.get_account_numbers puts account_numbers ``` ### Response #### Success Response (200) - An array of hashes, where each hash contains: - **accountNumber** (string) - The unique identifier for the account. - **hashValue** (string) - A hash value associated with the account. #### Response Example ```json [ {"accountNumber" => "123456789", "hashValue" => "ABC123..."}, {"accountNumber" => "987654321", "hashValue" => "DEF456..."} ] ``` ``` -------------------------------- ### Handle Schwab API Errors in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Demonstrates robust error handling for Schwab API requests using custom exception classes. It includes handling rate limiting, authorization failures, and bad requests, with mechanisms for retrying requests and refreshing access tokens. Requires the 'schwab' gem and proper environment variable setup for credentials. ```ruby require 'schwab' client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) begin quotes = client.get_quotes(['AAPL', 'MSFT', 'GOOGL']) rescue Schwab::RateLimitError => e puts "Rate limit exceeded: #{e.message}" puts "Please wait before making more requests" sleep 60 retry rescue Schwab::NotAuthorizedError => e puts "Authorization failed: #{e.message}" # Attempt to refresh token client.refresh_access_token retry rescue Schwab::BadRequestError => e puts "Bad request: #{e.message}" puts "Check your request parameters" rescue Schwab::APIError => e puts "API error occurred: #{e.message}" end ``` -------------------------------- ### Get Instrument by CUSIP in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieves detailed information about a financial instrument using its CUSIP identifier. This method provides specific details such as symbol, description, exchange, and asset type. Requires a Schwab client and a valid CUSIP string. ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Look up instrument by CUSIP cusip = '037833100' # Apple Inc CUSIP instrument = client.get_instrument_by_cusip(cusip) puts "Symbol: #{instrument['symbol']}" puts "Description: #{instrument['description']}" puts "CUSIP: #{instrument['cusip']}" puts "Exchange: #{instrument['exchange']}" puts "Asset Type: #{instrument['assetType']}" ``` -------------------------------- ### Get Instrument Fundamentals Source: https://github.com/wakproductions/schwab-api-ruby/blob/master/README.md Fetch the fundamental data for a given stock symbol using the initialized Schwab API client. The result is a hash where the key is the symbol and the value contains its fundamental details. ```ruby client.get_instrument_fundamentals('MSFT') ``` -------------------------------- ### Get Real-time Quotes for Multiple Symbols Source: https://github.com/wakproductions/schwab-api-ruby/blob/master/README.md Retrieve real-time quote data for a list of stock symbols. The `fields: :quote` option ensures that detailed quote information is returned for each symbol. ```ruby symbols = %w[SCHW HOOD MS] result = client.get_quotes(symbols, fields: :quote) ``` -------------------------------- ### Get Trade and Dividend Transactions in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieves trade transactions for the last 30 days and dividend transactions for a specific stock. It requires an initialized Schwab client and specifies account number, date ranges, and transaction types. The output includes formatted transaction details. ```ruby # Get trade transactions for the last 30 days account_number = '123456789' start_date = Time.now - (30 * 24 * 60 * 60) end_date = Time.now transactions = client.get_transactions( account_number: account_number, start_date: start_date, end_date: end_date, types: 'TRADE' ) transactions.each do |txn| puts "Date: #{txn['transactionDate']}" puts "Type: #{txn['type']}" puts "Description: #{txn['description']}" puts "Amount: $#{txn['netAmount']}" puts "---" end # Get dividend transactions dividends = client.get_transactions( account_number: account_number, start_date: start_date, end_date: end_date, types: 'DIVIDEND_OR_INTEREST', symbol: 'AAPL' ) ``` -------------------------------- ### Get Account Numbers (Ruby) Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieves a list of all account numbers associated with the authenticated user. This method requires a valid access token and returns an array of account objects, each containing an accountNumber and a hashValue. ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Fetch account numbers account_numbers = client.get_account_numbers puts account_numbers # => [ # {"accountNumber" => "123456789", "hashValue" => "ABC123..."}, # {"accountNumber" => "987654321", "hashValue" => "DEF456..."} # ] account_numbers.each do |account| puts "Account: #{account['accountNumber']}" end ``` -------------------------------- ### Client Initialization Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Initialize the Schwab API client with OAuth credentials and tokens to access all API endpoints. This requires client ID, secret, redirect URI, and existing access and refresh tokens. ```APIDOC ## Client Initialization ### Description Initialize the Schwab API client with OAuth credentials and tokens to access all API endpoints. ### Method Not applicable (Initialization) ### Endpoint Not applicable (Initialization) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```ruby require 'schwab' # Create a new client instance with OAuth credentials client = Schwab::Client.new( client_id: ENV.fetch('SCHWAB_CLIENT_ID'), secret: ENV.fetch('SCHWAB_SECRET'), redirect_uri: 'https://127.0.0.1', access_token: 'I0.b2F1dGgyLmNkYy5zY2h3YWJhcGkuY29t...', refresh_token: 'LGGun7cHodZkcfF6ZqZrFvIzFauNqa6W...', access_token_expires_at: Time.now + 1800, refresh_token_expires_at: Time.now + (7 * 24 * 60 * 60) ) # All API methods are now available on the client instance puts "Client initialized successfully" ``` ### Response #### Success Response (200) Client object is created and ready for API calls. #### Response Example ``` Client initialized successfully ``` ``` -------------------------------- ### Initialize Schwab API Client (Ruby) Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Initializes the Schwab API client with OAuth credentials and existing tokens. This client instance is then used to access all available API endpoints. It requires client ID, secret, redirect URI, and optionally access and refresh tokens with their expiration times. ```ruby require 'schwab' # Create a new client instance with OAuth credentials client = Schwab::Client.new( client_id: ENV.fetch('SCHWAB_CLIENT_ID'), secret: ENV.fetch('SCHWAB_SECRET'), redirect_uri: 'https://127.0.0.1', access_token: 'I0.b2F1dGgyLmNkYy5zY2h3YWJhcGkuY29t...', refresh_token: 'LGGun7cHodZkcfF6ZqZrFvIzFauNqa6W...', access_token_expires_at: Time.now + 1800, refresh_token_expires_at: Time.now + (7 * 24 * 60 * 60) ) # All API methods are now available on the client instance puts "Client initialized successfully" ``` -------------------------------- ### Initialize Schwab API Client Source: https://github.com/wakproductions/schwab-api-ruby/blob/master/README.md Initialize the Schwab API client with your credentials. Ensure you replace the placeholder values with your actual client ID and refresh token. The redirect_uri must be 'https://127.0.0.1' for local app authorization. ```ruby client = SchwabAPI::Client.new( client_id: , redirect_uri: 'https://127.0.0.1', refresh_token: '' ) ``` -------------------------------- ### Search Financial Instruments in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Searches for financial instruments using symbols or descriptions. Supports different projection types like 'fundamental', 'symbol-search', and 'desc-search' to tailor the search results. Requires a Schwab client instance. ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Search by exact symbol with fundamental data instruments = client.get_instrument('AAPL', projection: 'fundamental') instruments['instruments'].each do |instrument| fund = instrument['fundamental'] puts "Symbol: #{instrument['symbol']}" puts "Name: #{instrument['description']}" puts "Exchange: #{instrument['exchange']}" puts "52-Week High: $#{fund['high52']}" if fund puts "52-Week Low: $#{fund['low52']}" if fund puts "P/E Ratio: #{fund['peRatio']}" if fund end # Search by symbol pattern results = client.get_instrument('AA*', projection: 'symbol-search') # Search by description results = client.get_instrument('Apple Inc', projection: 'desc-search') ``` -------------------------------- ### Fetch Account Details and Positions in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieves account information, including account number, type, liquidation value, and detailed positions with symbol, quantity, price, market value, and P&L. This requires authentication with the Schwab client. ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Or specify fields explicitly accounts = client.get_accounts('positions') accounts.each do |account| securities_account = account['securitiesAccount'] puts "Account Number: #{securities_account['accountNumber']}" puts "Account Type: #{securities_account['type']}" puts "Liquid Value: $#{securities_account['currentBalances']['liquidationValue']}" securities_account['positions']&.each do |position| instrument = position['instrument'] puts " #{instrument['symbol']}: #{position['longQuantity']} shares @ $#{position['averagePrice']}" puts " Market Value: $#{position['marketValue']}" puts " P&L: $#{position['longOpenProfitLoss']}" end end ``` -------------------------------- ### Fetch Real-Time Stock Quotes in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Fetches real-time market quotes for one or multiple stock symbols. Supports specifying fields like 'quote' or 'fundamental' for detailed information. Requires a valid Schwab client configuration. ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Get quotes for multiple symbols with quote field symbols = %w[SCHW HOOD MS AAPL] quotes = client.get_quotes(symbols, fields: :quote) quotes.each do |symbol, data| quote = data['quote'] puts "#{symbol}: Last Price: $#{quote['lastPrice']}" puts " Bid: $#{quote['bidPrice']} x #{quote['bidSize']}" puts " Ask: $#{quote['askPrice']} x #{quote['askSize']}" puts " Change: $#{quote['netChange']} (#{quote['netPercentChange'].round(2)}%)" puts " Volume: #{quote['totalVolume']}" puts " 52-Week Range: $#{quote['52WeekLow']} - $#{quote['52WeekHigh']}" end # Get quotes with multiple fields extended_quotes = client.get_quotes(['AAPL'], fields: [:quote, :fundamental]) ``` -------------------------------- ### OAuth Authentication - Request Access Token Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Exchange an authorization grant code for access and refresh tokens. This is a crucial step for authenticating API requests after the user has granted permission. ```APIDOC ## OAuth Authentication - Request Access Token ### Description Exchange an authorization grant code for access and refresh tokens to authenticate API requests. ### Method POST ### Endpoint `/oauth2/token` (Implicitly handled by the gem) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **grant_type** (string) - Required - Typically 'authorization_code' - **code** (string) - Required - The authorization code received from the OAuth callback. - **redirect_uri** (string) - Required - The redirect URI used during authorization. - **client_id** (string) - Required - Your application's client ID. - **client_secret** (string) - Required - Your application's client secret. ### Request Example ```ruby require 'schwab' # Initialize client with basic credentials client = Schwab::Client.new( client_id: 'YOUR_CLIENT_ID', secret: 'YOUR_SECRET', redirect_uri: 'https://127.0.0.1' ) # Exchange authorization code for tokens authorization_code = 'CODE_FROM_OAUTH_CALLBACK' response = client.request_access_token(authorization_code) # Response contains access token, refresh token, and expiration times puts response ``` ### Response #### Success Response (200) - **expires_in** (integer) - The lifetime in seconds of the access token. - **token_type** (string) - The type of token, typically 'Bearer'. - **scope** (string) - The scope of the access token. - **refresh_token** (string) - The refresh token to obtain new access tokens. - **access_token** (string) - The access token for API requests. - **id_token** (string) - The ID token (JWT) containing user information. #### Response Example ```json { "expires_in": 1800, "token_type": "Bearer", "scope": "api", "refresh_token": "LGGun7cHodZkcfF6ZqZrFvIzFauNqa6W...", "access_token": "I0.b2F1dGgyLmNkYy5zY2h3YWJhcGkuY29t...", "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs..." } ``` ``` -------------------------------- ### Request Access Token with Authorization Code (Ruby) Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Exchanges an authorization grant code, obtained from an OAuth callback, for access and refresh tokens. This method is part of the OAuth 2.0 flow and requires the client's credentials and redirect URI. The response includes token details and expiration times. ```ruby require 'schwab' # Initialize client with basic credentials client = Schwab::Client.new( client_id: 'YOUR_CLIENT_ID', secret: 'YOUR_SECRET', redirect_uri: 'https://127.0.0.1' ) # Exchange authorization code for tokens authorization_code = 'CODE_FROM_OAUTH_CALLBACK' response = client.request_access_token(authorization_code) # Response contains access token, refresh token, and expiration times puts response # => { # "expires_in" => 1800, # "token_type" => "Bearer", # "scope" => "api", # "refresh_token" => "LGGun7cHodZkcfF6ZqZrFvIzFauNqa6W...", # "access_token" => "I0.b2F1dGgyLmNkYy5zY2h3YWJhcGkuY29t...", # "id_token" => "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs..." # } # Tokens are automatically stored in the client instance puts "Access token: #{client.access_token}" puts "Refresh token: #{client.refresh_token}" ``` -------------------------------- ### Retrieve Price History in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Retrieves historical price data (OHLCV candles) for a given stock symbol. Supports flexible date ranges and frequencies, including daily and intraday data. Requires a configured Schwab client and date/period parameters. ```ruby require 'date' client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Get daily price history using period history = client.get_price_history( 'AAPL', period_type: :month, period: 1, frequency_type: :daily, frequency: 1 ) # Get intraday data using date range start_date = Date.today - 5 end_date = Date.today history = client.get_price_history( 'MSFT', start_date: start_date, end_date: end_date, frequency_type: :minute, frequency: 5, need_extended_hours_data: true ) puts "Symbol: #{history['symbol']}" history['candles'].each do |candle| puts "#{candle['datetime']}: O=#{candle['open']}, H=#{candle['high']}, " \ "L=#{candle['low']}, C=#{candle['close']}, V=#{candle['volume']}" end ``` -------------------------------- ### Query Account Transactions in Ruby Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Queries the transaction history for a specified account. Allows filtering by date range and transaction type. This functionality requires an authenticated Schwab client instance. ```ruby client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', access_token: 'VALID_ACCESS_TOKEN', refresh_token: 'VALID_REFRESH_TOKEN' ) # Example placeholder for transaction query - actual API call would follow ``` -------------------------------- ### Refresh Access Token (Ruby) Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Refreshes an expired access token using a valid refresh token. This ensures continuous API access without requiring the user to re-authenticate. It requires the client's credentials and the refresh token. Error handling for token refresh failures is included. ```ruby require 'schwab' client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', refresh_token: 'LGGun7cHodZkcfF6ZqZrFvIzFauNqa6W...' ) # Refresh the access token before making API calls begin response = client.refresh_access_token puts "New access token: #{client.access_token}" puts "Token expires at: #{client.access_token_expires_at}" rescue Schwab::APIError => e puts "Failed to refresh token: #{e.message}" end ``` -------------------------------- ### OAuth Authentication - Refresh Access Token Source: https://context7.com/wakproductions/schwab-api-ruby/llms.txt Refresh an expired access token using the refresh token. This allows for continuous access to the API without requiring the user to re-authenticate. ```APIDOC ## OAuth Authentication - Refresh Access Token ### Description Refresh an expired access token using the refresh token to maintain continuous API access. ### Method POST ### Endpoint `/oauth2/token` (Implicitly handled by the gem) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **grant_type** (string) - Required - Must be 'refresh_token'. - **refresh_token** (string) - Required - The refresh token obtained previously. - **client_id** (string) - Required - Your application's client ID. - **client_secret** (string) - Required - Your application's client secret. ### Request Example ```ruby require 'schwab' client = Schwab::Client.new( client_id: ENV['SCHWAB_CLIENT_ID'], secret: ENV['SCHWAB_SECRET'], redirect_uri: 'https://127.0.0.1', refresh_token: 'LGGun7cHodZkcfF6ZqZrFvIzFauNqa6W...' ) # Refresh the access token before making API calls begin response = client.refresh_access_token puts "New access token: #{client.access_token}" puts "Token expires at: #{client.access_token_expires_at}" rescue Schwab::APIError => e puts "Failed to refresh token: #{e.message}" end ``` ### Response #### Success Response (200) - **expires_in** (integer) - The lifetime in seconds of the new access token. - **token_type** (string) - The type of token, typically 'Bearer'. - **scope** (string) - The scope of the new access token. - **refresh_token** (string) - The new refresh token (may be the same or new). - **access_token** (string) - The new access token for API requests. #### Response Example ```json { "expires_in": 1800, "token_type": "Bearer", "scope": "api", "refresh_token": "NEW_REFRESH_TOKEN_OR_SAME", "access_token": "NEW_ACCESS_TOKEN..." } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.