IbkrApi.Backtester.Portfolio (ibkr_api v1.0.0)

View Source

Portfolio management for backtesting.

Tracks cash, positions, and trade history during backtesting simulations. Supports simple long-only strategies with buy/sell/hold operations.

Summary

Functions

Executes a buy order if no position is currently held.

Returns the portfolio unchanged (hold position).

Creates a new portfolio with the specified starting cash.

Calculates the realized P&L from completed trades.

Sell shares at the given price if a position is currently held.

Calculates the current total value of the portfolio.

Calculates the unrealized P&L for the current position.

Types

t()

@type t() :: %IbkrApi.Backtester.Portfolio{
  cash: float(),
  entry_price: float() | nil,
  position: non_neg_integer(),
  trades: [trade()]
}

trade()

@type trade() :: {:buy | :sell, float(), DateTime.t()}

Functions

buy(portfolio, price, timestamp \\ DateTime.utc_now())

@spec buy(t(), float(), DateTime.t()) :: t()

Executes a buy order if no position is currently held.

Parameters

  • portfolio: Current portfolio state
  • price: Price per share to buy at
  • timestamp: Optional timestamp for the trade (defaults to current time)

Examples

iex> portfolio = %IbkrApi.Backtester.Portfolio{cash: 10000.0, position: 0}
iex> result = IbkrApi.Backtester.Portfolio.buy(portfolio, 150.0)
iex> result.cash
9850.0
iex> result.position
1
iex> result.entry_price
150.0

hold(portfolio)

@spec hold(t()) :: t()

Returns the portfolio unchanged (hold position).

new(starting_cash \\ 100_000.0)

@spec new(float()) :: t()

Creates a new portfolio with the specified starting cash.

Examples

iex> IbkrApi.Backtester.Portfolio.new(50_000.0)
%IbkrApi.Backtester.Portfolio{cash: 50000.0, position: 0, entry_price: nil, trades: []}

performance_stats(portfolio, current_price, starting_value \\ 100_000.0)

@spec performance_stats(t(), float(), float()) :: map()

Returns portfolio performance statistics.

Parameters

  • portfolio: Current portfolio state
  • current_price: Current market price (for unrealized P&L calculation)
  • starting_value: Initial portfolio value (defaults to 100,000.0)

realized_pnl(portfolio)

@spec realized_pnl(t()) :: float()

Calculates the realized P&L from completed trades.

Only considers buy/sell pairs, ignoring any open position.

sell(portfolio, price, timestamp \\ DateTime.utc_now())

@spec sell(t(), float(), DateTime.t()) :: t()

Sell shares at the given price if a position is currently held.

Parameters

  • portfolio: Current portfolio state
  • price: Price per share to sell at
  • timestamp: Optional timestamp for the trade (defaults to current time)

Examples

iex> portfolio = %IbkrApi.Backtester.Portfolio{cash: 8500.0, position: 1, entry_price: 150.0}
iex> result = IbkrApi.Backtester.Portfolio.sell(portfolio, 160.0)
iex> result.cash
8660.0
iex> result.position
0
iex> result.entry_price
nil

total_value(portfolio, current_price)

@spec total_value(t(), float()) :: float()

Calculates the current total value of the portfolio.

Parameters

  • portfolio: Current portfolio state
  • current_price: Current market price of the held security (if any)

Examples

iex> portfolio = %IbkrApi.Backtester.Portfolio{cash: 8500.0, position: 1, entry_price: 150.0}
iex> IbkrApi.Backtester.Portfolio.total_value(portfolio, 160.0)
8660.0

unrealized_pnl(portfolio, current_price)

@spec unrealized_pnl(t(), float()) :: float()

Calculates the unrealized P&L for the current position.

Returns 0.0 if no position is held.