49 lines
2 KiB
Python
49 lines
2 KiB
Python
"""Cyprus regime — non-dom 17-year exemption on foreign dividends +
|
||
interest, plus 2.65% GeSY healthcare levy capped at €180k.
|
||
|
||
The non-dom regime (Art 8(20)/(20A) Income Tax Law 118(I)/2002) gives
|
||
17 years of full exemption from SDC (Special Defence Contribution) on
|
||
foreign dividends and interest. Capital gains on shares are exempt
|
||
under standard CGT rules (only Cypriot real estate is taxed). Earned
|
||
income from employment is taxed under standard PIT bands — irrelevant
|
||
for our retirement scenarios.
|
||
|
||
GeSY (Γε.Σ.Υ. — General Healthcare System) levies 2.65% on worldwide
|
||
income with an annual cap of €180,000 of contributing income. We
|
||
convert the €180k cap to GBP via the FX rate at scenario time;
|
||
default = 0.86 GBP/EUR ≈ £154,800.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from decimal import Decimal
|
||
|
||
from fire_planner.tax.base import TaxBreakdown, TaxInputs, TaxRegime
|
||
|
||
DEFAULT_GESY_RATE = Decimal("0.0265")
|
||
DEFAULT_GESY_CAP_EUR = Decimal("180000")
|
||
|
||
|
||
class CyprusTaxRegime(TaxRegime):
|
||
name = "cyprus"
|
||
|
||
def __init__(
|
||
self,
|
||
gesy_rate: Decimal = DEFAULT_GESY_RATE,
|
||
gesy_cap_gbp: Decimal | None = None,
|
||
gbp_per_eur: Decimal = Decimal("0.86"),
|
||
) -> None:
|
||
self.gesy_rate = gesy_rate
|
||
self.gesy_cap_gbp = (gesy_cap_gbp if gesy_cap_gbp is not None else DEFAULT_GESY_CAP_EUR *
|
||
gbp_per_eur)
|
||
|
||
def compute_tax(self, inputs: TaxInputs) -> TaxBreakdown:
|
||
# Foreign divs/interest exempt under non-dom (assumed within 17y window).
|
||
# Foreign capital gains exempt unless the underlying is Cypriot real estate.
|
||
chargeable = (inputs.earned_income + inputs.pension_withdrawal + inputs.capital_gains +
|
||
inputs.dividends + inputs.interest)
|
||
capped = min(chargeable, self.gesy_cap_gbp)
|
||
return TaxBreakdown(
|
||
healthcare_levy=capped * self.gesy_rate,
|
||
notes=("cyprus-non-dom", f"gesy_rate={self.gesy_rate}",
|
||
f"gesy_cap_gbp={self.gesy_cap_gbp}"),
|
||
)
|