Class LpRouter
java.lang.Object
com.quantfinlib.fx.LpRouter
Last-look-aware LP router: chooses where to send an FX clip by
expected all-in price, not displayed price. The FX-specific
insight it encodes: a tight quote from an LP that rejects 20% of the time
— and whose rejects are followed by adverse markout — is more expensive
than a wider firm quote. Expected cost per LP:
quoted price ± rejectRate × max(postRejectMarkout, 0)(worse for the taker on either side), with LPs above a configurable reject-rate cap vetoed outright. Quotes come from an
FxTierBook
(full-amount tiers), behavior from an LpScorecard.
Full-amount only, one LP per clip — the FX convention that avoids
spraying child orders (each child leaks intent to another counterparty's
last-look window). For deliberate multi-LP sweeps, use
FxTierBook.sweepPlan(boolean, double, double[]) directly and accept the signaling.
Zero allocation, single writer. The route decision returns the LP
index; the prices behind the decision are readable until the next call
(lastQuotedPrice, lastExpectedPrice).
-
Constructor Summary
ConstructorsConstructorDescriptionLpRouter(FxTierBook book, LpScorecard card, double maxRejectRate) Wiring requirement: the scorecard's markout penalty only works ifcard.onMidis fed composite mids on the same clock asonReject— without it markouts never mature, the penalty is silently zero, and routing degrades to displayed-price-plus-veto.LpRouter(FxTierBook book, LpScorecard card, double maxRejectRate, double holdUrgencyBpsPerMs) With a hold-time urgency: an LP's last-look hold is FX's latency dimension — while it deliberates, the market drifts against you. -
Method Summary
Modifier and TypeMethodDescriptiondoubleReject-adjusted price behind the last successfulroute(boolean, double); NaN otherwise.doubleRaw quoted price behind the last successfulroute(boolean, double); NaN otherwise.introute(boolean buy, double size) Chooses the LP for a full-amount clip.longlongLP-candidate evaluations skipped for exceeding the reject-rate cap.
-
Constructor Details
-
LpRouter
Wiring requirement: the scorecard's markout penalty only works ifcard.onMidis fed composite mids on the same clock asonReject— without it markouts never mature, the penalty is silently zero, and routing degrades to displayed-price-plus-veto. Watchcard.maturedMarkouts()in monitoring: zero while rejects accrue means the hook is missing.- Parameters:
maxRejectRate- LPs whose EWMA reject rate exceeds this are vetoed regardless of price (e.g. 0.25)
-
LpRouter
public LpRouter(FxTierBook book, LpScorecard card, double maxRejectRate, double holdUrgencyBpsPerMs) With a hold-time urgency: an LP's last-look hold is FX's latency dimension — while it deliberates, the market drifts against you. A positiveholdUrgencyBpsPerMscharges each LP's EWMA hold time against its quote (bps of price per millisecond held), so a slow-holding LP loses ties exactly like a high-latency venue does inexecution.AdaptiveSor.
-
-
Method Details
-
route
public int route(boolean buy, double size) Chooses the LP for a full-amount clip. Returns the LP index, or -1 when no eligible LP quotes the size (book too shallow or all vetoed). After a successful call,lastQuotedPriceis the LP's raw tier price andlastExpectedPricethe reject-adjusted price the decision was made on. -
lastQuotedPrice
public double lastQuotedPrice()Raw quoted price behind the last successfulroute(boolean, double); NaN otherwise. -
lastExpectedPrice
public double lastExpectedPrice()Reject-adjusted price behind the last successfulroute(boolean, double); NaN otherwise. -
routeCount
public long routeCount() -
vetoCount
public long vetoCount()LP-candidate evaluations skipped for exceeding the reject-rate cap.
-