Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🛳️ PortOpt — Container Terminal Volume Forecasting

Python statsmodels OR-Tools Streamlit License

How many containers will a deep-sea terminal handle next week — and what should it do about it?

A SARIMAX model forecasts weekly container volume from five years of history plus named, dated drivers. The forecast is monitored the way a production model has to be. And it then sizes a berth and crane plan, because a volume forecast is only worth something if a decision hangs off it.

Inspired by automated deep-sea container terminals in the Port of Rotterdam. All data is synthetic; not affiliated with or endorsed by any terminal operator.

The drivers are real, dated events

Seasonality alone cannot explain a container terminal. These go in as exogenous regressors, and the app shows what the model learned from each:

Driver What it is Learned effect
Chinese New Year Asian factories shut for ~2 weeks; Rotterdam feels the gap ~5 weeks later, one sailing time downstream −18% on a week's volume, tight interval, highly significant
Pre-CNY rush Shippers pull cargo forward before the shutdown +9%, significant
Red Sea rerouting Since Dec 2023 carriers route Asia–Europe around the Cape of Good Hope. As of mid-2026 that is still the baseline in MSC's and CMA CGM's network design, with Maersk transiting Suez selectively −6%, significant — and switchable as a scenario
A16 heavy-truck restriction Since 1 July 2026 trucks over 45 t are barred from the J.F. Kennedy viaduct while the Van Brienenoord bridge is renewed; landside collection shifts to barge and rail not estimable yet — two weeks of data, and the app says so instead of inventing a number

That last row is deliberate. A model that reports a confident coefficient after a fortnight of data is lying; showing the interval instead is the point.

Two modelling choices worth defending

  1. Fit on log volume. Holidays, reroutings and storms act proportionally, not in absolute boxes. Logs make the model additive and every coefficient readable as a percentage.
  2. Fourier terms, not a seasonal ARIMA order. Weekly data has period 52; a (P,D,Q,52) term would estimate 52 lags from five years of data and overfit. Two sine/cosine pairs capture the annual shape with four parameters.

The rest is deliberately plain: ARIMA(1,1,1) errors with drift. d=1 was chosen by testing — d=0 variants scored worse on AIC and produced significant but wrong coefficients, which is the failure mode that actually hurts.

Honest numbers

Accuracy is measured by rolling-origin backtest: refit at each cut-off and score only weeks the model never saw.

  • MAPE 4.2%, bias −0.3%, stable across a 4-week horizon.
  • Storms and incidents are not model inputs — nobody forecasts a gale thirteen weeks out. They land in the residuals, where the outlier detector finds them: 10 weeks flagged, 8 of which already carry an operational note from the terminal's own log. That is the triage loop a production model needs: flag, explain, decide.
  • Drift is measured with PSI and a two-sample KS test on the recent error distribution versus the reference period, implemented in numpy so the maths stays inspectable.

The plan the forecast feeds

Take a week from the forecast and a CP-SAT model turns it into a berth and crane plan: which vessel berths where, with how many cranes, starting when.

  • Variables: x[v,b,k] vessel → berth with k cranes, s[v] start time.
  • Constraints: berth length and draft must fit the vessel · no overlap per berth · the shared crane pool is never oversubscribed at any moment (cumulative) · nothing starts before its ETA.
  • Objective: minimise demurrage for waiting plus penalties for departing after the requested time.
  • Handling time is 60 min berthing + moves / (cranes × productivity × η), where η falls away above four cranes because they interfere.

Benchmarked against handling vessels in arrival order — a real dispatcher's heuristic, which just cannot look ahead.

Quickstart

python -m venv .venv
# Windows: .venv\Scripts\activate     macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
streamlit run app.py

Optional: the assistant needs a free Groq key. Copy .streamlit/secrets.toml.example to .streamlit/secrets.toml. Without a key everything else still runs.

python scripts/selftest.py        # forecast recovery, monitoring, plan invariants
python scripts/ui_test.py         # headless UI test
python scripts/forecast_check.py  # learned vs. true effects, in detail

Project structure

app.py                    Streamlit UI: forecast, monitoring, capacity plan
forecast/
  data.py                 weekly history, anchored to published port magnitudes
  drivers.py              the dated real-world drivers and the exog matrix
  model.py                SARIMAX fit, forecast, backtest, contributions
  monitoring.py           residuals, rolling accuracy, outliers, PSI/KS drift
optimizer/
  data.py                 turns a forecast week into vessel calls
  model.py                CP-SAT berth allocation + crane assignment
  baseline.py             arrival-order benchmark
  kpis.py                 shared KPIs and the crane-usage profile
scripts/                  selftest, UI test, and the probes used to calibrate

From demo to production

  • Rolling re-forecast and re-optimisation as weeks close and ETAs update.
  • Drift as a gate, not a chart — past threshold, the plan waits for a human.
  • Terminal system integration — read volumes and calls from the operating system, write the accepted plan back, with a migration path that runs old and new data models side by side before cutting over.
  • Driver library — add and retire exogenous drivers as the world changes, with the interval on a new driver shown honestly until it earns its place.

Disclaimer

Educational portfolio project. The series is synthetic but anchored to published figures (Rotterdam handled 14.2 million TEU in 2025, +3.1%). Vessel names are real container-ship names used as flavour only. No real terminal, operator, schedule or customer data is involved.

About

QuayOpt - weekly container-throughput forecasting for a deep-sea terminal: SARIMAX with dated exogenous drivers, honest model monitoring, and a CP-SAT berth and crane plan. Live at portopt-rotterdam.streamlit.app

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages