code wiki / _hdl_build / nx_auction_core.nx
nx_auction_core.nx source
↩ module page · 60 lines · 2716 B
1// nx_auction_core.nx -- SHARED auction settlement engine (MANHEIM-BUILD): the reusable core under
2// EVERY auction channel (timed, proxy, simulcast, 2nd-chance, specialty). Pure integer-exact +
3// deterministic; NO syscalls -- operates only on caller-provided arrays. LIBRARY (no main); imported
4// by the per-channel gate organs. DRY law #15: the bid-validation + increment + reserve + anti-snipe
5// rules live in ONE place, so every channel settles identically and a rule fix lands once.
6// license_tier: ORIGINAL
7const AT_SOLD: i64 = 1
8const AT_NOSALE: i64 = 0
9
10// resolve one auction over the (time-ordered) concrete bid arrays. writes 8 results into out:
11// out[0]=winner_bidder out[1]=winning_price out[2]=status(1=SOLD/0=NOSALE)
12// out[3]=final_end out[4]=accepted out[5]=rejected
13// out[6]=high_amount out[7]=high_bidder (the RAW top bid regardless of reserve -- needed by the
14// second-chance channel: a NO-SALE still has a high bidder to negotiate with)
15// a bid is VALID iff start <= t <= effective_end AND amount >= (no-high ? opening : high+increment);
16// an accepted bid within snipe_window of the close extends the close to t+extension; at close SOLD to
17// the high bidder iff high >= reserve, else NO-SALE.
18func at_resolve(opening: i64, increment: i64, reserve: i64, start: i64, end: i64, snipe_window: i64, extension: i64, bidder: *i64, amount: *i64, time: *i64, n: i64, out: *i64) -> i64 {
19 var high: i64 = 0 // 0 = no high bid yet (amounts are positive cents)
20 var high_bidder: i64 = 0
21 var eff_end: i64 = end
22 var accepted: i64 = 0
23 var rejected: i64 = 0
24 var i: i64 = 0
25 while i < n {
26 let bt: i64 = time[i]
27 let ba: i64 = amount[i]
28 var ok: i64 = 1
29 if bt < start { ok = 0 }
30 if bt > eff_end { ok = 0 }
31 var req: i64 = opening
32 if high > 0 { req = high + increment }
33 if ba < req { ok = 0 }
34 if ok == 1 {
35 high = ba
36 high_bidder = bidder[i]
37 accepted = accepted + 1
38 // anti-snipe: bid within snipe_window of the close pushes the close out
39 if eff_end - bt < snipe_window { eff_end = bt + extension }
40 } else {
41 rejected = rejected + 1
42 }
43 i = i + 1
44 }
45 var status: i64 = AT_NOSALE
46 var winner: i64 = 0
47 var price: i64 = 0
48 if high >= reserve {
49 if high > 0 { status = AT_SOLD; winner = high_bidder; price = high }
50 }
51 out[0] = winner
52 out[1] = price
53 out[2] = status
54 out[3] = eff_end
55 out[4] = accepted
56 out[5] = rejected
57 out[6] = high // raw top bid (0 if no valid bid), independent of reserve
58 out[7] = high_bidder
59 return 0
60}