Skip to content

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