Finance Operations¶
Finance operations are available at two levels:
- Frame-level: Called on
af.finance(operates on the entire frame) - Column-level: Called on
af["column"].finance(operates on a specific column)
Frame-Level Operations¶
gaspatchio_core.accessors.finance.FinanceFrameAccessor
¶
Bases: BaseFrameAccessor
Financial operations at the frame level for ActuarialFrame.
Provides frame-level methods for financial calculations that require coordinated operations across multiple columns, particularly for list columns in actuarial projections.
Accessed via .finance on an ActuarialFrame instance.
Methods¶
discount_factor(rate_col, periods_col, output_col, method="spot") Calculate discount factors from list columns using native Polars. Supports spot and forward discounting without map_elements. present_value(cashflow_col, rate_col, period_col) Calculate present value of cash flows.
discount_factor(rate_col, periods_col, output_col, method='spot')
¶
Calculate discount factors for projection timelines using list_pow plugin.
Computes present value discount factors v^t from interest rates across entire projection timelines. Uses Rust list_pow plugin for optimal performance - eliminates EXPLODE/GROUP_BY pattern for 10x+ speedup on list columns.
When to use
- Reserve Calculations: Discount future benefit payments and expenses to present value for statutory reserves, GAAP liabilities, or embedded value calculations.
- Cash Flow Projections: Calculate present values of projected premiums, claims, and expenses in profit testing models for product pricing and profitability analysis.
- Guaranteed Benefits: Discount guaranteed minimum death benefits (GMDB), withdrawal benefits (GMWB), or income benefits (GMIB) in variable annuity and equity-indexed product valuations.
- Economic Scenario Testing: Apply forward rate curves from economic scenario generators for stochastic reserve calculations and risk capital models.
Parameters¶
rate_col : str Name of column containing interest rates (as lists). Typically monthly rates for projection periods. periods_col : str Name of column containing time periods (as lists). Must align element-wise with rate_col. output_col : str Name for the new column containing discount factors. method : {"spot", "forward"}, default "spot" Discount method:
- "spot": v[t] = (1 + r)^(-t) - Same rate for all periods
- "forward": v[t] = ∏(1 + r[i])^(-1) for i < t - Period-varying rates
Returns¶
ActuarialFrame New frame with discount factor column added.
Examples¶
Spot Discounting: Constant Rate
from gaspatchio_core import ActuarialFrame
data = {
"policy_id": [1, 2],
"monthly_rate": [[0.004, 0.004, 0.004], [0.003, 0.003]],
"month": [[0, 1, 2], [0, 1]],
}
af = ActuarialFrame(data)
af = af.finance.discount_factor(
rate_col="monthly_rate",
periods_col="month",
output_col="disc_factors",
method="spot",
)
print(af.collect())
shape: (2, 4)
┌───────────┬───────────────────────┬───────────┬───────────────────────────┐
│ policy_id ┆ monthly_rate ┆ month ┆ disc_factors │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ list[f64] ┆ list[i64] ┆ list[f64] │
╞═══════════╪═══════════════════════╪═══════════╪═══════════════════════════╡
│ 1 ┆ [0.004, 0.004, 0.004] ┆ [0, 1, 2] ┆ [1.0, 0.996016, 0.992048] │
│ 2 ┆ [0.003, 0.003] ┆ [0, 1] ┆ [1.0, 0.997009] │
└───────────┴───────────────────────┴───────────┴───────────────────────────┘
Forward Discounting: Varying Rates
from gaspatchio_core import ActuarialFrame
data = {
"policy_id": [1],
"forward_rates": [[0.003, 0.004, 0.005]],
"month": [[0, 1, 2]],
}
af = ActuarialFrame(data)
af = af.finance.discount_factor(
rate_col="forward_rates",
periods_col="month",
output_col="disc_factors",
method="forward",
)
print(af.collect())
shape: (1, 4)
┌───────────┬───────────────────────┬───────────┬───────────────────────────┐
│ policy_id ┆ forward_rates ┆ month ┆ disc_factors │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ list[f64] ┆ list[i64] ┆ list[f64] │
╞═══════════╪═══════════════════════╪═══════════╪═══════════════════════════╡
│ 1 ┆ [0.003, 0.004, 0.005] ┆ [0, 1, 2] ┆ [1.0, 0.997009, 0.993037] │
└───────────┴───────────────────────┴───────────┴───────────────────────────┘
See Also¶
to_monthly : Convert annual rates to monthly rates
present_value(cashflow_col, rate_col, period_col)
¶
Calculate the present value of cash flows.
Assumes cash flows occur at the end of each period.
Formula: PV = CF / (1 + rate)^period
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cashflow_col
|
IntoExprColumn
|
Column containing the cash flow amounts. |
required |
rate_col
|
IntoExprColumn
|
Column with discount rate per period (e.g., 0.05 for 5%). |
required |
period_col
|
IntoExprColumn
|
Column with period number (e.g., 1, 2, 3). Must be >= 1. |
required |
Returns:
| Type | Description |
|---|---|
ExpressionProxy
|
An ExpressionProxy representing the present value for each cash flow. |
Column-Level Operations¶
gaspatchio_core.accessors.finance.FinanceColumnAccessor
¶
Bases: BaseColumnAccessor
Financial mathematics and valuation operations.
Provides methods for rate conversion and present value computations on columns or expressions.
Accessed via .finance on an ActuarialFrame column or expression proxy,
e.g., af["annual_rate"].finance.to_monthly().
Methods¶
to_monthly(method="compound") Convert annual interest rates to monthly rates discount(rate_expr, n_periods_expr) Discount values using specified rate and periods
Notes¶
For discount factor calculations on list columns, use the frame-level
accessor: af.finance.discount_factor(rate_col, periods_col, output_col)
discount(rate_expr, n_periods_expr)
¶
Discount the value in the current column/expression.
Formula: Discounted Value = Value / (1 + rate)^n_periods
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rate_expr
|
IntoExprColumn
|
The discount rate per period (e.g., 0.05 for 5%). Can be a scalar, column name, or another expression. |
required |
n_periods_expr
|
IntoExprColumn
|
The number of periods to discount over. Can be a scalar, column name, or another expression. |
required |
Returns:
| Type | Description |
|---|---|
ExpressionProxy
|
An ExpressionProxy representing the discounted value. |
to_monthly(method='compound')
¶
Convert annual interest rate to monthly rate.
Transforms annual effective interest rates to equivalent monthly rates using either compound or simple interest conventions. Essential for actuarial projections with monthly timesteps when assumptions are provided annually.
For list columns, applies conversion element-wise within each list. For scalar columns, applies conversion to each row value.
When to use
- Monthly Projections: Convert annual discount rates, investment returns, or interest crediting rates to monthly equivalents for cash flow models with monthly timesteps.
- Pricing Models: Transform annual pricing assumptions to monthly rates for variable annuity, universal life, or investment-linked product models.
- Reserve Calculations: Convert annual reserve discount rates to monthly for mid-month or monthly reserve valuations.
- Policy Loans: Calculate monthly interest accrual on policy loans when loan terms specify annual interest rates.
Parameters¶
method : {"compound", "simple"}, default "compound" Conversion method: - "compound": (1 + r_annual)^(1/12) - 1 (standard actuarial practice) - "simple": r_annual / 12 (linear approximation)
Returns¶
ExpressionProxy Monthly interest rate with same structure as input (scalar or list)
Examples¶
Scalar Example: Convert annual discount rates
from gaspatchio_core import ActuarialFrame
data = {"annual_rate": [0.05, 0.06, 0.04]}
af = ActuarialFrame(data)
af.monthly_rate = af.annual_rate.finance.to_monthly()
print(af.collect())
shape: (3, 2)
┌─────────────┬──────────────┐
│ annual_rate ┆ monthly_rate │
│ --- ┆ --- │
│ f64 ┆ f64 │
╞═════════════╪══════════════╡
│ 0.05 ┆ 0.004074 │
│ 0.06 ┆ 0.004868 │
│ 0.04 ┆ 0.003274 │
└─────────────┴──────────────┘
Scalar Example: Simple conversion for approximation
from gaspatchio_core import ActuarialFrame
data = {"annual_rate": [0.05, 0.06, 0.04]}
af = ActuarialFrame(data)
af.monthly_rate = af.annual_rate.finance.to_monthly(method="simple")
print(af.collect())
shape: (3, 2)
┌─────────────┬──────────────┐
│ annual_rate ┆ monthly_rate │
│ --- ┆ --- │
│ f64 ┆ f64 │
╞═════════════╪══════════════╡
│ 0.05 ┆ 0.004167 │
│ 0.06 ┆ 0.005 │
│ 0.04 ┆ 0.003333 │
└─────────────┴──────────────┘
Vector Example: Projection timeline with varying rates
from gaspatchio_core import ActuarialFrame
data = {"annual_rates": [[0.05, 0.05, 0.06, 0.06]]}
af = ActuarialFrame(data)
af.monthly_rates = af.annual_rates.finance.to_monthly()
print(af.collect())
shape: (1, 2)
┌──────────────────────┬─────────────────────────────────┐
│ annual_rates ┆ monthly_rates │
│ --- ┆ --- │
│ list[f64] ┆ list[f64] │
╞══════════════════════╪═════════════════════════════════╡
│ [0.05, 0.05, … 0.06] ┆ [0.004074, 0.004074, … 0.00486… │
└──────────────────────┴─────────────────────────────────┘
Notes¶
- Compound method is standard actuarial practice (maintains equivalence)
- Simple method provides linear approximation (less accurate but faster)
- For list columns, conversion is applied to each element
- Formula: Compound = (1 + r_annual)^(1/12) - 1, Simple = r_annual / 12
See Also¶
discount_factor : Calculate discount factors from interest rates