FirmsValidateDebtCommitments#

class bamengine.events.revenue.FirmsValidateDebtCommitments[source]#

Bases: Event

Firms repay debts or write off if insufficient funds.

Firms attempt to repay all outstanding debt (principal + interest). If funds are insufficient, banks recover a proportional share of the firm’s remaining equity (if positive), capped at the loan principal. The bank’s actual loss is the unrecovered portion of the principal.

Algorithm

For each firm i:

  1. Calculate total debt: \(D_i = \sum \text{debt}\) for all loans to firm i

  2. If \(A_i \geq D_i\) (can repay): - Pay full debt: \(A_i \leftarrow A_i - D_i\) - Bank receives payment - Remove loans from LoanBook - Net profit: \(NP_i = GP_i - \text{interest\_paid}\)

  3. Else (cannot repay):

    • For each loan, compute the bank’s proportional claim \(\text{frac} = \text{principal}_\text{loan} / \text{principal}_\text{total}\)

    • Recovery (capped at principal, floored at 0): \(R = \text{clip}(\text{frac} \times A_i,\; 0,\; \text{principal}_\text{loan})\)

    • Bank loss: \(L = \text{principal}_\text{loan} - R\)

    • Bank absorbs loss: \(E_k \leftarrow E_k - L\)

    • Net profit: \(NP_i = GP_i - \text{interest\_paid}\) (partial)

Examples

>>> import bamengine as be
>>> sim = be.Simulation.init(n_firms=100, n_banks=10, seed=42)
>>> event = sim.get_event("firms_validate_debt_commitments")
>>> event.execute(sim)

Check firms that repaid fully:

>>> import numpy as np
>>> # Firms with zero debt repaid successfully
>>> total_debt = sim.lb.debt_per_borrower(n_borrowers=100)
>>> fully_repaid = total_debt == 0
>>> fully_repaid.sum()
65

Check net profit after interest:

>>> sim.bor.net_profit.sum()
1850.0

Notes

This event must execute after FirmsCollectRevenue (need funds from sales).

Write-offs reduce bank equity (banks absorb losses from defaults).

Net profit = gross_profit - interest_paid (after debt service).

See also

FirmsCollectRevenue

Provides funds for debt repayment

LoanBook

Stores debt relationships

bamengine.events._internal.firms_validate_debt_commitments

Implementation

execute(sim)[source]#

Execute the event’s logic.

Mutates simulation state in-place. This method must be implemented by all Event subclasses.

Parameters:

sim (Simulation) – The simulation instance containing all state and configuration.

Returns:

All mutations are in-place.

Return type:

None

Examples

Implement execute in a custom event:

>>> from bamengine import event, ops
>>>
>>> @event
... class CustomPricingEvent:
...     def execute(self, sim):
...         prod = sim.get_role("Producer")
...         # Apply 10% markup to all prices
...         new_prices = ops.multiply(prod.price, 1.1)
...         ops.assign(prod.price, new_prices)

Access configuration and RNG:

>>> @event
... class StochasticEvent:
...     def execute(self, sim):
...         shock = sim.config.h_rho
...         random_values = sim.rng.uniform(0, shock, size=sim.n_firms)
...         # Use random_values in calculations

Notes

The execute method receives full Simulation access, including: - All roles: sim.get_role(“RoleName”) or sim.prod, sim.wrk, etc. - Configuration: sim.config - RNG: sim.rng - Economy state: sim.ec

__init__()#
name = 'firms_validate_debt_commitments'#