A 2017 Swift ZXI, 64,200 km, priced from 8 comps over 60 days. Fixed illustrative settings —
p70 / p85, margin 8%, RF ₹12,000 + other ₹10,000, trim ×12, weightHalf 3.0. Your own
percentiles and weights are in Settings and may differ.
1 · Normalise the trim. Lowercase, expand “+” to “plus”, keep letters/numbers/decimals, drop noise, then sort the tokens. So ZXI+ and ZXI Plus both become plus zxi, and SX (O), (O) SX, SX(O) all become o sx. Word order stops mattering.
2 · Classify each token. Two words, used the same way everywhere in this app:
the trim is the whole text the source published (HIGHLINE PLUS 1.0 16 ALLOY);
the variant is the version it names (Highline Plus) — what decides whether two cars are comparable.
A variant is made of a base word plus any modifier:
HIGHLINE PLUS 1.0 16 ALLOY
base word highline · modifier plus → variant = Highline Plus
displacement 1.0 · equipment 16 alloy → ignored for comparability
A car has exactly one base word, so a base word can stand on its own (zxi, sx, asta).
A modifier means nothing on its own and sub-divides a base word (plus, o) — so a
Highline and a Highline Plus are different variants, as are SX and SX (O).
Everything else — amt, 16 alloy, dual tone, shvs — describes equipment, not version,
and is ignored when deciding whether two cars are comparable.
3 · Mismatch = Jaccard distance between the two token sets:
mismatch = 1 − |shared| ÷ |union|
ZXI vs ZXI → shared 1, union 1 → 1 − 1/1 = 0.00
ZXI vs ZXI AMT → shared 1, union 2 → 1 − 1/2 = 0.50
ZXI vs (no trim) → shared 0, union 1 → 1 − 0/1 = 1.00
A comp with no published trim scores the maximum distance but is never excluded — unknown is not the same as wrong.
4 · Adjust the price to the subject's year and odometer. Trim is not adjusted — no arithmetic turns a VXI into a ZXI, which is why trim has to be a filter:
adjusted = asking + year_adj + odo_adj
a 2014 at 76,860 km: 3,19,000 + 65,067 + 22,155 = 4,06,222
5 · Rank it. Distance accumulates in units; the falloff curve turns that into the Match % on the audit table:
distance = 12×mismatch + 1×|Δyear| + 1×min(|Δkm|÷10,000, 3) + proximity
Match % = 1 ÷ (1 + (distance ÷ 3.0)²)
the no-trim comp: 12×1.00 + 2 + 0.32 = 14.32 → 1 ÷ (1+22.78) = 4%
At distance 3.0 the weight is exactly 50% — that's what Match falloff names.
6 · Place each comp on a 0–100% axis. Comps do not count equally, so each owns a slice proportional to its Match %, and sits at the middle of its slice:
pos = (running total − own weight ÷ 2) ÷ total weight
| # |
yr · trim |
adjusted |
match |
pos |
| 1 | 2014 zxi | 4,06,222 | 33% | 3.6% |
| 2 | 2018 zxi | 4,12,980 | 83% | 16.3% |
| 3 | 2016 zxi | 4,84,174 | 65% | 32.5% |
| 4 | 2015 (no trim) | 4,98,011 | 4% | 40.1% |
| 5 | 2018 zxi | 5,00,572 | 78% | 49.1% |
| 6 | 2018 zxi | 5,27,263 | 67% | 64.9% |
| 7 | 2015 zxi | 5,59,867 | 60% | 78.9% |
| 8 | 2015 zxi | 5,94,506 | 66% | 92.7% |
7 · Interpolate. Find the two comps whose positions bracket the target:
p70 → between #6 (64.9%) and #7 (78.9%)
frac = (0.70 − 0.649) ÷ (0.789 − 0.649) = 0.365
5,27,263 + 0.365 × (5,59,867 − 5,27,263) = ₹5,39,158
p85 lands the same way between #7 and #8 → ₹5,75,206
8 · Apply margin and costs. Benchmark = 5,39,158 × (1 − 8%) − 22,000 = ₹4,74,025. Stop PP = 5,75,206 × (1 − 8%) − 22,000 = ₹5,07,190. The gap between them is the buffer, split into the green / yellow / red thirds.