QuantCalc QuantCalc Federal tax engine docs

Federal tax / Calculation order

Federal tax: the calculation, step by step

Every step the federal engine takes, in the order it takes them: the Form 1040 lines it fills, the code that does it, the tests that prove it and the official sources of the rule. The API returns the same line ids in lines[], each with its rule naming a section below. Line numbers follow the 2025 forms (the 2026 forms are not yet published).

Request handling (the API)

One field table: keys, types, limits and unknown keys

Every request key is one row of a table: its camelCase name, its snake_case spelling, its type and limits, whether it is required, and where its value goes in the engine input. The parser reads the body through the table; a key that is not a row is refused with 400 rather than ignored, because a field the engine does not model (wages, dividends, itemized deductions) would otherwise vanish from a figure that looks complete. Keys match case-insensitively; a row sent twice (two spellings or two cases) is refused. GET /api/federal-tax/schema is generated from the same table.

Code: backend/src/federal_tax_json.c federal_tax_json_fields, federal_tax_json_parse. Tests: test_federal_api.c test_parse_types; test_federal_api.c test_unknown_and_duplicate_keys; test_federal_api.c test_field_table_documented.

Sources: API design, not tax law.

Value checks and the return's facts

age is required: the filer's age at the end of the year decides the §72(t) additional tax, the §63(f) aged amount and the senior deduction, and no default would be right for everyone. Amounts are finite and at most $100 billion; gains may be negative (a loss), every other amount may not. spouseAge is required on a joint return and refused on any other; mfsLivedApart only on a separate return.

Code: backend/src/federal_tax_json.c federal_tax_request_eval. Tests: test_federal_api.c test_value_checks; test_federal_api.c test_status_dependent_fields.

Sources: API design, not tax law.

The year's parameters

The 2026 parameters of the filing status (Rev. Proc. 2025-32), the §63(f) aged amount for each 65+ filer (both spouses on a joint return) added to the standard deduction, and the senior deduction's amount, count, threshold and rate when someone qualifies: the same construction /api/simulate uses for its 2026 year (a test holds the two byte-identical for every status and age pair).

Code: backend/src/federal_tax_json.c federal_tax_json_config. Tests: test_federal_api_sim.c test_config_matches_simulation.

Sources: API design, not tax law: the rules themselves are the deduction steps below.

The response: result, Form 1040 lines and sources

The response carries the inputs as sent, the year's result, one entry per Form 1040 line the composition fills (with the rule that produced it) and, per calculation step on the return, its official sources with the quote that was checked and the date (only the bracket table of the return's filing status). includeSources: false leaves the sources out; nothing else changes. rules.notModeled lists what the engine does not compute.

Code: backend/src/federal_tax_json.c federal_tax_json_response. Tests: test_federal_api.c test_response_shape; test_federal_api.c test_sources_per_step; test_federal_api.c test_metadata_endpoints.

Sources: API design, not tax law.

The state API's computeFederal

POST /api/state-tax with computeFederal: true builds one federal return from the state request (IRA and employer-plan distributions, pensions including Railroad Retirement Tier 2, Roth conversions, gains, gross Social Security, the ages) and hands the state engine what /api/simulate hands it: the taxable Social Security, the income tax excluding the NIIT as the federal tax before and after credits, the NIIT, zero refundable credits and federal taxable income. A state request carrying anything the federal engine does not model (wages, interest and dividends, qualified dividends, disability pay, §72(t) exceptions, IRA basis, blindness, disability, dependents, qss) or its own federal figures is refused with 400. Off by default: without it the state API is unchanged, byte for byte. For a single filer the state tax then equals the planner's for the same year in every jurisdiction (tested); on a joint return the state API attributes each amount to the spouse who received it (the spouse object), which the planner's household model does not, so the two can differ in states with per-spouse rules while the federal return is the same.

Code: backend/src/state_tax_federal.c state_tax_federal_json_eval. Tests: test_federal_api_sim.c test_compute_federal_matches_simulation; test_federal_api.c test_compute_federal_values; test_federal_api.c test_compute_federal_refusals; test_federal_api.c test_compute_federal_off_is_unchanged.

Sources: API design, not tax law: it composes the federal and state engines exactly as /api/simulate does.

Income: Form 1040 lines 2a to 8

Tax-exempt interest

Tax-exempt interest (taxExemptInterest) is reported on line 2a and never taxed. It is added to provisional income for the Social Security test (§86(b)(2)(B)) and to the income the IRMAA tiers read, and nowhere else: not to AGI and not to the NIIT's MAGI.

Form lines: Form 1040 line 2a (Tax-exempt interest, 1040.2a)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_tax_exempt_interest.

IRA distributions and Roth conversions

A traditional IRA or plan distribution (iraDistributions) is ordinary income (§408(d)(1)), line 4b. A Roth conversion (rothConversion) is a distribution too and is reported on line 4b with it; the engine taxes it as ordinary income and, unlike the distribution, never charges the §72(t) additional tax on it. No after-tax basis (Form 8606) is modelled: every dollar is taxable.

Form lines: Form 1040 line 4b (IRA distributions, taxable amount, 1040.4b)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_single_senior_with_gains; test_federal_api.c test_lines_map_inputs.

Pensions and annuities

Pension and annuity income (pension) is ordinary income (§72(a)), line 5b, fully taxable (no exclusion ratio for after-tax contributions is modelled).

Form lines: Form 1040 line 5b (Pensions and annuities, taxable amount, 1040.5b)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_api.c test_lines_map_inputs.

Social Security benefits

Gross Social Security benefits (socialSecurityGross, with any Railroad Retirement Tier 1) are line 6a; the taxable part is the next step.

Form lines: Form 1040 line 6a (Social security benefits, 1040.6a)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_single_senior_with_gains.

Taxable Social Security (the Pub 915 worksheet)

Provisional income is every other income item (IRA, pension, conversions, other income and both gain buckets after netting), plus tax-exempt interest, plus half the benefits. Up to 50% of benefits are taxable above the base amount ($25,000; $32,000 joint; $0 separate) and up to 85% above the adjusted base ($34,000; $44,000 joint; $0 separate), the smaller of the two worksheet amounts. A separate filer who lived apart from the spouse all year (mfsLivedApart) uses the single amounts.

Form lines: Form 1040 line 6b (Social security benefits, taxable amount, 1040.6b)

Code: backend/src/tax_calculator.c compute_ss_taxable_amount_v2. Tests: test_tax_calculator.c test_ss_taxation; test_tax_calculator.c test_ss_mfj; test_tax_calculator.c test_ss_mfs_zero_thresholds; test_tax_calculator.c test_ss_mfs_lived_apart_single_thresholds.

Other ordinary income

otherOrdinaryIncome is ordinary income that is neither an IRA distribution, a conversion nor a pension, and is not net investment income (for example other income reported on Schedule 1). It goes to line 8. Interest and dividends are not this field: the engine does not model them yet (R1), and they would change the NIIT.

Form lines: Form 1040 line 8 (Additional income from Schedule 1, line 10, 1040.8)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_api.c test_lines_map_inputs.

Capital gains: Schedule D netting

Net short-term gain or loss

shortTermGains is the year's net short-term gain or loss (Schedule D line 7), signed.

Form lines: Schedule D line 7 (Net short-term capital gain or (loss), 1040sd.7)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_netting.

Net long-term gain or loss

longTermGains is the year's net long-term gain or loss (Schedule D line 15), signed.

Form lines: Schedule D line 15 (Net long-term capital gain or (loss), 1040sd.15)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_netting.

Combined net gain or loss

Schedule D line 16 is the sum of lines 7 and 15. A net loss in one bucket first offsets a net gain in the other; what is left in each bucket is taxed by its own character: short-term as ordinary income, long-term in the capital-gains worksheet.

Form lines: Schedule D line 16 (Lines 7 and 15 combined, 1040sd.16)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_netting.

Line 7a: a net loss enters as zero

Line 7a is the net gain after netting. When the year's combined result is a loss, the engine enters 0: it does not yet deduct up to $3,000 ($1,500 separate) of the loss against other income (§1211(b)) or carry the rest forward, so for a year with a net loss the federal tax it reports is up to the tax on $3,000 too high. The capital-loss deduction and carryover are planned (R2).

Form lines: Form 1040 line 7a (Capital gain or (loss), 1040.7a)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_netting; test_federal_tax.c test_identities.

Total income and adjusted gross income

Total income

Line 9 adds lines 4b, 5b, 6b, 7a and 8.

Form lines: Form 1040 line 9 (Total income, 1040.9)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_identities.

Adjusted gross income

No adjustment to income (Schedule 1 Part II) is modelled, so AGI (line 11a) equals total income. AGI is also the MAGI of the NIIT and of the senior deduction's phase-out.

Form lines: Form 1040 line 11a (Adjusted gross income, 1040.11a)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_identities; test_federal_tax.c test_single_senior_with_gains.

Deductions: the standard deduction, §63(f) and the senior deduction

Standard deduction and the §63(f) aged amount

The 2026 standard deduction of the filing status ($16,100 single and separate, $32,200 joint, $24,150 head of household), plus the §63(f) additional amount for each filer 65 or older at the end of the year ($2,050 unmarried, $1,650 per spouse married; on a joint return each spouse 65+ adds one). The engine does not itemize (Schedule A, R3) and has no blindness amount yet (R6).

Form lines: Form 1040 line 12e (Standard deduction, 1040.12e)

Code: backend/src/tax_calculator.c tax_config_init, additional_std_deduction_aged_2026_couple. Tests: test_tax_calculator.c test_std_deduction_2026_all_statuses; test_tax_calculator.c test_aged_deduction_couple.

The senior deduction (Schedule 1-A)

For tax years 2025 to 2028, $6,000 for each individual 65 or older at the end of the year (both spouses on a joint return), reduced by 6% of MAGI over $75,000 ($150,000 joint), each individual's amount separately, not below zero. A separate return does not qualify. MAGI here is AGI.

Form lines: Schedule 1-A line 37 (Enhanced deduction for seniors, 1040s1a.37)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_senior_branches; test_tax_calculator.c test_obbba_senior_deduction_couple.

Additional deductions on line 13b

Schedule 1-A's total (line 38) goes to Form 1040 line 13b. The engine's only Schedule 1-A deduction is the senior deduction; the tips, overtime and car-loan interest deductions are not modelled.

Form lines: Form 1040 line 13b (Additional deductions from Schedule 1-A, line 38, 1040.13b)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_single_senior_with_gains.

Total deductions

Line 14 adds the standard deduction (12e) and the senior deduction (13b). There is no qualified business income deduction (13a).

Form lines: Form 1040 line 14 (Total deductions (lines 12e, 13a and 13b), 1040.14)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_single_senior_with_gains.

Taxable income

Line 15 is AGI less the deductions, not below zero. The deductions reduce ordinary income first; what is left over (the unused deduction) reduces the long-term gain that enters the capital-gains worksheet.

Form lines: Form 1040 line 15 (Taxable income, 1040.15)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_unused_deduction; test_federal_tax.c test_identities.

Tax: the brackets and the capital-gains worksheet

Tax: the brackets and the capital-gains worksheet

Ordinary taxable income is taxed on the 2026 brackets of the filing status (10% to 37%). Long-term gain is stacked on top of it and taxed at 0%, 15% and 20% by where it falls on the 2026 capital-gains bands (the Qualified Dividends and Capital Gain Tax Worksheet). Line 16 is the sum.

Form lines: Form 1040 line 16 (Tax, 1040.16)

Code: backend/src/tax_calculator.c compute_ordinary_income_tax, compute_capital_gains_tax. Tests: test_tax_calculator.c test_ordinary_bracket_edges_2026; test_tax_calculator.c test_cg_stacking_15pct; test_tax_calculator.c test_cg_boundary_all_statuses; test_federal_tax.c test_single_senior_with_gains.

Other taxes: §72(t) and the NIIT

The 10% additional tax on early distributions

10% of iraDistributions when the filer is 59 or younger at the end of the year (every month of that year is before 59½); none from the year the filer turns 60. None of the §72(t)(2) exceptions (separation from service at 55, substantially equal payments, disability and others) is modelled yet (R5), and Roth conversions are never charged. Schedule 2 line 8.

Form lines: Schedule 2 line 8 (Additional tax on IRAs or other tax-favored accounts, 1040s2.8)

Code: backend/src/tax_calculator.c compute_early_withdrawal_penalty, early_withdrawal_penalty_rate. Tests: test_tax_calculator.c test_early_withdrawal_59; test_tax_calculator.c test_early_withdrawal_60; test_federal_tax.c test_niit_short_term_and_penalty.

Net investment income tax

3.8% of the smaller of net investment income and MAGI over the threshold ($200,000 single and head of household, $250,000 joint, $125,000 separate; not indexed). Net investment income here is the year's net short-term and long-term gain; the engine models no interest, dividends or other investment income yet (R1). Schedule 2 line 12.

Form lines: Schedule 2 line 12 (Net investment income tax, 1040s2.12)

Code: backend/src/tax_calculator.c compute_niit. Tests: test_tax_calculator.c test_cg_niit; test_tax_calculator.c test_niit_threshold_2026; test_federal_tax.c test_niit_short_term_and_penalty.

Other taxes

Line 23 carries Schedule 2's total: the §72(t) additional tax and the NIIT.

Form lines: Form 1040 line 23 (Other taxes, from Schedule 2, line 21, 1040.23)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_niit_short_term_and_penalty.

Total tax

Line 24 adds line 16 and line 23. No credit (child tax credit, credit for the elderly, premium tax credit reconciliation) and no alternative minimum tax is modelled (R7), so line 22 equals line 16. result.totalTax is this line; result.incomeTax leaves out the §72(t) additional tax.

Form lines: Form 1040 line 24 (Total tax, 1040.24)

Code: backend/src/federal_tax.c federal_tax_compute. Tests: test_federal_tax.c test_identities; test_federal_api.c test_response_shape.