Tastytrade Ruby SDK (Unofficial)
An unofficial Ruby SDK for the Tastytrade API
⚠️ IMPORTANT DISCLAIMER: This is an unofficial SDK and is not affiliated with, endorsed by, or sponsored by Tastytrade, Tastyworks, or any of their affiliates. This is an independent project created to help Ruby developers interact with the Tastytrade API.
This Ruby gem provides a simple interface to interact with the Tastytrade API, allowing you to:
- Authenticate with your Tastytrade account
- Retrieve account information and balances
- Access market data
- Place and manage orders
- Monitor positions and transactions
Features
- Secure authentication with Tastytrade API
- Real-time market data access
- Account management and portfolio tracking
- Order placement and management with dry-run support
- Position monitoring
- Transaction history with filtering and grouping
- Buying power calculations and monitoring
- CLI with interactive mode and rich formatting
Roadmap
See ROADMAP.md for the detailed development roadmap. Track progress on our GitHub Project Board.
Installation
Add this line to your application's Gemfile:
gem 'tastytrade'
And then execute:
bundle install
Or install it yourself as:
gem install tastytrade
Configuration
Environment Variables
The tastytrade gem supports authentication via environment variables, which is recommended for automation and CI/CD environments:
# Required for environment variable authentication
export TASTYTRADE_USERNAME="[email protected]"
export TASTYTRADE_PASSWORD="your_password"
# Optional environment variables
export TASTYTRADE_ENVIRONMENT="sandbox" # Use "sandbox" for test environment
export TASTYTRADE_REMEMBER="true" # Enable remember token
# Alternative shorter variable names
export TT_USERNAME="[email protected]"
export TT_PASSWORD="your_password"
export TT_ENVIRONMENT="sandbox"
export TT_REMEMBER="true"
When environment variables are set, the CLI will automatically use them for authentication without prompting for credentials.
Usage
Authentication
require 'tastytrade'
# Create a session
session = Tastytrade::Session.new(
username: 'your_username',
password: 'your_password',
remember_me: true # Optional: enables session refresh with remember token
)
# Login
session.login
# Check if authenticated
session.authenticated? # => true
# Session will automatically refresh when expired if remember_me was enabled
CLI Usage
The gem includes a command-line interface for common operations:
Authentication
# Login to your account interactively
tastytrade login
# Login with remember option for automatic session refresh
tastytrade login --remember
# Login using environment variables (recommended for automation)
export TASTYTRADE_USERNAME="[email protected]"
export TASTYTRADE_PASSWORD="your_password"
tastytrade login
# Or use shorter variable names
export TT_USERNAME="[email protected]"
export TT_PASSWORD="your_password"
tastytrade login
# Use sandbox environment for testing
export TASTYTRADE_ENVIRONMENT="sandbox"
tastytrade login
# Enable remember token via environment
export TASTYTRADE_REMEMBER="true"
tastytrade login
Account Operations
# View account balances
tastytrade balance
# View balances for all accounts
tastytrade balance --all
# View account positions
tastytrade positions
# Filter positions by symbol
tastytrade positions --symbol AAPL
# Filter positions by underlying symbol (for options)
tastytrade positions --underlying-symbol SPY
# View trading status and permissions
tastytrade trading_status
# View status for specific account
tastytrade trading_status --account 5WT0001
# Include closed positions
tastytrade positions --include-closed
Transaction History
# View all transactions
tastytrade history
# Filter by date range
tastytrade history --start-date 2024-01-01 --end-date 2024-12-31
# Filter by symbol
tastytrade history --symbol AAPL
# Group transactions by symbol, type, or date
tastytrade history --group-by symbol
tastytrade history --group-by type
tastytrade history --group-by date
# Limit number of transactions
tastytrade history --limit 50
# Combine filters
tastytrade history --symbol AAPL --start-date 2024-01-01 --group-by date
Buying Power Status
# View buying power status
tastytrade buying_power
# View buying power for specific account
tastytrade buying_power --account 5WX12345
Order Management
Order Placement
# Place a limit buy order
tastytrade order place --symbol AAPL --action buy_to_open --quantity 100 --price 150.50
# Place a market order
tastytrade order place --symbol SPY --action buy_to_open --quantity 10 --type market
# Sell to close a position
tastytrade order place --symbol AAPL --action sell_to_close --quantity 100 --price 155.00
# Dry-run validation (validate without placing)
tastytrade order place --symbol MSFT --action buy_to_open --quantity 50 --price 300 --dry-run
# Skip confirmation prompt
tastytrade order place --symbol TSLA --action buy_to_open --quantity 10 --price 200 --skip-confirmation
# Supported actions:
# - buy_to_open (bto)
# - sell_to_close (stc)
# - sell_to_open (sto)
# - buy_to_close (btc)
# Note: Orders that would use >80% of buying power will prompt for confirmation
Order Status and History
# List all live orders (open + last 24 hours)
tastytrade order list
# List orders with filters
tastytrade order list --status Live
tastytrade order list --symbol AAPL
tastytrade order list --all # Show for all accounts
# Output orders in JSON format
tastytrade order list --format json
# Get historical orders (beyond 24 hours)
tastytrade order history
tastytrade order history --status Filled
tastytrade order history --symbol AAPL
tastytrade order history --from 2024-01-01 --to 2024-12-31
tastytrade order history --limit 100
tastytrade order history --format json
# Get details for a specific order
tastytrade order get ORDER_ID
tastytrade order get ORDER_ID --format json
# Cancel an order
tastytrade order cancel ORDER_ID
tastytrade order cancel ORDER_ID --account 5WX12345
# Replace/modify an order
tastytrade order replace ORDER_ID # Interactive prompts for new price/quantity
tastytrade order replace ORDER_ID --price 155.00
tastytrade order replace ORDER_ID --quantity 50
Account Management
# List all accounts
tastytrade accounts
# Select an account
tastytrade select
# Check session status
tastytrade status
# Refresh session (requires remember token)
tastytrade refresh
# Logout
tastytrade logout
Account Information
# Get all accounts
accounts = Tastytrade::Models::Account.get_all(session)
# Get specific account
account = Tastytrade::Models::Account.get(session, 'account_number')
# Check account status
account.closed? # => false
account.futures_approved? # => true
Account Balances
# Get account balance
balance = account.get_balances(session)
# Access balance information
balance.cash_balance # => BigDecimal("10000.50")
balance.net_liquidating_value # => BigDecimal("42001.00")
balance. # => BigDecimal("20000.00")
balance.available_trading_funds # => BigDecimal("12000.00")
balance. # => BigDecimal("40000.00")
balance. # => BigDecimal("20000.00")
# Check buying power usage
balance. # => BigDecimal("40.00")
balance. # => BigDecimal("25.00")
balance. # => false (checks if > 80%)
# Check if sufficient buying power for order
balance.(15000) # => true
balance.(15000, buying_power_type: :derivative) # => true
# Calculate buying power impact
balance.(15000) # => BigDecimal("75.00")
# Calculate totals
balance.total_equity_value # => BigDecimal("30001.00")
balance.total_derivative_value # => BigDecimal("4500.00")
balance.total_market_value # => BigDecimal("34501.00")
Positions
# Get all positions
positions = account.get_positions(session)
# Filter positions
positions = account.get_positions(session,
symbol: 'AAPL',
underlying_symbol: 'AAPL',
include_closed: false
)
# Work with positions
positions.each do |position|
puts position.symbol
puts position.quantity
puts position.unrealized_pnl
puts position.unrealized_pnl_percentage
# Check position type
position.equity? # => true
position.option? # => false
position.long? # => true
position.short? # => false
end
Order Placement
# Create an order leg for buying stock
leg = Tastytrade::OrderLeg.new(
action: Tastytrade::OrderAction::BUY_TO_OPEN,
symbol: 'AAPL',
quantity: 100
)
# Create a market order
market_order = Tastytrade::Order.new(
type: Tastytrade::OrderType::MARKET,
legs: leg
)
# Create a limit order
limit_order = Tastytrade::Order.new(
type: Tastytrade::OrderType::LIMIT,
legs: leg,
price: 150.50 # Will be converted to BigDecimal
)
# Place the order
response = account.place_order(session, market_order)
# Dry run (simulate order without placing)
response = account.place_order(session, limit_order, dry_run: true)
# Check order response
puts response.order_id # => "123456"
puts response.status # => "Filled"
# Dry run orders return a BuyingPowerEffect object
if response..is_a?(Tastytrade::Models::)
bp_effect = response.
puts bp_effect. # => BigDecimal("15050.00")
puts bp_effect. # => BigDecimal("75.25")
puts bp_effect.exceeds_threshold?(80) # => false
puts bp_effect.debit? # => true
else
puts response. # => BigDecimal("-15050.00")
end
puts response.warnings # => [] or warning messages
Order Management
# Get live orders (open orders + orders from last 24 hours)
orders = account.get_live_orders(session)
# Filter orders by status
live_orders = account.get_live_orders(session, status: "Live")
filled_orders = account.get_live_orders(session, status: "Filled")
# Filter orders by symbol
aapl_orders = account.get_live_orders(session, underlying_symbol: "AAPL")
# Filter by time range
recent_orders = account.get_live_orders(session,
from_time: Time.now - 86400, # Last 24 hours
to_time: Time.now
)
# Work with order details
orders.each do |order|
puts order.id # => "12345"
puts order.status # => "Live"
puts order. # => "AAPL"
puts order.order_type # => "Limit"
puts order.price # => BigDecimal("150.50")
# Check order capabilities
puts order.cancellable? # => true
puts order.editable? # => true
puts order.terminal? # => false
puts order.working? # => true
# Check fill status
puts order.remaining_quantity # => 100
puts order.filled_quantity # => 0
# Work with order legs
order.legs.each do |leg|
puts leg.symbol # => "AAPL"
puts leg.action # => "Buy"
puts leg.quantity # => 100
puts leg.remaining_quantity # => 100
puts leg.partially_filled? # => false
end
end
# Cancel an order
account.cancel_order(session, "12345")
# Replace an order with new parameters
new_order = Tastytrade::Order.new(
type: Tastytrade::OrderType::LIMIT,
legs: leg,
price: 155.00 # New price
)
response = account.replace_order(session, "12345", new_order)
Order Validation
The SDK includes comprehensive order validation to prevent submission errors and ensure orders meet all requirements before reaching the API.
Validation Features
# Orders are automatically validated before submission
order = Tastytrade::Order.new(
type: Tastytrade::OrderType::LIMIT,
legs: leg,
price: 150.00
)
# Validation happens automatically when placing orders
begin
response = account.place_order(session, order)
rescue Tastytrade::OrderValidationError => e
puts "Validation failed:"
e.errors.each { |error| puts " - #{error}" }
end
# You can also validate manually
order.validate!(session, account) # Raises if invalid
# Or perform a dry-run validation
dry_run_response = order.dry_run(session, account)
puts dry_run_response.
puts dry_run_response.warnings
Validation Rules
The following validations are performed:
Symbol Validation
- Verifies symbol exists and is tradeable
- Checks instrument type compatibility
Quantity Validation
- Minimum quantity: 1
- Maximum quantity: 999,999
- No fractional shares (whole numbers only)
Price Validation
- Price must be positive for limit orders
- Price is rounded to appropriate tick size
- Price reasonableness checks
Account Permissions
- Validates trading permissions for instrument type
- Checks for account restrictions (frozen, closing-only, etc.)
- Verifies options/futures permissions if applicable
Buying Power Validation
- Ensures sufficient buying power via dry-run
- Warns if order uses >50% of available buying power
- Checks margin requirements
Market Hours Validation
- Warns about market orders outside regular hours
- Alerts for weekend submissions
Validation Errors
# Specific validation error types
Tastytrade::OrderValidationError # General validation failure
Tastytrade::InvalidSymbolError # Symbol doesn't exist
Tastytrade:: # Not enough buying power
Tastytrade::AccountRestrictedError # Account has restrictions
Tastytrade::InvalidQuantityError # Quantity out of range
Tastytrade::InvalidPriceError # Price validation failure
Tastytrade::MarketClosedError # Market is closed
Using the OrderValidator
# Direct use of OrderValidator for custom validation
validator = Tastytrade::OrderValidator.new(session, account, order)
# Perform full validation
validator.validate! # Raises if invalid
# Or just dry-run validation
dry_run_response = validator.dry_run_validate!
# Check warnings and errors
puts validator.warnings # Array of warning messages
puts validator.errors # Array of error messages
Skip Validation (Use with Caution)
# Skip validation when you're certain the order is valid
response = account.place_order(session, order, skip_validation: true)
Transaction History
# Get all transactions
transactions = account.get_transactions(session)
# Filter transactions
transactions = account.get_transactions(session,
start_date: Date.new(2024, 1, 1),
end_date: Date.new(2024, 12, 31),
symbol: 'AAPL',
transaction_types: ['Trade'],
per_page: 100
)
# Work with transactions
transactions.each do |transaction|
puts transaction.symbol # => "AAPL"
puts transaction.transaction_type # => "Trade"
puts transaction.transaction_sub_type # => "Buy"
puts transaction.quantity # => BigDecimal("100")
puts transaction.price # => BigDecimal("150.00")
puts transaction.value # => BigDecimal("-15000.00")
puts transaction.net_value # => BigDecimal("-15007.00")
puts transaction.executed_at # => Time object
# Fee breakdown
puts transaction.commission # => BigDecimal("5.00")
puts transaction.clearing_fees # => BigDecimal("1.00")
puts transaction.regulatory_fees # => BigDecimal("0.50")
end
Development
After checking out the repo, run bin/setup to install dependencies and verify your environment is configured correctly.
Run tests with:
bundle exec rake spec
Run linting with:
bundle exec rake rubocop
For an interactive console:
bin/console
To install this gem onto your local machine:
bundle exec rake install
Documentation
TODO: Add links to additional documentation
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/ryanhamamura/tastytrade. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
Security
Please see our security policy for reporting vulnerabilities.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Tastytrade project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
Legal Disclaimer
⚠️ IMPORTANT FINANCIAL DISCLAIMER
This software is provided for educational and informational purposes only. It is not intended to be used as financial advice, investment advice, or as a recommendation to buy, sell, or hold any securities or financial instruments.
TRADING RISKS: Trading securities, options, futures, and other financial instruments involves substantial risk of loss and is not suitable for all investors. Past performance is not indicative of future results. You may lose some or all of your invested capital.
NO WARRANTY: This software is provided "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.
YOUR RESPONSIBILITY: You are solely responsible for any investment and trading decisions you make using this software. You should consult with a qualified financial advisor before making any investment decisions.
API USAGE: By using this SDK, you are responsible for complying with Tastytrade's Terms of Service and API usage guidelines. Excessive API usage may result in rate limiting or account suspension by Tastytrade.
NOT AFFILIATED: This project is not affiliated with, endorsed by, or sponsored by Tastytrade, Tastyworks, or any of their affiliates. All trademarks and registered trademarks are the property of their respective owners.
The authors and contributors of this software shall not be held liable for any losses, damages, or costs of any kind arising from the use of this software.