How the Hong Kong first registration tax calculator is verified

Inputs

InputFieldType
Taxable value of the car (HKD)taxableValuenumber
Fuelfuelstring
Engine cylinder capacity (cc) — petrol and dieselccnumber
Rated power (kW) — electricratedPowerKwnumber

The formula

Each derived value below is computed by the Valem engine from the expression shown, in this order. Nothing else runs — there is no hidden code path.

Derived valueFieldFormula (JSONata)
First registration taxfirstRegistrationTax$round($bandedCharge(taxableValue, [{"upTo": $const.frtTier1, "rate": $const.frtRate1}, {"upTo": $const.frtTier2, "rate": $const.frtRate2}, {"upTo": $const.frtTier3, "rate": $const.frtRate3}, {"upTo": null, "rate": $const.frtRate4}]), 2)
Annual licence feeannualLicenceFee($c := $n(cc); $k := $n(ratedPowerKw); fuel = 'electric' ? ($k <= $const.kwBand1 ? $const.electricFee1 : ($k <= $const.kwBand2 ? $const.electricFee2 : ($k <= $const.kwBand3 ? $const.electricFee3 : ($k <= $const.kwBand4 ? $const.electricFee4 : $const.electricFee5)))) : (fuel = 'diesel' ? ($c <= $const.ccBand1 ? $const.dieselFee1 : ($c <= $const.ccBand2 ? $const.dieselFee2 : ($c <= $const.ccBand3 ? $const.dieselFee3 : ($c <= $const.ccBand4 ? $const.dieselFee4 : $const.dieselFee5)))) : ($c <= $const.ccBand1 ? $const.petrolFee1 : ($c <= $const.ccBand2 ? $const.petrolFee2 : ($c <= $const.ccBand3 ? $const.petrolFee3 : ($c <= $const.ccBand4 ? $const.petrolFee4 : $const.petrolFee5))))))

Rates and thresholds

The expressions above read these as $const. They are the figures the annual refresh replaces, so they live as data rather than being written into the formulas — which is what makes a year-on-year change a one-line diff instead of an edit to arithmetic.

ConstantValue
frtTier1150000
frtTier2300000
frtTier3500000
frtRate10.46
frtRate20.86
frtRate31.15
frtRate41.32
ccBand11500
ccBand22500
ccBand33500
ccBand44500
petrolFee15074
petrolFee27498
petrolFee39929
petrolFee412360
petrolFee514694
dieselFee16972
dieselFee29396
dieselFee311827
dieselFee414258
dieselFee516592
kwBand175
kwBand2125
kwBand3175
kwBand4225
electricFee11614
electricFee22114
electricFee32614
electricFee43114
electricFee55114

Test vectors (6)

Every case is executed against this model on each build, by the Java engine and independently by a JavaScript one. A mismatch of a single cent fails the build, so the page cannot ship advertising a figure the model no longer produces.

Case 1 — C1 petrol 1,598 cc at $250,000: FRT $155,000 and a $7,498 licence

given taxableValue250000
given fuelpetrol
given cc1598
given ratedPowerKw0
expect firstRegistrationTax155000
expect annualLicenceFee7498

Case 2 — C2 $600,000 reaches the 132% band

given taxableValue600000
given fuelpetrol
given cc2998
given ratedPowerKw0
expect firstRegistrationTax560000
expect annualLicenceFee9929

Case 3 — C3 electric 150 kW at $300,000: full FRT now the concession has ended

given taxableValue300000
given fuelelectric
given cc0
given ratedPowerKw150
expect firstRegistrationTax198000
expect annualLicenceFee2614

Case 4 — C4 light diesel 2,000 cc

given taxableValue0
given fueldiesel
given cc2000
given ratedPowerKw0
expect firstRegistrationTax0
expect annualLicenceFee9396

Case 5 — C5 exactly 1,500 cc is the lowest band ("not exceeding")

given taxableValue0
given fuelpetrol
given cc1500
given ratedPowerKw0
expect annualLicenceFee5074

Case 6 — C6 an electric car above 225 kW

given taxableValue0
given fuelelectric
given cc0
given ratedPowerKw300
expect annualLicenceFee5114

Sources

Check it yourself — and reuse it

The whole model as JSON — inputs, outputs, formulas, vectors and sources in one re-runnable document.

This model is published under CC BY 4.0: use it, adapt it, build on it, with attribution. The licence covers the model — the expression of each rule and the arrangement of the catalog. The rates and thresholds are law, and nobody licenses those; the sources above are where they come from.

← Back to the Hong Kong first registration tax calculator

Built with Valem — a live, verifiable calculator you can fork and embed.