CLI · commit 022b631

coverwise

Life & health insurance needs analyzer and policy comparator

Download coverwise.zip
Quickstart
unzip coverwise.zip && cd coverwise
uv venv .venv && uv pip install -p .venv/bin/python -e '.[dev]'
.venv/bin/python -m pytest -q

coverwise

Life and health insurance needs analyzer and policy comparator. People are routinely sold expensive endowment and ULIP policies while staying under-insured on term and health cover. coverwise works out how much cover a family actually needs, measures the real return (IRR) of the policies it already owns, compares them with "buy term and invest the rest", and checks health cover for room-rent traps and top-up gaps, with the working shown.

Not financial or insurance advice. Product numbers in examples/ are synthetic and illustrative.

Features

Install

Python 3.12+.

cd coverwise
uv venv .venv && uv pip install -p .venv/bin/python -e '.[dev]'

Quickstart

.venv/bin/coverwise needs examples/family.yaml
.venv/bin/coverwise policy examples/policy.yaml
.venv/bin/coverwise compare examples/policy.yaml --term-premium 12000 --policy "LIC-style Endowment"
.venv/bin/coverwise health examples/health.yaml
.venv/bin/coverwise report examples/family.yaml -o report.html

Usage

Command What it does
coverwise needs FILE HLV and needs-based cover, sensitivity, recommendation
coverwise policy FILE IRR per scenario, tax notes, continue-vs-surrender for every policy
coverwise compare FILE [--term-premium N] [--policy NAME] [--term-cover N] [--return R] [--tax R] bundled vs term + invest for each non-term policy
coverwise health FILE target sum insured, room-rent example, layering and out-of-pocket curves
coverwise report FILE -o out.html everything in the file as one report (.md also works, or --format md)

One YAML schema serves all commands and every section is optional: needs requires family and expenses, policy/compare require policies, health requires health. examples/family.yaml has everything (it is the file report is run against); policy.yaml and health.yaml are focused subsets. Errors in the input are reported as error: ... with exit code 2.

Input schema (abridged)

city: Pune
city_tier: 1
family:
  self: {age: 32, income: 2400000}
  spouse: {age: 30, income: 300000}
  retirement_age: 60
  children:
    - name: Aarav
      age: 3
      goals:
        - {name: Higher education, kind: education, year: 15, cost: 3000000}
expenses: {household_annual: 960000, personal_share: 0.25}
liabilities: {home_loan: {outstanding: 4500000, remaining_years: 18}}
assets: {investments: 600000, epf: 900000, ppf: 300000, emergency_fund: 300000}
assumptions: {inflation: 0.06, discount_rate: 0.08, portfolio_return: 0.10}
policies:        # type: term | endowment | money-back | ulip | whole-life
  - name: LIC-style Endowment
    type: endowment
    sum_assured: 1000000
    annual_premium: 62000
    premium_mode: quarterly          # annual | half-yearly | quarterly | monthly
    premium_paying_term: 16
    policy_term: 25
    years_elapsed: 5                 # enables continue-vs-surrender
    bonus_rate: {"4": 0.030, "8": 0.046}
    terminal_bonus: {"4": 0.10, "8": 0.25}
    surrender_values: {5: 140000}
health:
  base: {sum_insured: 500000, room_rent_cap_per_day: 5000, copay_pct: 0.0}
  bill: {room_rent_per_day: 8000, days: 4, other_room_linked: 60000, non_linked: 250000}
  quotes:
    - {name: Super top-up 1Cr (ded 5L), sum_insured: 10000000, deductible: 500000, premium: 9400}

Other policy keys: issue_date, guaranteed_addition_rate, survival_benefits: [{year, pct_of_sa}], maturity: {guaranteed, "4", "8"} (absolute amounts from the benefit illustration), return_of_premium, ulip: {allocation_charges, fmc, admin_charge_annual, mortality_pct_sa}, surrender_value, term_quote, counts_as_cover. Health: members (defaults to the family), top_ups (existing), quotes (proposed), claim_sizes, target_table. See examples/family.yaml for a complete file and docs/methodology.md for what each key does.

Example walkthrough

The sample is a family of four in Pune (32 and 30, children aged 3 and 1) with a home loan, an LIC-style endowment, a ULIP, an online term plan and employer group health of 5 lakh. Output below is captured from the commands above (terminal width 100, disclaimer footer omitted).

How much life cover?


== Life cover need ==
Earner age 32, retiring at 60; dependents supported for 24 years; discount rate 8.0%, inflation 
6.0%, income growth 7.0%.
 Item                                            ┃       Amount 
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━
 Human Life Value (gross)                        │ ₹5,01,44,193 
 Human Life Value less assets and existing cover │ ₹4,05,44,193 
 PV of dependents' expenses                      │   ₹70,10,752 
 PV of goals                                     │ ₹1,05,09,496 
 Liabilities to clear                            │   ₹45,00,000 
 Needs-based gross requirement                   │ ₹2,20,20,248 
 Less existing assets                            │  -₹21,00,000 
 Less existing life cover                        │  -₹75,00,000 
 Needs-based additional cover                    │ ₹1,24,20,248 
> Recommended additional term cover: ₹1,25,00,000 (₹1.25 Cr) for 27 years (until age 59). Capped at 
the gross Human Life Value, rounded up to ₹5 lakh.

Goals
 Goal                    ┃ In years ┃  Future cost ┃ Present value 
━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━
 Aarav: Higher education │       15 │ ₹1,25,31,745 │    ₹39,50,529 
 Aarav: Marriage         │       25 │   ₹85,83,741 │    ₹12,53,380 
 Anaya: Higher education │       17 │ ₹1,51,63,411 │    ₹40,98,199 
 Anaya: Marriage         │       27 │   ₹96,44,692 │    ₹12,07,388 

Sensitivity
Needs-based additional cover by discount rate (rows) and inflation (columns).
 Discount \ Inflation ┃     4.0% ┃     6.0% ┃     8.0% 
━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━
 6.0%                 │ ₹1.38 Cr │ ₹1.85 Cr │ ₹2.51 Cr 
 8.0%                 │ ₹91.70 L │ ₹1.24 Cr │ ₹1.69 Cr 
 10.0%                │ ₹58.59 L │ ₹81.78 L │ ₹1.14 Cr 
HLV-based additional cover by discount rate (rows) and income growth (columns).
 Discount \ Growth ┃     5.0% ┃     7.0% ┃     9.0% 
━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━
 6.0%              │ ₹4.00 Cr │ ₹5.62 Cr │ ₹7.88 Cr 
 8.0%              │ ₹2.92 Cr │ ₹4.05 Cr │ ₹5.62 Cr 
 10.0%             │ ₹2.15 Cr │ ₹2.96 Cr │ ₹4.07 Cr

The needs method says the family is short by about 1.24 crore even after counting the 75 lakh of existing cover (which includes the 10 lakh endowment and 15 lakh ULIP sums assured). HLV is far larger (about 5 crore) because it values every future rupee of surplus income; it is an upper bound, not the target.

What do the existing policies really return?


== Existing policies ==

LIC-style Endowment (endowment)
Sum assured ₹10,00,000; premium ₹62,000 quarterly for 16 years, term 25 years. Total premiums 
₹10,31,680, of which ₹39,680 is modal loading.
 Scenario        ┃ Maturity benefit ┃    IRR ┃ Tax on gains ┃ Post-tax IRR 
━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━
 Guaranteed      │       ₹10,00,000 │ -0.18% │            - │       -0.18% 
 4% illustration │       ₹18,50,000 │  3.40% │            - │        3.40% 
 8% illustration │       ₹24,00,000 │  4.90% │            - │        4.90% 
> Return of 3.40% (4% illustration) is below inflation (6.0%): the money loses purchasing power.
Maturity expected to be exempt under Section 10(10D).

Continue or surrender: LIC-style Endowment
After 5 years, surrender value ₹1,40,000. Past premiums are sunk; continuing means giving up 
₹1,40,000 now plus paying future premiums, versus investing at 8.75% post-tax.
 Scenario        ┃ IRR of continuing ┃ NPV at 8.75% ┃ Better to 
━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━
 Guaranteed      │             1.05% │   -₹4,21,243 │ surrender 
 4% illustration │             5.05% │   -₹2,62,449 │ surrender 
 8% illustration │             6.75% │   -₹1,59,700 │ surrender 
> Surrender wins in every scenario; replace the cover with a term plan.
...

The endowment's guaranteed return is slightly negative, and even the 8% illustration yields 4.9%, below the 6% inflation assumption. Surrendering and buying term beats continuing in every scenario. The ULIP and term plan sections follow in the full output.

Buy term and invest the rest


== Buy term and invest the rest ==

LIC-style Endowment
Term cover ₹10,00,000 for 25 years at ₹12,000/yr (as quoted). Invest the ₹52,480 difference at 
10.0%, 12.5% tax on gains.
 Scenario        ┃ Bundled policy value ┃ Term + invest corpus ┃ Difference ┃ Breakeven return 
━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━
 Guaranteed      │           ₹10,00,000 │           ₹42,16,397 │ ₹32,16,397 │            1.83% 
 4% illustration │           ₹18,50,000 │           ₹42,16,397 │ ₹23,66,397 │            5.35% 
 8% illustration │           ₹24,00,000 │           ₹42,16,397 │ ₹18,16,397 │            6.82% 
> Term + invest ends ahead in 3 of 3 scenarios. Breakeven return is the portfolio return at which 
the two strategies tie.

Premium 62,000 quarterly (64,480 after loading) versus a 12,000 term quote leaves 52,480 a year to invest. The portfolio only needs to earn 5.35% to match the 4% illustration.

Health cover


== Health cover ==
 Target sum insured ┃                                            Basis 
━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 ₹1,00,00,000       │         tier 1 base ₹40.00 L x size 2 x age 1.25 
 ₹3,15,00,000       │ same need in 10 years at 12.0% medical inflation 

Room-rent proportionate deduction
Bill of ₹3,42,000: room at ₹8,000/day, room-linked charges ₹92,000, other charges ₹2,50,000. 
Room-rent cap is ₹5,000/day, so only 62.5% of room-linked charges are admissible.
 Step                    ┃    Amount 
━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━
 Hospital bill           │ ₹3,42,000 
 Proportionate deduction │  -₹34,500 
 Admissible              │ ₹3,07,500 
 Co-pay (0%)             │        ₹0 
 Insurer pays            │ ₹3,07,500 
 Out of pocket           │   ₹34,500 

Layering options
                           ┃            ┃              ┃                ┃ Out of pocket at ₹1.00 Cr 
 Structure                 ┃ Premium/yr ┃ Covers up to ┃ Uncovered band ┃                     claim 
━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Base only                 │         ₹0 │    ₹5,00,000 │           none │                ₹95,00,000 
 Base + Super top-up 25L   │     ₹4,300 │   ₹30,00,000 │           none │                ₹70,00,000 
 (ded 5L)                  │            │              │                │                           
 Base + Super top-up 1Cr   │     ₹9,400 │ ₹1,05,00,000 │           none │                        ₹0 
 (ded 5L)                  │            │              │                │                           
 Base + Super top-up 1Cr   │     ₹6,100 │ ₹1,10,00,000 │      ₹5,00,000 │                 ₹5,00,000 
 (ded 10L)                 │            │              │                │                           
          ┃               ┃    Base + Super top-up ┃    Base + Super top-up ┃   Base + Super top-up 
 Claim    ┃ Base only OOP ┃       25L (ded 5L) OOP ┃       1Cr (ded 5L) OOP ┃     1Cr (ded 10L) OOP 
━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━
 ₹1.00 L  │       ₹10,088 │                ₹10,088 │                ₹10,088 │               ₹10,088 
 ₹2.50 L  │       ₹25,219 │                ₹25,219 │                ₹25,219 │               ₹25,219 
 ₹5.00 L  │       ₹50,439 │                ₹50,439 │                ₹50,439 │               ₹50,439 
...

The 5 lakh group cover with a 5,000/day room cap and an 8,000/day room loses 34,500 on a typical bill. The 1 crore / 10 lakh deductible quote is cheaper but leaves a 5 lakh uncovered band between the base and the top-up, so the tool picks the 5 lakh deductible quote.

Report

coverwise report examples/family.yaml -o report.html writes one self-contained HTML file (inline CSS, 7 inline SVG charts, dark-mode aware). Use -o report.md for Markdown with the same tables and SVG charts embedded.

Configuration

All rates are decimals (0.08 for 8%); a value of 1 or more is rejected with a hint. Assumption defaults are listed in docs/assumptions.md.

Architecture

coverwise/
  config.py    YAML -> typed dataclasses with validation (ConfigError)
  finance.py   PV, NPV, IRR solver (Newton + bisection), future-value series
  needs.py     HLV, needs-based method, recommendation, sensitivity
  policy.py    cash flows, modal loading, ULIP simulation, tax rules, continue-vs-surrender
  compare.py   buy-term-invest-the-rest, term premium estimate, breakeven
  health.py    target sum insured, room-rent deduction, layering, recommendation
  charts.py    inline SVG: waterfall, grouped bars, line charts
  report.py    builds neutral blocks (heading/table/chart) and renders them to terminal, Markdown, HTML
  cli.py       click commands
docs/          methodology.md (formulas, worked examples), assumptions.md (defaults, limits, disclaimers)
examples/      family.yaml, policy.yaml, health.yaml
tests/         pytest suite

Each command builds the same block list that the report uses, so terminal, Markdown and HTML always agree.

Tests

.venv/bin/python -m pytest -q

Covers HLV and needs PV against hand calculations, IRR on known flows including no-solution cases, modal loading and cash-flow timing, ULIP fund math, tax thresholds, BTIR equivalence, corpus and breakeven, continue-vs-surrender future flows, room-rent proportionate deduction, deductible and co-pay layering, and CLI/report generation.

Limitations

License

MIT, see LICENSE.