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

# Synthetic Index

> Construct custom indices from prediction market prices. Equal, inverse-vol, and liquidity weighting. Rebalancing signals and index arbitrage detection.

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

# Synthetic Index

There is no S\&P 500 for prediction markets. Horizon's index module lets you build one. Combine multiple markets into a weighted index, track rebalancing drift, and detect arbitrage between the index level and its components. All math is in Rust.

## Overview

<CardGroup cols={2}>
  <Card title="Index Construction" icon="chart-line">
    `hz.compute_index_level()` computes a weighted index from component prices.
  </Card>

  <Card title="Weighting Methods" icon="scale-balanced">
    Equal, inverse-vol, liquidity, or custom weight schemes.
  </Card>

  <Card title="Rebalancing" icon="arrows-rotate">
    `hz.rebalance_weights()` calculates drift and rebalance actions.
  </Card>

  <Card title="Index Arbitrage" icon="magnifying-glass-dollar">
    `hz.index_arb_signal()` detects deviations between index and components.
  </Card>
</CardGroup>

***

## Core Functions

### hz.compute\_index\_level

Compute a weighted index level from component prices.

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

level = hz.compute_index_level(
    prices=[0.55, 0.60, 0.45],
    weights=[0.333, 0.333, 0.333],
    base_level=100.0,
)
print(f"Index: {level.level:.2f}")
print(f"Components: {level.num_components}")
```

| Parameter    | Type          | Default  | Description                             |
| ------------ | ------------- | -------- | --------------------------------------- |
| `prices`     | `list[float]` | required | Component prices                        |
| `weights`    | `list[float]` | required | Component weights (should sum to \~1.0) |
| `base_level` | `float`       | `100.0`  | Base index level                        |

### hz.compute\_weights\_equal / inverse\_vol / liquidity

```python theme={null}
weights = hz.compute_weights_equal(3)           # [0.333, 0.333, 0.333]
weights = hz.compute_weights_inverse_vol([0.1, 0.2, 0.3])  # lower vol = higher weight
weights = hz.compute_weights_liquidity([1000, 500, 200])    # higher volume = higher weight
```

### hz.rebalance\_weights

Calculate delta between current and target weights.

```python theme={null}
actions = hz.rebalance_weights(
    market_ids=["A", "B", "C"],
    current_weights=[0.40, 0.35, 0.25],
    target_weights=[0.333, 0.333, 0.333],
)
for a in actions:
    print(f"{a.market_id}: delta={a.delta:+.3f}")
```

### hz.index\_tracking\_error

Tracking error between a portfolio and an index.

```python theme={null}
te = hz.index_tracking_error(
    portfolio_returns=[0.01, -0.02, 0.015],
    index_returns=[0.012, -0.018, 0.014],
)
print(f"Tracking error: {te:.4f}")
```

### hz.index\_arb\_signal

Detect deviation between the index level and its fair value from components.

```python theme={null}
signal = hz.index_arb_signal(
    index_level=102.0,
    component_prices=[0.55, 0.60, 0.45],
    weights=[0.333, 0.333, 0.333],
    threshold=0.02,
)
print(f"Signal: {signal.signal_strength:.4f}")
print(f"Deviation: {signal.deviation:.4f}")
```

***

## Pipeline Functions

### hz.index

Compute and track a synthetic index level each cycle.

```python theme={null}
idx = hz.index(
    market_feeds={"btc_100k": "btc_feed", "eth_10k": "eth_feed", "sol_500": "sol_feed"},
    weighting="inverse_vol",
    base_level=100.0,
)
```

| Parameter      | Type             | Default   | Description                                      |
| -------------- | ---------------- | --------- | ------------------------------------------------ |
| `config`       | `IndexConfig`    | `None`    | Full index configuration                         |
| `market_feeds` | `dict[str, str]` | `None`    | market\_id -> feed\_name mapping                 |
| `weighting`    | `str`            | `"equal"` | `equal`, `inverse_vol`, `liquidity`, or `custom` |
| `base_level`   | `float`          | `100.0`   | Base index level                                 |

### hz.track\_index

Track index weights and signal when rebalancing is needed.

```python theme={null}
tracker = hz.track_index(
    market_feeds={"btc": "btc_feed", "eth": "eth_feed"},
    rebalance_threshold=0.05,
)
```

### hz.index\_arb

Detect arbitrage opportunities between the index and its components.

```python theme={null}
arb = hz.index_arb(
    market_feeds={"btc": "btc_feed", "eth": "eth_feed"},
    threshold=0.02,
)
```

***

## Examples

### Custom Prediction Market Index

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

hz.run(
    name="crypto_prediction_index",
    feeds={
        "btc_100k": hz.PolymarketBook("will-btc-hit-100k"),
        "eth_10k": hz.PolymarketBook("will-eth-hit-10k"),
        "sol_500": hz.PolymarketBook("will-sol-hit-500"),
    },
    pipeline=[
        hz.index(
            market_feeds={
                "btc_100k": "btc_100k",
                "eth_10k": "eth_10k",
                "sol_500": "sol_500",
            },
            weighting="inverse_vol",
        ),
    ],
)
```

### Index Arbitrage Strategy

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

def arb_strategy(ctx):
    signal = ctx.params.get("arb_signal", 0.0)
    if abs(signal) < 0.02:
        return []
    # Trade the deviation
    side = "buy" if signal > 0 else "sell"
    return [hz.order(side=side, size=10, price=ctx.feed.price)]

hz.run(
    name="index_arb_trader",
    feeds={...},
    pipeline=[
        hz.index_arb(market_feeds={...}, threshold=0.02),
        arb_strategy,
    ],
)
```
