npm package: @finctrl/core
Description: Core financial engines for Indian taxation, mutual fund comparison, and lifestyle-driven retirement planning.
Author: FinCtrl
Latest version: 1.0.6

<div align="center">

# FinCtrl Core

<img src="https://unpkg.com/%40finctrl/core/assets/logo.png" alt="FinCtrl Logo" width="120" />

### Financial Engines Built for India
Lightweight JavaScript engines built to model Indian taxation, investing, and retirement planning with domain-aware assumptions.

[![npm version](https://img.shields.io/npm/v/%40finctrl/core.svg?style=flat-square)](https://www.npmjs.com/package/%40finctrl/core)
[![License](https://img.shields.io/npm/l/%40finctrl/core.svg?style=flat-square)](https://github.com/finctrl/core/blob/main/LICENSE)
[![Node.js Version](https://img.shields.io/node/v/%40finctrl/core.svg?style=flat-square)](https://nodejs.org)
</div>

## What is this?

**FinCtrl Core** is the brain behind our financial applications. It's a collection of pure JavaScript calculation engines designed specifically for the unique financial landscape of India.

We built this because most financial tools are packaged as closed UI calculators rather than reusable computation engines.
FinCtrl provides composable financial models designed for Indian contexts - covering **taxation**, **mutual funds**, and **lifestyle-driven planning** - so developers can integrate realistic financial logic directly into their applications.


This library is essentially a set of "business logic" modules. It doesn't care about React, Vue, or the DOM. It takes numbers in and returns structured results.

---

## The Engines

### 1. Advance Tax Estimator
🔗 **Live demo:** [finctrl.app/advance-tax-estimator](https://finctrl.app/advance-tax-estimator)

**The Problem:**
Most people wait until March to think about taxes. But the government expects you to pay as you earn. Calculating advance tax installments manually (15% by June, 45% by Sept, etc.) while accounting for TDS and estimated capital gains is a headache.

**Our Design Approach:**
The Indian Tax Code is treated as **configuration, not hardcoded logic**. All year-specific constants - tax slabs, basic exemptions (by age), LTCG exemption threshold, cess rate - live in a single versioned config file (`src/config/taxRules.js`). The engine looks up the right rules at runtime based on `taxYear` and `regime`. When the Finance Minister announces a new budget, you add one entry to the config and the engine adapts automatically. Capital Gains (STCG/LTCG) are handled with their own flat-rate logic, separate from the slab calculation, which is a common omission in generic calculators.

**Usage:**

```javascript
import { AdvanceTaxEngine } from '@finctrl/core'

const inputs = {
  taxYear: '2024-25',          // Which FY to compute for
  regime: 'new',               // 'new' or 'old'
  fdAndOtherIncome: 12_00_000, // 12 Lakhs from FD / other sources
  stcgAmount: 50_000,          // Short Term Capital Gains
  stcgTaxRate: 20,             // 20%
  ltcgAmount: 1_00_000,        // Long Term Capital Gains
  ltcgTaxRate: 12.5,           // 12.5%
  tdsDeducted: 20_000,         // TDS already deducted
  advanceTaxPaid: 10_000,      // Advance tax already paid
  ageGroup: '0-60',            // '0-60', '60-80', or '80+'
  exemptionMode: 'age-based',  // 'age-based' (standard) or 'custom'
  manualSlab: 'auto'           // 'auto' = engine picks the right slab
};

const result = AdvanceTaxEngine.calculate(inputs);

console.log(result.totalTax);      // Total tax liability (before TDS/payments)
console.log(result.netTaxPayable); // Tax remaining after TDS & advance paid
console.log(result.schedule);      // Array of installments with due dates & amounts
console.log(result.ltcgExemption); // Exemption applied (e.g. 125000 for FY 2024-25)
```

> **Tip**: If `taxYear` and `regime` are omitted, the engine defaults to the latest year and new regime (`DEFAULT_TAX_YEAR`, `DEFAULT_REGIME`).

---

### 2. Mutual Fund Comparator (Direct vs Regular)
🔗 **Live demo:** [finctrl.app/regular-vs-direct](https://finctrl.app/regular-vs-direct)

**The Problem:**
A 1% difference in expense ratio (TER) sounds trivial. Agents often say, "It's just a small fee for my advice." But over 20 years, that "small fee" can eat up 20-30% of your total corpus due to the lost compounding effect.

**Our Design Approach:**
We wanted to make the "Cost of Ignorance" visible. The engine uses standard compound interest formulas but runs two parallel simulations: one for the Direct plan and one for the Regular plan. It then diffs the final amounts to show the raw currency value of that 1% difference. It's designed to be a "shock" engine - simple math, profound impact.

**Usage:**

```javascript
import { MFComparatorEngine } from '@finctrl/core'

const inputs = {
  currentInvestment: 5_00_000, // Initial lump sum (5 Lakhs)
  investmentPeriod: 20,        // Years to grow
  expectedReturn: 12,          // 12% annual return
  terRegular: 2.0,             // 2% Expense Ratio (Agent)
  terDirect: 1.0               // 1% Expense Ratio (Direct)
};

const result = MFComparatorEngine.calculate(inputs);

console.log(result.difference);     // Extra money made in Direct plan
console.log(result.percentageGain); // % gain over Regular plan
```

---

### 3. Lifestyle Retirement Planner
🔗 **Live demo:** [finctrl.app/retirement-planner](https://finctrl.app/retirement-planner)

**The Problem:**
Traditional retirement calculators ask, "What is your current income?" This is flawed. You don't replace your income in retirement; you pay for your *lifestyle*. A person earning ₹50L but living simply needs less corpus than a person earning ₹30L with expensive tastes.

**Our Design Approach:**
We flipped the model. Instead of income, we ask about lifestyle markers:
- Do you send kids to international schools?
- Do you vacation in Europe or local hill stations?
- Do you drive a luxury sedan or a hatchback?

The engine assigns a "Lifestyle Index" (0-100) based on these inputs and places you in one of 5 classes:

1.  **Lower Middle** (0-25): Basic sustenance, government schools, minimal travel.
2.  **Middle** (25-45): Stability, mid-range schools, occasional domestic travel.
3.  **Upper Middle** (45-65): Comfort, good private schools, active lifestyle.
4.  **Affluent** (65-85): Luxury, international schools, frequent travel.
5.  **High Affluence** (85-100): Elite lifestyle, no compromise on quality of life.

It then calculates the retirement corpus needed to *sustain that specific lifestyle*, adjusting for inflation and medical buffers particular to that class. It's a behavioral model, not just a financial one.

**Usage:**

```javascript
import { RetirementPlannerEngine } from '@finctrl/core'

const inputs = {
  currentAge: 30,
  yearsToRetirement: 25,
  cityTier: 'Metro',         // 'Metro', 'Tier-1', 'Tier-2', 'Tier-3'
  housing: 'Rented',         // 'Rented', 'Owned apartment', 'Gated society', ...
  rentEmi: '25k–50k',        // Rent/EMI bracket
  schoolFees: '1.5L–3L',     // Annual school fees bracket
  travel: 'Twice a year',    // Travel frequency
  car: 'Mid Range',          // Car segment
};

const result = RetirementPlannerEngine.calculate(inputs);

// Classification
console.log(result.lifestyleCategory.name); // e.g., "Upper Middle"
console.log(result.lifestyleIndex);         // e.g., "54.3"

// Expenses (decimal strings, in Lakhs per year)
console.log(result.annualExpenseToday);           // e.g., "9.45" (today's annual spend)
console.log(result.retirementAnnualExpenseToday); // e.g., "7.56" (retirement spend, today's ₹)

// Corpus (decimal strings, in Crores - future inflated value)
console.log(result.corpusRange.standard.corpusInCrores);   // e.g., "3.82" Cr
console.log(result.corpusRange.standard.corpusInCroresPV); // e.g., "1.79" Cr (today's ₹)
```

---

## Tax Rules Configuration

All year- and regime-specific tax constants are stored in `src/config/taxRules.js`. These are fully exported so consuming applications can build dynamic UIs (e.g. year pickers, regime toggles) without hardcoding their own copies.

```javascript
import {
  TAX_RULES,        // Full config object keyed by year → regime
  getTaxRules,      // (taxYear, regime) → rule set for that year/regime
  getTaxYears,      // () → sorted list of supported years, e.g. ['2025-26', '2024-25', ...]
  DEFAULT_TAX_YEAR, // '2025-26'
  DEFAULT_REGIME,   // 'new'
} from '@finctrl/core';

// Look up the LTCG exemption for a specific year
const rules = getTaxRules('2024-25', 'old');
console.log(rules.ltcgExemption);            // 125000
console.log(rules.basicExemption['0-60']);   // 250000
console.log(rules.slabs);                    // [...old regime slab array]
```

**Adding a new budget year** (e.g. after Budget 2026):
1. Open `src/config/taxRules.js`
2. Add a `'2026-27'` key with `new` and `old` regime entries
3. No engine or UI changes needed - the new year appears automatically

---

## Installation

Requires [Node.js 18.0.0 or higher](https://nodejs.org/en/download). Install via npm:

```bash
npm install @finctrl/core
```

## API Reference

| Engine | Method | Key Output Fields |
|---|---|---|
| `AdvanceTaxEngine` | `calculate(inputs)` | `totalTax`, `netTaxPayable`, `schedule`, `ltcgExemption` |
| `MFComparatorEngine` | `calculate(inputs)` | `difference`, `percentageGain` |
| `RetirementPlannerEngine` | `calculate(inputs)` | `lifestyleCategory`, `lifestyleIndex`, `corpusRange`, `annualExpenseToday` |
| `getTaxRules` | `getTaxRules(year, regime)` | Full rule set: `slabs`, `basicExemption`, `ltcgExemption`, `cess` |
| `getTaxYears` | `getTaxYears()` | Sorted array of supported FY strings |

---

## Examples

Detailed code examples for each engine are available in the `examples/` directory.

```bash
# Advance Tax Calculator
node examples/advance_tax_example.js

# MF Direct vs Regular Comparator
node examples/mf_comparator_example.js

# Retirement Planner
node examples/retirement_planner_example.js
```

### Debugging

Pass `debug: true` in any engine's inputs to log verbose internal calculations to the console:

```javascript
AdvanceTaxEngine.calculate({ ...inputs, debug: true })
```

## Contributing

We welcome contributions! If you find a bug in a tax calculation or want to add a new engine, here's how to get started:

1. Fork the repo and create your branch from `main`.
2. Make your changes and add tests where applicable.
3. Run the test suite: `npm test`
4. Open a pull request - describe what you changed and why.

For bugs or feature ideas, open an issue on [GitHub](https://github.com/finctrl/core/issues).

**Ideas for future engines:** Home Loan Prepayment Analyzer, NPS Corpus Estimator, HRA Exemption Calculator.

## License

This project is licensed under the **Apache License 2.0**.

-   You are free to use, modify, and distribute this software.
-   You can use it in commercial applications.
-   You must include a copy of the license and copyright notice with any distribution.
-   This software is provided "as is" without warranty.

See the [LICENSE](LICENSE) file for the full text.

---

<div align="center">
  <b>Made with ❤️ in India</b>
</div>