Panel

Overview

Panel is the explicit data object in BagelQuant. Every input panel is created through a Domain, which defines trading sessions and asset membership. A panel stores a numeric two-dimensional frame:

Time x Assets
import pandas as pd

from bagelquant_core import Domain, Panel

domain = Domain(
    calendar=pd.bdate_range("2024-01-01", "2024-12-31"),
    universe=["AAPL", "MSFT"],
)
price = Panel.from_domain(price_df, domain, name="price")

Role

Panels are:

  • Raw input data
  • DAG leaf nodes
  • Materialized graph outputs
  • Cache values stored by the internal execution runtime

Factors, predictions, and portfolio weights are normally represented as lazy graphs until their output panels are needed.

Invariants

Panels:

  • Have a one-dimensional unique index
  • Have one-dimensional unique columns
  • Contain only numeric values
  • Copy input data at construction
  • Return a defensive copy when data is accessed through Panel.data
  • Are immutable from the public API
  • Match their Domain’s trading-session index and universe columns
  • Mask inactive cells for dynamic universes

Alignment

Multi-input composer functions require equivalent Domains. The runtime reapplies dynamic-universe membership after each derived computation so inactive cells cannot affect later operations.

Dynamic Universes

A dynamic universe is a boolean frame indexed by dates and asset columns. Missing rows and cells are inactive; membership is not forward-filled:

membership = pd.DataFrame(
    {"AAPL": [True], "MSFT": [False]},
    index=pd.to_datetime(["2024-01-03"]),
)
domain = Domain(
    calendar=pd.bdate_range("2024-01-01", "2024-01-31"),
    universe=membership,
)

Calendar

Domain never retrieves calendars. Provide a non-empty, unique, sorted calendar from your data layer. The first and last sessions define the domain’s start and end dates.

Category Panels

CategoryPanel is an immutable leaf node for labels such as industry, sector, or country. It follows the same time-by-asset shape as Panel but accepts string labels:

import pandas as pd

from bagelquant_core import CategoryPanel

industry = CategoryPanel.from_domain(
    pd.DataFrame(...),
    domain,
    name="industry",
)

Use category panels with the category operations exported from bagelquant_core.transformer.