Pure funding-income projections for margin payback timelines.
Computes best-, expected-, and worst-case payback horizons from remaining debt, average daily funding income, and funding-rate volatility. Income tracking and persistence live in the dashboard — this module is projection math only.
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
project_payback_timeline | 1 | Project best-, expected-, and worst-case payback days under funding income volatility (not single-scenario payoff dates — see MarginBridge.payback_timeline/3). | params: value |
Summary
Functions
Projects payback days under high-, current-, and low-funding scenarios.
Types
@type payback_days() :: non_neg_integer() | nil
@type payback_params() :: %{ remaining_debt: DeltaCalc.Decimal.input(), daily_funding: DeltaCalc.Decimal.input(), funding_volatility: DeltaCalc.Decimal.input() }
@type payback_timeline() :: %{ best_case: payback_days(), expected: payback_days(), worst_case: payback_days() }
Functions
@spec project_payback_timeline(payback_params()) :: payback_timeline()
Projects payback days under high-, current-, and low-funding scenarios.
Volatility scales daily income by ±funding_volatility:
- best_case — debt divided by
daily_funding * (1 + volatility)(funding stays high) - expected — debt divided by
daily_funding(current rate continues) - worst_case — debt divided by
daily_funding * (1 - volatility)(funding stays low)
Returns nil for scenarios where effective daily income is zero or negative.
Zero remaining debt yields 0 for all cases.
Day counts are an intrinsic whole-day boundary, so positive fractional days
round up to the next integer day.
Examples
iex> DeltaCalc.FundingProjection.project_payback_timeline(%{
...> remaining_debt: 2700,
...> daily_funding: 90,
...> funding_volatility: "0.2"
...> })
%{best_case: 25, expected: 30, worst_case: 38}
iex> DeltaCalc.FundingProjection.project_payback_timeline(%{
...> remaining_debt: 0,
...> daily_funding: 90,
...> funding_volatility: "0.2"
...> })
%{best_case: 0, expected: 0, worst_case: 0}