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" becomes an estimate only by probing and remembering;
  • Post-fill markout (adverse selection): what the mid does one horizon after your fill, signed in your trading direction. Positive means the price kept going your way (a clean fill); negative means 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); it is 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. Use 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 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