Market Microstructure·Order Book Analysis·Advanced

Level2 Data Fetch

Fetch and process streaming Level 2 order book data from exchange WebSocket feeds, maintaining a local high-fidelity order book reconstruction with incremental update application for latency-sensitive real-time microstructure analysis and trading signal generation.

data-fetchingmarket-microstructureorder-booktechnical-analysis

Understanding Level 2 Order Book Data

This notebook provides a structured introduction to Level 2 order book data, a crucial concept in financial markets, especially for high-frequency trading and market analysis.

What is Level 2 Order Book Data?

Level 2 order book data provides a detailed, real-time view of all outstanding buy (bid) and sell (ask) orders for a specific financial instrument (like a stock, cryptocurrency, or commodity) at various price levels. Unlike Level 1 data, which only shows the best bid and ask prices (the top of the book), Level 2 data exposes the full depth of the market.

Key Components:

  • Bid Side: Represents orders from buyers indicating the maximum price they are willing to pay. These orders are sorted in descending order by price.
  • Ask Side: Represents orders from sellers indicating the minimum price they are willing to accept. These orders are sorted in ascending order by price.
  • Price Level: The specific price at which an order is placed.
  • Quantity (Size): The number of units (e.g., shares, contracts) available at a given price level.

Importance:

Level 2 data is vital for:

  • Market Depth Analysis: Understanding the liquidity and potential price impact of large orders.
  • Price Discovery: Gaining insights into where supply and demand are concentrated.
  • Identifying Support/Resistance: Large clusters of bids/asks can indicate potential price barriers.
  • Order Flow Analysis: Observing how orders are placed, modified, and executed to infer market sentiment and potential future price movements.

Setting up the Environment

First, let's import the necessary libraries.

[ ]
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import random

Mock Data Generation

To demonstrate the concepts, we will generate a realistic-looking mock Level 2 order book. In a real-world scenario, this data would be fetched from a trading API (e.g., Binance, Coinbase, LMAX, Interactive Brokers).

[ ]
def generate_mock_order_book_data(
    mid_price: float = 100.0,
    spread: float = 0.05,
    depth: int = 10,
    qty_range: tuple = (10, 100)
) -> dict:
    """
    Generates mock Level 2 order book data for demonstration.

    Args:
        mid_price (float): The central price around which bids and asks are generated.
        spread (float): The difference between the best ask and best bid.
        depth (int): The number of price levels to generate for bids and asks.
        qty_range (tuple): A tuple (min_qty, max_qty) for random quantities.

    Returns:
        dict: A dictionary containing 'bids' and 'asks' DataFrames.
              Each DataFrame has 'Price' and 'Quantity' columns.
    """
    best_ask = mid_price + spread / 2
    best_bid = mid_price - spread / 2

    # Generate Ask orders
    ask_prices = [best_ask + i * 0.01 for i in range(depth)]
    ask_quantities = [random.randint(qty_range[0], qty_range[1]) for _ in range(depth)]
    asks_df = pd.DataFrame({'Price': ask_prices, 'Quantity': ask_quantities})

    # Generate Bid orders
    bid_prices = [best_bid - i * 0.01 for i in range(depth)]
    bid_quantities = [random.randint(qty_range[0], qty_range[1]) for _ in range(depth)]
    bids_df = pd.DataFrame({'Price': bid_prices, 'Quantity': bid_quantities})

    return {"bids": bids_df, "asks": asks_df}

# Generate and display mock data
order_book = generate_mock_order_book_data(mid_price=1500.00, spread=0.10, depth=15)

print("### Mock Bid Orders (Buyers wanting to buy) ###")
display(order_book['bids'].head())

print("\n### Mock Ask Orders (Sellers wanting to sell) ###")
display(order_book['asks'].head())
### Mock Bid Orders (Buyers wanting to buy) ###
Price Quantity
0 1499.95 44
1 1499.94 28
2 1499.93 58
3 1499.92 58
4 1499.91 29

### Mock Ask Orders (Sellers wanting to sell) ###
Price Quantity
0 1500.05 49
1 1500.06 59
2 1500.07 28
3 1500.08 30
4 1500.09 53

Core Metrics from Level 2 Data

From the Level 2 order book, we can derive several important metrics that help in understanding market dynamics.

1. Bid-Ask Spread

Definition: The difference between the best (highest) bid price and the best (lowest) ask price.

Formula: Spread = Best Ask Price - Best Bid Price

Importance: A narrower spread generally indicates higher liquidity and lower transaction costs, while a wider spread suggests lower liquidity or higher volatility.

2. Mid-Price

Definition: The average of the best bid and best ask prices.

Formula: Mid-Price = (Best Bid Price + Best Ask Price) / 2

Importance: Often used as a proxy for the true market price of an asset, especially when the last traded price might be stale.

[ ]
def calculate_spread(order_book: dict) -> float:
    """
    Calculates the bid-ask spread from the order book.

    Args:
        order_book (dict): A dictionary containing 'bids' and 'asks' DataFrames.

    Returns:
        float: The bid-ask spread.
    """
    best_bid = order_book['bids']['Price'].max()
    best_ask = order_book['asks']['Price'].min()
    spread = best_ask - best_bid
    return spread

def calculate_mid_price(order_book: dict) -> float:
    """
    Calculates the mid-price from the order book.

    Args:
        order_book (dict): A dictionary containing 'bids' and 'asks' DataFrames.

    Returns:
        float: The mid-price.
    """
    best_bid = order_book['bids']['Price'].max()
    best_ask = order_book['asks']['Price'].min()
    mid_price = (best_bid + best_ask) / 2
    return mid_price

# Demonstrate calculations with mock data
mock_spread = calculate_spread(order_book)
mock_mid_price = calculate_mid_price(order_book)

print(f"Best Bid Price: {order_book['bids']['Price'].max():.2f}")
print(f"Best Ask Price: {order_book['asks']['Price'].min():.2f}")
print(f"Calculated Bid-Ask Spread: {mock_spread:.2f}")
print(f"Calculated Mid-Price: {mock_mid_price:.2f}")
Best Bid Price: 1499.95
Best Ask Price: 1500.05
Calculated Bid-Ask Spread: 0.10
Calculated Mid-Price: 1500.00

3. Order Book Depth (Cumulative Quantity)

Definition: The total quantity of orders available at or up to a certain price level (or a certain number of levels away from the best bid/ask).

Importance: Provides insight into the liquidity available at different price points. A high depth on one side (e.g., many bids) might indicate strong buying interest (support), while high depth on the other side (e.g., many asks) might indicate strong selling pressure (resistance).

[ ]
def calculate_order_book_depth(df: pd.DataFrame) -> pd.DataFrame:
    """
    Calculates the cumulative quantity for an order book side (bids or asks).

    Args:
        df (pd.DataFrame): DataFrame representing either bids or asks, with 'Price' and 'Quantity' columns.

    Returns:
        pd.DataFrame: A DataFrame with 'Price', 'Quantity', and 'Cumulative Quantity' columns,
                      sorted appropriately for the order book side.
    """
    df_sorted = df.sort_values(by='Price', ascending=True if 'asks' in df.columns else False)
    df_sorted['Cumulative Quantity'] = df_sorted['Quantity'].cumsum()
    return df_sorted

# Calculate and display depth for bids and asks
bids_with_depth = calculate_order_book_depth(order_book['bids'].sort_values(by='Price', ascending=False).reset_index(drop=True))
asks_with_depth = calculate_order_book_depth(order_book['asks'].sort_values(by='Price', ascending=True).reset_index(drop=True))

print("### Bid Orders with Cumulative Depth ###")
display(bids_with_depth.head())

print("\n### Ask Orders with Cumulative Depth ###")
display(asks_with_depth.head())
### Bid Orders with Cumulative Depth ###
Price Quantity Cumulative Quantity
0 1499.95 44 44
1 1499.94 28 72
2 1499.93 58 130
3 1499.92 58 188
4 1499.91 29 217

### Ask Orders with Cumulative Depth ###
Price Quantity Cumulative Quantity
14 1500.19 32 32
13 1500.18 54 86
12 1500.17 35 121
11 1500.16 72 193
10 1500.15 58 251

Visualizing Level 2 Order Book Data

Visualizations help to quickly grasp the distribution of orders and market depth. We will create two types of plots:

  1. Order Book Profile: A multi-panel plot showing the individual bid and ask levels.
  2. Cumulative Order Book Depth: A plot illustrating the cumulative quantity at various price levels.

1. Order Book Profile Visualization

This plot shows the quantity at each price level for both bids and asks, providing a snapshot of the current market structure. The best bid and ask prices are highlighted to indicate the current spread.

[ ]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6), sharey=True)

# Plot Bids
ax1.barh(order_book['bids']['Price'], order_book['bids']['Quantity'], color='green', alpha=0.7)
ax1.set_title('Bid Orders (Buyers)', fontsize=14)
ax1.set_xlabel('Quantity', fontsize=12)
ax1.set_ylabel('Price', fontsize=12)
ax1.invert_xaxis() # Bids typically shown decreasing quantity from best price
ax1.tick_params(axis='x', rotation=45)
ax1.grid(axis='x', linestyle='--', alpha=0.6)

# Highlight Best Bid
best_bid_price = order_book['bids']['Price'].max()
ax1.axhline(best_bid_price, color='darkgreen', linestyle='--', linewidth=1.5, label=f'Best Bid: {best_bid_price:.2f}')
ax1.legend()

# Plot Asks
ax2.barh(order_book['asks']['Price'], order_book['asks']['Quantity'], color='red', alpha=0.7)
ax2.set_title('Ask Orders (Sellers)', fontsize=14)
ax2.set_xlabel('Quantity', fontsize=12)
ax2.tick_params(axis='x', rotation=45)
ax2.grid(axis='x', linestyle='--', alpha=0.6)

# Highlight Best Ask
best_ask_price = order_book['asks']['Price'].min()
ax2.axhline(best_ask_price, color='darkred', linestyle='--', linewidth=1.5, label=f'Best Ask: {best_ask_price:.2f}')
ax2.legend()

fig.suptitle(f'Level 2 Order Book Profile (Mid-Price: {mock_mid_price:.2f}, Spread: {mock_spread:.2f})', fontsize=16)
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.show()
cell output

2. Cumulative Order Book Depth Visualization

This plot aggregates the quantity of orders at each price level, showing the total liquidity available as you move away from the current mid-price. This helps in understanding market resilience to large orders.

[ ]
plt.figure(figsize=(12, 7))

# Plot Cumulative Bids
plt.plot(bids_with_depth['Price'], bids_with_depth['Cumulative Quantity'], drawstyle='steps-post', color='green', label='Cumulative Bids')
# Plot Cumulative Asks
plt.plot(asks_with_depth['Price'], asks_with_depth['Cumulative Quantity'], drawstyle='steps-post', color='red', label='Cumulative Asks')

plt.axvline(mock_mid_price, color='purple', linestyle=':', label=f'Mid-Price: {mock_mid_price:.2f}')
plt.axvline(order_book['bids']['Price'].max(), color='darkgreen', linestyle='--', label=f'Best Bid: {order_book['bids']['Price'].max():.2f}')
plt.axvline(order_book['asks']['Price'].min(), color='darkred', linestyle='--', label=f'Best Ask: {order_book['asks']['Price'].min():.2f}')

plt.title('Cumulative Order Book Depth', fontsize=16)
plt.xlabel('Price', fontsize=12)
plt.ylabel('Cumulative Quantity', fontsize=12)
plt.legend(fontsize=10)
plt.grid(True, linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()
cell output

Conclusion

This notebook has introduced the fundamental concepts of Level 2 order book data, including its structure, key metrics like bid-ask spread, mid-price, and cumulative depth, and methods for visualizing this data. Analyzing Level 2 data is essential for understanding market microstructure, liquidity, and potential price movements in dynamic financial markets.

Level2 Data Fetch · BitPredict