Float: Agentic Liquidity
Jared Borders • Ollo Finance • December 19, 2025
Market making is a primary source of liquidity in modern financial markets, achieved by continuously and strategically posting bid and ask quotes. The core challenge is to earn the bid-ask spread while controlling inventory risk and limiting adverse selection, where informed counterparties trade before adverse price movements and impose losses on passive liquidity. We introduce Float, an agentic market-making strategy that distributes liquidity across a discrete ladder of price levels instead of concentrating size at a single quote. Float combines the Avellaneda-Stoikov (2008) inventory management framework with a novel Rayleigh-distributed order sizing rule that shapes depth as a function of distance from the reference price. This design targets three objectives: reducing inventory variance through adaptive skewing, lowering exposure to toxic flow through an emergent low-liquidity gap near the reference price, and improving spread capture through structured placement across levels. We provide a complete mathematical specification, clarify the link between classical optimal control and our heuristic allocation, and validate the expected behavior through synthetic market simulations.
01 Introduction
Before diving into equations, let's build intuition. Understanding why market making is difficult illuminates how Float addresses these challenges.
1.1 The Market Maker's Dilemma
Imagine operating a currency exchange booth at an international airport. You maintain a drawer of US dollars and another of Euros. Travelers approach throughout the day seeking to exchange one currency for the other.
Your profit model is straightforward: buy Euros for slightly less than the “true” exchange rate and sell them for slightly more. That difference—the spread—constitutes your margin. If the true rate is €1 = $1.10, you might buy at $1.09 and sell at $1.11. Each round-trip nets $0.02. Simple enough, right? Here's where it becomes interesting.
Suppose you've just purchased €50,000 from a departing tourist, then hear breaking news: the European Central Bank is cutting rates. The Euro is about to depreciate. You're now holding €50,000 in rapidly devaluing currency, and all those $0.02 spreads you collected? They won't cover your losses.
This exemplifies the winner's curse of market making. Whenever someone wants to trade with you, ask yourself: “Why? What information do they possess that I lack?”
A sophisticated market maker cannot simply quote the “fair” price—they must adjust prices based on current inventory and its associated risk. The direction of adjustment follows a simple rule: if you're holding too much of something, make it cheaper to encourage others to take it off your hands.
1.2 From Booth to Algorithm
In modern electronic markets, this currency booth manifests as a Limit Order Book (LOB). Rather than travelers approaching physically, we publish prices electronically. The LOB is a priority-ranked list of all participants' willingness to buy (bids) and sell (asks) at various price levels.
When we place a limit order, we commit: “I will buy 500 units if the price reaches \(X\).” We're not trading immediately—we're providing liquidity. Other participants (takers) seeking immediate execution will “take” our resting orders.
Float functions as a sophisticated version of that airport booth operator—one that:
- Continuously adjusts prices based on inventory risk exposure
- Distributes liquidity strategically across price levels
- Maintains protective buffers against predatory strategies
- Operates at millisecond timescales responding to market dynamics
1.3 Scope and Contribution
This paper presents Float as a methodological proposal—a principled heuristic adaptation of optimal market-making theory for practical deployment in continuous (24/7) electronic markets.
Float is designed to seed two-sided liquidity in newly listed or low-activity markets where the limit order book may be sparse or initially empty. In this setting, the goal is to provide a clean, tradable surface without encountering the confusing experience of a blank book.
Our primary contributions are:
- Continuous-Operation A-S Adaptation: We simplify the classical time-dependent framework using an effective risk horizon suitable for perpetual operation
- Rayleigh Liquidity Shaping: We introduce a distribution whose boundary conditions naturally create protective buffers
- Unified “Probability Cloud” Model: We reconceptualize the market maker as projecting a floating, skewed distribution rather than discrete quotes
03 The Avellaneda–Stoikov Framework
3.1 The Core Question
Avellaneda and Stoikov posed a beautifully simple question: “At what price am I truly indifferent to buying or selling one more unit?”
Consider this carefully. With zero inventory, your indifference price equals the market mid-price \(p^*\). You have no directional bias.
But holding 50,000 units (a long position) exposes you to downside risk. If prices fall, your inventory loses value. Rationally, you should be:
- Eager to sell: Lower your ask to attract buyers
- Reluctant to buy: Lower your bid to avoid accumulating more
The price reflecting this inventory-adjusted indifference is the Reservation Price.
3.2 Classical Formulation
Through stochastic optimal control with exponential utility (constant absolute risk aversion), Avellaneda and Stoikov derived:
- \(p^*(t)\): Current fair value (mid-price)
- \(q(t)\): Current inventory (positive = long, negative = short)
- \(\gamma\): Risk aversion parameter
- \(\sigma^2\): Market variance
- \((T-t)\): Time remaining until horizon
3.3 Continuous Operation and Effective Horizon
The classical model assumes a finite liquidation time \(T\)—appropriate for strategies that explicitly unwind inventory by a known deadline. Float targets 24/7 markets (cryptocurrency, FX) with no natural terminal time.
A practical way to retain the meaning of the classical expression is to replace \((T-t)\) with an effective risk horizon \(\tau > 0\): a characteristic time scale over which inventory is actively managed (for example, the typical time between risk resets, inventory re-hedges, or strategy re-centering). This yields:
In implementation, \(\gamma\) and \(\tau\) are not separately identifiable from fills alone, so we absorb \(\tau\) into a single calibrated coefficient. By abuse of notation, we continue to write this effective coefficient as \(\gamma\) (see Cartea et al., 2015, Ch. 10), giving:
The reservation price formula encodes a simple but powerful idea: shift your pricing center away from your inventory risk. The term \(q \cdot \gamma \cdot \sigma^2\) measures “how worried you should be” about your current position—it scales with inventory size (\(q\)), your risk tolerance (\(\gamma\)), and market turbulence (\(\sigma^2\)). When you're long, this term is positive, so you subtract it from the fair price, shifting everything down. When short, the term is negative, so subtracting it shifts everything up. The market maker essentially “leans away” from their accumulated risk.
3.4 Interpreting the Formula
Let's verify intuition with a concrete example:
- Oracle (fair) price: \(p^* = \) $100.00
- Current inventory: \(q = \) +1,000 units (long position)
- Risk coefficient: \(\gamma = 0.001\)
- Market variance: \(\sigma^2 = 0.04\) (20% annualized volatility, squared)
The reservation price shifts 4 cents below the oracle price.
- Bid (buy) prices shift down → Less attractive to sellers → Discourages adding to long position
- Ask (sell) prices shift down → More attractive to buyers → Encourages inventory reduction
Over thousands of trades, this systematic 4-cent skew drives inventory back toward zero.
Key insight: The minus sign is crucial. Positive inventory subtracts from price, shifting everything down—our ask drops (encouraging buys from us), and our bid drops (discouraging further accumulation).
This lab illustrates the direction and magnitude of the skew term \(q\gamma\sigma^2\). (It does not attempt to calibrate \(\gamma\) for any specific venue.)
04 Rayleigh-Distributed Order Sizing
We've established where to center prices (reservation price). Now we determine how to distribute liquidity around that center.
4.1 The Problem with Naive Approaches
The simplest approach places all liquidity at a single bid-ask pair. This creates critical vulnerabilities:
- Concentration risk: All capital exposed at one price
- Sniper vulnerability: High-frequency arbitrageurs easily pick off stale quotes
Uniform distribution (equal size at every tick) wastes capital—why allocate equally to prices that rarely execute?
We need a shaped distribution providing:
- Minimal liquidity near center: Protection against noise and latency
- Ramping at moderate distances: Capturing execution in healthy zones
- Tapering at extremes: Capital efficiency
4.2 Why Rayleigh? A Principled Selection
The critical insight motivating Rayleigh selection is its boundary condition: \(f(0)=0\).
| Distribution | At Origin | Implication |
|---|---|---|
| Gaussian | Maximum | Most liquidity where adverse selection risk is highest |
| Exponential | Maximum | Significant mass in the “danger zone” |
| Rayleigh | Zero | Natural “soft gap” providing inherent protection |
The Rayleigh distribution starts at zero, rises to a peak at distance \(s\) (the scale parameter), then decays. This shape inherently incorporates a safety buffer that purely decaying distributions lack.
4.3 Mathematical Formulation
The Rayleigh probability density function:
where \(s\) is a scale parameter controlling distribution breadth.
The Rayleigh formula has two competing terms. The \(\frac{x}{s^2}\) term increases linearly with distance—farther from center means more liquidity. The \(e^{-\frac{x^2}{2s^2}}\) term decreases exponentially—very far prices get negligible size. Together, they create an “inverted bell”: zero at center, rising to a peak at \(x=s\), then decaying. This shape naturally protects the reservation price (zero liquidity there) while concentrating capital at “optimal” distances where execution is likely but adverse selection is manageable.
We denote the Rayleigh scale parameter by \(s\) to avoid collision with market volatility \(\sigma\).
- Mode (peak): \(s\)
- Mean: \(s\sqrt{\pi/2} \approx 1.253s\)
- \(f(0)=0\): Zero liquidity at center
- Light tail: Capital-efficient decay at extremes
4.4 Graphical Representation
To build intuition, we plot the following theoretical Rayleigh distribution:
By assigning \(s\) to \(1\) and simplifying, we see:
Note the characteristic shape: liquidity (y-axis) starts at zero at the reservation price (x=0), rises to a peak at \(x=s\), and then gently decays. This “hump” structure is key to Float's design, concentrating capital in a useful band while naturally protecting the core.
4.5 Mapping to Discrete Order Sizes
Rayleigh provides a convenient shape, but real venues require discrete orders at discrete price levels. Float therefore uses the Rayleigh profile as an unnormalized weighting function and then normalizes to a fixed quoting budget.
Let \(d = |p - r|\) be distance from the reservation price. With a hard gap \(x_{gap}\), define:
Define the Rayleigh-shaped weight:
Let \(K\) be the total base-asset quantity the strategy is willing to quote across both sides on each refresh. We split it evenly by default:
Given a discrete set of \(N\) bid levels and \(N\) ask levels at distances \(\{d_i\}\) from \(r\), the allocated size at each level is:
This guarantees bounded posted size (exactly \(K/2\) per side before rounding) while preserving the Rayleigh shape.
4.6 The Hard Gap Enhancement and Spread Safety
Beyond Rayleigh's natural soft gap, we introduce an explicit hard gap \(x_{gap}\): no orders are placed within \(|p-r|\le x_{gap}\).
This creates a deterministic buffer that helps:
- High-frequency noise: Small fluctuations don't trigger execution
- Latency arbitrage: Time buffer for quote updates
- Internal spread floor: After tick rounding, our own best bid remains below our own best ask
When the venue publishes a best bid \(b_t\) and best ask \(a_t\), Float additionally enforces a top-of-book safety rule: it drops (or clips) any bid that would lock or cross \(a_t\), and any ask that would lock or cross \(b_t\). This ensures we remain a passive liquidity provider even under rounding edge cases or fast oracle moves.
Context: Consider EUR/USD where price is USD per EUR and 1 pip \(=0.0001\) USD per EUR.
- Reservation price: \(r=\) 0.9970
- Hard gap: \(x_{gap}=\) 0.0004 (4 pips)
- Scale parameter: \(s=0.0005\)
- Total quote budget: \(K=100,000\) EUR (so \(K_{bid}=K_{ask}=50,000\) EUR)
Compute the weight at price \(p=0.9960\) (10 pips below reservation):
Normalization keeps total posted size bounded, while the gap provides absolute protection near \(r\).
$$ w(d') = \frac{d'}{s^2}\cdot e^{-\frac{{d'}^2}{2s^2}} $$
Here the x-axis is a normalized “distance from center.” When \(x < x_{gap}\), the hard gap forces liquidity to zero; otherwise \(d'=x-x_{gap}\) shapes size.
05 Problem Formulation
Having established building blocks, let's formally define the optimization problem.
5.1 Market Environment
Float operates in a Continuous Double Auction (CDA) mechanism with two data streams:
Oracle Feed
High-frequency fair value signal \(p^*(t)\), potentially:
- External price feed from more liquid venue
- Composite index across exchanges
- Model-derived fair value estimate
Exchange Feed
Real-time updates including:
- Current inventory \(q(t)\)
- Order book state, including best bid \(b_t\) and best ask \(a_t\) (when available)
- Execution confirmations
5.2 Volatility Estimation
We estimate volatility using an Exponentially Weighted Moving Average (EWMA) of squared log-returns, a common approach in risk management and trading systems (Hull, 2018):
Rather than treating \(\lambda\) as a fixed constant, it is often more intuitive to choose an EWMA half-life \(h\) measured in update steps. Update steps are the number of observations after which a return's influence decays by half (i.e., 50%). The corresponding decay factor is:
If updates arrive every \(\Delta t\) seconds, then the half-life in time is \(h\Delta t\). Smaller \(h\) adapts faster to regime changes but is noisier; larger \(h\) is smoother but slower. The right choice depends on the oracle update rate and the microstructure of the market being bootstrapped.
EWMA blends yesterday's variance estimate with the newest squared return. The half-life \(h\) makes responsiveness explicit: a return observed \(h\) updates ago receives half the weight of the current return, \(2h\) updates ago receives one quarter, and so on. This captures volatility clustering observed in real markets (Gould et al., 2013): when large moves occur, \(\sigma^2\) rises quickly; when markets are calm, it decays gradually. Since the reservation price skew scales with \(\sigma^2\), Float naturally becomes more defensive in turbulent regimes.
5.3 Agent Definition
We define the Float agent \(\alpha\) as a mapping from state to orders:
State vector:
where \(\Theta = \{\gamma, x_{gap}, s, K, N, \Delta_{\max}, \delta_p, \delta_v, h\}\) is the parameter set.
Output: The agent produces two sets of limit orders: bids (buy orders below the reservation price) and asks (sell orders above it):
Each order is a price-size pair \((p_i, v_i)\) where \(p_i\) is the limit price and \(v_i\) is the order quantity.
5.4 Success Criteria
We define success along three dimensions:
Over time, the agent's position should oscillate around zero rather than accumulating directional exposure:
The profits earned from capturing the bid-ask spread must exceed losses incurred when trading against informed flow:
Inventory variance must remain within acceptable limits to prevent catastrophic drawdowns:
06 Float Specification
6.1 Concepts
Float reconceptualizes market making not as a static ladder of discrete quotes, but as a dynamic probability cloud centered on a reservation price. This reservation price acts as an anchor, calculated from the external oracle but continually shifted by internal inventory pressures.
Analogous to a vessel moored in a tidal current, the strategy's quoting distribution “drifts” in response to inventory accumulation (the current). A long position shifts the reservation price downward, skewing liquidity to discourage further buying and facilitate selling. Conversely, a short position shifts prices upward. This adaptive skew ensures the agent remains tethered to fundamental value while actively neutralizing directional exposure risk.
6.2 Symbol Definitions
Base and quote convention. We write prices in quote currency per 1 unit of base currency. For example, in EUR/USD the base asset is EUR and the quote asset is USD, so \(p=1.1000\) means 1 EUR costs 1.10 USD. In this convention, 1 pip for EUR/USD is 0.0001 USD per EUR.
| Symbol | Name | Type | Unit | Description |
|---|---|---|---|---|
| \(p^*\) | Oracle Price | Input | Quote/Base | Exogenous fair value signal (e.g., USD per EUR) |
| \(q\) | Inventory | Input | Base units | Net position (+ long, − short) |
| \(\sigma\) | Volatility | Input | Scalar | EWMA standard deviation of log-returns |
| \(\gamma\) | Risk Coefficient | Parameter | Scalar | Skew coefficient (absorbs an effective horizon) |
| \(r\) | Reservation Price | Calculated | Quote/Base | Center of liquidity cloud |
| \(x_{gap}\) | Gap Width | Parameter | Quote/Base | Hard no-quote zone radius |
| \(s\) | Scale Width | Parameter | Quote/Base | Rayleigh scale parameter |
| \(K\) | Quote Budget | Parameter | Base units | Total base quantity allocated across both sides |
| \(N\) | Levels per Side | Parameter | Scalar | Max bid levels and ask levels |
| \(\Delta_{\max}\) | Quote Half-Range | Parameter | Quote/Base | Max distance from \(r\) considered for quoting |
| \(\delta_p\) | Tick Size | Parameter | Quote/Base | Minimum price increment |
| \(\delta_v\) | Lot Size | Parameter | Base units | Minimum size increment |
| \(h\) | EWMA Half-Life | Parameter | updates | EWMA half-life in update steps |
6.3 Market Incentivization by Example
Given: \(q=+5000\) units
The agent has accumulated inventory and faces downside risk.
- Reservation price: shifts DOWN below oracle
- Bid prices: Drop → Less attractive to sellers → Avoid adding more
- Ask prices: Drop → More attractive to buyers → Encourage taking inventory
Effect: Market participants are incentivized to buy from us, reducing long exposure.
Given: \(q=-5000\) units
The agent is short and faces upside risk.
- Reservation price: shifts UP above oracle
- Bid prices: Rise → More attractive to sellers → Encourage selling to us
- Ask prices: Rise → Less attractive to buyers → Avoid adding more short
Effect: Market participants are incentivized to sell to us, reducing short exposure.
Given: \(q\approx 0\)
Minimal inventory; balanced exposure.
- Reservation price: \(\approx\) Oracle price (negligible skew)
- Symmetric liquidity on both sides
Effect: Agent captures spread from both directions equally.
The market itself becomes the mechanism neutralizing exposure.
6.4 Reference Configuration
| Parameter | Value | Rationale |
|---|---|---|
| \(N\) | 10 | Bootstrap-friendly: at most 10 bids and 10 asks |
| \(\Delta_{\max}\) | 0.0020 (20 pips) | Visible depth around \(r\) for an initially empty book |
| \(x_{gap}\) | 0.0004 (4 pips) | Buffer near \(r\) (tuned per market) |
| \(s\) | 0.0005 (5 pips) | Places liquidity peak just outside gap |
| \(\gamma\) | \(1\times 10^{-4}\) | Effective skewing under inventory stress |
| \(K\) | 100,000 | Total base units posted per refresh (split across sides) |
| \(\delta_p\) | 0.0001 (1 pip) | Example tick size (EUR/USD-like) |
| \(\delta_v\) | 1 | Example lot size |
| \(h\) | 20 updates (\(\lambda \approx 0.966\)) | EWMA half-life; \(\lambda\) via \(\lambda=0.5^{1/h}\) |
6.5 Algorithm Specification
Require: Oracle price \(p^*\), inventory \(q\), best bid/ask
\((b_t,a_t)\) (optional), parameters \(\Theta\)
Ensure: Bid orders, Ask orders
- Estimate Volatility
- Compute Reservation Price
- Generate Discrete Distance Ladder
- Compute Rayleigh Weights
- Normalize Sizes to Budget
- Construct Orders Around \(r\)
- Apply Tick/Lot Rounding and Spread Safety
- Return Bids, Asks
6.6 Reference Pseudocode Implementation
6.6.1 Configuration ▶
The configuration is defined below in simpler key-value format. The unit “Updates” used in ewma_half_life refers to the number of discrete price updates (ticks) received from the oracle.
{
"gamma": 0.0004,
"gap_width": 0.0004,
"scale": 0.0005,
"delta_max": 0.0020,
"tick_size": 0.0001,
"lot_size": 1.0,
"min_size": 1.0,
"quote_budget": 100000,
"levels_per_side": 10,
"ewma_half_life": 20
}
6.6.2 Volatility Update ▶
The update_volatility method implements EWMA variance estimation. We express responsiveness through a half-life (in update steps) and compute the implied decay factor \(\lambda\) via \(\lambda=0.5^{1/h}\).
def _ewma_lambda(self) -> float:
h = max(1, int(self.config.ewma_half_life))
return float(np.exp(np.log(0.5) / h))
def update_volatility(self, log_return: float) -> float:
lam = self._ewma_lambda()
self._sigma_sq = lam * self._sigma_sq + (1 - lam) * (log_return ** 2)
return float(np.sqrt(self._sigma_sq))
6.6.3 Price and Size Rounding ▶
Market protocols enforce discrete ticks for prices and lots for sizes. Float implements conservative rounding: bid prices are rounded down (floor) and ask prices are rounded up (ceil) to ensure the strategy never inadvertently crosses its own reservation price or narrows the spread beyond intent.
def _round_bid_price(self, p: float) -> float:
t = self.config.tick_size
return float(np.floor(p / t) * t)
def _round_ask_price(self, p: float) -> float:
t = self.config.tick_size
return float(np.ceil(p / t) * t)
def _round_size(self, v: float) -> float:
lot = self.config.lot_size
return float(np.floor(v / lot) * lot)
6.6.4 Order Computation ▶
The compute_orders method is the orchestrator. To improve readability and maintainability, we decompose the logic into smaller helper functions.
First, we calculate the reservation price based on inventory and volatility:
def _calc_reservation_price(
self,
oracle_price: float,
inventory: float
) -> float:
return oracle_price - inventory * self.config.gamma * self._sigma_sq
Next, we generate the discrete price ladder. This function handles the conversion of continuous distances into discrete tick multiples, ensuring we satisfy the minimum gap and maximum range constraints while attempting to space levels evenly.
def _generate_tick_ladder(self) -> np.ndarray:
cfg = self.config
tick = cfg.tick_size
min_ticks = int(np.floor(cfg.gap_width / tick)) + 1
max_ticks = int(np.floor(cfg.delta_max / tick))
if max_ticks <= min_ticks:
return np.array([])
ticks = np.linspace(min_ticks, max_ticks, cfg.levels_per_side)
ticks = ticks.round().astype(int)
ticks = np.unique(ticks)
if ticks.size < cfg.levels_per_side:
tick_cap = min(min_ticks + cfg.levels_per_side, max_ticks + 1)
ticks = np.arange(min_ticks, tick_cap, dtype=int)
return ticks * tick
With the distance ladder established, we calculate the Rayleigh weights for each level and normalize them to the fixed quoting budget.
def _compute_weights_and_sizes(self, distances: np.ndarray) -> np.ndarray:
if len(distances) == 0:
return np.array([])
d_prime = np.maximum(0.0, distances - self.config.gap_width)
s2 = self.config.scale ** 2
w = (d_prime / s2) * np.exp(-(d_prime ** 2) / (2 * s2))
w_sum = float(w.sum())
if w_sum <= 0:
return np.zeros_like(distances)
K_side = self.config.quote_budget / 2.0
sizes = K_side * (w / w_sum)
return sizes
Finally, the main compute_orders function ties these together, converting abstract distances into concrete prices and enforcing safety checks:
def compute_orders(
self,
oracle_price: float,
inventory: float,
best_bid: Optional[float] = None,
best_ask: Optional[float] = None,
) -> Tuple[List[Tuple[float, float]], List[Tuple[float, float]]]:
r = self._calc_reservation_price(oracle_price, inventory)
distances = self._generate_tick_ladder()
sizes = self._compute_weights_and_sizes(distances)
if len(distances) == 0:
return [], []
bids: List[Tuple[float, float]] = []
asks: List[Tuple[float, float]] = []
for dist, sz in zip(distances, sizes):
bid_p = self._round_bid_price(r - dist)
ask_p = self._round_ask_price(r + dist)
v = self._round_size(sz)
if v < self.config.min_size:
continue
if best_ask is None or bid_p < best_ask:
bids.append((bid_p, v))
if best_bid is None or ask_p > best_bid:
asks.append((ask_p, v))
return bids, asks
07 Visualization
Figure 2 illustrates Float's liquidity distribution for an EUR/USD-like market. The oracle is \(p^*=0.9969\) and the reservation price is \(r=0.9970\), a 1 pip upward skew consistent with a short inventory position. We use a hard gap of \(\pm 0.0004\) (4 pips), a scale parameter \(s=0.0005\), and \(N=10\) discrete levels per side. Sizes follow the Rayleigh-shaped weights and are then normalized so total posted quantity is bounded.
The shaded gray region represents the hard gap where no orders are placed.
08 Operational Considerations
7.1 Computational Performance
Float achieves low latency through vectorization and a small fixed number of price levels. The core computation is \(O(N)\) per refresh, and for bootstrap settings (e.g., \(N \le 10\)) it is typically sub-millisecond on modern CPUs. The exact latency depends on hardware, runtime, and how much surrounding infrastructure (serialization, risk checks, RPC) is included.
| Operation | Complexity | Typical scale (illustrative) |
|---|---|---|
| Volatility update | \(O(1)\) | tens of ns to a few \(\mu s\) |
| Reservation calculation | \(O(1)\) | tens of ns to a few \(\mu s\) |
| Weights + normalization | \(O(N)\) | \(\mu s\) to hundreds of \(\mu s\) |
| Rounding + safety checks | \(O(N)\) | \(\mu s\) to hundreds of \(\mu s\) |
| Total (bootstrap \(N\le 10\)) | \(O(N)\) | typically < 1 ms |
| Implementation | Expected latency tier | Notes |
|---|---|---|
| Python + NumPy | sub-ms to a few ms | Great for iteration; overhead dominated by glue code |
| Go | tens to hundreds of \(\mu s\) | Good systems integration; watch allocations |
| OCaml (native) | tens to hundreds of \(\mu s\) | Strong correctness story; tune GC and allocation |
| Rust | single-digit to tens of \(\mu s\) | Best-case low latency; more engineering effort |
In electronic markets, price updates can arrive every few milliseconds. If Float takes longer to recompute quotes than the interval between price changes, it will quote stale prices and increase adverse selection exposure. Keeping refresh latency comfortably below the update cadence helps ensure quotes remain fresh.
7.2 Fail-Safe Mechanisms
| Mechanism | Purpose | Behavior |
|---|---|---|
| Hard Gap | Reduce near-center toxicity | No orders within \(|p-r|\le x_{gap}\) |
| Top-of-Book Safety | Avoid locking/crossing | Drop/clip orders that would cross \(b_t/a_t\) |
| Inventory Limits | Prevent runaway exposure | Cancel/flatten if \(|q| > q_{max}\) |
| Staleness Detection | Handle oracle failures | Cancel orders if feed silent |
| Size Caps | Prevent concentration | Max per-order size limit |
09 Expected Behavior and Simulation
8.1 Synthetic Market Generator
To validate Float's behavior without risking capital in live markets, we employ a synthetic price process that captures key statistical properties of real order flow. Specifically, we model the oracle price as an Ornstein-Uhlenbeck process—a mean-reverting stochastic differential equation that produces realistic ranging behavior (Hull, 2018):
Here, \(\theta\) controls the speed of mean reversion, \(\mu\) is the long-run equilibrium price, and \(dW_t\) is a Wiener process providing random shocks. This model produces price paths that wander but tend to return to \(\mu\), mimicking the behavior of many financial instruments over short horizons.
To capture the empirical phenomenon of volatility clustering—the observation that large price moves tend to follow other large moves—we allow volatility itself to evolve stochastically. One simple choice is a mean-reverting stochastic variance process (Hull, 2018; Cartea et al., 2015):
The parameter \(\kappa\) governs how quickly volatility reverts to its long-run mean \(\bar{\sigma}^2\), while \(\xi\) controls the volatility-of-volatility. This two-factor model generates realistic market conditions ranging from quiet consolidation periods to turbulent high-volatility regimes.
8.2 Evaluation Metrics
| Metric | Definition | Target |
|---|---|---|
| Inventory Mean | \(\frac{1}{T}\int_0^T q(t)\,dt\) | \(\approx 0\) |
| Inventory Std | \(\sqrt{\text{Var}[q(t)]}\) | Bounded |
| Sharpe Ratio | \(\mathbb{E}[\text{PnL}]/\text{Std}[\text{PnL}]\) | > 1.0 |
| Fill Rate | Executions / Quotes | Stable |
The Inventory Mean approaching zero indicates that the skewing mechanism successfully prevents directional drift. A bounded Inventory Standard Deviation confirms that position sizes remain within acceptable risk limits rather than ballooning during adverse conditions. The Sharpe Ratio measures risk-adjusted profitability—values above 1.0 suggest the strategy generates returns commensurate with the volatility of those returns. Finally, a stable Fill Rate indicates consistent market participation without excessive quote staleness.
8.3 Expected Qualitative Behavior
Ranging Markets. When prices oscillate within a band without clear trend, Float operates in its most favorable environment. The agent captures spread on both sides as prices bounce between bid and ask regions. The inventory skew mechanism gently corrects any position drift, maintaining near-zero average inventory. In these conditions, Float accumulates small, consistent profits while keeping risk bounded.
Trending Markets. Sustained directional moves present the classic market-making challenge: the agent accumulates inventory against the trend. However, Float's \(\gamma\) parameter causes the reservation price to shift away from inventory risk. As the agent accumulates long inventory in a downtrend, for example, the reservation price moves downward relative to the oracle, increasing the probability of fills that reduce inventory before losses compound.
High Volatility Regimes. When market turbulence increases, the EWMA volatility estimator adapts \(\sigma^2\) upward. Because the skew term \(q\cdot \gamma \cdot \sigma^2\) scales with variance, the reservation price shifts more dramatically for a given inventory level. The hard gap and top-of-book safety checks reduce exposure precisely when adverse selection risk is highest.
Float Engine Simulator
Live Ornstein–Uhlenbeck oracle (illustrative UI)
This simulator illustrates OU oracle motion + inventory skew + Rayleigh-shaped depth (not a full exchange emulation).
10 Limitations and Future Work
9.1 Model Assumptions
Float's design rests on several simplifying assumptions that may not hold in all market conditions. Understanding these limitations is essential for practitioners considering deployment.
Price Dynamics. The Avellaneda-Stoikov framework assumes prices follow geometric Brownian motion, a standard modeling baseline in continuous-time finance (Hull, 2018). In reality, financial markets exhibit fat-tailed return distributions and occasional discontinuous jumps (e.g., flash crashes, news events). During such episodes, the smooth skewing mechanism may respond too slowly to prevent significant adverse selection. Practitioners should implement additional circuit breakers for extreme market conditions.
Order Arrival Process. The theoretical foundation assumes market orders arrive according to a Poisson process—independently and at a constant rate. Empirical studies reveal substantial clustering in order flow: executions tend to arrive in bursts rather than uniformly. This clustering can cause rapid inventory accumulation that outpaces the skewing mechanism's ability to compensate. More sophisticated models might incorporate Hawkes processes or other self-exciting point processes to better capture this dynamic.
Market Impact. Float assumes orders execute without affecting the underlying price—the “price-taker” assumption. For sufficiently large order sizes or illiquid markets, this assumption breaks down. The agent's own quotes can move the market, creating feedback effects not captured in the model. Position limits and maximum order sizes provide partial mitigation, but a complete treatment would require incorporating market impact functions into the optimization.
9.2 Parameter Sensitivity
Float's performance depends critically on parameter calibration. The risk coefficient \(\gamma\) presents a fundamental tradeoff: values too low fail to skew aggressively enough, allowing inventory to accumulate dangerously; values too high sacrifice profitability by quoting prices that rarely execute. Optimal calibration requires backtesting across diverse market conditions and may need periodic recalibration as market microstructure evolves.
Similarly, the gap width \(x_{gap}\) balances protection against execution probability. An excessively wide gap provides safety but misses profitable trading opportunities; too narrow a gap exposes the agent to latency arbitrage. Market-specific tuning based on typical bid-ask spreads, tick size, and order book depth is essential.
9.3 Future Directions
Several extensions could enhance Float's robustness and profitability:
Rather than static configuration, online learning algorithms could adjust \(\gamma\), \(s\), and \(x_{gap}\) based on realized performance. Bayesian optimization or reinforcement learning approaches might discover parameter schedules that adapt to changing market conditions.
The current implementation reacts only to price and inventory. Incorporating additional signals—order book imbalance, trade flow toxicity metrics, or cross-asset correlations—could improve adverse selection detection and enable more sophisticated quote shading.
Float currently manages a single instrument. Portfolio-level inventory management would account for correlations between assets, enabling cross-hedging and more efficient capital utilization. This extension requires modeling the covariance structure of returns and solving a higher-dimensional optimization problem.
End-to-end learning of the liquidity distribution shape, rather than assuming Rayleigh, could discover more effective profiles for specific market microstructures. Neural network policies trained via reinforcement learning have shown promise in related market-making contexts.
Conclusion
This paper introduced Float, a market-making service designed to provide stable, two-sided liquidity in electronic limit order books, with particular emphasis on bootstrapping newly launched or low-activity markets. In these environments the immediate goal is not to outcompete mature market makers; it is to prevent the poor user experience of an empty book by posting a small, legible ladder of bids and asks that early participants can trade against.
Float combines two ideas. First, it uses an inventory-aware reservation price derived from the Avellaneda-Stoikov perspective, expressed in a continuous-operation form through an effective risk coefficient. This causes the quoting center to move away from inventory risk in a predictable and controllable way. Second, it shapes depth using a Rayleigh-profile weighting function and then normalizes those weights into a fixed quoting budget across a discrete number of price levels. The result is a bounded, interpretable liquidity profile that can be implemented directly on venues with tick and lot constraints.
Operationally, Float is designed to be simple to reason about. A hard gap defines a no-quote zone around the reservation price, conservative rounding keeps orders on valid discrete increments, and top-of-book safety checks prevent accidental locking or crossing when an external spread exists. Together, these mechanisms aim to reduce stale-quote risk, keep inventory behavior well-behaved, and maintain a clean quoting surface even when the surrounding market is thin.
Future work is primarily empirical: calibrating parameters per market, validating behavior under more realistic order-flow models, and introducing adaptive controls that respond to changing liquidity conditions. In particular, the bootstrapping setting suggests a natural schedule: as organic depth and two-sided flow appear, Float can reduce quoted size, reduce the number of levels, or widen protections to transition from seeding liquidity to operating conservatively alongside real participants.
11 References
- M. Avellaneda and S. Stoikov. High-frequency trading in a limit order book. Quantitative Finance, 8(3):217–224, 2008.
- Á. Cartea, S. Jaimungal, and J. Penalva. Algorithmic and High-Frequency Trading. Cambridge University Press, 2015.
- L. R. Glosten and P. R. Milgrom. Bid, ask and transaction prices in a specialist market. Journal of Financial Economics, 14(1):71–100, 1985.
- M. D. Gould, M. A. Porter, S. Williams, M. McDonald, D. J. Fenn, and S. D. Howison. Limit order books. Quantitative Finance, 13(11):1709–1742, 2013.
- O. Guéant, C.-A. Lehalle, and J. Tapia. Dealing with the inventory risk: a solution to the market making problem. Mathematics and Financial Economics, 7(4):477–507, 2013.
- T. Ho and H. R. Stoll. Optimal dealer pricing under transactions and return uncertainty. Journal of Financial Economics, 9(1):47–73, 1981.
- A. S. Kyle. Continuous auctions and insider trading. Econometrica, 53(6):1315–1335, 1985.
- J. C. Hull. Options, Futures, and Other Derivatives, 10th edition. Pearson, 2018.