HKUDS/Vibe-Trading · error · ConvergenceError

ConvergenceError(period, iterations, delta, circularity_tole

Error message

ConvergenceError(period, iterations, delta, circularity_tolerance)

What it means

The three-statement model solves debt/cash circularity iteratively per period; _project_period iterates up to max_circularity_iterations and declares convergence when the update delta falls below circularity_tolerance*scale. If the fixed point is not reached in the budget, it raises ConvergenceError with the period, iterations, final delta and tolerance so you can tell how far off it is.

Source

Thrown at agent/src/quantlib/valuation/threestatement.py:614

            surplus = cash_before_revolver - minimum_cash
            revolver_repayment = min(surplus, debt_begin)
            revolver_draw = 0.0
        else:
            revolver_draw = minimum_cash - cash_before_revolver
            revolver_repayment = 0.0

        debt_end_actual = debt_begin + revolver_draw - revolver_repayment
        cash_end = cash_before_revolver + revolver_draw - revolver_repayment

        scale = max(abs(debt_end_actual), 1.0)
        delta = abs(debt_end_actual - debt_end_guess)
        if delta <= circularity_tolerance * scale:
            converged = True
            break
        debt_end_guess = debt_end_actual

    if not converged:
        raise ConvergenceError(period, iterations, delta, circularity_tolerance)

    financing_activities = revolver_draw - revolver_repayment - dividends_paid
    net_change_in_cash = net_income + depreciation_amortization - change_in_nwc - capex + financing_activities

    income_statement = IncomeStatement(
        period=period,
        revenue=revenue,
        gross_profit=gross_profit,
        opex=opex,
        ebitda=ebitda,
        depreciation_amortization=depreciation_amortization,
        ebit=ebit,
        interest_expense=interest_expense,
        pretax_income=pretax_income,
        tax_expense=tax_expense,
        net_income=net_income,
    )
    cash_flow_statement = CashFlowStatement(

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Raise max_circularity_iterations (e.g. 100 -> 1000) — check the reported delta trend to see if it is converging slowly vs oscillating.
  2. Relax circularity_tolerance to something commensurate with your figures' scale (it is relative to balance size).
  3. If delta is not decreasing, revisit extreme drivers (payout > earnings, capex > FCF) that may create a divergent or oscillating fixed point.

Example fix

# before
result = project_three_statement(opening, drivers)  # ConvergenceError
# after
result = project_three_statement(
    opening, drivers,
    max_circularity_iterations=1000,
    circularity_tolerance=1e-8,
)
Defensive patterns

Strategy: retry

Validate before calling

# cannot fully pre-validate; sanity-check extremes
assert all(abs(g) < 2.0 for g in drivers['revenue_growth'])  # implausible growth hints at divergence

Try / catch

from quantlib.valuation.threestatement import ConvergenceError
for iters in (100, 500, 2000):
    try:
        return project_three_statement(opening, drivers, max_circularity_iterations=iters)
    except ConvergenceError as e:
        last = e
raise last

Prevention

When it happens

Trigger: Highly levered or volatile driver sets where debt swings large amounts each iteration; circularity_tolerance set extremely small (e.g. 1e-14); max_circularity_iterations left at a low default while the model needs more passes; NaN-adjacent scale issues.

Common situations: Stress-test scenarios with extreme growth or payout ratios; tightening tolerance for audit-grade precision without raising iterations; opening balance sheets far from steady state.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/d7ac132851f9cfdf. Report an issue: GitHub.