Engineering

91.3% win rate across 100 live trades. The architecture that got there didn't optimize one trading philosophy — it reconciled two opposing ones inside a single async loop.

June 29, 2026
8 min read
#trading-systems#signal-architecture#asyncio
Dual-Path Signal Engine: Combining Reactive Snipe Windows with Predictive Early Entry in High-Frequency Trading⊕ zoom
Share

Most trading systems fail not because they pick the wrong direction — but because they pick the wrong moment. The signal is right. The timing is wrong. The market moved before the order landed, or the entry was so early the window expired before the thesis resolved. Two different failure modes, same dead trade.

The instinct is to choose a side. Reactive systems wait for confirmation — they catch moves already in progress, pay worse prices, but know the direction before committing. Predictive systems enter early — they get the price, but they're betting on a thesis that hasn't printed yet. Most architectures pick one and optimize hard. I spent the last several weeks building a system that runs both simultaneously, inside a single asyncio event loop, across 16 active market slots. The result is a 91.3% win rate across 100 live trades. What I learned is that the tension between these two philosophies isn't a problem to solve. It's the architecture.

Live Win Rate
91.3%
100 trades · last 7 days

The Sequential Default Is a Cognitive Artifact

Every engineer who builds a trading bot defaults to sequential evaluation. Scan markets. Find a signal. Evaluate it. Place a trade. The loop repeats. It's clean, debuggable, and wrong — not because the logic is bad, but because the market doesn't behave sequentially.

A 5-minute candle closes. A snipe window opens — there's a 30-second gap where the market price is known, the Polymarket resolution criteria are locked, and the binary is still mispriced. Miss that window and the edge closes. Simultaneously, a 15-minute candle is building. A predictive read says the next close will print above the current bid. That's a different opportunity on a different timeframe with different conviction mechanics. Sequential processing means one of these always waits. In a 30-second snipe window, waiting is losing.

INSIGHT

The sequential default doesn't come from bad engineering — it comes from how engineers are trained to think about state. Mutable shared state is dangerous in concurrent systems, so we serialize. But market signals aren't shared state that needs locking. They're independent streams that need parallel evaluation. The cognitive artifact is conflating concurrency safety with evaluation order.

Foresight runs a 5-second market scanner poll as the heartbeat. Every tick, 16 slots are evaluated in parallel via asyncio task groups — not queued, not serialized. The reactive path and predictive path run as concurrent coroutines against each slot. This sounds like an obvious architectural choice. It isn't. Most systems I've reviewed serialize by default and add concurrency only when latency becomes obviously painful. By then, the snipe windows are already gone.

Two Clocks, One Decision Surface

The reactive path and predictive path don't just use different signal logic — they operate on fundamentally different time horizons. Reactive snipe windows are <60 seconds wide. They're event-driven: a candle closes, a condition triggers, a bet has to land before the window expires. Predictive early entry is horizon-driven: a set of indicators converges on a thesis about where price will be at candle close, and the entry happens 2-4 minutes before that resolution.

This is where the architecture gets interesting. Two paths. Two different definitions of "now." A single position budget per slot.

The naive solution is priority ordering — reactive signals override predictive ones, or vice versa. I rejected this. Priority ordering just picks a philosophy and names it the winner. It doesn't reconcile the two; it silences one.

The actual design uses a conviction-weighted arbitration layer that runs after both paths complete their evaluation. Each path outputs a direction (UP/DOWN), a confidence score, and a decay curve — how quickly that signal degrades if the trade doesn't land. Reactive signals have steep decay curves; they're worth a lot right now and nearly nothing in 45 seconds. Predictive signals have shallow decay; they're worth roughly the same across a 3-minute window.

The arbitration layer computes a composite score, checks for directional agreement, and makes one decision per slot. When the paths disagree on direction, the slot is skipped entirely — disagreement is information, not a tiebreaker problem. When they agree, the composite score determines position sizing within the $5 conservative bet constraint. A slot where both paths converge on the same direction with high confidence gets full allocation. A slot where one path is weak gets a scaled entry or a pass.

Variety and rapidity destroy the opponent's plans and create uncertainty that causes him to lose the initiative.

John Boyd · Patterns of Conflict

Boyd was describing air combat. The principle applies to market microstructure. Foresight doesn't have a single predictable entry pattern. The Polymarket market maker can't anticipate whether the next fill will be a reactive snipe or a predictive front-run. That unpredictability is edge.

The Async Event Loop Is the Strategy

Most people read "asyncio event loop with a 5-second poll" and think: infrastructure detail. It's not. The loop design is the strategy.

Here's the constraint the architecture has to respect: Binance WebSocket candle feeds are push-based. Polymarket market data is pull-based. They don't tick on the same clock. A reactive snipe window opens when a Binance candle closes — that's a WebSocket event. Whether the Polymarket binary is still at a favorable price is a pull call that decays. Coordinating these two data sources under time pressure, across 16 slots, without blocking the event loop, requires treating the loop itself as a state machine.

Each slot carries a state object: last evaluated timestamp, current path outputs, open position flag, and a window expiry timer. The 5-second heartbeat doesn't re-evaluate a slot if its window timer is still hot — that would be redundant processing burning cycles that the event loop needs for other slots. A slot that has a live snipe window running gets lightweight status checks, not full re-evaluation. Full evaluation triggers on candle close events from the WebSocket feed and on the predictive cycle timer.

DOCTRINE

The event loop is a resource. Treating it as infinite leads to the same failure mode as treating bandwidth as infinite — everything works until it doesn't, and when it fails, it fails all at once. Design the loop with explicit budget accounting. Know what you're spending on each slot and why.

This is the design decision I'd make differently in retrospect. The current architecture runs on Tesseract as a persistent asyncio process. The slot state lives in memory. A crash loses the state. I've since added a Redis-backed state checkpoint that writes on every evaluation cycle, so a restart recovers in-flight windows rather than losing them. The cost is ~2ms per checkpoint write. The benefit is that live trades don't evaporate when the process bounces. That's not a performance optimization — it's a reliability architecture that should have been in v1.

The deeper lesson: stateful concurrency under time pressure requires explicit durability design from day one. Adding it later means you're threading persistence into a system that wasn't built to accommodate it. In Foresight's case, that retrofit took a day. It's a day I won't spend again on the next system.

91.3% Reveals the Real Design Constraint

The win rate is real. It's also the wrong metric to optimize. Foresight runs binary options — every trade resolves as a win or loss. A 91.3% win rate across 100 trades sounds like an optimization target. It's actually a constraint surface.

Binary options on Polymarket have asymmetric payout structures. A win pays out at whatever the market implies — sometimes 1.3x, sometimes 1.8x, occasionally 2.5x on high-uncertainty events. A loss is a full write-off of the bet. The system is profitable not because it wins 91.3% of trades, but because it's running with disciplined position sizing ($5 conservative bets) that makes the math work at that win rate. If the win rate dropped to 80%, the current sizing model would still be profitable at average payout multiples above 1.25x. The architecture was designed around that math, not around chasing the highest possible win rate.

This distinction matters architecturally because it changes what the signal engine optimizes for. A system chasing maximum win rate will overtrade high-confidence, low-payout setups. A system optimizing for risk-adjusted return will pass on a 95%-confidence trade that pays 1.05x and take a 75%-confidence trade that pays 2.2x. Foresight's conviction-weighted arbitration layer does exactly this — confidence scores are multiplied by implied payout before the position decision is made. A high-confidence signal on a tight Polymarket spread gets down-weighted. A moderate-confidence signal with wide spread gets up-weighted.

Active Market Slots
16
6 assets · 5m and 15m timeframes

What This Architecture Actually Generalizes

The dual-path pattern isn't specific to prediction markets. It's a solution to a class of problem: systems where the same underlying asset has multiple valid evaluation timescales, and where the optimal entry logic differs by timescale in ways that can't be collapsed into a single model.

Options pricing faces this. A day trader and a swing trader watching the same underlying are running different signal engines against different time horizons. A system that tries to serve both with one signal path will be mediocre at both. The correct architecture separates the evaluation paths, gives each path its own time-domain logic, and runs a meta-layer that arbitrates the outputs — not by picking a winner, but by finding where the paths agree.

The asyncio event loop as execution substrate generalizes too. Any system with multiple push-and-pull data sources operating on different cl

Go deeper in the AcademyOperator

The engineering patterns in this article are covered in the AI Infrastructure track — persistent platforms that run themselves. 11 lessons.

Start the AI Infrastructure track →

Explore the Tesseract Labs Ecosystem

// Join the Network

Follow the Signal

If this was useful, follow along. Daily intelligence across AI, crypto, and strategy — before the mainstream catches on.

No spam. Unsubscribe anytime.

Share
// More SignalsAll Posts →