Skip to content

algotrade-plutus/PostLOBI

Repository files navigation

VN30 Futures Post-Lunch Order-Book Imbalance Hypothesis

Test whether strong positive top-3 bid-ask imbalance during 13:00–13:25, combined with a bottom-quartile spread, predicts a positive 5-minute midprice return in VN30 futures.

Abstract

This project evaluates a post-lunch microstructure hypothesis on VN30 futures. For each eligible order-book snapshot, it sums visible top-3 bid and ask quantities, computes top-of-book spread and depth-1 midprice, and marks a signal when the snapshot occurs in the post-lunch window 13:00:00 to 13:25:00, the normalized imbalance is greater than 0.2, and the spread is in the bottom 25% of post-lunch spreads for that month. The 5-minute forward return is measured using the first available quote at or after the 5-minute horizon within a 30-second tolerance.

The study is developed and evaluated end-to-end on committed HERMES VN30 futures order-book data from 2023-01 to 2026-06, following the 9-step Development Process and in a structure compatible with the Plutus Reproducibility Standard. On the in-sample period (2023-01 to 2024-12), the signal has average 5-minute return 0.00009922, compared with 0.00007336 for other post-lunch rows, for a return spread of 0.00002586. On the out-of-sample period (2025-01 to 2026-06), the signal has average 5-minute return 0.00009593, compared with 0.00007516 for other post-lunch rows, for a return spread of 0.00002077. The repo includes the scripts, committed inputs, committed derived dataset, committed result artifacts, and .plutus/manifest.yaml needed to reproduce the analysis workflow.

Introduction

Visible order-book pressure often contains short-horizon information, but signal quality varies by time of day and by liquidity conditions. The post-lunch period is a natural regime to test separately because it avoids the pre-break discontinuity and may reflect the market re-forming after the midday pause. This project tests whether a stronger-than-zero bid-side imbalance, combined with a tight spread, identifies more favorable 5-minute forward returns in that window.

The analysis stays deliberately simple: no trained model, no parameter optimization, and no execution-cost model yet. The goal is to determine whether a clearly defined order-book condition contains predictive information that is stable enough in-sample and out-of-sample to justify deeper strategy work.

1. Forming Algorithm Hypothesis

The testable hypothesis is:

During 13:00:00 to 13:25:00, if the visible top-3 bid-ask imbalance is greater than 0.2 and the spread is in the bottom 25% of spreads for that month, then the next 5-minute futures midprice return is positive.

Let

$$ B_t = \sum_{d=1}^{3} q^{bid}_{t,d}, \qquad A_t = \sum_{d=1}^{3} q^{ask}_{t,d} $$

and define the normalized imbalance

$$ I_t = \frac{B_t - A_t}{B_t + A_t}. $$

Let the depth-1 spread and midprice be

$$ S_t = P^{ask}_{t,1} - P^{bid}_{t,1}, \qquad M_t = \frac{P^{bid}_{t,1} + P^{ask}_{t,1}}{2}. $$

For each month, define the post-lunch spread threshold as the 25th percentile of observed spreads within the 13:00:00 to 13:25:00 window:

$$ Q_{0.25,m} = \text{25th percentile of } S_t \text{ within month } m \text{ and post-lunch rows}. $$

The binary signal is

$$ L_t = \mathbf{1}[t \in [13{:}00{:}00, 13{:}25{:}00] \land I_t > 0.2 \land S_t \le Q_{0.25,m}]. $$

The 5-minute forward return is

$$ R_{t,5m} = \frac{M_{t^+ + 5m}}{M_t} - 1, $$

where $M_{t^+ + 5m}$ is the first available future midprice quote at or after $t + 5$ minutes, subject to a maximum delay of 30 seconds. The main claim being tested is

$$ \mathbb{E}[R_{t,5m} \mid L_t = 1] > 0. $$

A secondary relative comparison is also reported:

$$ \mathbb{E}[R_{t,5m} \mid L_t = 1] > \mathbb{E}[R_{t,5m} \mid L_t = 0,\ t \in \text{post-lunch window}]. $$

2. Data Preparation

  • Source: committed HERMES VN30 futures parquet data under HERMES_DATA_ROOT/merged/derivatives_orderbook/ and HERMES_DATA_ROOT/merged/derivatives_orderbook_size/.
  • Period: raw order-book-size coverage used here is 2023-01 to 2026-06; in-sample is 2023-01 to 2024-12; out-of-sample is 2025-01 to 2026-06.
  • Fees: none. This is a predictive hypothesis study, not yet a cost-aware executable trading strategy.

The raw data is committed in the repository. scripts/build_orderbook_5m_dataset.py transforms it into a derived monthly parquet dataset under derived/orderbook_top3_5m_dataset/ with one row per eligible (datetime, tickersymbol) snapshot. Each row includes total bid volume, total ask volume, imbalance, best bid, best ask, spread, current midprice, future midprice, and future 5-minute return.

Obtaining the data

The required data is already committed in this repository, so no credentials are needed. The relevant layout is:

.
├── HERMES_DATA_ROOT
│   └── merged
│       ├── derivatives_orderbook
│       │   └── month=YYYY-MM.parquet
│       └── derivatives_orderbook_size
│           └── month=YYYY-MM.parquet
└── derived
    └── orderbook_top3_5m_dataset
        └── month=YYYY-MM.parquet

To rebuild the derived dataset from raw committed parquet files, run:

python scripts/build_orderbook_5m_dataset.py --output-root derived/orderbook_top3_5m_dataset

3. Forming Set of Rules

This project evaluates a fixed post-lunch hypothesis rather than a cost-aware live strategy. The executable rules used in the study are:

  • Observation unit: every committed order-book snapshot for which top-3 bid and ask sizes are available and a valid future quote exists.
  • Post-lunch filter: keep rows with market_time between 13:00:00 and 13:25:00 inclusive.
  • Tight-spread filter: within each month, compute the 25th percentile of post-lunch spreads and require spread <= spread_q25.
  • Signal: set lunch_signal = 1 when imbalance > 0.2 and the tight-spread condition holds; otherwise lunch_signal = 0 within the post-lunch window.
  • Return target: compute future_5m_return = future_midprice_5m / current_midprice - 1.
  • Forward-price matching: use the first quote at or after t + 5 minutes, with a maximum delay tolerance of 30 seconds.
  • Filtering: drop rows with no valid future midprice match.
  • Sizing: none. The output is a conditional return study, not a leveraged portfolio.
  • Cadence: event-based; the dataset uses every eligible snapshot.
  • Costs: none included at this stage.

Evaluation Metrics

The main reported metrics are:

  • Average Return Signal: mean future_5m_return for post-lunch rows satisfying imbalance > 0.2 and bottom-quartile spread.
  • Return Difference: signal average return minus average return for other post-lunch rows.
  • Hit Rate Difference: positive-return rate for signal rows minus positive-return rate for other post-lunch rows.
  • Monthly Positive Return-Diff Share: fraction of months where the return difference is positive.

Implementation & Reproducibility

The pipeline is implemented as standalone Python scripts:

  • scripts/build_orderbook_5m_dataset.py
  • scripts/evaluate_lunch_imbalance_hypothesis.py

Environment setup

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Dependencies are pinned in requirements.txt.

Reproducibility

Run the full workflow directly:

python scripts/build_orderbook_5m_dataset.py --output-root derived/orderbook_top3_5m_dataset

python scripts/evaluate_lunch_imbalance_hypothesis.py \
  --start-month 2023-01 \
  --end-month 2024-12 \
  --output-dir result/in_sample \
  --label in-sample

python scripts/evaluate_lunch_imbalance_hypothesis.py \
  --start-month 2025-01 \
  --end-month 2026-06 \
  --output-dir result/out_of_sample \
  --label out-of-sample

The repository also includes .plutus/manifest.yaml, which encodes the same environment, local data source, commands, outputs, and expected metrics so the workflow can be checked with plutus check . in a compatible Plutus environment.

4. In-sample Backtesting

The in-sample evaluation reads derived/orderbook_top3_5m_dataset/ and aggregates months 2023-01 through 2024-12.

python scripts/evaluate_lunch_imbalance_hypothesis.py \
  --start-month 2023-01 \
  --end-month 2024-12 \
  --output-dir result/in_sample \
  --label in-sample

Artifacts are written to result/in_sample/.

In-sample result (2023-01 to 2024-12)

Metric Value
Average Return Signal 0.00009922
Return Difference 0.00002586
Hit Rate Difference 0.016635
Monthly Positive Return-Diff Share 0.583333

Average 5-minute return in the post-lunch window by signal — result/in_sample/avg_return_by_signal.svg

In-sample average return by signal

Monthly post-lunch return difference (signal minus other post-lunch rows) — result/in_sample/monthly_return_difference.svg

In-sample monthly return difference

5. Out-of-sample Backtesting

The out-of-sample evaluation uses months 2025-01 through 2026-06 with the same fixed hypothesis and no parameter tuning.

python scripts/evaluate_lunch_imbalance_hypothesis.py \
  --start-month 2025-01 \
  --end-month 2026-06 \
  --output-dir result/out_of_sample \
  --label out-of-sample

Out-of-sample result (2025-01 to 2026-06)

Metric Value
Average Return Signal 0.00009593
Return Difference 0.00002077
Hit Rate Difference 0.012159
Monthly Positive Return-Diff Share 0.722222

Average 5-minute return in the post-lunch window by signal — result/out_of_sample/avg_return_by_signal.svg

Out-of-sample average return by signal

Monthly post-lunch return difference (signal minus other post-lunch rows) — result/out_of_sample/monthly_return_difference.svg

Out-of-sample monthly return difference

Reference

[1] R. Cont, A. Kukanov, and S. Stoikov, “The Price Impact of Order Book Events,” Journal of Financial Econometrics, vol. 12, no. 1, pp. 47–88, 2014.

[2] J.-P. Bouchaud, J. Bonart, J. Donier, and M. Gould, Trades, Quotes and Prices: Financial Markets Under the Microscope. Cambridge University Press, 2018.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages