Class VenueScorecard

java.lang.Object
com.quantfinlib.execution.VenueScorecard

public final class VenueScorecard extends Object
Streaming per-venue execution quality — the equities counterpart of fx.LpScorecard: displayed prices tell you where a venue CLAIMS you'll trade; the scorecard tells you what actually happens when you send there. Everything the AdaptiveSor needs beyond the quote:
  • Fill rate — EWMA of {1 fill, 0 miss} per marketable child: the venue's reliability. Quotes fade, systems reject, sessions hiccup — a venue that fills 80% of what you send is worth less than its displayed price says;
  • Response latency — EWMA of send→ack/fill time as YOU measure it, which routinely disagrees with the venue's advertised number;
  • Hidden liquidity — for dark venues, an EWMA of the shares each probe actually found. "Unknown" hardens into an estimate the only honest way: by probing and remembering;
  • Post-fill markout (adverse selection) — what the mid does one horizon after your fill, signed in your trading direction: positive = the price kept going your way (a clean fill), negative = it reverted (you paid the spread to trade against informed or stale flow — the "fade" venues). Arm it via the extended onFill(int, long, boolean, double, long) and feed mids via onMid(double, long); the equities counterpart of fx.LpScorecard's post-REJECT markout. The markout leg makes the card single-symbol: onMid(double, long) matures every pending fill against the one mid it is given, and the markout is in absolute price units — one card per symbol once you use it (the fill-rate/latency stats alone were symbol-agnostic).

All statistics are exponentially weighted per event so the card tracks current behavior (each EWMA seeds from the prior / first observation, so a venue is never scored below "never tried" for its first fill). Before any data, fillRate(int) returns a configurable optimistic prior (a new venue deserves flow until it proves otherwise). Zero allocation per event, single writer (the execution-events thread).

This is the streaming venue-quality tool for the routing hot path; VenueBenchmark is the batch counterpart (fill rate, effective spread and markout over a sample list) for post-trade venue analysis.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Pending fill-markout slots per venue (bursts deeper overwrite oldest).
  • Constructor Summary

    Constructors
    Constructor
    Description
    VenueScorecard(int venueCount)
    5% event weight, 0.95 prior, 100 ms markout horizon.
    VenueScorecard(int venueCount, double alpha, double fillRatePrior)
    100 ms markout horizon.
    VenueScorecard(int venueCount, double alpha, double fillRatePrior, long markoutHorizonNanos)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    double
    EWMA shares found per dark probe (0 before any probe).
    long
    filled(int venue)
     
    double
    fillRate(int venue)
    EWMA fill probability; the optimistic prior before any data.
    double
    The before-any-data prior (also what unregistered venues score as).
    long
    Fill markouts matured across all venues — the wiring canary: zero while fills accrue means onMid(double, long) is not being fed and the router's adverse-selection term is silently disabled.
    double
    EWMA measured response latency in nanos (0 before any data).
    void
    onDarkProbe(int venue, long sharesFilled)
    A dark probe's outcome: how many shares it actually found (0 is a real observation — an empty pool teaches as much as a full one).
    void
    onFill(int venue, long responseNanos)
    A marketable child filled (fully or partially counts as a fill).
    void
    onFill(int venue, long responseNanos, boolean buy, double midAtFill, long timestampNanos)
    A fill WITH the context that arms its markout: direction, the mid at fill time, and the fill timestamp.
    void
    onMid(double mid, long timestampNanos)
    Mid update FOR THE CARD'S ONE SYMBOL (see the class doc): matures every pending fill markout whose horizon has elapsed.
    void
    onMiss(int venue, long responseNanos)
    A marketable child that came back unfilled (faded, rejected, expired).
    double
    postFillMarkout(int venue)
    EWMA post-fill markout in price units — positive means the mid kept moving your way after fills at this venue; negative means it reverted: you crossed the spread into informed or stale flow, the per-share cost AdaptiveSor prices as adverse selection. 0 before any matured markout.
    long
    probes(int venue)
     
    void
    Restores the card; pending fill markouts (intraday) reset.
    long
    sent(int venue)
     
    int
     
    void
    Persists the learned venue quality — fill rates, measured latencies, dark-probe estimates and fill markouts are exactly what a router should not have to relearn every morning.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • PENDING_RING

      public static final int PENDING_RING
      Pending fill-markout slots per venue (bursts deeper overwrite oldest).
      See Also:
  • Constructor Details

    • VenueScorecard

      public VenueScorecard(int venueCount, double alpha, double fillRatePrior, long markoutHorizonNanos)
      Parameters:
      venueCount - number of venues (dense indices)
      alpha - EWMA weight per event, e.g. 0.05
      fillRatePrior - fill rate assumed before any data, e.g. 0.95
      markoutHorizonNanos - how long after a fill the markout is read, e.g. 100ms = 100_000_000L
    • VenueScorecard

      public VenueScorecard(int venueCount, double alpha, double fillRatePrior)
      100 ms markout horizon.
    • VenueScorecard

      public VenueScorecard(int venueCount)
      5% event weight, 0.95 prior, 100 ms markout horizon.
  • Method Details

    • onFill

      public void onFill(int venue, long responseNanos)
      A marketable child filled (fully or partially counts as a fill).
    • onMiss

      public void onMiss(int venue, long responseNanos)
      A marketable child that came back unfilled (faded, rejected, expired).
    • onFill

      public void onFill(int venue, long responseNanos, boolean buy, double midAtFill, long timestampNanos)
      A fill WITH the context that arms its markout: direction, the mid at fill time, and the fill timestamp. Feed mids via onMid(double, long) and the move one horizon later is attributed to this venue. A NaN mid still counts the fill but can never start a markout (maturing against NaN would poison the EWMA and silently distort routing).
    • onMid

      public void onMid(double mid, long timestampNanos)
      Mid update FOR THE CARD'S ONE SYMBOL (see the class doc): matures every pending fill markout whose horizon has elapsed. Non-finite mids are ignored — one Inf sentinel maturing a slot would seed the EWMA at ±Inf and the next blend would NaN it forever, silently disabling the router's adverse-selection term. The common no-pending case is a single compare.
    • onDarkProbe

      public void onDarkProbe(int venue, long sharesFilled)
      A dark probe's outcome: how many shares it actually found (0 is a real observation — an empty pool teaches as much as a full one). The estimate seeds from the first probe rather than ramping from 0, so one good probe doesn't collapse subsequent probe sizes.
    • fillRate

      public double fillRate(int venue)
      EWMA fill probability; the optimistic prior before any data.
    • fillRatePrior

      public double fillRatePrior()
      The before-any-data prior (also what unregistered venues score as).
    • measuredLatencyNanos

      public double measuredLatencyNanos(int venue)
      EWMA measured response latency in nanos (0 before any data).
    • expectedHiddenShares

      public double expectedHiddenShares(int venue)
      EWMA shares found per dark probe (0 before any probe).
    • postFillMarkout

      public double postFillMarkout(int venue)
      EWMA post-fill markout in price units — positive means the mid kept moving your way after fills at this venue; negative means it reverted: you crossed the spread into informed or stale flow, the per-share cost AdaptiveSor prices as adverse selection. 0 before any matured markout.
    • maturedFillMarkouts

      public long maturedFillMarkouts()
      Fill markouts matured across all venues — the wiring canary: zero while fills accrue means onMid(double, long) is not being fed and the router's adverse-selection term is silently disabled.
    • sent

      public long sent(int venue)
    • filled

      public long filled(int venue)
    • probes

      public long probes(int venue)
    • venueCount

      public int venueCount()
    • writeState

      public void writeState(DataOutput out) throws IOException
      Persists the learned venue quality — fill rates, measured latencies, dark-probe estimates and fill markouts are exactly what a router should not have to relearn every morning. Format version 2 (version 1, from before the markout existed, is still readable). See persist.Checkpoint.
      Throws:
      IOException
    • readState

      public void readState(DataInput in) throws IOException
      Restores the card; pending fill markouts (intraday) reset. Reads both format versions: a v1 checkpoint restores everything it has and leaves the markout state cold. Throws on a venue-count mismatch or an unknown version.
      Throws:
      IOException