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
- Life cover need: Human Life Value and expense/needs-based methods side by side, goal and loan present values, 3x3 sensitivity tables, recommended term cover and term.
- Policy analyzer: IRR via Newton + bisection for guaranteed, 4% and 8% illustrations; annual/half-yearly/quarterly/monthly premiums with modal loading; money-back survival benefits; ULIP fund simulation; 10(10D) tax notes and post-tax IRR; continue-vs-surrender on future cash flows only.
- Buy term, invest the rest: equivalent term premium (your quote or an illustrative table), post-tax corpus vs bundled maturity, breakeven return, protection over time.
- Health adequacy: target sum insured by city tier, family size and age, room-rent proportionate deduction, base + super top-up layering with co-pay and deductibles, out-of-pocket by claim size, cheapest adequate structure.
- Reports: rich terminal output, plus Markdown or self-contained HTML with inline SVG charts (cover waterfall, IRR bars, corpus lines, out-of-pocket curves).
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
- Illustrative term-premium table, flat bonus model and simplified tax rules (see
docs/assumptions.md). - Single-claim health simulation; no waiting periods, sub-limits or multi-claim aggregates.
- Needs-based method stops supporting dependents at the youngest child's independence unless
dependency_yearsis set. - Rupee formatting uses Indian digit grouping; there is no multi-currency support.
License
MIT, see LICENSE.