> ## 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.

# Wallet Signals

> Per-wallet directional signals, multi-wallet consensus, and auto-discovery with 4-component signal decomposition.

<Warning>
  **Ultra Feature.** Requires an Ultra subscription. [Get started at api.mathematicalcompany.com](https://api.mathematicalcompany.com)
</Warning>

# Wallet Signals

Unified entry point for tracking wallets and extracting directional signals. Combines wallet scoring, position analysis, trade flow, and behavioral profiling into a single actionable signal per wallet per market.

<CardGroup cols={3}>
  <Card title="Track Wallet" icon="user">
    Given a wallet, compute signals for every market it holds.
  </Card>

  <Card title="Consensus" icon="users">
    Aggregate top holders into a weighted directional signal.
  </Card>

  <Card title="Auto-Discover" icon="magnifying-glass">
    Find high-signal wallets in a target market automatically.
  </Card>
</CardGroup>

***

## Quick Start

### Mode 1: Track a Wallet

```python theme={null}
import horizon as hz

signals = hz.track_wallet("0x1234...")
for s in signals:
    print(f"{s.market_id[:12]} signal={s.signal:.4f} regime={s.regime}")
```

### Mode 2: Market Consensus

```python theme={null}
consensus = hz.compute_consensus("0xcondition...", market_price=0.65)
print(f"Signal: {consensus.signal:.4f}")
print(f"Agreement: {consensus.agreement:.2f}")
print(f"Wallets: {consensus.n_wallets}")
```

### Mode 3: Auto-Discover

```python theme={null}
consensus = hz.scan_wallets(market_id="0xcondition...")
if consensus.is_actionable:
    print(f"Edge: {consensus.edge_bps:.0f} bps")
```

### Pipeline Integration

```python theme={null}
hz.run(
    markets=[market],
    pipeline=[
        hz.wallet_tracker(wallets=["0xaaa...", "0xbbb..."]),
        my_quoter,
    ],
)

# In your quoter:
def my_quoter(ctx):
    sig = ctx.params.get("wallet_tracker_signal")
    if sig and sig.is_actionable:
        # Use sig.signal as directional bias
        ...
```

***

## Signal Math

Each per-wallet signal is a 4-component decomposition:

### Direction D(w,m)

Net position direction from wallet positions. YES positions contribute +1, NO contributes -1, size-weighted.

```
net = sum(size_i * direction_i) / total_size
D = (net + 1) / 2    # maps [-1, 1] to [0, 1]
```

### Conviction C(w,m)

Position size in this market relative to the wallet's average position across all markets.

```
ratio = market_size_usdc / avg_position_size_usdc
C = (tanh(ratio - 1) + 1) / 2
```

When ratio = 1 (average-sized position), C = 0.5. Larger than average positions push C toward 1.

### Recency R(w,m)

Exponential decay from the most recent trade, using the Rust `decay_weight()` function.

```
R = decay_weight(age_secs, half_life)
```

Default half-life is 6 hours. No trades = R = 0.0, which kills the signal entirely.

### Momentum M(w,m)

Volume-weighted buy ratio shift between the recent half and older half of trades.

```
M = 0.5 + (recent_buy_ratio - old_buy_ratio)
```

Detects direction changes. Needs 3+ trades; returns 0.5 otherwise.

### Composition

```
deviation = D - 0.5
amplified = deviation * C * 2
with_momentum = amplified + (M - 0.5) * momentum_weight
decayed = with_momentum * R
quality_adjusted = decayed * Q
S = clamp(0.5 + quality_adjusted, 0.01, 0.99)
```

Where Q is the wallet's `composite_score` from `score_wallet()`. Negative Q inverts the signal (fade bad wallets).

***

## Consensus Aggregation

For multi-wallet consensus:

1. Fetch top 20 holders via `get_top_holders()`
2. Score each wallet via `score_wallet()` (cached 5 min)
3. Filter by `|composite_score| >= min_wallet_quality`
4. Compute `WalletMarketSignal` for each
5. Weight: `|quality| * sqrt(position_size) * recency`
6. Weighted average of signals
7. Agreement = `1 - CV(signals)` (coefficient of variation)
8. Confidence interval from IQR of individual signals

Requires 3+ wallets by default; returns neutral otherwise.

***

## Pipeline Mode

The `wallet_tracker()` factory creates a pipeline function that:

* Refreshes signals every N cycles (default: 20)
* EMA-smooths signal between refreshes
* Detects regime changes and emits `WalletRegimeChange` events
* Supports both explicit wallet lists and auto-discovery

### Injected Context Parameters

| Parameter                       | Type                       | Description                           |
| ------------------------------- | -------------------------- | ------------------------------------- |
| `wallet_tracker_signal`         | `WalletMarketSignal`       | Best signal for current market        |
| `wallet_tracker_consensus`      | `ConsensusSignal`          | Multi-wallet consensus (if available) |
| `wallet_tracker_edge_bps`       | `float`                    | Signed edge in basis points           |
| `wallet_tracker_regime_changes` | `list[WalletRegimeChange]` | Regime flips detected this cycle      |

***

## Oracle Integration

The wallet tracker can optionally feed into the Oracle as a 7th signal:

```python theme={null}
config = hz.OracleConfig()
config.signal_weights["wallet_consensus"] = 0.20

fc = hz.forecast_market(
    "0xcondition...",
    market_price=0.65,
    config=config,
    include_wallet_signal=True,
)
```

The `wallet_consensus` signal weight defaults to 0.0 (disabled). You must explicitly set a non-zero weight and pass `include_wallet_signal=True`.

***

## Configuration Reference

```python theme={null}
@dataclass
class TrackerConfig:
    decay_half_life_secs: float = 21600.0     # 6h for recency decay
    ema_alpha: float = 0.3                     # signal smoothing
    min_signal_strength: float = 0.05          # |signal - 0.5| threshold
    min_confidence: float = 0.3
    min_edge_bps: float = 200.0
    min_wallets_for_consensus: int = 3
    min_wallet_quality: float = 0.1            # smart money filter
    momentum_weight: float = 0.2              # max momentum shift
    regime_change_threshold: float = 0.4
    wallet_score_cache_ttl: float = 300.0      # 5 min
    poll_interval_cycles: int = 20
```

***

## Types Reference

### WalletMarketSignal

| Field                | Type    | Description                            |
| -------------------- | ------- | -------------------------------------- |
| `wallet`             | `str`   | Wallet address                         |
| `market_id`          | `str`   | Market condition ID                    |
| `signal`             | `float` | Composite signal \[0.01, 0.99]         |
| `direction`          | `float` | Position direction D(w,m)              |
| `conviction`         | `float` | Relative sizing C(w,m)                 |
| `recency`            | `float` | Decay weight R(w,m)                    |
| `momentum`           | `float` | Trade direction shift M(w,m)           |
| `wallet_quality`     | `float` | Composite score \[-1, 1]               |
| `confidence`         | `float` | Signal confidence \[0, 1]              |
| `confidence_low`     | `float` | Lower bound                            |
| `confidence_high`    | `float` | Upper bound                            |
| `trade_count`        | `int`   | Trades in this market                  |
| `position_size_usdc` | `float` | Position value in USDC                 |
| `regime`             | `str`   | bullish / bearish / neutral / flipping |
| `edge_bps`           | `float` | Edge vs market price                   |
| `is_actionable`      | `bool`  | Passes all thresholds                  |

### ConsensusSignal

| Field            | Type                       | Description                      |
| ---------------- | -------------------------- | -------------------------------- |
| `market_id`      | `str`                      | Market condition ID              |
| `signal`         | `float`                    | Weighted consensus \[0.01, 0.99] |
| `confidence`     | `float`                    | Aggregate confidence             |
| `agreement`      | `float`                    | Wallet agreement \[0, 1]         |
| `n_wallets`      | `int`                      | Contributing wallets             |
| `edge_bps`       | `float`                    | Consensus edge                   |
| `wallet_signals` | `list[WalletMarketSignal]` | Individual signals               |
| `best_wallet`    | `str`                      | Highest-confidence wallet        |
| `is_actionable`  | `bool`                     | Passes thresholds                |

### WalletRegimeChange

| Field        | Type    | Description          |
| ------------ | ------- | -------------------- |
| `wallet`     | `str`   | Wallet address       |
| `market_id`  | `str`   | Market condition ID  |
| `old_regime` | `str`   | Previous regime      |
| `new_regime` | `str`   | New regime           |
| `confidence` | `float` | Detection confidence |
