Quantitative Grand Exchange market advisor for Old School RuneScape. Built as a sandbox for
- testing the effectiveness of Claude code (everything in this repo was written by Claude code with my directives)
- quant finance workflows — signal research, backtesting, and portfolio construction — on top of a real (if small) market.
See docs/paper/osrs_market_overview.pdf for a write-up of the methodology.
GE slot data (current offers, fill status) requires two pieces of software not in requirements.txt:
- RuneLite — open-source OSRS client. The slot tracker reads data written by RuneLite plugins.
- Flipping Utilities — RuneLite plugin that logs offer history to
~/.runelite/flipping/<character>.json.trade.pyreads this for slot state.
conda create -n osrs_trader python=3.12 -y
conda activate osrs_trader
pip install -r requirements.txtThe main entry point is trade.py, a live terminal advisor that shows GE slot actions and ranked buy candidates.
python trade.py # live view, refreshes every 5 min
python trade.py --gp 10M # set capital (K/M/B suffixes accepted)
python trade.py --interval 10 # custom refresh interval (minutes)
python trade.py --top 8 # show up to 8 buy candidates
python trade.py --simple # hide the detailed opportunity breakdown
python trade.py --once # single render and exit
python trade.py --study "dragon bones" # deep-dive on one item instead of buy panel
python trade.py --study 534 # deep-dive by item IDWhile the live view is running, type a command and press Enter:
1–8— open HTML study for GE slot Nb1–b6— open HTML study for buy candidate N- any item name or ID — open HTML study for that item
To refresh prices manually: python data/update_prices.py
Find low-volume items where you can place a resting buy offer well below market price and be the only buyer in the queue.
python snipe_candidates.py # defaults: vol/hr ≤ 10, mid ≥ 200K
python snipe_candidates.py --min-price 5M --max-price 100M # filter by price range
python snipe_candidates.py --max-vol 3 --top 30 # tighter volume filterSorted by time since last trade (stalest first). Columns: last trade age, mid/high/low price, avg vol/hr (6h window), spread %, buy limit.
Interactive visualisation of all free GE conversions (armour sets, godswords, jewelry chains, potion doses). Edges are coloured by ROI on a diverging red→grey→green scale.
python plot_item_graph.py # saves dashboard/item_graph.html, then opens itScripts for validating signal performance against historical price data. Results are saved to signal_validation/logs/.
python signal_validation/calibrate_momentum.py # calibrate momentum thresholds
python signal_validation/calibrate_momentum_comprehensive.py # extended sweep (window + thresholds)Signal health as of Mar 2026:
| Metric | Definition | Value |
|---|---|---|
| Hit rate | Fraction of directional predictions (up/down) that were correct | 19/22 = 86.4%, p = 0.0004 |
| ICIR | Information coefficient (IC) information ratio — IC is the Pearson correlation between predicted direction and actual return; ICIR is mean IC divided by its standard deviation, measuring consistency of predictive skill | +0.751 |
| MR Sharpe | Mean return divided by return volatility for the mean-reversion signal (prices reverting toward a rolling average) | +0.46 |
| MOM Sharpe | Same metric for the momentum signal (trending price continuation) | −0.59 |
Planned (see signal_validation/README.md): hit rate test, information coefficient test, walk-forward test, Sharpe t-test, parameter sweep, log analysis script.
This project ships with a CLAUDE.md that configures a Claude Code agent. The agent has deep context about both the codebase and OSRS itself — it is equally useful as a GE trading advisor, a PvM advisor, and a coding assistant.
claude # from the project rootAt the start of every session the agent reads 8 knowledge base files from agent_kb/ before doing anything else:
| File | Contents |
|---|---|
agent_kb/game/OSRS_OVERVIEW.md |
What OSRS is, player archetypes, skills, quests, game modes, recent updates, roadmap |
agent_kb/game/pvm/COMBAT_MECHANICS.md |
Combat system, gear selection principles, expert techniques (prayer flick, tick manipulation) |
agent_kb/game/pvm/GEAR_REFERENCE.md |
Weapon/armour stats, gear progression paths, counterintuitive facts |
agent_kb/ge/GE_MECHANICS.md |
GE order matching, tax formula, buy limits, item sink, slot management |
agent_kb/ge/GE_MARKET_DYNAMICS.md |
Trading strategies, supply chains, market tiers, manipulation clans, seasonal patterns |
agent_kb/ge/GE_SIGNAL_METHODOLOGY.md |
S1–S6 signal taxonomy, reasoning protocol, ROI/day formula, signal combining rules |
agent_kb/ge/GE_PREDICTIONS.md |
Active price predictions — updated after each major update or weekly scan |
agent_kb/dev/ECONOMY_RESEARCH_PLAN.md |
Phased research plan; agent auto-executes the next incomplete phase each session |
Additional files are loaded on demand when the conversation topic calls for them:
| File | Loaded when discussing… |
|---|---|
agent_kb/game/pvm/bosses/RAIDS.md |
CoX, ToB, ToA |
agent_kb/game/pvm/bosses/WORLD_BOSSES.md |
GWD, Nex, Nightmare, DKS, Barrows, Hueycoatl |
agent_kb/game/pvm/bosses/INSTANCED_BOSSES.md |
Vorkath, Zulrah, Yama, Doom, Royal Titans |
agent_kb/game/pvm/bosses/DT2_BOSSES.md |
Vardorvis, Duke, Leviathan, Whisperer |
agent_kb/game/pvm/bosses/SLAYER_BOSSES.md |
Cerberus, Hydra, Araxxor, Corp, etc. |
agent_kb/game/pvm/bosses/WILDERNESS_BOSSES.md |
Wilderness bosses, Revenants |
agent_kb/game/pvm/bosses/MINIGAME_BOSSES.md |
Gauntlet, Corrupted Gauntlet, Fortis Colosseum |
agent_kb/game/pvm/GP_METHODS.md |
Top PvM GP/hr methods |
agent_kb/game/pvp/PVP.md |
Wilderness, PvP mechanics, spec weapons |
agent_kb/game/skilling/SKILLING.md |
All 24 skills: training methods, economic relevance |
After loading the knowledge base, the agent asks three optional drills:
- Wiki scan — fetches 30 random OSRS wiki pages, extracts mechanically important facts not yet in the KB, and commits them.
- Boss drill — picks a random boss, answers gear strategy at four tiers (low / mid / high / BiS), fact-checks against the wiki, and corrects any errors.
- Skill drill — picks a random skill, deep-dives training methods and GE supply-chain effects, updates
SKILLING.md, and commits.
Answer yes or no to each. The agent also auto-executes the next incomplete phase from ECONOMY_RESEARCH_PLAN.md without asking.
GE / trading
What should I flip with 10M GP?
Which items are showing mean-reversion signals right now?
Predict what happens to [item] after the latest update.
Explain the margin calculation for [item].
What does the S1 signal taxonomy mean?
PvM / game knowledge
What's the BiS melee setup for Bandos?
How do I gear for Vorkath on a budget?
What bosses drop the best GP/hr for a main?
Explain how the Tumeken's Shadow multiplier works.
What gear do I bring to Chambers of Xeric at mid-level?
Codebase
Why is item 12345 classified as TRENDING?
Walk me through how get_buy_candidates() works.
Add a new signal to the scanner.
Fix the crash I'm seeing in trade.py.
Run the signal validation suite and explain the results.
The agent_kb/ directory is the agent's domain knowledge — it is read by the agent, not by the Python code. Keeping it up to date is the mechanism by which the agent learns about new game updates, price predictions, and methodology changes.
agent_kb/
├── game/
│ ├── OSRS_OVERVIEW.md
│ ├── pvm/
│ │ ├── COMBAT_MECHANICS.md
│ │ ├── GEAR_REFERENCE.md
│ │ ├── ACCOUNT_BUILDS.md
│ │ ├── GP_METHODS.md
│ │ └── bosses/ ← one file per boss category
│ ├── pvp/PVP.md
│ └── skilling/SKILLING.md
├── ge/
│ ├── GE_MECHANICS.md
│ ├── GE_MARKET_DYNAMICS.md
│ ├── GE_SIGNAL_METHODOLOGY.md
│ ├── GE_PREDICTIONS.md
│ └── GE_BACKTEST.md
└── dev/
├── ECONOMY_RESEARCH_PLAN.md
├── KNOWLEDGE_TEST.md
└── NOTES.md
- docs/api_data.md —
data/modules (WikiClient, cache, Flipping Utilities reader) - docs/api_market.md —
market/modules (scan, slots, study, HTML dashboard) - docs/api_analysis.md —
analysis/modules (regime classifier, 24h scanner, momentum signal) - docs/api_display.md —
display/modules (Rich renderables)
osrs_trader/
├── trade.py ← main live advisor (slots + buy candidates)
├── plot_item_graph.py ← interactive item conversion graph (saves dashboard/item_graph.html)
├── snipe_candidates.py ← low-volume GE items susceptible to snipe offers
├── config.py ← all tunable parameters
├── data/
│ ├── api.py ← OSRS Wiki API client
│ ├── cache.py ← parquet cache with TTL
│ ├── item_graph.json ← conversion data (armour sets, godswords, jewelry chains, potions)
│ ├── item_graph.py ← ItemGraph class (load, arbitrage, NetworkX graph)
│ ├── update_prices.py ← refresh data/prices.csv
│ └── read_flipping_utils.py ← read Flipping Utilities JSON for slot state
├── market/
│ ├── scan.py ← candidate scoring and buy recommendations
│ ├── study.py ← deep-dive analysis for a single item
│ ├── slots.py ← GE slot state + RAISE/LOWER/ABORT advice
│ ├── html_study.py ← generate Plotly HTML dashboard for an item
│ ├── prices.py ← price fetching and resolution helpers
│ └── types.py ← shared dataclasses
├── display/
│ └── tables.py ← Rich renderables for trade.py
├── analysis/
│ ├── scanner.py ← bulk scorer, regime-aware signal routing
│ ├── regime.py ← ADF + linear R² regime classifier
│ └── momentum.py ← momentum signal features
├── signal_validation/
├── agent_kb/ ← knowledge base (game + GE market + dev notes)
└── docs/
├── paper/ ← LaTeX write-ups and figures
└── images/ ← screenshots
