Skip to content

Callbacks

Planned interventions with an audit trail. Guide: Callbacks.

SimulationCallback

Base class for planned interventions in a run, in the spirit of Keras callbacks.

Override one or both hooks. Return None to change nothing. The engine validates each proposal, applies it, and records it in SimulationResult.to_callback_audit_frame(). Callbacks receive copies of the state; they never change it directly.

  • on_after_prediction runs after the policy proposes an order and before ordering constraints. It can set new order quantities.
  • on_after_demand runs after demand is served. It can add or remove on-hand stock, which affects later decisions.
Example
class DoubleOrdersOn(SimulationCallback):
    def __init__(self, date):
        self.date = pd.Timestamp(date)

    def on_after_prediction(self, decision, context):
        if context.date != self.date:
            return None
        orders = decision.get_dataframe()
        return OrderAdjustmentResult(pd.DataFrame({
            "unique_id": orders["unique_id"],
            "order_quantity": 2 * orders["order_quantity"],
            "reason": "promotion", "source": "marketing",
        }))

reset

reset(context: CallbackContext) -> None

Reset run-local state. Called before every run and comparison branch.

Parameters:

Name Type Description Default
context CallbackContext

Context of the opening state.

required

on_after_demand

on_after_demand(
    context: CallbackContext,
) -> InventoryAdjustmentResult | None

Propose on-hand adjustments after demand is served.

Parameters:

Name Type Description Default
context CallbackContext

The state after demand, and the period's date and window.

required

Returns:

Type Description
InventoryAdjustmentResult | None

An InventoryAdjustmentResult, or None for no change.

on_after_prediction

on_after_prediction(
    decision: OrderDecision, context: CallbackContext
) -> OrderAdjustmentResult | None

Propose order quantities after the policy's prediction.

Parameters:

Name Type Description Default
decision OrderDecision

A copy of the current OrderDecision.

required
context CallbackContext

The state before demand, and the period's date and window.

required

Returns:

Type Description
OrderAdjustmentResult | None

An OrderAdjustmentResult, or None for no change.

get_config

get_config() -> dict

Settings recorded in the run manifest.

Returns:

Type Description
dict

A JSON-serialisable dict (empty by default).

CallbackContext dataclass

CallbackContext(
    inventory: DataFrame,
    sku_column: str,
    period: int,
    date: Timestamp,
    run_window: str,
    phase: str,
)

Read-only information given to a callback at one hook.

Attributes:

Name Type Description
inventory DataFrame

A copy of the state table at this moment.

sku_column str

Name of the SKU column.

period int

State period (opening period + demand period + 1).

date Timestamp

Date of the period.

run_window str

"warmup", "scoring" or "settlement".

phase str

"on_after_prediction" or "on_after_demand".

OrderAdjustmentResult

OrderAdjustmentResult(adjustments: DataFrame)

Order quantities proposed by on_after_prediction.

Parameters:

Name Type Description Default
adjustments DataFrame

One row per SKU to change, with unique_id and order_quantity (the new absolute quantity, >= 0); optionally reason and source labels for the audit. SKUs not listed keep their quantity.

required

get_dataframe

get_dataframe() -> DataFrame

Return a copy of the proposed quantities.

InventoryAdjustmentResult

InventoryAdjustmentResult(adjustments: DataFrame)

Signed on-hand changes proposed by on_after_demand.

Parameters:

Name Type Description Default
adjustments DataFrame

One row per SKU with unique_id and quantity_delta (positive adds stock, negative removes it); optionally reason and source labels for the audit, and received_date (needed for added stock under shelf life).

required

get_dataframe

get_dataframe() -> DataFrame

Return a copy of the proposed adjustments.

ScheduledOrderOverride

ScheduledOrderOverride(
    schedule: DataFrame,
    *,
    sku_column: str = "unique_id",
    date_column: str = "date",
    period_column: str = "period",
)

Bases: _ScheduledCallback

Set the order to a fixed quantity on scheduled dates.

Parameters:

Name Type Description Default
schedule DataFrame

One row per SKU and date (or state period), with columns unique_id, date and/or period, and optional reason and source labels recorded in the audit; plus order_quantity (>= 0).

required
sku_column str

SKU column of schedule (default "unique_id").

'unique_id'
date_column str

Date column of schedule (default "date").

'date'
period_column str

Period column of schedule (default "period").

'period'

ScheduledOrderMultiplier

ScheduledOrderMultiplier(
    schedule: DataFrame,
    *,
    sku_column: str = "unique_id",
    date_column: str = "date",
    period_column: str = "period",
)

Bases: _ScheduledCallback

Multiply the policy's order on scheduled dates.

Parameters:

Name Type Description Default
schedule DataFrame

One row per SKU and date (or state period), with columns unique_id, date and/or period, and optional reason and source labels recorded in the audit; plus multiplier (>= 0).

required
sku_column str

SKU column of schedule (default "unique_id").

'unique_id'
date_column str

Date column of schedule (default "date").

'date'
period_column str

Period column of schedule (default "period").

'period'

ScheduledOrderHold

ScheduledOrderHold(
    schedule: DataFrame,
    *,
    sku_column: str = "unique_id",
    date_column: str = "date",
    period_column: str = "period",
)

Bases: _ScheduledCallback

Set the order to zero on scheduled dates, for example supplier holidays.

Parameters:

Name Type Description Default
schedule DataFrame

One row per SKU and date (or state period), with columns unique_id, date and/or period, and optional reason and source labels recorded in the audit.

required
sku_column str

SKU column of schedule (default "unique_id").

'unique_id'
date_column str

Date column of schedule (default "date").

'date'
period_column str

Period column of schedule (default "period").

'period'

ScheduledInventoryAdjustment

ScheduledInventoryAdjustment(
    schedule: DataFrame,
    *,
    sku_column: str = "unique_id",
    date_column: str = "date",
    period_column: str = "period",
)

Bases: _ScheduledCallback

Add or remove on-hand stock after demand on scheduled dates.

Useful for stock counts, damages, and one-off corrections. Removals cannot exceed on-hand stock, and stock cannot be added while the SKU has backorders.

Parameters:

Name Type Description Default
schedule DataFrame

One row per SKU and date (or state period), with columns unique_id, date and/or period, and optional reason and source labels recorded in the audit; plus a signed quantity_delta and, for stock added under shelf life, an optional received_date.

required
sku_column str

SKU column of schedule (default "unique_id").

'unique_id'
date_column str

Date column of schedule (default "date").

'date'
period_column str

Period column of schedule (default "period").

'period'

CallbackError

Bases: RuntimeError

A callback failed or returned an invalid adjustment.

The message names the callback, its position, the hook, the period, and the date; the original exception is chained as the cause.