lob-orderbook 0.1.1

High-performance limit order book with real-time market depth updates, NATS integration, and SQLite metrics
Documentation
# Guide — lob-orderbook

High-performance limit order book for multi-broker trading systems.

## Import

```toml
[dependencies]
lob-orderbook = "0.1.0"
```

## Quick Start

### Option A — Full System (NATS + Health Server + Market Window)

Each broker runs as its own process with unique config:

```rust
use lob_orderbook::{run_limit_order_book_full, BrokerConfig};

#[tokio::main]
async fn main() {
    let config = BrokerConfig {
        broker_name: "zerodha".to_string(),
        health_port: 8081,
    };
    let store = run_limit_order_book_full(config).await.unwrap();
    // store: Arc<OrderBookStore> — keep for queries
    tokio::signal::ctrl_c().await.unwrap();
}
```

### Option B — Just the Order Book Store (no NATS)

```rust
use lob_orderbook::{run_limit_order_book, init_module_logger};
use jsonl_logger::jsonl_logger;

#[tokio::main]
async fn main() {
    let logger = jsonl_logger::init().unwrap().clone();
    let store = run_limit_order_book(logger, "my_broker").await.unwrap();
}
```

## Feeding Market Data

Deserialize exchange data into `MarketDepthData` and call `update_book`:

```rust
use lob_orderbook::MarketDepthData;

let data = MarketDepthData {
    exch_timestamp: 1700000000123,
    unified_symbol: "BTCUSD".to_string(),
    bids: vec![(50000.0, 10), (49900.0, 20)],
    asks: vec![(50100.0, 5), (50200.0, 15)],
};
store.update_book(&data)?;
```

> Timestamp gating: strictly older timestamps are rejected. Equal timestamps are allowed (safe for exchange reconnects).

## Querying the Book

```rust
let best_bid  = store.get_best_bid("BTCUSD")?;        // Some(50000.0)
let best_ask  = store.get_best_ask("BTCUSD")?;        // Some(50100.0)
let mid       = store.calculate_mid_price("BTCUSD")?;  // Some(50050.0)
let spread    = store.calculate_spread("BTCUSD")?;     // Some(100.0)
let liquidity = store.calculate_order_book_liquidity("BTCUSD")?;
let symbols   = store.get_all_symbols();
```

## Pre-Trade Checks

Check if an order is fillable:

```rust
// Is there 30+ units of BTC on the bid side at price >= 49900?
let available = store.check_quantity_availability_with_price("BTCUSD", 49900.0, 30, true)?;
```

Simulate market impact:

```rust
// Walk the ask book for a buy order of 50 units
let result = store.calculate_market_impact("BTCUSD", 50, true)?;
if let Some((avg_price, impact_price, executed, filled)) = result {
    println!("Avg: {avg_price}, Filled: {filled}");
}
```

## Multi-Broker Setup

Run one process per broker, each with unique `BrokerConfig`:

| Broker   | `broker_name` | `health_port` | Log file                | Metrics DB                    |
|----------|---------------|---------------|-------------------------|-------------------------------|
| Zerodha  | `"zerodha"`   | `8081`        | `ORDER_MANAGER_zerodha` | `limit_order_book_zerodha.db` |
| ICICI    | `"icici"`     | `8082`        | `ORDER_MANAGER_icici`   | `limit_order_book_icici.db`   |
| Angel    | `"angel"`     | `8083`        | `ORDER_MANAGER_angel`   | `limit_order_book_angel.db`   |

## Environment Variables

| Variable            | Required | Description                     |
|---------------------|----------|---------------------------------|
| `NATS_PORT`          | Yes      | NATS server port (e.g. `4222`)  |
| `PROJECT_DIRECTORY`  | Yes      | Root path for logs + metrics DB |

## Public API

| Item | Description |
|---|---|
| `BrokerConfig` | Per-broker config: `broker_name`, `health_port` |
| `OrderBookStore` | Thread-safe order book store (dashmap) |
| `MarketDepthData` | Input data struct: `exch_timestamp`, `unified_symbol`, `bids`, `asks` |
| `OrderBook` | Per-symbol book with `BTreeMap`-based price levels |
| `MarketWindowConfig` | Trading hours window config |
| `run_limit_order_book_full(config)` | Full system entry point (NATS + health server + market window) |
| `run_limit_order_book(logger, name)` | Store-only entry point |
| `process_buffered_messages(messages, store, logger)` | Batch process pre-serialized JSON messages |
| `print_best_ask_loop(store, logger, symbol)` | Debug monitor for best ask |
| `init_module_logger(name)` | Initialize logger with broker prefix |

## Notes

- **One broker per process** — each process runs independently with its own `BrokerConfig`
- All brokers subscribe to the same NATS subject `"marketdepth.data"`
- NATS URL is always `nats://127.0.0.1:{NATS_PORT}` (from env, no `NATS_URL` override)
- Market window uses `trading_hours` library — standard across all brokers