> ## Documentation Index
> Fetch the complete documentation index at: https://mathematicalcompany.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Resolution Sniping

> Detect resolution events in real-time and capture payout with aggressive positioning.

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

```python theme={null}
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:

```python theme={null}
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:

1. Fetches latest news from configured RSS sources
2. LLM evaluates if the event has definitively resolved
3. If confidence >= threshold: generates aggressive quote at near-parity
4. Tracks already-triggered markets to avoid double-sniping

## Configuration

```python theme={null}
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:

```python theme={null}
# 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                                            |
