~/kaustubh-lall

~/writing $ cat writing/mmg-daily-feasibility.md

MMG experiment log: daily-horizon feasibility

2026-07-03 · Experiment Logs · 2 min read

The first test of whether OSRS Grand Exchange prices carry a tradeable signal: a small, real directional edge on daily bars, 57.43% versus a 54.86% baseline, that a tax-aware backtest turned into a loss of 1,529,993 gp across 1,629 trades. No signal shipped.

Setup

The study's dataset came from a public Kaggle snapshot of Grand Exchange prices, CC BY 4.0 licensed: 1.55 million price observations spanning 4,420 items from 2021 to 2026. A 50-item spot check against Weird Gloop's independent archive agreed on daily direction 60.2% of the time, with a sub-1% median price gap between the two sources, enough to trust the primary dataset.

Six model types trained side by side on time-based splits with a purge-and-embargo gap between train and test: a persistence baseline, a smoothed trend model, ridge regression, gradient-boosted trees, a direction classifier, and a tax-hurdle classifier. A separate check of the tax and fee math itself ran 50,512 comparisons between the browser calculator and the backend, zero mismatches.

Result

57.43% of the classifier's daily direction calls landed correct, against a 54.86% baseline from always picking the majority class, a 2.51 to 2.90 percentage point edge that held up across all three walk-forward test regimes. A second model, built specifically to flag which moves would clear the full cost of a trade, scored a 0.727 ROC-AUC and turned in 45.7% precision on the calls it selected, against a 17.2% base rate, a 2.65x lift.

None of that translated into profit once a real backtest ran the numbers. The model's picks lost 1,529,993 gp across 1,629 trades: a 33.7% win rate and a -3.06% average return per trade. Even the single most confident pick, isolated by an uncertainty filter, lost money on its own.

Verdict

The verdict was blunt: no profitability claim, no automation, no live "buy now" badge, not from this model. That set the template going forward: ship what held up, volatility and spread forecasting, keep every trade recommendation out of the product, and rerun the same question on faster, higher-resolution data before calling it final.

No signal shipped from this study. The full story lives in the MMG case study.

mmg architectureTwo public price APIs, the OSRS Wiki real-time prices API and Weird Gloop's historical archive, feed a gap-healing collector daemon, which writes into a SQLite archive of five-minute, hourly, and daily price tables. A feature and label builder reads that archive and trains three model families: a direction classifier, quantile magnitude regressors, and volatility and spread risk models. A separate evaluation harness scores all of them with walk-forward validation. A static frontend on Cloudflare Pages serves the public product; an optional local backend serves the ML layer, but the deployed https site cannot reach an http localhost backend, so the frontend degrades gracefully when no local backend is running.OSRS Wiki prices API + Weird Gloop archivepublic, no auth · 5m/1h live bars + daily history to ~2015Collector daemon5m / 1h / daily polling, ~0.8 req/s · gap-heal on startup + hourly · idempotent writesSQLite archiveprice_5m / price_1h / daily_history: never pruned · audit tables: 90-day retentionFeature + label builder14 features/bucket · labels joined at wall-clock horizon · walk-forward, embargo ≥ horizonDirection classifierLightGBM: P(mid return ≥1% / 4h)Quantile magnitudeq10/q50/q90, conformal wideningVolatility + spreadrisk models, not yet in UIEvaluation harnessseparate eval-v2 repo · walk-forward scoring · PSI drift · champion/challengerStatic frontendCloudflare Pages · https · staticLocal helper backendFastAPI · localhost:8788 · httpblocked: https can't call http localhost (mixed content)

architecture · mmg · the static frontend also reads live prices directly from the public API at the top, independent of the collector and model pipeline below it

Related projects

← All writing