Professional-grade Low-Income Housing Tax Credit (LIHTC) calculator for Python.
Model LIHTC transactions end-to-end: eligible and qualified basis, QCT/DDA 30% boost, 4% vs 9% applicable percentage, 10-year credit delivery, investor IRR, 15-year compliance tracking, and IRC §42(j) recapture math — all with type hints and structured result objects.
LIHTC is the primary federal subsidy for affordable housing in the United States, allocating ~$10 billion in annual tax credits. Transactions involve layers of IRC §42 math that are easy to mis-model in spreadsheets. lihtc-calc provides auditable, tested Python functions that match IRS and state-agency conventions.
pip install lihtc-calcNo external dependencies — pure Python 3.9+.
from datetime import date
from lihtccalc import (
LIHTCDeal,
build_credit_result,
ComplianceTracker,
recapture_amount,
investor_irr,
build_investor_cash_flows,
gp_lp_split,
)
# Define a 9% new-construction deal in a QCT
deal = LIHTCDeal(
project_name="Riverside Commons",
total_dev_cost=12_000_000,
eligible_basis_adjustment=0.82, # 82% of TDC is eligible basis
applicable_fraction_units=0.95,
applicable_fraction_floor_area=0.93, # floor-area fraction is binding
credit_type="9pct",
placed_in_service_date=date(2024, 3, 1),
qct_or_dda=True, # 130% basis boost applied
low_income_set_aside_pct=0.40,
total_units=80,
low_income_units=76,
)
# Credit summary
result = build_credit_result(deal)
print(result.summary())
# === LIHTC Credit Summary: Riverside Commons ===
# Credit type : 9pct
# QCT/DDA boost : Yes (130%)
# Eligible basis : $9,840,000
# Boosted basis : $12,792,000
# Applicable fraction : 93.00%
# Qualified basis : $11,896,560
# Annual credit : $1,070,690
# 10-year credits : $10,706,904
# Investor IRR
annual = result.annual_credit
equity = result.total_credits_10yr * 0.95 # 95-cent credit price
flows = build_investor_cash_flows(equity, annual, residual_value=100_000)
irr = investor_irr(flows)
print(f"Investor IRR: {irr:.2%}")
# GP/LP equity split (standard 99.99% LP structure)
gp, lp = gp_lp_split(equity)
print(f"LP equity: ${lp:,.0f} | GP equity: ${gp:,.0f}")
# 15-year compliance tracking
tracker = ComplianceTracker(deal=deal)
for yr in range(1, 6):
cy = tracker.track_year(yr, low_income_units=76, total_units=80)
print(tracker.summary())
# Recapture if compliance breaks in year 5
event = recapture_amount(deal, violation_year=5)
print(event.summary())| Feature | Detail |
|---|---|
| Basis math | Eligible basis, QCT/DDA 130% boost, qualified basis via lower of unit/floor-area fraction |
| 4% vs 9% credit | Fixed applicable percentages (3.64% / 9.00%) matching IRS 2024 guidance |
| 10-year delivery | Level annual credit schedule, summed total credits |
| Equity modeling | Credit-price-to-equity, 99.99% LP / 0.01% GP split |
| Investor IRR | Newton-Raphson IRR with arbitrary cash-flow vectors |
| Compliance tracker | Year-by-year set-aside and AMI verification over 15-year period |
| Recapture (IRC §42(j)) | Declining recapture schedule, interest penalty, bond-disposition analysis |
| Result objects | CreditResult, RecaptureEvent with .summary() methods |
- Syndicators & investors — Quickly model credit delivery and investor return sensitivity.
- Developers & consultants — Validate qualified basis before submitting state tax credit applications.
- Compliance officers — Track annual set-aside and AMI tests; flag violation years automatically.
- Asset managers — Model recapture exposure for portfolio risk reporting.
- Policy researchers — Batch-analyze LIHTC economics across geographies and deal types.
eligible_basis(deal) # total_dev_cost × adjustment factor
applicable_fraction(deal) # min(unit_fraction, floor_area_fraction)
boosted_basis(deal) # eligible_basis × 1.30 if QCT/DDA
qualified_basis(deal) # boosted_basis × applicable_fraction
annual_credit(deal) # qualified_basis × applicable_percentage
total_credits_10yr(deal) # annual_credit × 10
credit_price_to_equity(deal, price)
build_credit_result(deal) # → CreditResult with .summary()
investor_irr(cash_flows) # Newton-Raphson IRR
gp_lp_split(equity, lp_pct) # → (gp_equity, lp_equity)
build_investor_cash_flows(equity, annual_credit, residual_value)
ComplianceTracker(deal)
.track_year(year, low_income_units)
.set_aside_compliance(year)
.ami_verification(household_income, ami, limit_pct)
.any_violation()
.violation_years()
.summary()
recapture_amount(deal, violation_year) # → RecaptureEvent
accelerated_credits(deal) # 15-year at-risk schedule
bond_disposition(deal, disposition_year) # § 42(j)(6) analysisMIT © Jay Patel