Skip to content

Commit aa0816f

Browse files
committed
balance synthetic add and cancel rates so the book is steady-state under any seed
PR #24 stabilized the book under seed 11 but the live deploy uses seed 42, which (as a property of that particular RNG path) produces a much less mobile reference and lets both sides accumulate to 1500+ qty even with the cancel-window targeting in place. Verified locally with seed 42 plus the rate=400, 72/8/20 mix: top size sat at 1207 to 3087 after a 25-second warm-up. That is the right fix in the wrong place: the cancel window helps cancels actually hit resting orders, but the per-event cancel share is still too low to balance the per- event add share. Shift the mix from 72 / 8 / 20 to 50 / 10 / 40 (limits / markets / cancels). At qty range [1, 6], the expected per-second add qty (~700) now matches the expected per-second removal qty from cancels plus market sweeps (~640), so the book reaches a steady state in the low hundreds rather than accumulating. The 40 percent cancel share is still a visually legible undercount of what real-exchange ITCH feeds actually show (often 80 percent plus cancels), but it reads as a busy market. Local verification with seed 42 (the live deploy's seed), 30s warm-up plus 20s sample at rate 400: top size min / median / max = 277 / 338 / 728 Compared to the previous run on the same seed and same code minus this commit, which sat at 1207 to 3087. 182/182 release tests still pass.
1 parent ffa8aba commit aa0816f

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

apps/server/main.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,16 @@ int main(int argc, char** argv) {
266266
if (reference < kPriceFloor) reference = kPriceFloor;
267267
if (reference > kPriceCeiling) reference = kPriceCeiling;
268268

269+
// Event mix tuned for steady state: at this share with the
270+
// current qty range, the expected add and cancel rates are
271+
// roughly balanced, so the resting book hovers in the low
272+
// hundreds rather than accumulating into the thousands.
273+
// Real-exchange ITCH feeds show much higher cancel ratios
274+
// than this (often 80 percent plus); 50 / 10 / 40 is a
275+
// visually legible undercount that still reads as a busy
276+
// market.
269277
const int b = bucket(rng);
270-
if (b < 72 || max_id == 0) {
278+
if (b < 50 || max_id == 0) {
271279
// Limit order placed near the reference, with a small
272280
// offset so the resting book builds depth across a
273281
// handful of ticks rather than at one price.
@@ -280,7 +288,7 @@ int main(int argc, char** argv) {
280288
: reference + offset;
281289
ev.qty = qty_dist(rng);
282290
max_id = ev.order_id;
283-
} else if (b < 80) {
291+
} else if (b < 60) {
284292
// Occasional market sweep that lifts the resting book.
285293
ev.kind = meridian::EventKind::NewOrder;
286294
ev.type = meridian::OrderType::Market;

0 commit comments

Comments
 (0)