Problem Description
Solution
To check your available USDT balance in a QuantConnect strategy, you should access the cash_book object within the portfolio.
The specific property is self.portfolio.cash_book["USDT"].amount.
Below is a complete, runnable example demonstrating how to check the USDT balance before placing an order for a crypto pair (e.g., BTCUSDT).
Implementation Details
- Access Portfolio: Use
self.portfolio. - Access CashBook: Use
.cash_book. - Select Currency: Index with the string ticker of the currency, e.g.,
["USDT"]. - Get Amount: Use the
.amountproperty.
Code Example
from AlgorithmImports import *
class CryptoBalanceCheckAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2023, 1, 1)
self.set_end_date(2023, 2, 1)
# Set account currency to USDT for simplicity (optional, but common in crypto-only strats)
self.set_account_currency("USDT")
self.set_cash(10000)
# Set Brokerage Model (e.g., Binance, Bybit)
self.set_brokerage_model(BrokerageName.BINANCE, AccountType.MARGIN)
# Add Crypto Pair
self.symbol = self.add_crypto("BTCUSDT", Resolution.MINUTE).symbol
# Minimum USDT required to trade
self.min_usdt_balance = 1000
def on_data(self, data: Slice):
if not self.portfolio.invested:
# ---------------------------------------------------
# CHECK USDT BALANCE HERE
# ---------------------------------------------------
# Ensure the key "USDT" exists in the cash_book before accessing
if "USDT" in self.portfolio.cash_book:
available_usdt = self.portfolio.cash_book["USDT"].amount
self.log(f"Current USDT Balance: {available_usdt}")
# Logic: Only buy if we have more than the minimum required balance
if available_usdt > self.min_usdt_balance:
# Calculate quantity to buy with 50% of available USDT
# We use available_usdt explicitly in the calculation
quantity = (available_usdt * 0.5) / data[self.symbol].close
self.buy(self.symbol, quantity)
self.log(f"Buying {quantity} BTC with USDT")
else:
self.log("Insufficient USDT to place trade.")
Key Considerations
- Currency Ticker: Ensure you use the correct ticker string. For Tether, it is
"USDT". If you are trading USD pairs (e.g., BTCUSD on Coinbase), the cash is likely in"USD". - Settled vs. Unsettled:
self.portfolio.cash_book["USDT"].amountreturns the total cash. If you are trading in a margin account, this is usually immediately available. If you need to check specifically for settled cash (rare in standard crypto backtests but relevant in some contexts), you can checkself.portfolio.unsettled_cash_book. - Buying Power: While checking the cash balance is useful, it does not account for margin requirements or leverage. If you want to know how much you can buy including leverage, use:
buying_power = self.portfolio.get_buying_power(self.symbol, OrderDirection.BUY)
Q&A
Q: What happens if I try to access a currency that I don't own in cash_book?
A: If you try to access self.portfolio.cash_book["ETH"] but have never held ETH, it may raise a KeyError. It is best practice to check if "ETH" in self.portfolio.cash_book: or use .get("ETH") which allows handling cases where the key is missing.
Q: Does cash_book["USDT"].amount include the value of my open positions?
A: No. .amount strictly represents the uninvested cash sitting in the account. To see the total value of your account (Cash + Unrealized Profit/Loss + Position Value), use self.portfolio.total_portfolio_value.
Q: How do I check the conversion rate of my USDT to the account base currency?
A: If your account is in USD but you hold USDT, you can check the conversion rate using self.portfolio.cash_book["USDT"].conversion_rate.