Pipeline Customization#
The pipeline manages event execution order during each simulation period. BAM Engine uses explicit ordering: events run in the exact order listed, with no automatic dependency resolution. This matches the original BAM model specification and makes the execution flow predictable and debuggable.
The Default Pipeline#
The default pipeline executes 8 phases per period. Labor and credit market matching uses batch processing with vectorized NumPy operations. The goods market uses sequential processing where each consumer completes all visits before the next consumer starts.
Phase 1: Planning (6 events)
firms_decide_desired_production
firms_plan_breakeven_price
firms_plan_price
firms_decide_desired_labor
firms_decide_vacancies
firms_fire_excess_workers
Phase 2: Labor Market (4 setup + max_M rounds + wage bill)
calc_inflation_rate
adjust_minimum_wage
firms_decide_wage_offer
workers_decide_firms_to_apply
labor_market_round x max_M
firms_calc_wage_bill
labor_market_round x max_M expands to max_M batch matching rounds
(default: 4). Each round processes all applications simultaneously using
vectorized conflict resolution.
Phase 3: Credit Market (5 setup + max_H rounds + firing)
banks_decide_credit_supply
banks_decide_interest_rate
firms_decide_credit_demand
firms_calc_financial_fragility
firms_prepare_loan_applications
credit_market_round x max_H
firms_fire_workers
Phase 4: Production (5 events)
firms_pay_wages
workers_receive_wage
firms_run_production
update_avg_mkt_price
workers_update_contracts
Phase 5: Goods Market (5 events)
consumers_calc_propensity
consumers_decide_income_to_spend
consumers_decide_firms_to_visit
goods_market_round
consumers_finalize_purchases
Phase 6: Revenue (3 events)
firms_collect_revenue
firms_validate_debt_commitments
firms_pay_dividends
Phase 7: Bankruptcy (3 events)
firms_update_net_worth
mark_bankrupt_firms
mark_bankrupt_banks
Phase 8: Entry (2 events)
spawn_replacement_firms
spawn_replacement_banks
Pipeline Hooks (Recommended)#
The simplest way to customize the pipeline is using pipeline hooks. Declare where your custom event should be inserted directly in the decorator:
from bamengine import event, Simulation
import bamengine as bam
@event(after="firms_pay_dividends")
class MyCustomEvent:
"""Positioned after firms_pay_dividends via hook metadata."""
def execute(self, sim: Simulation) -> None:
pass
# Hooks are NOT auto-applied; use sim.use_events() to activate them
sim = bam.Simulation.init(seed=42)
sim.use_events(MyCustomEvent)
Hook types:
after="event_name": Insert immediately after the target eventbefore="event_name": Insert immediately before the target eventreplace="event_name": Replace the target event entirely
Key points:
Hooks are stored as class attributes, NOT applied automatically
Call
sim.use_events(*event_classes)to apply hooks to the pipelineMultiple events targeting the same point are inserted in the order passed to
use_events()No import ordering constraints: import extensions anywhere before calling
use_events()
Manual Pipeline Modification#
For more control, modify the pipeline directly after initialization:
import bamengine as bam
sim = bam.Simulation.init(seed=42)
# Insert events at specific positions
sim.pipeline.insert_after("firms_adjust_price", "my_custom_event")
sim.pipeline.insert_before("firms_adjust_price", "pre_pricing_check")
# Remove an event
sim.pipeline.remove("labor_market_round_0")
# Replace an event
sim.pipeline.replace("firms_decide_desired_production", "my_production_rule")
All pipeline modifications should happen before calling sim.run() or
sim.step().
Custom Pipeline YAML#
For full control over the event sequence, create a custom pipeline YAML file:
sim = bam.Simulation.init(pipeline_path="custom_pipeline.yml", seed=42)
YAML syntax:
events:
# Simple event: execute once per period
- firms_decide_desired_production
# Repeated event: execute N times
- labor_market_round x 4
# Parameter substitution: use config values
- labor_market_round x {max_M}
- credit_market_round x {max_H}
Parameter substitution replaces {param_name} with the corresponding
configuration value at pipeline load time. Available substitutions:
{max_M}: Number of labor market matching rounds{max_H}: Number of credit market matching rounds
Planning-Phase Pricing (Alternative)#
BAM Engine provides an alternative pair of pricing events that run during the planning phase instead of the production phase:
firms_plan_breakeven_price: Breakeven from previous period’s costs / desired productionfirms_plan_price: Price adjustment with breakeven floor
These are mutually exclusive with the production-phase pair
(firms_calc_breakeven_price, firms_adjust_price). The default pipeline
uses planning-phase pricing. To switch to production-phase pricing, create a
custom pipeline that moves the pricing events:
events:
# Planning (no pricing events)
- firms_decide_desired_production
- firms_decide_desired_labor
- firms_decide_vacancies
- firms_fire_excess_workers
# ... labor and credit market phases ...
# Production (pricing moved here)
- firms_pay_wages
- workers_receive_wage
- firms_calc_breakeven_price
- firms_adjust_price
- firms_run_production
- update_avg_mkt_price
- workers_update_contracts
Inspecting the Pipeline#
View the current pipeline to verify event ordering:
sim = bam.Simulation.init(seed=42)
# List all events in execution order
for entry in sim.pipeline:
print(entry.name)
# Check total event count
print(f"Pipeline has {len(sim.pipeline)} events")
This is especially useful after applying hooks to verify insertion points.
Tips#
Explicit ordering is intentional: BAM Engine deliberately avoids topological sorting. The execution order is a core part of the model specification.
Hook activation is explicit: Always call
sim.use_events()after init; declaring@event(after=...)alone does nothing.Modify before running: Pipeline changes should happen between
Simulation.init()andsim.run(), not during execution.Batch matching: Labor and credit markets use vectorized batch matching with conflict resolution. The goods market uses sequential processing.
See also
Custom Events for creating events to hook into the pipeline
The BAM Model for the economic logic of each phase
Model Extensions for how built-in extensions modify the pipeline