Documentation Index
Fetch the complete documentation index at: https://mathematicalcompany.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Resolution Sniping monitors news sources and uses LLM analysis to detect when a prediction market’s underlying event has resolved. When resolution is detected with high confidence, it generates aggressive quotes to buy the resolving side near parity.
Standalone Scan
import horizon as hz
markets = [
{"id": "market-1", "title": "Will team X win the championship?"},
{"id": "market-2", "title": "Will bill Y pass the Senate?"},
]
signals = hz.scan_resolutions(markets)
for s in signals:
print(f"{s.market_title}: resolved={s.resolved} side={s.resolution_side}")
print(f" Confidence: {s.confidence:.2%}")
print(f" Evidence: {s.evidence}")
Pipeline Mode
Integrate sniping into your hz.run() pipeline:
hz.run(
name="sniper-bot",
markets=["championship-2026", "senate-bill-xyz"],
feeds={"poly": hz.PolymarketBook("championship-2026")},
pipeline=[hz.resolution_sniper()],
)
When resolution is detected:
- Fetches latest news from configured RSS sources
- LLM evaluates if the event has definitively resolved
- If confidence >= threshold: generates aggressive quote at near-parity
- Tracks already-triggered markets to avoid double-sniping
Configuration
config = hz.SniperConfig(
provider="anthropic", # or "openai", or any litellm provider
model="", # empty = provider default; or "openrouter/..."
news_sources=[ # RSS feeds to monitor
"https://feeds.bbci.co.uk/news/rss.xml",
],
exa_query="election results", # Exa.ai semantic search (optional)
tavily_query="vote count", # Tavily real-time search (optional)
confidence_threshold=0.85, # minimum confidence to trigger
max_position_size=50.0, # max USDC per snipe
price_offset=0.02, # offset from 1.0 for pricing
scan_interval_cycles=5, # cycles between scans
cache_ttl=60.0, # signal cache TTL
)
hz.run(
pipeline=[hz.resolution_sniper(config=config)],
...
)
Kalshi Markets
The MCP sniper_scan tool supports Kalshi markets via the exchange parameter. Market discovery will pull from Kalshi instead of Polymarket:
# Via MCP tool
sniper_scan(exchange="kalshi")
The resolution detection logic (news + LLM) is exchange-agnostic: it works identically for both Polymarket and Kalshi markets.
How It Works
News Feed -> LLM Analysis -> Resolution Signal -> Aggressive Quote
|
confidence >= 0.85?
/ \
yes no
| |
Generate Quote Skip
(bid=0.98)
Confidence Tuning
| Threshold | Behavior |
|---|
| 0.95+ | Very conservative, few false positives |
| 0.85 (default) | Balanced sensitivity |
| 0.70 | Aggressive, more false positives |
Higher confidence = fewer trades but higher accuracy. Lower confidence = more trades but risk of sniping before actual resolution.
Types
ResolutionSignal
| Field | Type | Description |
|---|
market_id | str | Market identifier |
market_title | str | Market question |
resolved | bool | Whether event appears resolved |
confidence | float | Detection confidence [0, 1] |
resolution_side | str | ”yes” or “no” |
evidence | list[str] | Triggering headlines |
reasoning | str | LLM reasoning |
timestamp | float | Unix timestamp |
SniperConfig
| Field | Default | Description |
|---|
provider | "anthropic" | LLM provider (or any litellm provider) |
model | "" | Model name. Accepts litellm strings like "openrouter/..." |
news_sources | [] | RSS feed URLs |
exa_query | "" | Exa.ai semantic search query |
tavily_query | "" | Tavily real-time search query |
confidence_threshold | 0.85 | Min confidence to trigger |
max_position_size | 50.0 | Max USDC per snipe |
price_offset | 0.02 | Offset from parity |
scan_interval_cycles | 5 | Cycles between scans |
cache_ttl | 60.0 | Signal cache TTL |