Track a resting order's market position¶
A resting limit order's place in the book changes as quotes move
around it: a better quote may appear ahead, the spread may widen
until the order sits mid-spread, the level may empty until only the
order remains. The simulator surfaces these categorical transitions
as MARKET_POSITION_CHANGED events.
States¶
Five categorical states for any resting limit order:
best— order is at the current best on its sidebehind_best— a better quote exists on the same sidemid_spread— order price is strictly between best bid and best ask (neither side has a quote at our price)level_empty— no other quantity remains at the order's levelcrossed— order price crosses the opposite side; the simulator should have filled or rejected (used as a diagnostic)
Events fire only when the categorical state transitions. The
continuous distance_to_best_ticks field is available on every
event payload for strategies that want finer granularity.
React from a strategy¶
"""React to a resting limit order moving across market-position states."""
import flox_py as flox
class MarketPositionWatcher(flox.Strategy):
def __init__(self, symbols):
super().__init__(symbols)
self.last = {}
def on_market_position_change(self, ctx, ev):
prev = self.last.get(ev.order_id)
self.last[ev.order_id] = ev.market_position
print(f"order {ev.order_id}: {prev} -> {ev.market_position} "
f"distance={ev.distance_to_best_ticks}")
# Example: cancel and reprice when we slip from best to behind_best.
if ev.market_position == "behind_best":
self.cancel(ev.order_id)
Notes¶
- The state is recomputed after every book update and after every trade that may shift the top-of-book.
distance_to_best_ticksis signed raw price units from best on our side. Positive means behind; negative means ahead of best (mid-spread or crossed). Strategies that care about ticks should divide by their tick size.- Backtest only. Live exchanges do not generally publish enough book state to compute market position reliably on every tick from a client.