galaxis-po/backend/app/services/tax_simulation.py
머니페니 12d235a1f1 feat: add 9 new modules - notification alerts, trading journal, position sizing, pension allocation, drawdown monitoring, benchmark dashboard, tax simulation, correlation analysis, parameter optimizer
Phase 1:
- Real-time signal alerts (Discord/Telegram webhook)
- Trading journal with entry/exit tracking
- Position sizing calculator (Fixed/Kelly/ATR)

Phase 2:
- Pension asset allocation (DC/IRP 70% risk limit)
- Drawdown monitoring with SVG gauge
- Benchmark dashboard (portfolio vs KOSPI vs deposit)

Phase 3:
- Tax benefit simulation (Korean pension tax rules)
- Correlation matrix heatmap
- Parameter optimizer with grid search + overfit detection
2026-03-29 10:03:08 +09:00

109 lines
3.4 KiB
Python

"""
Tax simulation service for Korean retirement pension (퇴직연금) tax benefits.
"""
IRP_ANNUAL_LIMIT = 9_000_000 # DC+IRP 합산 연간 한도
INCOME_THRESHOLD = 55_000_000 # 총급여 기준
LOW_INCOME_RATE = 16.5 # 5,500만원 이하 공제율
HIGH_INCOME_RATE = 13.2 # 5,500만원 초과 공제율
LUMP_SUM_TAX_RATE = 16.5 # 기타소득세 (일시금)
def _get_pension_tax_rate(age: int) -> float:
if age >= 80:
return 3.3
elif age >= 70:
return 4.4
else:
return 5.5
def calculate_tax_deduction(
annual_income: int,
contribution: int,
account_type: str,
) -> dict:
deduction_rate = LOW_INCOME_RATE if annual_income <= INCOME_THRESHOLD else HIGH_INCOME_RATE
deductible = min(contribution, IRP_ANNUAL_LIMIT)
tax_deduction = deductible * (deduction_rate / 100)
return {
"annual_income": annual_income,
"contribution": contribution,
"account_type": account_type,
"deduction_rate": deduction_rate,
"irp_limit": IRP_ANNUAL_LIMIT,
"deductible_contribution": deductible,
"tax_deduction": tax_deduction,
}
def calculate_pension_tax(
withdrawal_amount: int,
withdrawal_type: str,
age: int,
) -> dict:
pension_tax_rate = _get_pension_tax_rate(age)
pension_tax = withdrawal_amount * (pension_tax_rate / 100)
lump_sum_tax = withdrawal_amount * (LUMP_SUM_TAX_RATE / 100)
tax_saving = lump_sum_tax - pension_tax
return {
"withdrawal_amount": withdrawal_amount,
"withdrawal_type": withdrawal_type,
"age": age,
"pension_tax_rate": pension_tax_rate,
"pension_tax": pension_tax,
"lump_sum_tax_rate": LUMP_SUM_TAX_RATE,
"lump_sum_tax": lump_sum_tax,
"tax_saving": tax_saving,
}
def simulate_accumulation(
monthly_contribution: int,
years: int,
annual_return: float,
tax_deduction_rate: float,
) -> dict:
annual_contribution = monthly_contribution * 12
monthly_return = (1 + annual_return / 100) ** (1 / 12) - 1
yearly_data = []
current_value = 0.0
cumulative_contribution = 0
cumulative_tax_deduction = 0.0
for year in range(1, years + 1):
for _ in range(12):
current_value = current_value * (1 + monthly_return) + monthly_contribution
cumulative_contribution += annual_contribution
deductible = min(annual_contribution, IRP_ANNUAL_LIMIT)
yearly_tax_deduction = deductible * (tax_deduction_rate / 100)
cumulative_tax_deduction += yearly_tax_deduction
yearly_data.append({
"year": year,
"contribution": annual_contribution,
"cumulative_contribution": cumulative_contribution,
"investment_value": round(current_value, 0),
"tax_deduction": yearly_tax_deduction,
"cumulative_tax_deduction": cumulative_tax_deduction,
})
total_contribution = annual_contribution * years
total_return = round(current_value - total_contribution, 0)
return {
"monthly_contribution": monthly_contribution,
"years": years,
"annual_return": annual_return,
"tax_deduction_rate": tax_deduction_rate,
"total_contribution": total_contribution,
"final_value": round(current_value, 0),
"total_return": total_return,
"total_tax_deduction": cumulative_tax_deduction,
"yearly_data": yearly_data,
}