Overview
The abstention system is a safety filter that prevents trading when the model lacks a statistical edge. Even with a confident prediction (e.g., 85% UP), the system may abstain if volatility is anomalous, recent accuracy is poor, or the edge vs market is too narrow.Critical Principle: Abstention is not failure. It’s the system recognizing “I don’t know” and protecting capital.
The 7 Abstention Conditions
Condition 1: Insufficient Data
Trigger: Fewer than 50 price ticks receivedRationale: EWMA volatility requires ~50 ticks to stabilize. Trading before this produces unreliable σ estimates.Implementation (Config:
src/engine/predictor.js:82-85):engine.abstention.minTicks = 50Duration: First ~50 seconds of each interval (1 tick/sec)Condition 2: Dead Zone
Trigger: Black-Scholes probability within 10% of 50%Rationale: When the base probability is near 50% (40%-60% range), the model has no directional edge. Even after momentum/reversion adjustments, the final probability rarely moves outside 35%-65%, insufficient for profitable trading.Implementation (Config:
src/engine/predictor.js:96-99):engine.abstention.deadZone = 0.10Example:- BTC = 64,245 (13 bps apart)
- σ = 0.00012/sec, T = 180s
- Black-Scholes → 48% UP (dead zone: 40% < 48% < 60%)
- System abstains even though momentum might push to 55%
Condition 3: Anomalous Volatility Regime
Trigger: Current volatility > 2× rolling mean volatilityRationale: Volatility spikes indicate regime changes (news events, flash crashes, oracle issues). Model calibrated for normal markets may fail during anomalous periods.Implementation (Config:
src/engine/predictor.js:101-105):engine.abstention.sigmaMultiplier = 2.0Example:- Normal σ = 0.00012/sec (mean over 100 ticks)
- Spike: σ = 0.00028/sec (2.33× mean)
- System abstains until volatility normalizes
- FOMC announcements
- Exchange hacks
- Whale market orders
- Oracle data feed interruptions
Condition 4: Cold Streak
Trigger: Accuracy < 40% over last 20 predictionsRationale: Consecutive misses indicate model miscalibration or strategy breakdown. Continue trading would compound losses.Implementation (Config:
src/engine/predictor.js:108-111):engine.abstention.minAccuracy = 0.40engine.abstention.minAccuracyWindow = 20
- Last 20 predictions: 7 correct, 13 wrong (35% accuracy)
- System abstains until accuracy recovers to 40%+
Condition 5: Insufficient Expected Value
Trigger: Best EV < 5%Rationale: After Polymarket’s 3% fee, trades with < 5% EV are marginally profitable and don’t justify execution risk (slippage, oracle delays, etc.).Implementation (Config:
src/index.js:157-161):engine.abstention.minEV = 0.05Example:- Model: p = 0.52 (52% UP)
- Market: q = 0.50 (50% UP)
- EV(YES) = 0.52/0.50 - 1 = 4% (below 5% threshold)
- System abstains
q, so it happens after prediction generation (post-prediction filter).Condition 6: Insufficient Margin
Trigger: |p - q| / max(p, 1-p) < 15%Rationale: Even with high EV, if the model probability is too close to market probability, small calibration errors can flip the trade into negative EV. The margin check ensures a safety buffer.Implementation (Config:
src/index.js:162-165):engine.abstention.minMargin = 0.15Formula: margin = |p - q| / max(p, 1-p)Example:- Model: p = 0.60 (60% UP)
- Market: q = 0.52 (52% UP)
- Edge: |0.60 - 0.52| = 8pp
- Margin: 0.08 / max(0.60, 0.40) = 0.08 / 0.60 = 13.3% (below 15%)
- System abstains despite 15% EV
Condition 7: Drawdown Suspension
Trigger: Drawdown level = RED or CRITICALRationale: When bankroll has declined 20%+ from high-water mark, risk management forces a trading pause to prevent catastrophic losses.Implementation (Levels:
src/index.js:169-180):- Green (0-10% DD): No suspension
- Yellow (10-20% DD): Raise EV threshold to 10% (vs 5%)
- Red (20-30% DD): Suspend all trading
- Critical (30%+ DD): Suspend all trading
risk.drawdown.{yellowPct, redPct, criticalPct}Example:- Bankroll started at 75 (25% drawdown = RED)
- System suspends trading until bankroll recovers to $80+ (20% drawdown = YELLOW)
Abstention Cascade
Conditions are checked in order. First failure triggers immediate abstention:Statistics & Tracking
The system records abstention reasons per interval indata/history.json:
Analyzing Abstention Patterns
High abstention rate by reason:| Reason | High Rate (>30%) | Interpretation | Action |
|---|---|---|---|
insufficient_data | Normal | System warming up | None (expected) |
dead_zone | Normal | Tight markets near 50/50 | Increase deadZone to reduce noise |
anomalous_regime | Concerning | Frequent volatility spikes | Check oracle health, increase sigmaMultiplier |
cold_streak | Concerning | Model miscalibrated | Review prediction logic, adjust weights |
insufficient_ev | Normal | Market efficient | Increase minEV for higher bar |
insufficient_margin | Normal | Close calls rejected | Decrease minMargin if too conservative |
drawdown_suspended | Concerning | Sustained losses | Review overall strategy, reduce risk |
Configuration Trade-offs
Lowering Abstention Thresholds (More Trades)
Lowering Abstention Thresholds (More Trades)
- More frequent trading (higher volume)
- Lower edge per trade (thinner margins)
- Higher variance (more losses mixed with wins)
- High confidence in model calibration
- Seeking volume for statistical convergence
- Liquidity is abundant (can fill small-edge trades)
Raising Abstention Thresholds (Fewer, Higher-Quality Trades)
Raising Abstention Thresholds (Fewer, Higher-Quality Trades)
- Rare trading (low volume)
- High edge per trade (strong opportunities only)
- Lower variance (fewer bad trades)
- Model calibration uncertain
- Capital preservation priority
- Liquidity scarce (avoid low-edge slippage)
Special Case: Abstention During Prediction
The system still generates predictions even when abstaining. This allows:- Performance tracking - Evaluate model accuracy without trading
- Calibration learning - Feed outcomes to Platt scaler
- Display transparency - User sees “model says 85% UP, but abstaining because insufficient margin”
src/index.js:141-149:
data/history.json contains:
Abstention vs Risk Management
Abstention System (pre-trade filter):- Blocks trades when model has no edge
- Based on statistical properties (volatility, accuracy, EV)
- Binary decision: trade or don’t trade
- Sizes trades when edge exists
- Based on calibration quality (Brier Score) and bankroll state (drawdown)
- Continuous scaling: bet size from 0% to 5% of bankroll
Example Scenarios
Scenario 1: Green Light (Trade Executes)
Scenario 2: Dead Zone (Abstain)
Scenario 3: Anomalous Regime (Abstain)
Scenario 4: Insufficient Margin (Abstain)
Monitoring Abstention Health
Fromsrc/ui/display.js, the console shows abstention reason in real-time:
src/reporter/daily.js) aggregate abstention stats:
Next Steps
System Architecture
See how abstention fits into the overall workflow
Risk Management
Understand bet sizing and drawdown tracking