Class PortfolioBacktester
java.lang.Object
com.quantfinlib.backtest.portfolio.PortfolioBacktester
Multi-asset, long/short portfolio backtester: rebalances positions (possibly
fractional and negative) toward the strategy's target weights at a
configurable cadence, charging commission on traded notional. This is where
the
optimization package meets the backtester — feed optimizer
weights, vol-target overlays, or momentum rankings straight in.
The survivorship-aware overload additionally consumes a
PointInTimeUniverse and per-symbol cash dividends, closing the
engine-side gaps that make naive backtests survivorship-biased:
- Delistings terminate positions at
lastClose × (1 + delistingReturn)on the event bar — a bankruptcy really costs −100%, instead of a forward-filled flat line; - Mergers convert positions to cash and/or acquirer shares at the recorded deal terms;
- Index drops (membership ends, security lives on) force a sale at that bar's close — non-members are untradeable thereafter;
- Cash dividends credit
position × amounton the ex-date (shorts pay), so unadjusted price series carry the full total return and cash drag is real.
Feed this overload unadjusted prices (dividends are cash here —
adjusted prices would double-count them) aligned via
SeriesAligner.unionForwardFill; the forward-filled ghost bars of a
dead symbol are harmless because its position terminates at the event.
The engine cannot remove the bias in the data: the universe and
delisting returns must come from a point-in-time dataset that includes
dead tickers.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordcostModel, when set, supersedes the flatcommissionRatefor every trade (rebalances and forced index-drop sales alike) — the sharedTradeCostModelseam that makes a run simultaneously survivorship-aware AND execution-aware.static final recorddividendCashCreditedandlifecycleEventsAppliedare populated by the survivorship-aware overload (zero otherwise). -
Method Summary
Modifier and TypeMethodDescriptionstatic PortfolioBacktester.Resultrun(PortfolioStrategy strategy, Map<String, BarSeries> data, PortfolioBacktester.Config config) Classic run: every supplied symbol is tradeable on every bar.static PortfolioBacktester.Resultrun(PortfolioStrategy strategy, Map<String, BarSeries> data, PortfolioBacktester.Config config, PointInTimeUniverse universe, Map<String, List<CorporateActions.CorporateAction>> cashDividends) Survivorship-aware run (see the class doc for semantics).
-
Method Details
-
run
public static PortfolioBacktester.Result run(PortfolioStrategy strategy, Map<String, BarSeries> data, PortfolioBacktester.Config config) Classic run: every supplied symbol is tradeable on every bar. -
run
public static PortfolioBacktester.Result run(PortfolioStrategy strategy, Map<String, BarSeries> data, PortfolioBacktester.Config config, PointInTimeUniverse universe, Map<String, List<CorporateActions.CorporateAction>> cashDividends) Survivorship-aware run (see the class doc for semantics).- Parameters:
universe- point-in-time membership and terminal events;nullbehaves like the classic overloadcashDividends- per-symbolCASH_DIVIDENDactions applied as cash on the ex-date (other action types are ignored here — apply splits to the price series viaCorporateActions.adjust(com.quantfinlib.core.BarSeries, java.util.List<com.quantfinlib.data.CorporateActions.CorporateAction>)instead)
-