Comprehensive algorithmic trading framework for Python with backtesting, simulation, and live trading capabilities
—
Portfolio, account, and position management with real-time P&L tracking, multi-account support, comprehensive position analytics, and fund management operations. The portfolio system supports stocks, futures, bonds, and mixed asset strategies.
Functions for accessing current positions and position details.
def get_positions():
"""
Get all current positions.
Returns:
list[Position]: List of Position objects for all non-zero positions
"""
def get_position(order_book_id, direction=POSITION_DIRECTION.LONG):
"""
Get specific position with direction.
Parameters:
- order_book_id (str): Instrument identifier
- direction (POSITION_DIRECTION): Position direction (LONG, SHORT)
Returns:
Position: Position object with quantity, market_value, etc.
"""Functions for managing account funds and borrowing operations.
def deposit(account_type, amount, receiving_days=0):
"""
Deposit funds to account.
Parameters:
- account_type (DEFAULT_ACCOUNT_TYPE): Account type (STOCK, FUTURE, BOND)
- amount (float): Deposit amount
- receiving_days (int): Days until funds are available
Returns:
bool: True if deposit successful
"""
def withdraw(account_type, amount):
"""
Withdraw funds from account.
Parameters:
- account_type (DEFAULT_ACCOUNT_TYPE): Account type
- amount (float): Withdrawal amount
Returns:
bool: True if withdrawal successful
"""
def finance(amount, account_type=DEFAULT_ACCOUNT_TYPE.STOCK):
"""
Finance/borrow funds.
Parameters:
- amount (float): Amount to borrow
- account_type (DEFAULT_ACCOUNT_TYPE): Account type for borrowing
Returns:
bool: True if financing successful
"""
def repay(amount, account_type=DEFAULT_ACCOUNT_TYPE.STOCK):
"""
Repay borrowed funds.
Parameters:
- amount (float): Amount to repay
- account_type (DEFAULT_ACCOUNT_TYPE): Account type
Returns:
bool: True if repayment successful
"""The portfolio system is organized hierarchically with comprehensive tracking:
class Portfolio:
"""
Main portfolio container with accounts and positions.
Properties:
- total_value (float): Total portfolio value
- cash (float): Total available cash across accounts
- market_value (float): Total market value of positions
- pnl (float): Total unrealized P&L
- daily_pnl (float): Daily P&L change
- total_returns (float): Total return percentage
- daily_returns (float): Daily return percentage
- positions (dict): Dictionary of all positions keyed by instrument ID
- accounts (dict): Dictionary of accounts keyed by account type
"""class Account:
"""
Trading account (stock/future/bond specific).
Properties:
- type (DEFAULT_ACCOUNT_TYPE): Account type
- total_value (float): Account total value
- cash (float): Available cash
- market_value (float): Market value of positions
- frozen_cash (float): Cash frozen in pending orders
- pnl (float): Unrealized P&L
- daily_pnl (float): Daily P&L change
- total_returns (float): Account total return
- daily_returns (float): Account daily return
- positions (dict): Account-specific positions
"""class Position:
"""
Individual position with P&L tracking.
Properties:
- order_book_id (str): Instrument identifier
- quantity (float): Position quantity (positive=long, negative=short)
- market_value (float): Current market value
- pnl (float): Unrealized P&L
- daily_pnl (float): Daily P&L change
- avg_price (float): Average cost price
- last_price (float): Current market price
- bought_quantity (float): Total bought quantity
- sold_quantity (float): Total sold quantity
- bought_value (float): Total bought value
- sold_value (float): Total sold value
- total_orders (int): Total number of orders
- total_trades (int): Total number of trades
"""class FuturePosition:
"""
Futures position with direction-specific tracking.
Properties:
- buy_quantity (float): Long position quantity
- sell_quantity (float): Short position quantity
- buy_avg_price (float): Average long price
- sell_avg_price (float): Average short price
- buy_market_value (float): Long position market value
- sell_market_value (float): Short position market value
- buy_pnl (float): Long position P&L
- sell_pnl (float): Short position P&L
- margin (float): Required margin
- contract_multiplier (float): Contract size multiplier
"""Portfolio information is accessible through the strategy context:
# Available in strategy functions as context properties:
context.portfolio # Main Portfolio object
context.stock_account # Stock trading account
context.future_account # Futures trading account
context.bond_account # Bond trading account
# Portfolio properties:
context.portfolio.total_value # Total portfolio value
context.portfolio.cash # Available cash
context.portfolio.market_value # Market value of positions
context.portfolio.pnl # Unrealized P&L
context.portfolio.positions # All positions dict
# Account properties:
context.stock_account.cash # Stock account cash
context.stock_account.total_value # Stock account value
context.stock_account.positions # Stock positions
# Position access:
position = context.portfolio.positions["000001.XSHE"]
position.quantity # Position size
position.market_value # Position value
position.pnl # Position P&Ldef handle_bar(context, bar_dict):
# Portfolio overview
total_value = context.portfolio.total_value
cash = context.portfolio.cash
market_value = context.portfolio.market_value
# Check if portfolio is profitable
if context.portfolio.pnl > 0:
logger.info(f"Portfolio profit: {context.portfolio.pnl:.2f}")
# Account-specific information
stock_cash = context.stock_account.cash
stock_positions = len(context.stock_account.positions)
logger.info(f"Portfolio value: {total_value:.2f}, Cash: {cash:.2f}")
logger.info(f"Stock positions: {stock_positions}")def handle_bar(context, bar_dict):
# Get all positions
positions = get_positions()
for position in positions:
stock = position.order_book_id
quantity = position.quantity
pnl = position.pnl
# Check position P&L
if pnl < -1000: # Stop loss at -1000
order_target_percent(stock, 0) # Close position
logger.info(f"Stop loss triggered for {stock}")
# Position sizing check
position_weight = position.market_value / context.portfolio.total_value
if position_weight > 0.1: # Max 10% per position
target_value = context.portfolio.total_value * 0.1
order_target_value(stock, target_value)def handle_bar(context, bar_dict):
# Portfolio risk metrics
total_value = context.portfolio.total_value
daily_return = context.portfolio.daily_returns
# Maximum drawdown check
if not hasattr(context, 'peak_value'):
context.peak_value = total_value
else:
context.peak_value = max(context.peak_value, total_value)
drawdown = (context.peak_value - total_value) / context.peak_value
if drawdown > 0.1: # 10% max drawdown
# Reduce positions
for position in get_positions():
current_weight = position.market_value / total_value
new_weight = current_weight * 0.5 # Halve positions
order_target_percent(position.order_book_id, new_weight)
logger.warning(f"Drawdown limit reached: {drawdown:.2%}")def handle_bar(context, bar_dict):
# Stock account management
if context.stock_account.cash < 10000:
# Transfer funds from futures account
if context.future_account.cash > 20000:
withdraw(DEFAULT_ACCOUNT_TYPE.FUTURE, 10000)
deposit(DEFAULT_ACCOUNT_TYPE.STOCK, 10000)
# Futures account margin check
total_margin = sum(pos.margin for pos in context.future_account.positions.values())
available_margin = context.future_account.cash - total_margin
if available_margin < 5000: # Maintain minimum margin
logger.warning("Low margin available in futures account")def after_trading(context):
# Daily performance summary
portfolio = context.portfolio
performance_data = {
"date": context.now.date(),
"total_value": portfolio.total_value,
"cash": portfolio.cash,
"market_value": portfolio.market_value,
"daily_pnl": portfolio.daily_pnl,
"daily_return": portfolio.daily_returns,
"total_return": portfolio.total_returns,
"position_count": len(get_positions())
}
# Store performance data
if not hasattr(context, 'performance_history'):
context.performance_history = []
context.performance_history.append(performance_data)
# Log daily summary
logger.info(f"Daily P&L: {portfolio.daily_pnl:.2f}")
logger.info(f"Daily Return: {portfolio.daily_returns:.2%}")
logger.info(f"Total Return: {portfolio.total_returns:.2%}")def handle_bar(context, bar_dict):
# Maintain minimum cash levels
min_cash_ratio = 0.05 # 5% minimum cash
current_cash_ratio = context.portfolio.cash / context.portfolio.total_value
if current_cash_ratio < min_cash_ratio:
# Sell some positions to raise cash
positions = get_positions()
if positions:
# Sell smallest position first
smallest_position = min(positions, key=lambda p: p.market_value)
order_target_percent(smallest_position.order_book_id, 0)
logger.info(f"Selling {smallest_position.order_book_id} to raise cash")
# Invest excess cash
elif current_cash_ratio > 0.2: # More than 20% cash
# Find underweight positions to invest in
for stock in context.universe:
current_weight = 0
if stock in context.portfolio.positions:
pos_value = context.portfolio.positions[stock].market_value
current_weight = pos_value / context.portfolio.total_value
target_weight = 1.0 / len(context.universe) # Equal weight
if current_weight < target_weight * 0.8: # 20% underweight
order_target_percent(stock, target_weight)
breakInstall with Tessl CLI
npx tessl i tessl/pypi-rqalpha