Configuration Reference#

The configuration file is Config/backtest_engine_parameters.xlsx, created by running kaxanuk.backtest_engine init excel. Open it in any spreadsheet editor and edit column B only. Column A contains the parameter names (do not modify) and column C contains descriptions.

Backtest Settings#

Parameter

Example value

Description

portfolio_name

my_portfolio

Filename of your portfolio without extension. Must exist in the portfolio directory.

benchmark_file_name

SPY

Ticker used as benchmark. A market data file for this ticker must exist in the data directory.

start_date

2020-01-02

Backtest start date (YYYY-MM-DD). Use auto to derive from the first date in the portfolio file.

end_date

2024-12-31

Backtest end date (YYYY-MM-DD). Use auto to derive from the last date in the portfolio file.

initial_capital

1000000

Starting capital in currency units.

cash_reserve_percentage

0.01

Fraction of portfolio value reserved as cash on each rebalance. Range: 0.0–0.50.

commission_cents

0.05

Per-share commission in dollars. Range: 0.0–0.10. Example: 0.01 means $0.01 per share.

File Paths and Formats#

Parameter

Example value

Description

input_market_data_directory

Input/Data

Absolute or relative path to the directory containing market data files.

input_portfolio_directory

Input/Portfolios

Absolute or relative path to the directory containing portfolio files.

backtest_results_output_directory

Output

Path where backtest results and reports are saved.

market_data_input_format

csv

Format of market data files: csv or parquet.

portfolio_input_format

csv

Format of portfolio files: csv or excel.

Column Name Mappings#

These values must exactly match the column headers in your market data files.

Parameter

Example value

Purpose

commission_price_column

vwap

Column used to calculate the share count for commission fees (typically unadjusted VWAP).

trade_execution_price_column

vwap_adjusted

Column used as the trade execution price for buying/selling shares.

mark_to_market_price_column

close_adjusted

Column used for daily portfolio valuation between rebalancing dates.

date_column

date

Column containing trading dates.

System Settings#

Parameter

Example value

Description

logger_level

error

Logging verbosity. Valid values: debug, info, warning, error, critical.

Complete Example#

After editing, your Excel file (column A | column B) should look like this:

portfolio_name                     | my_portfolio
benchmark_file_name                | SPY
start_date                         | 2020-01-02
end_date                           | 2024-12-31
initial_capital                    | 100000
cash_reserve_percentage            | 0.05
commission_cents                   | 0.01
input_market_data_directory        | Input/Data
input_portfolio_directory          | Input/Portfolios
backtest_results_output_directory  | Output
market_data_input_format           | csv
portfolio_input_format             | csv
commission_price_column            | vwap
trade_execution_price_column       | vwap_adjusted
mark_to_market_price_column        | close_adjusted
date_column                        | date
logger_level                       | info

Programmatic Configuration#

When using BatchConfigParser.parse_dict() the dict keys follow the same parameter names, with column mappings prefixed by user_column_:

{
    "global_defaults": {
        "start_date": "2020-01-02",
        "end_date": "2024-12-31",
        "commission_cents": 0.01,
        "cash_reserve_percentage": 0.05,
        "user_column_commission_price": "vwap",
        "user_column_trade_execution_price": "vwap_adjusted",
        "user_column_mark_to_market_price": "close_adjusted",
        "user_column_date": "date",
        ...
    }
}

API Reference#

The following classes back the configuration system. Their docstrings are the authoritative reference for all parameters and validation rules.

class Configuration(initial_capital: Scalar | int | float | Decimal, start_date: date | Literal['auto'], end_date: date | Literal['auto'], cash_reserve_percentage: Scalar | float | Decimal, commission_cents: Scalar | float | Decimal, market_data_input_format: str, portfolio_name: str, portfolio_input_format: str, benchmark_file_name: str, input_market_data_directory: str, input_portfolio_directory: str, backtest_results_output_directory: str, user_column_commission_price: str, user_column_trade_execution_price: str, user_column_mark_to_market_price: str, user_column_date: str, commission_model: str = 'per_share', commission_basis_points: Scalar | float | Decimal = 0.0, max_gross_exposure: Scalar | float = 1.0, max_net_exposure: Scalar | float | None = None, financing_benchmark_rate: Scalar | float | str | None = 0.0, borrow_fee_rate: Scalar | float | None = 0.0, margin_interest_spread: Scalar | float | None = 0.0, cash_interest_spread: Scalar | float | None = 0.0, rebalance_date_handling: str = 'exact', delisted_position_handling: str = 'fail', delisting_exit_lead_days: int | float | Scalar | None = 0, user_column_borrow_fee_rate: str | None = None, slippage_model: str = 'none', slippage_basis_points: Scalar | float | Decimal = 0.0, market_impact_coefficient: Scalar | float | None = 0.1, user_column_volume: str | None = None, user_column_high: str | None = None, user_column_low: str | None = None, user_column_close: str | None = None, user_column_spread: str | None = None, execution_cost_window_days: int | float | Scalar | None = 20, spread_estimator: str = 'corwin_schultz')

Bases: object

Central configuration entity for the backtest engine.

Variables:
  • initial_capital (pa.Scalar | int | float | decimal.Decimal) – Starting capital for the backtest. Converted to PyArrow decimal128 during post-init validation.

  • start_date (DateConfig) – Backtest start date as datetime.date or "auto" to derive from portfolio data.

  • end_date (DateConfig) – Backtest end date as datetime.date or "auto".

  • cash_reserve_percentage (pa.Scalar | float | decimal.Decimal) – Fraction of capital held as cash (0.0 to 0.5). Converted to PyArrow decimal128 during post-init validation.

  • commission_cents (pa.Scalar | float | decimal.Decimal) – Per-share commission in cents (0.0 to 0.1). Converted to PyArrow decimal128 during post-init validation. Only used when commission_model is "per_share".

  • commission_model (str) – Commission model selector. One of CommissionModelType values ("per_share" or "basis_points"). Defaults to "per_share".

  • commission_basis_points (pa.Scalar | float | decimal.Decimal) – Commission in basis points (0 to 1000), used when commission_model is "basis_points". Validated via BasisPoints. Defaults to 0.0.

  • max_gross_exposure (pa.Scalar | float) – Maximum sum of absolute portfolio weights, as a multiple of capital. Defaults to 1.0, which is the long-only constraint of deploying at most 100% of capital. A 130/30 book needs 1.6. Validated via ExposureLimits.

  • max_net_exposure (pa.Scalar | float | None) – Maximum absolute net exposure (bound on |sum of weights|). None (the default) leaves it unconstrained; a market-neutral mandate would set something like 0.05.

  • financing_benchmark_rate (pa.Scalar | float | str | None) – Annual reference rate (Fed Funds effective for US dollars) as a fraction, e.g. 0.0433, or the name (without extension) of a rate file in the market data directory holding a dated series of such rates. Drives margin interest and cash interest, and is the risk-free rate of the Sharpe ratio. 0.0 or blank (the default) switches both off. Validated via FinancingTerms; after construction the attribute holds the number or the file name.

  • borrow_fee_rate (pa.Scalar | float | None) – Annual fee charged every day on the market value of short positions, as a fraction (0.003 for 30 bps). Not linked to the benchmark. 0.0 or blank (the default) switches it off.

  • margin_interest_spread (pa.Scalar | float | None) – Spread over the benchmark charged on a negative cash balance, as a fraction. Default 0.0.

  • cash_interest_spread (pa.Scalar | float | None) – Spread over the benchmark paid on a positive cash balance, as a fraction; usually zero or negative. The effective rate never goes below zero. Default 0.0.

  • rebalance_date_handling (str) – What to do when a rebalancing date in the portfolio file is not a trading day in the market data. One of RebalanceDateHandling values: "exact" (the default; such a date is an error) or "next_trading_day" (the rebalance moves to the next trading day with a warning).

  • delisted_position_handling (str) – What to do with a position whose price series ends before the backtest does. One of DelistedPositionHandling values: "fail" (the default; the integrity check rejects the portfolio), "sell_at_last_price" (the position is closed at the last available price and the proceeds stay in cash) or "mark_to_zero" (the position is written off on the first day without a price).

  • delisting_exit_lead_days (int | pa.Scalar | None) – With sell_at_last_price, how many trading days before the last price date the position is sold. 0 or blank (the default) sells on the last price date. Validated via DelistingPolicy.

  • market_data_input_format (str) – Market data file format (e.g. "csv", "parquet").

  • portfolio_name (str) – Name of the portfolio file (without extension).

  • portfolio_input_format (str) – Portfolio file format (e.g. "csv", "excel").

  • benchmark_file_name (str) – Benchmark ticker symbol (e.g. "SPY").

  • input_market_data_directory (str) – Path to the directory containing market data files.

  • input_portfolio_directory (str) – Path to the directory containing portfolio files.

  • backtest_results_output_directory (str) – Path to the directory for backtest output.

  • user_column_commission_price (str) – User’s CSV/Parquet column name for the commission price (typically unadjusted VWAP).

  • user_column_trade_execution_price (str) – User’s CSV/Parquet column name for the trade execution price (typically split/dividend-adjusted VWAP).

  • user_column_mark_to_market_price (str) – User’s CSV/Parquet column name for the mark-to-market price (typically split/dividend-adjusted close).

  • user_column_date (str) – User’s CSV/Parquet column name for date.

  • user_column_borrow_fee_rate (str | None) – User’s CSV/Parquet column name for an optional per-ticker annual borrow fee (a fraction). None or blank (the default) charges borrow_fee_rate on every short; when mapped, a ticker or day without a value falls back to it.

  • user_column_volume (str | None) – User’s column name for an optional daily share volume. Mapping it makes the engine compute each ticker’s average daily volume, which market-impact slippage models divide the order size by.

  • user_column_high (str | None) – User’s column name for an optional daily high. Mapping it together with user_column_low makes the engine estimate each ticker’s bid-ask spread from daily ranges.

  • user_column_low (str | None) – User’s column name for an optional daily low.

  • user_column_close (str | None) – User’s column name for an optional daily close. Only the Abdi-Ranaldo spread estimator needs it.

  • user_column_spread (str | None) – User’s column name for an optional vendor-provided full relative bid-ask spread, as a fraction of the price. When mapped it takes precedence over the estimators.

  • slippage_model (str) – Which slippage model runs: "none" (the default, no execution cost beyond commission), "basis_points", "half_spread", "square_root" or "spread_plus_impact".

  • slippage_basis_points (float) – Flat rate the basis_points model charges, and the half spread every other model falls back to for a ticker or day with no data of its own. Default 0.

  • market_impact_coefficient (float) – The k of k * volatility * sqrt(participation) in the models that price market impact. Default 0.1.

  • execution_cost_window_days (int) – Number of trading days in the window used for the average daily volume, the volatility and the spread estimate. Default 20; every window ends on the day before the one it is stamped on, so a model never sees the bar it is trading into.

  • spread_estimator (str) – Which estimator turns daily bars into a bid-ask spread: "corwin_schultz" (the default, needs only highs and lows) or "abdi_ranaldo" (more stable, also needs closes). Ignored when user_column_spread is mapped, since a vendor spread beats an estimate of one.

Notes

User column names are stored as explicit attributes matching StandardField. These map directly to StandardField enum values.

Both start_date and end_date support two modes:

  • Explicit date: A datetime.date object specifying the exact date.

  • Auto mode: The string "auto" to derive dates from portfolio data.

When "auto" is specified, dates are resolved during the data pipeline execution based on the first and last rebalancing dates in the portfolio.

backtest_results_output_directory: str
benchmark_file_name: str
borrow_fee_rate: Scalar | float | None
cash_interest_spread: Scalar | float | None
cash_reserve_percentage: Scalar | float | Decimal
commission_basis_points: Scalar | float | Decimal
commission_cents: Scalar | float | Decimal
commission_model: str
delisted_position_handling: str
delisting_exit_lead_days: int | float | Scalar | None
end_date: date | Literal['auto']
execution_cost_window_days: int | float | Scalar | None
financing_benchmark_rate: Scalar | float | str | None
get_benchmark_file_names() → list[str]

Parse benchmark_file_name into an ordered list of tickers.

The field accepts a single ticker ("SPY") or several comma-separated ones ("SPY,QQQ,IWM"). Surrounding whitespace is trimmed and blank entries are dropped. The first entry is the primary (comparison) benchmark. Returns an empty list when no benchmark is set.

Returns:

Benchmark tickers in the order given, primary first.

Return type:

list[str]

Examples

>>> config = Configuration(..., benchmark_file_name="SPY,QQQ")
>>> config.get_benchmark_file_names()
['SPY', 'QQQ']
get_delisting_policy() → DelistingPolicy

Build the DelistingPolicy these settings describe.

Returns:

Validated handling and exit lead. Already validated during __post_init__, so this cannot raise for a constructed Configuration. is_fail is True with the defaults.

Return type:

DelistingPolicy

Examples

>>> config.get_delisting_policy().is_fail
True
get_exposure_limits() → ExposureLimits

Build the ExposureLimits these settings describe.

Returns:

Validated gross and net bounds. Already validated during __post_init__, so this cannot raise for a constructed Configuration.

Return type:

ExposureLimits

Examples

>>> config.get_exposure_limits().gross
1.0
get_financing_terms() → FinancingTerms

Build the FinancingTerms these settings describe.

Returns:

Validated annual rates, plus the name of the rate file and of the per-ticker borrow column when configured. Already validated during __post_init__, so this cannot raise for a constructed Configuration. is_zero is True with the defaults.

Return type:

FinancingTerms

Examples

>>> config.get_financing_terms().is_zero
True
get_numeric_user_columns() → list[str]

Get user column names for numeric fields (excludes date).

Returns:

User column names for numeric fields (commission price, trade execution price, mark-to-market price).

Return type:

list[str]

get_primary_benchmark() → str | None

Return the primary (comparison) benchmark ticker, or None.

The primary benchmark is the first entry of get_benchmark_file_names() and is the one used for the portfolio-vs-benchmark comparison metrics (Alpha, information ratio).

get_rebalance_date_handling() → RebalanceDateHandling

The RebalanceDateHandling these settings select.

Returns:

Already validated during __post_init__.

Return type:

RebalanceDateHandling

Examples

>>> config.get_rebalance_date_handling()
<RebalanceDateHandling.EXACT: 'exact'>
get_slippage_terms() → SlippageTerms

The SlippageTerms these settings describe.

The value object is the authority on the ranges and on whether the selected model can work with the columns that are mapped, so this raises on a configuration that would charge nothing or price a whole universe off one made-up volume.

Returns:

Validated terms, with spread_source and the column flags derived from the mappings rather than read from the sheet: a mapped vendor spread column beats an estimate from daily bars, and an estimate beats one constant for every ticker.

Return type:

SlippageTerms

Raises:

ConfigurationError – If a parameter is out of range, or the model cannot work with the mapped columns.

get_spread_estimator() → SpreadEstimator

The SpreadEstimator these settings select.

Returns:

The member matching spread_estimator, already validated in __post_init__.

Return type:

SpreadEstimator

get_user_column(standard_field: StandardField) → str

Get the user’s column name for a given StandardField.

Parameters:

standard_field (StandardField) – The StandardField enum member to look up.

Returns:

The user’s column name string.

Return type:

str

Raises:

ConfigurationError – If standard_field is not a recognised mapping.

get_user_columns_dict() → dict[str, str]

Get mapping from standard field names to user column names.

Returns:

Dictionary mapping StandardField.value to user column name. An optional column is included only when mapped.

Return type:

dict[str, str]

get_user_columns_tuple() → tuple[str, ...]

Get all user column names as a tuple, ordered by STANDARD_FIELDS_ORDER.

Returns:

User column names in standard field order.

Return type:

tuple[str, …]

has_auto_dates() → bool

Check if either start_date or end_date is set to “auto”.

Returns:

True if at least one date is configured as “auto”, False if both dates are explicit datetime.date values.

Return type:

bool

Examples

>>> config = Configuration(..., start_date="auto", end_date=date(2024, 12, 31))
>>> config.has_auto_dates()
True
>>> config = Configuration(..., start_date=date(2024, 1, 1), end_date=date(2024, 12, 31))
>>> config.has_auto_dates()
False
initial_capital: Scalar | int | float | Decimal
input_market_data_directory: str
input_portfolio_directory: str
is_end_date_auto() → bool

Check if end_date is set to “auto”.

is_start_date_auto() → bool

Check if start_date is set to “auto”.

margin_interest_spread: Scalar | float | None
market_data_input_format: str
market_impact_coefficient: Scalar | float | None
max_gross_exposure: Scalar | float
max_net_exposure: Scalar | float | None
portfolio_input_format: str
portfolio_name: str
rebalance_date_handling: str
slippage_basis_points: Scalar | float | Decimal
slippage_model: str
spread_estimator: str
start_date: date | Literal['auto']
user_column_borrow_fee_rate: str | None
user_column_close: str | None
user_column_commission_price: str
user_column_date: str
user_column_high: str | None
user_column_low: str | None
user_column_mark_to_market_price: str
user_column_spread: str | None
user_column_trade_execution_price: str
user_column_volume: str | None
with_overrides(*, commission_cents: float | None = None, cash_reserve_percentage: float | None = None, start_date: date | Literal['auto'] | None = None, end_date: date | Literal['auto'] | None = None, initial_capital: int | float | Decimal | None = None, commission_model: str | None = None, commission_basis_points: float | None = None, max_gross_exposure: float | None = None, max_net_exposure: float | None = None, financing_benchmark_rate: float | str | None = None, borrow_fee_rate: float | None = None, margin_interest_spread: float | None = None, cash_interest_spread: float | None = None, rebalance_date_handling: str | None = None, delisted_position_handling: str | None = None, delisting_exit_lead_days: int | None = None, user_column_borrow_fee_rate: str | None = None, user_column_volume: str | None = None, user_column_high: str | None = None, user_column_low: str | None = None, user_column_close: str | None = None, user_column_spread: str | None = None, execution_cost_window_days: int | None = None, spread_estimator: str | None = None, slippage_model: str | None = None, slippage_basis_points: float | None = None, market_impact_coefficient: float | None = None) → Configuration

Create a new Configuration with specified field overrides.

This method provides a clean API for creating configuration variations without directly using dataclasses.replace(). Only the specified fields are modified; all other fields retain their original values.

Parameters:
  • commission_cents (float | None, optional) – Override for commission rate per share in cents. Must be in range [0.0, 0.1].

  • cash_reserve_percentage (float | None, optional) – Override for cash reserve percentage. Must be in range [0.0, 0.5].

  • start_date (DateConfig | None, optional) – Override for backtest start date. Can be datetime.date or “auto”.

  • end_date (DateConfig | None, optional) – Override for backtest end date. Can be datetime.date or “auto”.

  • initial_capital (int | float | Decimal | None, optional) – Override for initial capital amount.

  • commission_model (str | None, optional) – Override for the commission model selector ("per_share" or "basis_points").

  • commission_basis_points (float | None, optional) – Override for the commission in basis points (0 to 1000).

  • max_gross_exposure (float | None, optional) – Override for the gross exposure limit (sum of absolute weights, as a multiple of capital).

  • max_net_exposure (float | None, optional) – Override for the net exposure limit. Note that None means “no override” here, so this method cannot clear an existing net limit — build a new Configuration for that.

  • financing_benchmark_rate (float | str | None, optional) – Override for the annual benchmark rate (fraction) or the name of a rate file in the market data directory.

  • borrow_fee_rate (float | None, optional) – Override for the annual borrow fee on short positions (fraction).

  • margin_interest_spread (float | None, optional) – Override for the margin interest spread over the benchmark.

  • cash_interest_spread (float | None, optional) – Override for the cash interest spread over the benchmark.

  • rebalance_date_handling (str | None, optional) – Override for the rebalancing-date handling selector ("exact" or "next_trading_day").

  • delisted_position_handling (str | None, optional) – Override for the delisted-position handling selector ("fail", "sell_at_last_price" or "mark_to_zero").

  • delisting_exit_lead_days (int | None, optional) – Override for the number of trading days before the last price date on which a delisted position is sold.

  • user_column_borrow_fee_rate (str | None, optional) – Override for the optional per-ticker borrow fee column. Note that None means “no override” here, so this method cannot unmap the column — build a new Configuration for that.

  • user_column_volume (str | None, optional) – Override for the optional daily volume column, on the same terms as the borrow fee column.

  • user_column_high (str | None, optional) – Override for the optional daily high column.

  • user_column_low (str | None, optional) – Override for the optional daily low column.

  • user_column_close (str | None, optional) – Override for the optional daily close column.

  • user_column_spread (str | None, optional) – Override for the optional vendor spread column.

  • execution_cost_window_days (int | None, optional) – Override for the window of the execution-cost metrics.

  • spread_estimator (str | None, optional) – Override for the spread estimator selector.

  • slippage_model (str | None, optional) – Override for the slippage model selector.

  • slippage_basis_points (float | None, optional) – Override for the flat slippage rate and half-spread fallback.

  • market_impact_coefficient (float | None, optional) – Override for the market-impact coefficient.

Returns:

New Configuration instance with the specified overrides applied.

Return type:

Configuration

Raises:

ConfigurationError – If any override value fails validation.

Examples

Create a commission variation:

>>> config_low_comm = base_config.with_overrides(commission_cents=0.01)

Create a date range variation:

>>> config_2022 = base_config.with_overrides(
...     start_date=datetime.date(2022, 1, 1),
...     end_date=datetime.date(2022, 12, 31),
... )

Combine multiple overrides:

>>> config_var = base_config.with_overrides(
...     commission_cents=0.02,
...     cash_reserve_percentage=0.10,
... )

Notes

This method is designed for use with BacktestVariationRunner to efficiently create multiple configuration variations from a single base configuration. The returned Configuration undergoes full validation through __post_init__.

class ExcelConfigurator(file_path: str, logger_format: str = '[%(levelname)s] %(message)s')

Bases: ConfiguratorInterface

Excel-based configuration loader.

Reads configuration from an Excel file with a ‘General’ sheet containing all configuration parameters including user’s CSV column name mappings.

get_configuration() → Configuration

Return the loaded Configuration entity.

Return type:

The Configuration instance

get_dashboard_port() → int

Return the dashboard port parsed from the Excel configuration.

Returns:

A valid port number (1-9999).

Return type:

int

get_logger_level() → int

Return the logger level parsed from the Excel configuration.

Returns:

A logging level constant (e.g. logging.INFO).

Return type:

int

class BatchConfigParser

Bases: object

Static parser for batch backtest configuration.

All methods are static/classmethod — no instance state needed.

static expand_portfolio_directory(directory: str, portfolio_input_format: str = 'csv', existing_names: set[str] | None = None) → list[PortfolioDefinition]

Scan a directory for portfolio files and create PortfolioDefinitions.

Auto-discovers all portfolio files in the given directory. The portfolio name is derived from the filename (without extension). Files whose stem matches an already-defined portfolio name are skipped to avoid duplicates.

Parameters:
  • directory (str) – Path to the directory containing portfolio files.

  • portfolio_input_format (str) – File format to scan for: “csv” or “excel”.

  • existing_names (set[str] | None) – Portfolio names already defined. Files matching these names are skipped.

Returns:

One PortfolioDefinition per discovered file.

Return type:

list[PortfolioDefinition]

static expand_variations(portfolio_def: PortfolioDefinition, sweeps: list[ParametricSweep]) → list[VariationDict]

Expand per-portfolio variations and applicable parametric sweeps.

Combines the portfolio’s own variations list with any parametric sweeps that apply to this portfolio.

Parameters:
  • portfolio_def (PortfolioDefinition) – Portfolio definition with optional variations.

  • sweeps (list[ParametricSweep]) – Global parametric sweeps.

Returns:

List of variation dicts, each with “name” and override fields.

Return type:

list[VariationDict]

static normalize_inline_weights(inline_weights: dict[str, dict[str, float]] | dict[str, float], start_date: str | date | None) → dict[str, dict[str, float]]

Normalize inline weights to dated format.

If weights are flat ({"AAPL": 0.5, "MSFT": 0.5}), converts to dated format using the provided start_date as the single date key.

Parameters:
  • inline_weights (dict) – Either flat or dated weight dictionary.

  • start_date (str | datetime.date | None) – Start date to use for flat weights.

Returns:

Dated weights: {"YYYY-MM-DD": {"TICKER": weight, ...}}.

Return type:

dict[str, dict[str, float]]

Raises:

BatchConfigError – If flat weights are provided but no start_date is available.

static parse_dict(raw: dict[str, YamlValue]) → BatchConfig

Parse a raw dictionary into a BatchConfig.

Parameters:

raw (dict) – Dictionary with batch configuration keys.

Returns:

Parsed batch configuration.

Return type:

BatchConfig

Raises:

BatchConfigError – If required keys are missing or structure is invalid.

static parse_file(yaml_path: str | Path) → BatchConfig

Parse a YAML file into a BatchConfig.

Parameters:

yaml_path (str | Path) – Path to the YAML configuration file.

Returns:

Validated batch configuration object.

Return type:

BatchConfig

Raises:

BatchConfigError – If the file cannot be read or contains invalid YAML.

static resolve_configuration(portfolio_def: PortfolioDefinition, defaults: GlobalDefaults, templates: dict[str, PortfolioTemplate]) → Configuration

Build a Configuration from global defaults + template + portfolio overrides.

Merge order (later takes precedence): 1. Global defaults 2. Template overrides (if portfolio references a template) 3. Portfolio-level overrides

Parameters:
  • portfolio_def (PortfolioDefinition) – The portfolio definition to build a config for.

  • defaults (GlobalDefaults) – Global default values.

  • templates (dict[str, PortfolioTemplate]) – Available templates.

Returns:

Fully resolved Configuration entity.

Return type:

Configuration

Raises:

BatchConfigError – If required fields are missing after merging.

static resolve_template_weights(portfolio_def: PortfolioDefinition, templates: dict[str, PortfolioTemplate]) → dict[str, dict[str, float]] | None

Resolve portfolio weights from template + weight_overrides.

Returns None if the portfolio doesn’t use a template or if the template has no tickers (file-based portfolio).

Parameters:
  • portfolio_def (PortfolioDefinition) – Portfolio definition.

  • templates (dict[str, PortfolioTemplate]) – Available templates.

Returns:

Dated weights dict ready for PortfolioEntity.from_dict(), or None if not template-based.

Return type:

dict[str, dict[str, float]] | None