Skip to content

rule_engine

Position-aware RuleEngine: applies accounting rules to open positions.

Rules are executed in a defined priority order to ensure logical consistency:

  1. Accruals — recognize earned/owed amounts (no cash movement)
  2. Mark-to-market — revalue positions to fair value
  3. Cash flows — coupon payments, interest settlements, amortization
  4. Maturity — settle and close positions (must be last)

Classes:

  • AccountingRule

    Protocol for position-aware accounting rules.

  • RuleEngine

    Applies accounting rules declared by each instrument to open positions.

AccountingRule

Bases: Protocol

Protocol for position-aware accounting rules.

Methods:

  • applies_to

    Return True if this rule applies to the given instrument and position.

  • generate

    Generate transactions for the given instrument and position.

applies_to

applies_to(
    instrument: Instrument,
    position: Position,
    context: RuleContext,
) -> bool

Return True if this rule applies to the given instrument and position.

generate

generate(
    instrument: Instrument,
    position: Position,
    context: RuleContext,
) -> list[Transaction]

Generate transactions for the given instrument and position.

RuleEngine

RuleEngine(
    rules: dict[type, AccountingRule]
    | Iterable[AccountingRule] = (),
)

Applies accounting rules declared by each instrument to open positions.

Rules are keyed by their class. Each instrument declares which rule classes apply to it via instrument.applicable_rules (a frozenset of rule classes). The engine only runs rules that the instrument opts into.

Rules are executed in priority order (accruals → mark-to-market → cash flows → maturity) to ensure logical consistency.

Methods:

  • apply

    Apply instrument-declared rules to every open position.

  • register

    Register an accounting rule with the engine.

apply

apply(
    bank: Bank,
    valuation_store: ValuationStore,
    market_state: MarketState | None,
    date: date,
    previous_date: date | None = None,
    *,
    has_market_data: bool = True,
) -> list[Transaction]

Apply instrument-declared rules to every open position.

For each open position the engine reads instrument.applicable_rules to determine which rules to evaluate. Only rules whose applies_to returns True produce transactions. Rules are sorted by priority so that accruals run before mark-to-market, cash flows, and maturity.

register

register(rule: AccountingRule) -> None

Register an accounting rule with the engine.