Backtesting in TFire

Portfolio based backtesting in TFire involves propagating a PortfolioHistory forward in time. Each timestep of the PortfolioHistory contains a PortfolioAtDate object which tracks holdings of assets and cash at that date. At every timestep, the portfolio is reweighted based on PositionScores.

The system consists of three main components:

  1. PortfolioAtDate: A snapshot of holdings at a single point in time, typically initialized from a Collection to define which assets can be traded
  2. PortfolioHistory: A sequence of portfolio snapshots over time
  3. PositionScores: The scoring system that drives portfolio reweighting

Workflow Overview

There are two main approaches to creating a backtest:

  1. Starting with a PortfolioAtDate and propagating it with PositionScores:
# Initialize portfolio with tradeable assets
initial_portfolio = initialize_portfolio(collection, DateTime(2020,1,1))

# Propagate forward using position scores
portfolio_history = propagate_portfolio(
    initial_portfolio,
    position_scores,
    to_date=DateTime(2023,12,31)
)
  1. Creating a PortfolioHistory directly from PositionScores:
portfolio_history = PortfolioHistory(
    position_scores,
    start_date=DateTime(2020,1,1),
    to_date=DateTime(2023,12,31),
    start_cash=1.0
)

Both approaches support features like trading fees and leverage:

# With trading fees
portfolio_history = propagate_portfolio(
    initial_portfolio,
    position_scores,
    fee_type=:prop,  # :free, :fixed, or :prop
    prop_fee=0.001   # 0.1% fee per trade
)

Functions

For a list of related functions see Backtesting - Functions.