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

# NAV Methodology

> Complete specification of how Belief Index computes Net Asset Value – transparent, verifiable, and rules-based.

**Methodology Version:** `midprice-v1`
**Last Updated:** February 2026

This document provides the complete specification of how Belief Index computes Net Asset Value. The methodology is designed to be transparent and independently verifiable – anyone with a spreadsheet and access to public market data can replicate any published NAV figure.

<Info>
  This is the key transparency document for Belief Index. Every formula is explained in plain English with worked examples. If anything is unclear, start with the [Glossary](/reference/glossary) for term definitions.
</Info>

## Overview

The `midprice-v1` methodology computes index NAV using the arithmetic midpoint of best bid and best ask prices from the Polymarket order book. This approach provides a simple, transparent, and deterministic price discovery mechanism.

The computation produces two outputs:

| Output          | Description                                  | Range  | Analogous To                                 |
| --------------- | -------------------------------------------- | ------ | -------------------------------------------- |
| **Raw NAV**     | Weighted average of underlying market prices | 0 to 1 | An index's raw level                         |
| **Index Level** | Rebased index value starting at 100          | Varies | S\&P 500 level, Dow Jones Industrial Average |

<Note>
  The Raw NAV is a probability-weighted aggregate. A Raw NAV of 0.65 means the weighted-average implied probability across all markets in the basket is 65%. The Index Level simply rebases this to start at 100 so readers can track percentage performance over time without thinking in raw probability terms.
</Note>

## Step-by-Step Computation

### Step 1: Determine Market Prices

For each market in the series, a price must be determined. The source depends on whether the market is still active or has resolved.

<Tabs>
  <Tab title="Active markets">
    For unresolved markets, the price is the midpoint of the best bid and best ask quotes:

    ```
    midprice = (best_bid + best_ask) / 2
    ```

    **In plain English:** The order book shows what buyers are willing to pay (bids) and what sellers are asking (asks). The midprice is the average of the highest bid and the lowest ask – the theoretical fair value sitting between buyers and sellers.

    **Worked example:**

    If the best bid for a YES outcome token is \$0.65 and the best ask is \$0.67:

    ```
    midprice = (0.65 + 0.67) / 2 = 0.66
    ```

    This means the market implies roughly a 66% probability that the tracked event occurs.
  </Tab>

  <Tab title="Resolved markets">
    When a market has settled, there is no ambiguity:

    * If the tracked outcome **won**: price = **\$1.00**
    * If the tracked outcome **lost**: price = **\$0.00**

    Resolution prices are binary. There is no partial outcome, no appeal, and no middle ground. Once resolved, the settlement price is final and the market's contribution to the index is locked.
  </Tab>

  <Tab title="Fallback behavior">
    If a price cannot be fetched due to API failure or network issues:

    1. The system retries up to 3 times with increasing delays
    2. If all retries fail, the last successfully fetched price is used
    3. The computation is marked as **stale** (see [Staleness](#staleness) below)

    This ensures the system never halts entirely due to a temporary data interruption, but data users are always informed when a computation relies on potentially outdated data.
  </Tab>
</Tabs>

### Step 2: Normalize Weights

Raw weights from the series composition are normalized so they sum to exactly 1.0:

```
normalized_weight = raw_weight / sum_of_all_raw_weights
```

**In plain English:** Each market's raw weight is divided by the total of all weights, ensuring the percentages add up to exactly 100%. This is standard practice in index construction – it guarantees the aggregate NAV stays within a predictable range regardless of how the raw weights are specified.

<Accordion title="Worked example: weight normalization">
  A 7-market series with nearly equal raw weights:

  ```
  Raw weights: 0.1429, 0.1429, 0.1429, 0.1429, 0.1429, 0.1429, 0.1429
  Sum of raw weights: 7 x 0.1429 = 1.0003

  Normalized weights: each = 0.1429 / 1.0003 = 0.14285714
  Sum of normalized weights: 1.00000000
  ```

  The normalization corrects for the tiny rounding error in the raw weights. In this case, the correction is negligible, but normalization becomes more important when raw weights are specified as round numbers that don't sum precisely to 1.
</Accordion>

### Step 3: Compute Raw NAV

The Raw NAV is a weighted average of all market prices:

```
raw_nav = sum of (normalized_weight_i x price_i) for all markets
```

**In plain English:** Multiply each market's price by its weight, then add up all the results. The output is a single number between 0 and 1 representing the aggregate implied probability across the entire basket.

**Why it's bounded:** Since every weight is non-negative, all weights sum to 1, and every price is between 0 and 1, the Raw NAV is mathematically guaranteed to fall between 0 and 1. As a defensive measure, the system also explicitly enforces this bound.

<Accordion title="Worked example: full Raw NAV calculation">
  A 4-market equal-weighted series (each market has normalized weight 0.25):

  | Market    | Status         | Midprice | Weight   | Contribution |
  | --------- | -------------- | -------- | -------- | ------------ |
  | Market A  | Active         | 0.73     | 0.25     | 0.18250      |
  | Market B  | Active         | 0.555    | 0.25     | 0.13875      |
  | Market C  | Resolved (won) | 1.00     | 0.25     | 0.25000      |
  | Market D  | Active         | 0.42     | 0.25     | 0.10500      |
  | **Total** |                |          | **1.00** | **0.67625**  |

  ```
  raw_nav = (0.25 x 0.73) + (0.25 x 0.555) + (0.25 x 1.00) + (0.25 x 0.42)
          = 0.18250 + 0.13875 + 0.25000 + 0.10500
          = 0.67625
  ```

  The Raw NAV of 0.67625 means the weighted-average implied probability is approximately 67.6%.
</Accordion>

### Step 4: Compute Index Level

The Index Level provides a rebased representation starting at a base value of 100, making it easy to track percentage performance over time:

```
index_level = 100 x (raw_nav / inception_raw_nav)
```

Where:

* **inception\_raw\_nav** is the Raw NAV at the first successful computation for this series
* **100** is the base index level (analogous to setting any price index to 100 at its starting date)

<Accordion title="Worked example: Index Level calculation">
  If a series had an inception Raw NAV of 0.62000000 and the current Raw NAV is 0.67625:

  ```
  index_level = 100 x (0.67625 / 0.62000)
              = 100 x 1.09073
              = 109.07
  ```

  The Index Level of 109.07 means the index has gained approximately 9.07% from inception. If the Index Level were 95.50, the index would have declined approximately 4.5%.
</Accordion>

### Step 5: Chain-Linking (Perpetual Series)

When a [Perpetual series](/indices/perpetual-series) changes composition through reconstitution, `raw_nav` changes mechanically – different markets, different weights, different numbers. To keep the published Index Level continuous across the change, the series is **chain-linked**: a new `inception_raw_nav` is computed so that the first post-reconstitution Index Level equals the level immediately before the event (the *chain-link anchor*).

```
new_inception_raw_nav = post_reconstitution_raw_nav x (100 / anchor_index_level)
```

Equivalently: the anchor is recorded, and all subsequent levels are computed as `100 x (raw_nav / new_inception_raw_nav)` under the new composition. The evaluation is a single Decimal expression at 8 decimal places.

<Accordion title="Worked example: chain-linking across a reconstitution">
  A Perpetual series trades at an Index Level of **112.50** immediately before a reconstitution (the anchor). After new markets are admitted and weights renormalized, the new composition's Raw NAV computes to 0.54000000.

  ```
  new_inception_raw_nav = 0.54000 x (100 / 112.50)
                        = 0.48000000

  first post-event level = 100 x (0.54000 / 0.48000)
                         = 112.50
  ```

  The published chart shows 112.50 before and after the event – no artificial jump. If the new basket then rises to a Raw NAV of 0.60000:

  ```
  index_level = 100 x (0.60000 / 0.48000) = 125.00
  ```

  The 11.1% gain reflects genuine movement of the new basket, measured against the re-anchored inception value.
</Accordion>

Fixed series never chain-link – their composition is immutable, so `inception_raw_nav` is set once at inception and never changes.

## Precision

All calculations use controlled precision to ensure consistency and reproducibility:

| Parameter      | Value               | Why                                                                              |
| -------------- | ------------------- | -------------------------------------------------------------------------------- |
| Decimal places | 8                   | Sufficient precision for financial calculations without floating-point artifacts |
| Rounding mode  | Round half up       | Standard symmetric rounding for informational metrics                            |
| Storage format | Fixed-point decimal | Avoids floating-point representation errors                                      |

## Staleness

A computation is marked **stale** when all three conditions are met:

1. Any underlying market price fetch failed
2. A fallback (last-known) price was used instead
3. The series is not fully resolved

<Warning>
  A stale NAV may not reflect current market conditions. Stale computations are flagged transparently so data users know the published value may rely on outdated price data for one or more markets. When a series is fully resolved, the terminal NAV is definitive and is never marked as stale.
</Warning>

**One-sided order books:** If a market shows only bids and no asks (or vice versa), the midprice cannot be computed. The market falls back to its last known good price and is marked as stale. Prolonged one-sided books result in increasingly outdated component prices.

## Resolution Handling

Markets within a series resolve independently as their underlying events occur. The series continues operating with a mix of resolved and active markets until all markets have settled.

| Series State           | Condition              | Behavior                                                                        |
| ---------------------- | ---------------------- | ------------------------------------------------------------------------------- |
| **Active**             | All markets unresolved | Normal computation using live midprices                                         |
| **Partially resolved** | Some markets resolved  | Resolved markets use settlement price (\$1 or \$0); active markets use midprice |
| **Fully resolved**     | All markets resolved   | Terminal NAV computed; no further updates; value is definitive                  |

<Accordion title="How partial resolution works">
  Consider a 4-market series where Market C has resolved (the tracked outcome won):

  | Market   | Status         | Price Used               |
  | -------- | -------------- | ------------------------ |
  | Market A | Active         | Midprice from order book |
  | Market B | Active         | Midprice from order book |
  | Market C | Resolved (won) | \$1.00 (settlement)      |
  | Market D | Active         | Midprice from order book |

  Market C's contribution is now locked at \$1.00. Its weight remains in the index – it continues to contribute its full weighted value. The remaining active markets continue to fluctuate with market prices.

  If Market C had lost, its contribution would be locked at \$0.00, reducing the Raw NAV by that market's full weighted amount.
</Accordion>

<Accordion title="Terminal NAV">
  When every market in a series resolves, the series reaches its terminal NAV. This final value is:

  * **Definitive** – not subject to further change
  * **Not stale** – there is no data quality concern since all prices are settlement prices
  * **Binary by component** – each market contributed either \$1.00 or \$0.00

  For an equal-weighted 7-market series where 5 outcomes won and 2 lost:

  ```
  terminal_raw_nav = (5 x 1.00 + 2 x 0.00) / 7 = 0.71428571
  ```

  This is the final value of the index. No further computations occur.
</Accordion>

## Known Limitations

The `midprice-v1` methodology is designed for simplicity and transparency. These design choices come with known trade-offs that data users should understand.

### Theoretical vs. Executable Pricing

The midprice is a theoretical value. It does not account for:

* **Trading fees** (typically 0.5-2% on underlying markets)
* **Slippage** for market-sized orders
* **Market impact** of hypothetical replication trades

The published NAV represents a theoretical value, not an executable portfolio price. The actual value realizable through liquidation may be lower.

### Liquidity Variance

Markets within an index may have vastly different liquidity profiles, yet carry equal weight:

| Market Type         | Typical Depth | Spread Characteristics                    |
| ------------------- | ------------- | ----------------------------------------- |
| High-profile events | \$1M+         | Tight spreads (\< 0.1% relative)          |
| Moderate interest   | $10K - $100K  | Moderate spreads                          |
| Niche markets       | \< \$1K       | Wide spreads; price signals less reliable |

A market with \$30 million in depth may sit alongside one with \$400 in depth – both carrying equal weight and contributing equally to the index.

### Static Weighting

Current indices use fixed weights assigned at composition time:

* Weights do not adjust for changes in liquidity
* No automatic rebalancing based on market conditions
* A market that becomes illiquid after inclusion continues to receive its full weight

### No Correlation Adjustment

Markets within a series may be correlated (e.g., multiple Federal Reserve-related events). The methodology treats each market as independent and does not discount for information overlap. This may overstate the diversification benefit of holding multiple related markets.

## Independent Verification Guide

One of the core design principles of Belief Index is that anyone can independently verify a published NAV using only public data and a spreadsheet. This section provides a step-by-step process.

### What You Need

| Item                                            | Where to Find It                                   |
| ----------------------------------------------- | -------------------------------------------------- |
| Series composition (markets, outcomes, weights) | Published on the series detail page on our website |
| Current order book data                         | Polymarket public order book (no account required) |
| A spreadsheet or calculator                     | Any tool that supports basic arithmetic            |

### Step-by-Step Verification

<Steps>
  <Step title="Get the series composition">
    From the series page on our website, note down:

    * The list of underlying markets (by question/title)
    * The **tracked outcome** for each market (YES or NO)
    * The **raw weight** assigned to each market

    For example, a series might have 5 markets, each with raw weight 0.20, all tracking the YES outcome.
  </Step>

  <Step title="Look up each market on Polymarket">
    Go to Polymarket and find each market by its question. On the market page, you can see the current order book.

    For each market, record:

    * **Best bid** – the highest price someone is willing to pay for the tracked outcome token
    * **Best ask** – the lowest price someone is willing to sell the tracked outcome token

    If a market has resolved, record its outcome instead (won = \$1.00, lost = \$0.00).

    <Accordion title="Reading the Polymarket order book">
      On Polymarket, each binary market has two outcome tokens: YES and NO. The order book for each token shows:

      * **Bids** (buy orders): Sorted with the highest bid at the top. This is the best bid.
      * **Asks** (sell orders): Sorted with the lowest ask at the top. This is the best ask.

      You need the best bid and best ask for the **tracked outcome** only (the one listed in the series composition). If the series tracks "YES" for a given market, use the YES token's order book.
    </Accordion>
  </Step>

  <Step title="Compute midprices">
    For each active market:

    ```
    midprice = (best_bid + best_ask) / 2
    ```

    For resolved markets, use \$1.00 (if the tracked outcome won) or \$0.00 (if it lost).
  </Step>

  <Step title="Normalize weights">
    Sum all raw weights, then divide each by the total:

    ```
    normalized_weight = raw_weight / sum_of_all_raw_weights
    ```

    **Check:** The normalized weights must sum to exactly 1.00.
  </Step>

  <Step title="Compute Raw NAV">
    Multiply each normalized weight by its midprice and sum:

    ```
    raw_nav = sum of (normalized_weight_i x midprice_i)
    ```
  </Step>

  <Step title="Compute Index Level (optional)">
    If you know the inception Raw NAV (published on the series page):

    ```
    index_level = 100 x (your_raw_nav / inception_raw_nav)
    ```
  </Step>

  <Step title="Compare to published NAV">
    Your computed Raw NAV should match the published value. Acceptable discrepancy:

    | Difference           | Likely Cause                                                     |
    | -------------------- | ---------------------------------------------------------------- |
    | Less than 0.00000010 | Normal rounding differences                                      |
    | 0.0001 to 0.001      | Timing gap (your price fetch was a few seconds off)              |
    | Greater than 0.01    | Investigate further – check if a market resolved between fetches |
  </Step>
</Steps>

### Common Verification Issues

<AccordionGroup>
  <Accordion title="My number doesn't match – what should I check?">
    1. **Timing:** The NAV is computed at a specific moment. If you fetch prices even a few minutes later, markets may have moved. Try to fetch prices as close to the published computation time as possible.

    2. **Wrong outcome token:** Make sure you are looking at the order book for the **tracked outcome** (YES or NO) as specified in the series composition, not the opposite side.

    3. **Resolved markets:** If a market resolved between computations, the system uses the settlement price (\$1.00 or \$0.00), not the last trading price.

    4. **One-sided book:** If a market shows only bids and no asks (or vice versa), the midprice cannot be computed. The published NAV may be using a cached price for that market and will be flagged as stale.

    5. **Precision:** Use at least 8 decimal places in your calculations. Rounding intermediate results too aggressively can compound into noticeable differences.
  </Accordion>

  <Accordion title="Can I automate this verification?">
    Yes. The Polymarket order book data is publicly available via their API. No authentication is required for reading order book data. You can build a script that fetches order books for all markets in a series composition and computes the NAV automatically.
  </Accordion>
</AccordionGroup>

<Note>
  The verification process above applies to the **Raw NAV** and **Index Level**. To verify **NAV per Share** (an Alpha Program metric), you would additionally need to know the series' custody cash balance and accrued fees – see [NAV Per Share](/investing/nav-per-share) for how these components relate.
</Note>

## Future Methodology Versions

All methodology changes are tracked via a version string recorded with each computation. Any methodology change will be announced in advance and clearly documented.

| Version       | Description                   | Status         |
| ------------- | ----------------------------- | -------------- |
| `midprice-v1` | Simple bid-ask midpoint       | **Production** |
| `midprice-v2` | Liquidity-weighted midpoint   | Proposed       |
| `vwap-v1`     | Volume-weighted average price | Research       |
| `twap-v1`     | Time-weighted average price   | Research       |

<Accordion title="What would future versions change?">
  * **Liquidity-weighted midpoint** (`midprice-v2`): Would reduce the influence of thinly-traded markets on aggregate NAV by weighting each market's contribution by its order book depth.
  * **Volume-weighted average price** (`vwap-v1`): Would use actual executed trade prices rather than quoted prices, reflecting real market activity.
  * **Time-weighted average price** (`twap-v1`): Would smooth prices over a rolling window, reducing the impact of short-term volatility or manipulation.

  Each alternative trades simplicity for additional sophistication. The current `midprice-v1` is intentionally simple and transparent.
</Accordion>

<CardGroup cols={2}>
  <Card title="NAV Per Share" icon="coins" href="/investing/nav-per-share">
    How the published NAV translates to your share value.
  </Card>

  <Card title="Index Series" icon="layer-group" href="/indices/index-series">
    How series are structured and composed.
  </Card>

  <Card title="On-Chain Verification" icon="magnifying-glass" href="/trust/on-chain-verification">
    How to verify that custody holdings match reported positions.
  </Card>

  <Card title="Risk Factors" icon="triangle-exclamation" href="/risk/risk-factors">
    Methodology limitations and their practical implications.
  </Card>
</CardGroup>
