ExecutionIntelligence
VPIN toxicity, inventory risk, order-flow microstructure
ExecutionIntelligence is v1’s microstructure module. It computes VPIN (Volume-synchronized Probability of Informed Trading), tracks inventory risk per market, and flags orders that are likely to face toxic counter-flow.
The key insight: if VPIN is elevated, the other side of your order probably knows something you don’t. Reducing size in those moments is free alpha.
Import
from horizon.fund._execution_intelligence import (
ExecutionIntelligence,
VPINResult,
InventoryRisk,
)
What is VPIN?
VPIN is a microstructure metric from Easley, López de Prado, and O’Hara (2012). It estimates the probability that a given volume bucket contains informed trading by comparing buy vs sell volume imbalance.
The intuition: if informed traders have private information, they’ll trade aggressively in one direction. Buckets with high buy/sell imbalance ⇒ high probability of informed trading ⇒ the other side of the market (you) is probably being adversely selected.
The formula
Volume bucketing
Classify each trade as buy or sell
Compute imbalance
imbalance = |V_buy - V_sell| / (V_buy + V_sell)
Average over a window
n buckets. High VPIN (> 0.5) = likely informed trading.API
class ExecutionIntelligence:
def __init__(
self,
bucket_volume: float = 10_000,
lookback_buckets: int = 50,
) -> None:
...
def update_trade(
self,
market_id: str,
price: float,
volume: float,
timestamp: float,
is_buy: bool,
) -> None:
"""Feed a trade observation into the VPIN calculator."""
def get_vpin(self, market_id: str) -> VPINResult | None:
"""Current VPIN for a market."""
def is_toxic(
self,
market_id: str,
threshold: float = 0.5,
) -> bool:
"""True if VPIN > threshold. don't place orders."""
def inventory_risk(
self,
market_id: str,
current_position: float,
) -> InventoryRisk:
"""How risky is the current inventory given microstructure state?"""
def update_order_flow(
self,
market_id: str,
buy_volume: float,
sell_volume: float,
) -> None:
"""Alternative ingress: pre-classified buy/sell volumes."""
Result types
@dataclass(frozen=True)
class VPINResult:
vpin: float # [0, 1]
buy_volume: float
sell_volume: float
imbalance: float
n_buckets: int
timestamp: float
@dataclass(frozen=True)
class InventoryRisk:
current_inventory: float
risk_score: float # [0, 1], higher = riskier
recommended_max_order_size: float # based on VPIN and inventory
reason: str
Usage
from horizon.fund._execution_intelligence import ExecutionIntelligence
exec_int = ExecutionIntelligence(
bucket_volume=10_000, # one VPIN bucket per 10k units
lookback_buckets=50, # 50-bucket rolling window
)
# Feed trade data
for trade in my_tick_feed:
exec_int.update_trade(
market_id=trade.market_id,
price=trade.price,
volume=trade.volume,
timestamp=trade.timestamp,
is_buy=trade.is_buy,
)
# Before placing an order, check VPIN
vpin = exec_int.get_vpin("AAPL")
if vpin and vpin.vpin > 0.6:
print(f"VPIN is {vpin.vpin:.2f}. skipping trade, likely toxic flow")
return
# Check inventory risk for a specific size
inv_risk = exec_int.inventory_risk("AAPL", current_position=100)
if inv_risk.risk_score > 0.7:
print(f"Inventory risky: {inv_risk.reason}")
desired_size = min(desired_size, inv_risk.recommended_max_order_size)
Integration with Horizon
As a pre-trade risk check
Wrap ExecutionIntelligence as a custom RiskCheck that blocks orders when VPIN is elevated:
from horizon.types import Decision
from horizon.fund._execution_intelligence import ExecutionIntelligence
class VPINRiskCheck:
def __init__(self, threshold: float = 0.6):
self.exec_int = ExecutionIntelligence()
self.threshold = threshold
def check(self, action, state):
vpin = self.exec_int.get_vpin(action.market_id)
if vpin is None:
return Decision.pass_()
if vpin.vpin > self.threshold:
return Decision.reject(f"VPIN {vpin.vpin:.2f} > {self.threshold}")
return Decision.pass_()
Pass to RiskConfig(extra_checks=[VPINRiskCheck()]).
As a feature
Make VPIN available to strategies as a feature they can read:
from horizon.features.base import Feature, PriceHistory
from horizon.fund._execution_intelligence import ExecutionIntelligence
class VPINFeature(Feature):
def __init__(self, market: str | None = None):
super().__init__(market=market)
self.exec_int = ExecutionIntelligence()
def compute(self, market_id, history, feeds):
# This requires that you've been feeding trades into exec_int
vpin = self.exec_int.get_vpin(market_id)
return vpin.vpin if vpin else 0.5 # neutral default
Use in a strategy:
class VPINAwareStrategy(Strategy):
features = {
"vpin": VPINFeature(),
"z": Zscore(20),
}
def evaluate(self, f, universe):
return [
Signal.from_score(m, score=-f.z[m.id], edge_per_stdev=15)
for m in universe
if f.vpin[m.id] < 0.5 # only trade in low-toxicity regime
and abs(f.z[m.id]) > 2
]
When to use
Pitfalls
Source
python/horizon/fund/_execution_intelligence.py. ~350 lines. Includes bucket management, rolling VPIN computation, and inventory risk scoring.