# Market Depth Specification

Query interfaces for order book depth, following Betfair's model.

## Overview

Betfair provides market depth through `listMarketBook` with configurable price depth. Default is 3 levels per side per runner.

## Depth Query Types

### Best Offers (Default)

Returns the N best prices on each side (back/lay) for each runner.

```rust
pub struct PriceSize {
    pub price: OddsX10000,
    pub size: Money,  // Total available at this price
}

pub struct RunnerPrices {
    pub runner_id: RunnerId,
    pub back: Vec<PriceSize>,  // Best back prices (highest first)
    pub lay: Vec<PriceSize>,   // Best lay prices (lowest first)
}

impl Book {
    /// Get best N prices per side for a runner
    pub fn runner_prices(&self, runner_id: RunnerId, depth: usize) -> RunnerPrices;

    /// Get best N prices per side for all runners
    pub fn all_runner_prices(&self, depth: usize) -> Vec<RunnerPrices>;
}
```

**Depth parameter:**
- Default: 3
- Maximum: configurable (Betfair allows up to full ladder)

### Full Ladder

Returns all available prices with liquidity.

```rust
impl Book {
    /// Get full depth for a runner
    pub fn runner_ladder(&self, runner_id: RunnerId) -> RunnerPrices;
}
```

## Price Ordering

**Back side:** Best = highest price (backer wants highest odds)
```
back[0] = 2.50  (best for backer)
back[1] = 2.48
back[2] = 2.46
```

**Lay side:** Best = lowest price (layer wants lowest odds)
```
lay[0] = 2.52  (best for layer)
lay[1] = 2.54
lay[2] = 2.56
```

## Aggregation

Sizes are aggregated per price level. Individual order details are not exposed.

```rust
// At price 2.50, there might be orders:
//   Order A: 50
//   Order B: 30
//   Order C: 20
//
// Returned as single PriceSize:
//   { price: 2.50, size: 100 }
```

## Best Price Accessors

Convenience methods for common queries:

```rust
impl Book {
    /// Best available back price for a runner (highest)
    pub fn best_back_price(&self, runner_id: RunnerId) -> Option<PriceSize>;

    /// Best available lay price for a runner (lowest)
    pub fn best_lay_price(&self, runner_id: RunnerId) -> Option<PriceSize>;

    /// Spread between best back and lay (in ticks)
    pub fn spread_ticks(&self, runner_id: RunnerId) -> Option<u32>;

    /// Total matched volume on a runner
    pub fn runner_matched_volume(&self, runner_id: RunnerId) -> Money;

    /// Total unmatched volume on a runner (both sides)
    pub fn runner_available_volume(&self, runner_id: RunnerId) -> Money;
}
```

## Market-Level Queries

```rust
impl Book {
    /// Total matched volume across all runners
    pub fn total_matched(&self) -> Money;

    /// Number of active (resting) orders
    pub fn active_order_count(&self) -> usize;
}
```

`active_order_count()` is maintained as an incremental cache in all book variants (`TwoRunnerBook`, `MultiRunnerBook`, `BinaryYesBook`), so reads are O(1) rather than full order-map scans.

## Response Structure

Matches Betfair's `ExchangePrices` structure:

```rust
pub struct ExchangePrices {
    pub available_to_back: Vec<PriceSize>,
    pub available_to_lay: Vec<PriceSize>,
    pub traded_volume: Vec<PriceSize>,  // Historical at each price
}
```

## Performance Considerations

1. **Depth queries are read-only** - no events emitted
2. **Aggregate totals cached** - `total_remaining` maintained per price level
3. **Active order count cached** - lifecycle updates keep `active_order_count()` cheap
4. **Lazy computation** - full ladder only computed when requested

## Example Usage

```rust
let book = Book::new(market_id, runners);
// ... orders placed ...

// Get top 3 prices for runner
let prices = book.runner_prices(RunnerId(1), 3);

// Best back available
if let Some(best) = prices.back.first() {
    println!("Best back: {} @ {}", best.size, best.price);
}

// Check spread
if let Some(ticks) = book.spread_ticks(RunnerId(1)) {
    println!("Spread: {} ticks", ticks);
}
```

## Sources

- [Betfair listMarketBook](https://docs.developer.betfair.com/display/1smk3cen4v3lu3yomq5qye0ni/listMarketBook)
- [Betfair Market Data FAQ](https://support.developer.betfair.com/hc/en-us/articles/6540502258077-What-Betfair-Exchange-market-data-is-available-from-listMarketBook-Stream-API)
