SPB Git

spb/rareindex

Public

Auction fees foundation: buyer-premium schedules (data/fees/auction-houses.json), fees.ts (marginal tiers, min/max/fixed, all-in price with basis), sales.all_in_usd/fee_basis, auction_lots USD + assessment columns; migration 0007

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Sep 11, 2026) parent a1e47ef Browse files

8 changed files +9,523 −1

added data/fees/auction-houses.json +66 −0
@@ -0,0 +1,66 @@
1+{
2+ "$comment": "Buyer's premium schedules (§35). Marginal tiers on the hammer price, in the house's billing currency (tiers are approximated in other currencies at the current FX rate). confidence: 'published' = taken from the house's terms at as_of; 'approximate' = widely reported but not re-verified against the current terms — shown as ≈ and labelled 'estimated' everywhere; 'none' = no buyer premium by design. Anything not listed falls back to `default` (auction_house 22 %, labelled 'default'). VAT/sales tax on the premium, import duties and shipping are NOT included and are stated as such in the UI. Never present these numbers as the exact invoice a buyer will receive.",
3+ "version": 1,
4+ "as_of": "2026-09-11",
5+ "default": { "auction_house": { "rate": 0.22, "confidence": "default", "note": "Typical contemporary buyer's premium for a regional auction house; used only when the house is unknown." }, "marketplace": { "rate": 0, "confidence": "none", "note": "Fixed-price marketplaces bill the asking price; fees are the seller's." } },
6+ "houses": [
7+ { "id": "sothebys", "name": "Sotheby's", "aliases": ["Sotheby's", "Sothebys", "sothebys", "RM Sotheby's Online"], "currency": "USD", "tiers": [{ "upTo": 1000000, "rate": 0.27 }, { "upTo": 8000000, "rate": 0.22 }, { "upTo": null, "rate": 0.15 }], "confidence": "published", "source": "https://www.sothebys.com/en/buy-sell/buying/buyers-premium", "note": "Standard schedule reinstated Feb 2025; wine, cars and some online sales use different rates." },
8+ { "id": "christies", "name": "Christie's", "aliases": ["Christie's", "Christies", "christies"], "currency": "USD", "tiers": [{ "upTo": 1000000, "rate": 0.26 }, { "upTo": 6000000, "rate": 0.21 }, { "upTo": null, "rate": 0.15 }], "confidence": "published", "source": "https://www.christies.com/en/help/buying-guide/financial-information" },
9+ { "id": "phillips", "name": "Phillips", "aliases": ["Phillips", "phillips-watches", "phillips-art"], "currency": "USD", "tiers": [{ "upTo": 1000000, "rate": 0.27 }, { "upTo": 6000000, "rate": 0.21 }, { "upTo": null, "rate": 0.145 }], "confidence": "approximate", "source": "https://www.phillips.com/buysell/buy" },
10+ { "id": "bonhams", "name": "Bonhams", "aliases": ["Bonhams", "the-market-bonhams", "Bonhams Skinner", "Bonhams Cornette de Saint Cyr"], "currency": "USD", "tiers": [{ "upTo": 50000, "rate": 0.28 }, { "upTo": 1000000, "rate": 0.27 }, { "upTo": 6000000, "rate": 0.21 }, { "upTo": null, "rate": 0.145 }], "confidence": "approximate", "source": "https://www.bonhams.com/buyers_guide/" },
11+ { "id": "heritage", "name": "Heritage Auctions", "aliases": ["Heritage Auctions", "Heritage", "HA.com"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "minimum": 19, "confidence": "approximate", "source": "https://www.ha.com/c/ref/terms-and-conditions.zx", "note": "20 % (min $19) for most categories; some comics/art sessions differ." },
12+ { "id": "goldin", "name": "Goldin", "aliases": ["Goldin", "Goldin Auctions"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "published", "source": "https://goldin.co/terms" },
13+ { "id": "catawiki", "name": "Catawiki", "aliases": ["Catawiki"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.09 }], "fixedFee": 1, "confidence": "approximate", "source": "https://www.catawiki.com/en/help_center", "note": "Buyer protection fee ≈ 9 % + €1 per lot." },
14+ { "id": "bring-a-trailer", "name": "Bring a Trailer", "aliases": ["Bring a Trailer", "bring-a-trailer", "BaT"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.05 }], "minimum": 250, "maximum": 7500, "confidence": "published", "source": "https://bringatrailer.com/faq/" },
15+ { "id": "cars-and-bids", "name": "Cars & Bids", "aliases": ["Cars & Bids", "cars-and-bids"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.05 }], "minimum": 225, "maximum": 7500, "confidence": "approximate", "source": "https://carsandbids.com/faq" },
16+ { "id": "collecting-cars", "name": "Collecting Cars", "aliases": ["Collecting Cars", "collecting-cars"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.072 }], "maximum": 6000, "confidence": "approximate", "note": "6 % + VAT on the fee, capped." },
17+ { "id": "mecum", "name": "Mecum Auctions", "aliases": ["Mecum Auctions", "Mecum", "mecum"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.1 }], "confidence": "approximate", "note": "10 % on-site; internet/phone bidders pay more." },
18+ { "id": "rm-sothebys", "name": "RM Sotheby's", "aliases": ["RM Sotheby's", "rm-sothebys", "RM Auctions"], "currency": "USD", "tiers": [{ "upTo": 250000, "rate": 0.12 }, { "upTo": null, "rate": 0.1 }], "confidence": "approximate" },
19+ { "id": "gooding", "name": "Gooding & Company", "aliases": ["Gooding & Company", "Gooding", "gooding"], "currency": "USD", "tiers": [{ "upTo": 250000, "rate": 0.12 }, { "upTo": null, "rate": 0.1 }], "confidence": "approximate" },
20+ { "id": "hakes", "name": "Hake's Auctions", "aliases": ["Hake's Auctions", "Hake's", "hakes"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "approximate" },
21+ { "id": "scp", "name": "SCP Auctions", "aliases": ["SCP Auctions", "scp-auctions"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "approximate" },
22+ { "id": "lelands", "name": "Lelands", "aliases": ["Lelands", "lelands"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "approximate" },
23+ { "id": "comiclink", "name": "ComicLink", "aliases": ["ComicLink", "comiclink"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0 }], "confidence": "none", "note": "No buyer's premium; the seller pays the commission." },
24+ { "id": "comicconnect", "name": "ComicConnect", "aliases": ["ComicConnect", "comicconnect"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0 }], "confidence": "approximate", "note": "No buyer's premium on most sales." },
25+ { "id": "yahoo-auctions-jp", "name": "Yahoo! Auctions Japan", "aliases": ["Yahoo! Auctions Japan", "Yahoo! Auctions Japan (ヤフオク!)", "yahoo-auctions-jp", "ヤフオク!"], "currency": "JPY", "tiers": [{ "upTo": null, "rate": 0 }], "confidence": "none", "note": "No buyer's fee; the seller pays the system fee. Proxy/forwarding fees for overseas buyers are not modelled." },
26+ { "id": "noonans", "name": "Noonans Mayfair", "aliases": ["Noonans Mayfair", "Noonans", "noonans", "DNW"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.24 }], "confidence": "approximate", "note": "VAT on the premium not included." },
27+ { "id": "potter", "name": "Potter & Potter Auctions", "aliases": ["Potter & Potter Auctions", "Potter & Potter", "potter-auctions"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "approximate", "note": "Online bidding platforms add their own surcharge." },
28+ { "id": "swann", "name": "Swann Auction Galleries", "aliases": ["Swann Auction Galleries", "Swann", "swann"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.25 }], "confidence": "approximate" },
29+ { "id": "pba", "name": "PBA Galleries", "aliases": ["PBA Galleries", "pba-galleries"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.25 }], "confidence": "approximate" },
30+ { "id": "doyle", "name": "Doyle", "aliases": ["Doyle", "doyle", "Doyle New York"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.27 }], "confidence": "approximate" },
31+ { "id": "wright", "name": "Wright", "aliases": ["Wright", "wright", "Rago/Wright", "Rago"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.25 }], "confidence": "approximate" },
32+ { "id": "lama", "name": "Los Angeles Modern Auctions", "aliases": ["Los Angeles Modern Auctions", "LAMA", "lama"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.25 }], "confidence": "approximate" },
33+ { "id": "whisky-auction", "name": "Whisky.Auction", "aliases": ["Whisky.Auction", "whisky-auction"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.12 }], "confidence": "approximate", "note": "≈ 10 % buyer fee + VAT on the fee." },
34+ { "id": "just-whisky", "name": "Just Whisky", "aliases": ["Just Whisky", "just-whisky"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.12 }], "confidence": "approximate" },
35+ { "id": "whisky-hammer", "name": "Whisky Hammer", "aliases": ["Whisky Hammer", "whisky-hammer"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.12 }], "confidence": "approximate" },
36+ { "id": "scotch-whisky-auctions", "name": "Scotch Whisky Auctions", "aliases": ["Scotch Whisky Auctions", "scotch-whisky-auctions"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.12 }], "confidence": "approximate" },
37+ { "id": "hdh", "name": "Hart Davis Hart Wine Co.", "aliases": ["Hart Davis Hart Wine Co.", "HDH", "hdh-wine"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.24 }], "confidence": "approximate" },
38+ { "id": "winebid", "name": "WineBid", "aliases": ["WineBid", "winebid"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.17 }], "confidence": "approximate" },
39+ { "id": "tokyo-chuo", "name": "Tokyo Chuo Auction", "aliases": ["Tokyo Chuo Auction", "tokyo-chuo"], "currency": "JPY", "tiers": [{ "upTo": null, "rate": 0.15 }], "confidence": "approximate" },
40+ { "id": "sgbaldwins", "name": "Stanley Gibbons Baldwin's", "aliases": ["Stanley Gibbons Baldwin's", "Baldwin's", "sgbaldwins"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "approximate", "note": "VAT on the premium not included." },
41+ { "id": "corinphila", "name": "Corinphila Auctions", "aliases": ["Corinphila Auctions", "Corinphila", "corinphila"], "currency": "CHF", "tiers": [{ "upTo": null, "rate": 0.22 }], "confidence": "approximate" },
42+ { "id": "kuenker", "name": "Künker", "aliases": ["Künker", "Kuenker", "kuenker", "Fritz Rudolf Künker"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.25 }], "confidence": "approximate" },
43+ { "id": "noble", "name": "Noble Numismatics", "aliases": ["Noble Numismatics", "noble"], "currency": "AUD", "tiers": [{ "upTo": null, "rate": 0.1925 }], "confidence": "approximate", "note": "17.5 % + GST." },
44+ { "id": "dunbar-sloane", "name": "Dunbar Sloane", "aliases": ["Dunbar Sloane", "dunbar-sloane"], "currency": "NZD", "tiers": [{ "upTo": null, "rate": 0.175 }], "confidence": "approximate" },
45+ { "id": "miller-miller", "name": "Miller & Miller Auctions", "aliases": ["Miller & Miller Auctions", "Miller & Miller", "miller-miller"], "currency": "CAD", "tiers": [{ "upTo": null, "rate": 0.18 }], "confidence": "approximate" },
46+ { "id": "aguttes", "name": "Aguttes", "aliases": ["Aguttes", "aguttes"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.3 }], "confidence": "approximate", "note": "≈ 25 % HT + TVA." },
47+ { "id": "artcurial", "name": "Artcurial", "aliases": ["Artcurial", "artcurial"], "currency": "EUR", "tiers": [{ "upTo": 700000, "rate": 0.3 }, { "upTo": null, "rate": 0.24 }], "confidence": "approximate", "note": "TTC; motorcars use a different schedule." },
48+ { "id": "millon", "name": "Millon", "aliases": ["Millon", "millon"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.3 }], "confidence": "approximate" },
49+ { "id": "piasa", "name": "PIASA", "aliases": ["PIASA", "piasa"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.3 }], "confidence": "approximate" },
50+ { "id": "ader", "name": "Ader", "aliases": ["Ader", "ader"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.28 }], "confidence": "approximate" },
51+ { "id": "osenat", "name": "Osenat", "aliases": ["Osenat", "osenat"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.3 }], "confidence": "approximate" },
52+ { "id": "chiswick", "name": "Chiswick Auctions", "aliases": ["Chiswick Auctions", "Chiswick", "chiswick"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.3 }], "confidence": "approximate", "note": "25 % + VAT." },
53+ { "id": "dominic-winter", "name": "Dominic Winter Auctioneers", "aliases": ["Dominic Winter Auctioneers", "Dominic Winter", "dominic-winter"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.288 }], "confidence": "approximate", "note": "24 % + VAT." },
54+ { "id": "sworders", "name": "Sworders", "aliases": ["Sworders", "sworders"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.3 }], "confidence": "approximate", "note": "25 % + VAT." },
55+ { "id": "woolley-wallis", "name": "Woolley & Wallis", "aliases": ["Woolley & Wallis", "woolley-wallis"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.312 }], "confidence": "approximate", "note": "26 % + VAT." },
56+ { "id": "lyon-turnbull", "name": "Lyon & Turnbull", "aliases": ["Lyon & Turnbull", "lyon-turnbull"], "currency": "GBP", "tiers": [{ "upTo": null, "rate": 0.312 }], "confidence": "approximate", "note": "26 % + VAT." },
57+ { "id": "auctionet", "name": "Auctionet", "aliases": ["Auctionet", "auctionet"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.225 }], "confidence": "approximate", "note": "Varies by partner house." },
58+ { "id": "aste-bolaffi", "name": "Aste Bolaffi", "aliases": ["Aste Bolaffi", "Bolaffi", "aste-bolaffi"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0.24 }], "confidence": "approximate" },
59+ { "id": "antiquorum", "name": "Antiquorum", "aliases": ["Antiquorum", "antiquorum"], "currency": "CHF", "tiers": [{ "upTo": null, "rate": 0.25 }], "confidence": "approximate" },
60+ { "id": "dlrc", "name": "David Lawrence Rare Coins", "aliases": ["David Lawrence Rare Coins", "DLRC", "dlrc"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.1 }], "confidence": "approximate" },
61+ { "id": "kelleher", "name": "Kelleher Auctions", "aliases": ["Kelleher Auctions", "Kelleher", "kelleher"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "approximate" },
62+ { "id": "clean-sweep", "name": "Clean Sweep Auctions", "aliases": ["Clean Sweep Auctions", "clean-sweep"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0.2 }], "confidence": "approximate" },
63+ { "id": "mycomicshop", "name": "MyComicShop", "aliases": ["MyComicShop", "mycomicshop"], "currency": "USD", "tiers": [{ "upTo": null, "rate": 0 }], "confidence": "approximate", "note": "No buyer's premium on MyComicShop auctions." },
64+ { "id": "e-rocks", "name": "e-Rocks", "aliases": ["e-Rocks", "e-rocks"], "currency": "EUR", "tiers": [{ "upTo": null, "rate": 0 }], "confidence": "approximate", "note": "Marketplace auctions billed at the hammer price." }
65+ ]
66+}
added packages/database/migrations/0007_organic_colonel_america.sql +21 −0
@@ -0,0 +1,21 @@
1+ALTER TABLE "auction_lots" ADD COLUMN "estimate_low_usd" numeric(18, 4);--> statement-breakpoint
2+ALTER TABLE "auction_lots" ADD COLUMN "estimate_high_usd" numeric(18, 4);--> statement-breakpoint
3+ALTER TABLE "auction_lots" ADD COLUMN "current_bid_usd" numeric(18, 4);--> statement-breakpoint
4+ALTER TABLE "auction_lots" ADD COLUMN "hammer_price_usd" numeric(18, 4);--> statement-breakpoint
5+ALTER TABLE "auction_lots" ADD COLUMN "fx_rate" real;--> statement-breakpoint
6+ALTER TABLE "auction_lots" ADD COLUMN "fx_date" date;--> statement-breakpoint
7+ALTER TABLE "auction_lots" ADD COLUMN "buyer_premium_rate" real;--> statement-breakpoint
8+ALTER TABLE "auction_lots" ADD COLUMN "fee_basis" text;--> statement-breakpoint
9+ALTER TABLE "auction_lots" ADD COLUMN "all_in_bid_usd" numeric(18, 4);--> statement-breakpoint
10+ALTER TABLE "auction_lots" ADD COLUMN "all_in_estimate_low_usd" numeric(18, 4);--> statement-breakpoint
11+ALTER TABLE "auction_lots" ADD COLUMN "all_in_estimate_high_usd" numeric(18, 4);--> statement-breakpoint
12+ALTER TABLE "auction_lots" ADD COLUMN "riv_usd_at_assessment" numeric(18, 4);--> statement-breakpoint
13+ALTER TABLE "auction_lots" ADD COLUMN "bid_vs_riv" real;--> statement-breakpoint
14+ALTER TABLE "auction_lots" ADD COLUMN "estimate_vs_riv" real;--> statement-breakpoint
15+ALTER TABLE "auction_lots" ADD COLUMN "assessment_verdict" text;--> statement-breakpoint
16+ALTER TABLE "auction_lots" ADD COLUMN "assessed_at" timestamp with time zone;--> statement-breakpoint
17+ALTER TABLE "sales" ADD COLUMN "all_in_usd" numeric(18, 4);--> statement-breakpoint
18+ALTER TABLE "sales" ADD COLUMN "fee_basis" text;--> statement-breakpoint
19+ALTER TABLE "sales" ADD COLUMN "buyer_premium_rate" real;--> statement-breakpoint
20+CREATE INDEX "auction_lots_status_ends_idx" ON "auction_lots" USING btree ("status","ends_at");--> statement-breakpoint
21+CREATE INDEX "auction_lots_bid_vs_riv_idx" ON "auction_lots" USING btree ("bid_vs_riv") WHERE bid_vs_riv is not null and status in ('live','upcoming');
\ No newline at end of file
added packages/database/migrations/meta/0007_snapshot.json +9186 −0
Large diff (9,187 lines) is not loaded by default to keep the page fast.Load diff
modified packages/database/migrations/meta/_journal.json +7 −0
Large diff (14 lines) is not loaded by default to keep the page fast.Load diff
modified packages/database/src/schema/market.ts +27 −1
Large diff (46 lines) is not loaded by default to keep the page fast.Load diff
added packages/valuation/src/fees.test.ts +48 −0
Large diff (48 lines) is not loaded by default to keep the page fast.Load diff
added packages/valuation/src/fees.ts +167 −0
Large diff (167 lines) is not loaded by default to keep the page fast.Load diff
modified packages/valuation/src/index.ts +1 −0
Large diff (5 lines) is not loaded by default to keep the page fast.Load diff
Menu

Theme