Midwicket # Midwicket ### Cricket Analytics for Python

20,888+ Matches  ·  9,148,005+ Deliveries  ·  25+ Years of Coverage

Open In Colab   PyPI   CI   Python   MIT

Ball-by-ball cricket analytics. Local. Fast. No cloud required.


Why Midwicket?

Real findings from the IPL corpus:

Finding
Virat Kohli's 2026 IPL season (155.6 SR) is his fastest ever — at age 37
Sixes per match nearly doubled — 10.7 (2008) → 19.3 (2026) — while dot ball % fell 5.4 points
Vaibhav Suryavanshi: 211 SR in Powerplay — the highest ever recorded in IPL
85% of IPL batters perform better when chasing than when setting a target
DW Steyn's 44.65% dot rate at 6.79 economy would be structurally impossible in 2024 IPL

See all 10 showcase analyses →


Quick Start

30 seconds. No data download. No account.

pip install midwicket
import midwicket.express as px

# Win probability — works instantly
result = px.predict_win(
    venue="Wankhede Stadium",
    target=180,
    current_score=120,
    wickets_down=5,
    overs_done=15.0,
)
print(f"Win probability: {result['win_prob']:.1%}")
# Win probability: 22.5%

That's it. No API key, no download.

Open in Colab → — zero-install, browser-based.


Loading Datasets

Load any major cricket dataset in one line.

from midwicket.datasets import load_dataset

# IPL — 1,100+ matches, 2008–present (~50 MB, downloads once)
session = load_dataset("ipl")

# Big Bash League
session = load_dataset("bbl")

# Everything — all formats, all genders, 25+ years
session = load_dataset("all")

Browse the registry:

from midwicket.datasets import list_datasets, describe_dataset

# See every registered dataset at a glance
for ds in list_datasets():
    print(f"{ds['name']:10s}  {ds['matches']:5d} matches  {ds['date_range']}")

# Full metadata for one dataset
info = describe_dataset("ipl")
print(info["description"])        # Indian Premier League — ...
print(info["statistics"])         # {'matches': 1100, 'deliveries': 480000, ...}
print(info["competitions"])       # ['Indian Premier League']
print(info["coverage"])           # complete
print(info["example_usage"])      # from midwicket.datasets import load_dataset ...

Available datasets:

Key Competition Matches Venues Range
"ipl" Indian Premier League 1,100+ 15 2008–2026
"t20is" T20 Internationals (M + W) 3,200+ 220 2005–2026
"bbl" Big Bash League 650+ 8 2011–2025
"psl" Pakistan Super League 350+ 8 2016–2025
"cpl" Caribbean Premier League 380+ 8 2013–2025
"wbbl" Women's Big Bash League 550+ 8 2015–2025
"odis" One Day Internationals 2,400+ 220 2002–2026
"tests" Test Matches 700+ 110 2004–2026
"all_t20" All T20 globally 8,500+ 380 2005–2026
"all" Complete corpus 20,000+ 450 2002–2026

Full catalog: docs/datasets.md

Once loaded, query ball-by-ball events with SQL:

df = session.engine.execute_sql("""
    SELECT batter,
           SUM(runs_batter) AS runs,
           ROUND(SUM(runs_batter) * 100.0 / COUNT(*), 1) AS strike_rate,
           COUNT(DISTINCT match_id) AS matches
    FROM ball_events
    WHERE over >= 15              -- death overs only
    GROUP BY batter
    HAVING COUNT(*) >= 100
    ORDER BY runs DESC LIMIT 10
""").to_pandas()

Feature Store

Six production-grade metrics:

from midwicket.features import (
    build_pressure_index,
    build_bowler_quality_rating,
    build_match_context_score,
    build_venue_bias_rating,
    build_batter_intent_score,
    build_expected_runs,
)

# Pressure Index — situational leverage per delivery
pi = build_pressure_index(session)
# Returns DataFrame: match_id, inning, over, ball, batter_id, bowler_id, pressure_index

# Bowler Quality Rating — dot balls + wicket rate combined
bqr = build_bowler_quality_rating(session)
# Returns DataFrame: bowler_id, total_balls, dot_balls, wickets, bowler_quality_rating

# Venue Bias Rating — batter-friendly vs bowler-friendly grounds
vbr = build_venue_bias_rating(session)
# VBR > 1.0 = batter-friendly  |  VBR < 1.0 = bowler-friendly

# Match Context Score — chase pressure at any moment in the 2nd innings
mcs = build_match_context_score(session)

All features support date filtering:

bqr_2023 = build_bowler_quality_rating(session, start_date="2023-01-01", end_date="2023-12-31")

Scouting Reports

import midwicket as md

session = md.init("./data")          # point at your local dataset
report = md.scouting_report("Virat Kohli")

print(report["role"])                # "Batter"
print(report["strengths"])           # ["Powerplay anchor", "Middle-over accelerator", ...]
print(report["phase_batting"])       # {"Powerplay": {...}, "Middle": {...}, "Death": {...}}
print(report["venue_performance"])   # per-venue batting average and SR
print(report["recent_form"])         # last-N-matches rolling stats

Names work in any form — "V Kohli", "Virat Kohli", "kohli" all return the same report.


Showcase Gallery

Ten analyses built on real IPL data. Click any image to see the full walkthrough.

**All-Time Run Leaders** [![Run Leaders](docs/showcases/01_run_leaders/01_run_leaders.png)](docs/showcases/01_run_leaders/WALKTHROUGH.md) Kohli's 9,228 runs lead by 1,897. Bars coloured by strike rate — greener hits faster. **IPL Scoring: 18 Years of Evolution** [![Season Trends](docs/showcases/10_season_trends/10_season_trends.png)](docs/showcases/10_season_trends/WALKTHROUGH.md) Avg 1st innings: 161 (2008) → 192 (2026). Sixes per match nearly doubled.
**Venue Scoring Atlas (76 grounds)** [![Venue Atlas](docs/showcases/04_venue_atlas/04_venue_atlas.png)](docs/showcases/04_venue_atlas/WALKTHROUGH.md) VBR 0.848 → 1.253 across IPL grounds. 40% swing in expected scoring. **Death Over Bowler Landscape** [![Death Bowlers](docs/showcases/03_bumrah_death/03_death_bowlers.png)](docs/showcases/03_bumrah_death/WALKTHROUGH.md) 141 bowlers, economy vs wicket rate. Bumrah: #11, economy 8.07.
**Chase Specialists** [![Chase Scatter](docs/showcases/07_chase_specialists/07_chase_scatter.png)](docs/showcases/07_chase_specialists/WALKTHROUGH.md) 85%+ of batters hit harder when chasing. Pat Cummins: +46 SR points. **Powerplay Kings** [![Powerplay Kings](docs/showcases/06_powerplay_kings/06_pp_kings.png)](docs/showcases/06_powerplay_kings/WALKTHROUGH.md) Suryavanshi: 211 SR — the highest ever recorded in IPL powerplay.

View all 10 showcases with charts, queries, and walkthroughs →


Five-Minute Tutorial

New to Midwicket? docs/getting_started.md takes you from install to first insight in under 5 minutes — using real data, real outputs.


Examples

The examples/ directory contains 36 runnable scripts organised by complexity:

Scripts Topic
01–05 Session setup, data ingest, player lookup, venue stats
06–15 Win prediction, fantasy points, SQL queries, season filters
16–27 Leaderboards, partnerships, consistency, full pipeline demos
28–36 Express API, config, debug, full library tour
showcase_01–25 Deep-dive analyses with charts and findings
portfolio/ 14 player and team scouting studies

Start here: examples/28_express_quickstart.py


Contributing

Contributions welcome. Areas where help is most needed:

  • Additional competition datasets (WBBL scouting, CPL analysis)
  • Jupyter notebook tutorials for the showcase analyses
  • Performance benchmarks across dataset sizes
  • Documentation translations

Read CONTRIBUTING.md before submitting a PR.


**MIT License** · Built on [Cricsheet](https://cricsheet.org/) data · Powered by [DuckDB](https://duckdb.org/) + [PyArrow](https://arrow.apache.org/docs/python/) [Getting Started](docs/getting_started.md) · [Showcase Gallery](docs/gallery.md) · [API Reference](docs/api.md) · [Changelog](CHANGELOG.md) **Built by Srijan Upadhyay with ❤️**

Built With

Share this project:

Updates