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.
Computes present value using the formula PV = CF / (1 + rate)^period,
assuming cash flows occur at the end of each period. Essential for
discounting future cash flows in pricing, reserving, and valuation.
When to use
- Reserve Calculations: Discount future benefit payments and expenses to calculate policy reserves under various standards.
- Product Pricing: Calculate present value of expected premiums and claims to determine pricing margins and profitability.
- Embedded Value: Discount projected profits for embedded value and value of in-force business calculations.
- Cash Flow Testing: Present value cash flows for asset adequacy testing and scenario analysis.
Parameters¶
cashflow_col : IntoExprColumn Column containing the cash flow amounts to discount. rate_col : IntoExprColumn Column with discount rate per period (e.g., 0.05 for 5% annual). period_col : IntoExprColumn Column with period number (1, 2, 3...). Must be >= 1.
Returns¶
ExpressionProxy Present value of each cash flow discounted to time zero.
Examples¶
Scalar Example: Discount policy cash flows
from gaspatchio_core import ActuarialFrame
data = {
"policy_id": ["P001", "P002"],
"cashflow": [1000.0, 2000.0],
"rate": [0.05, 0.04],
"period": [1, 2],
}
af = ActuarialFrame(data)
af.pv = af.finance.present_value(af.cashflow, af.rate, af.period)
print(af.collect())
shape: (2, 5)
┌───────────┬──────────┬──────┬────────┬─────────────┐
│ policy_id ┆ cashflow ┆ rate ┆ period ┆ pv │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ f64 ┆ f64 ┆ i64 ┆ f64 │
╞═══════════╪══════════╪══════╪════════╪═════════════╡
│ P001 ┆ 1000.0 ┆ 0.05 ┆ 1 ┆ 952.380952 │
│ P002 ┆ 2000.0 ┆ 0.04 ┆ 2 ┆ 1849.112426 │
└───────────┴──────────┴──────┴────────┴─────────────┘
See Also¶
discount_factor : Calculate discount factors for projection timelines
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)
compound(rate, periods_per_year)
¶
Calculate compound growth factor for periods.
Computes growth factors using the formula
(1 + rate)^(period / periods_per_year).
Commonly used for inflation adjustments, investment growth, or other
compound growth calculations in actuarial projections.
When to use
- Inflation Adjustments: Calculate inflation factors for expenses, benefits, or premiums that grow with inflation over projection periods.
- Investment Growth: Model accumulation of funds under compound interest assumptions.
- Benefit Increases: Calculate growth factors for benefits that increase at a fixed compound rate.
Parameters¶
rate : float Annual growth rate (e.g., 0.01 for 1% annual growth) periods_per_year : int Number of periods per year (e.g., 12 for monthly, 4 for quarterly)
Returns¶
ExpressionProxy Growth factors with same structure as input column (scalar or list)
Examples¶
List column example: Monthly inflation factors
from gaspatchio_core import ActuarialFrame
data = {"month": [[0, 1, 6, 12]]}
af = ActuarialFrame(data)
af.inflation_factor = af.month.finance.compound(rate=0.01, periods_per_year=12)
print(af.collect())
Scalar column example: Quarterly growth
from gaspatchio_core import ActuarialFrame
data = {"quarter": [0, 1, 4]}
af = ActuarialFrame(data)
af.growth_factor = af.quarter.finance.compound(rate=0.02, periods_per_year=4)
print(af.collect())
See Also¶
to_monthly : Convert annual rates to monthly rates discount_factor : Calculate discount factors from interest rates
discount(rate_expr, n_periods_expr)
¶
Discount the value in the current column/expression.
Computes discounted values using the formula
Discounted Value = Value / (1 + rate)^n_periods. Useful for
converting future values to present values with flexible rate and
period inputs from other columns or expressions.
When to use
- Future Value Discounting: Convert guaranteed maturity values, surrender values, or death benefits to present value.
- Reserve Calculations: Discount projected liabilities back to valuation date for statutory or GAAP reserves.
- Profit Testing: Calculate present value of future profits in pricing models and profitability analysis.
- Investment Returns: Discount expected investment income or fund values in unit-linked or variable product models.
Parameters¶
rate_expr : IntoExprColumn The discount rate per period (e.g., 0.05 for 5% annual). Can be a scalar, column reference, or expression. n_periods_expr : IntoExprColumn The number of periods to discount over. Can be a scalar, column reference, or expression.
Returns¶
ExpressionProxy Discounted values with same structure as input column.
Examples¶
Scalar Example: Discount future values
from gaspatchio_core import ActuarialFrame
data = {
"policy_id": ["P001", "P002"],
"future_value": [1050.0, 2080.0],
"rate": [0.05, 0.04],
"periods": [1, 2],
}
af = ActuarialFrame(data)
af.present_value = af.future_value.finance.discount(af.rate, af.periods)
print(af.collect())
shape: (2, 5)
┌───────────┬──────────────┬──────┬─────────┬───────────────┐
│ policy_id ┆ future_value ┆ rate ┆ periods ┆ present_value │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ f64 ┆ f64 ┆ i64 ┆ f64 │
╞═══════════╪══════════════╪══════╪═════════╪═══════════════╡
│ P001 ┆ 1050.0 ┆ 0.05 ┆ 1 ┆ 1000.0 │
│ P002 ┆ 2080.0 ┆ 0.04 ┆ 2 ┆ 1923.076923 │
└───────────┴──────────────┴──────┴─────────┴───────────────┘
See Also¶
present_value : Calculate present value of cash flows at frame level discount_factor : Calculate discount factors for projection timelines
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