How ArbDesk works
Written for someone who did not build it. No SQL, no jargon that is not explained. The parts about your database — what is filled, what is empty, when it last updated — are read live, so this page is never out of date about your own desk.
What this is
ArbDesk trades one kind of bet: how hot will it get in a city today. Polymarket runs a market for each city each day, split into temperature buckets — 70–71°F, 72–73°F, and so on. You buy the bucket you think will win. If the day's highest temperature lands in your bucket, it pays out; otherwise it is worth nothing.
The whole desk exists to answer one question better than the market does: which bucket will win, and is it priced too cheaply right now?
Nothing here trades real money on its own. It writes down what it would do, and every strategy ships switched off.
How it works, end to end
Five steps, in order. Each one needs the one before it.
- 1Collect. Jobs fetch the weather (what it is now, what it was, what the forecast says) and the market (which buckets exist, what they cost, what has traded). This is the only part that talks to the outside world.
- 2Learn. From the days that have finished, work out how wrong each forecast usually is for each city, what hour each city peaks, and how fast it warms. This is the desk's advantage and it only exists once enough days have finished.
- 3Predict. Take today's public forecast, apply the correction learned in step 2, and turn it into a probability for every bucket — not one number but a spread, because a forecast two days out is less certain than one made this morning.
- 4Compare. Put that probability next to what the market charges. The gap is the edge. Then subtract what it would really cost to trade: fees, and the fact that buying moves the price against you.
- 5Decide. A strategy is a rule about when an edge is worth taking. Each writes down what it would do. Nothing is automatic and nothing is real money.
Every page, and when to open it
The desk in one screen: what is happening now, what needs attention, and whether the machinery is running.
Every live bucket in every city, with the desk's probability next to the market's price. This is the trading screen.
Only the buckets worth looking at, ranked, with what a real order would actually fill at rather than the headline price.
Was the forecast right, and did being right pay? Those are different questions. Actual against predicted, error by how far ahead the call was, and whether edges scale.
What the archive has established, in sentences, each with the evidence behind it — and whether the learning chain is up to date. The Learn button lives here.
Every trading rule, what it is waiting for, its record, and a switch. All ship off.
Which cities move together. Ten positions across cities under one weather system is not ten bets.
The cities under real daylight. Which are inside their peak window right now, and which whole regions are hot together.
What each city is doing right now against what it normally does, and how much climb is usually left at this hour.
One city in detail: today's path, its forecast, its buckets, its history.
Is the model honest? When it says 70%, does it happen 70% of the time — and where does it go wrong.
Everything the desk has collected and frozen, and how much of it there is.
Run a strategy over history. It now tells you whether the window has data in it before you spend twenty minutes finding out.
One strategy, pointed at some cities, for a window, with its own P&L — and a live view of what it would take right now.
Work backwards from an amount you want to make to the trades that would get there, sized so the venue will actually accept them.
Every job, when it last ran, what it wrote, and a button to run it now.
The jobs that fill it
Nothing appears on its own. Every table is written by a named job, and there are two kinds. GitHub Actions run in this repository on a schedule and do the thinking — learning, scoring, backtesting. n8n workflows run wherever you host n8n and do the fetching — weather and market data. Both are listed on Workflows.
| Job | Kind | How often | Fills |
|---|---|---|---|
| Archive Observations | GitHub Action | on a schedule (0 3 1 * *) | derived_city_day_features, derived_climb_profile |
| Backtest | GitHub Action | only when you run it | backtest_results, backtest_trades |
| Daily Pipeline (forecasts, settlement, skill, databank, derived) | GitHub Action | daily | backtest_results, backtest_trades, derived_calibration_adjustment, derived_capacity, derived_city_climate, derived_city_correlation, derived_city_day_features, derived_climb_profile, derived_forecast_skill, derived_forecast_skill_model, derived_weather_peak, fact_band_outcome, fact_forecast_outcome, fact_signal_outcome, paper_activity, paper_position_settlements, paper_resolution_evidence, settings, weather_forecasts, weather_resolution_attempts, weather_resolution_evidence |
| Forecasts (Open-Meteo Previous Runs) | GitHub Action | daily | weather_forecasts |
| Intraday Pipeline (model, probabilities, edges) | GitHub Action | daily | anomalies, band_probabilities, derived_model_forecast, derived_weather_model, edges, paper_activity, paper_book_evidence, paper_orders, paper_position_settlements, paper_positions, paper_resolution_evidence, paper_trade_plans, research_captures |
| Live Weather Monitor | GitHub Action | only when you run it | live_weather, weather_events, weather_observations |
| Observations (IEM METAR) | GitHub Action | daily | weather_observations |
| Verify Resolution Source | GitHub Action | only when you run it | ledger |
| Weather Model | GitHub Action | weekly | derived_model_forecast, derived_weather_model |
| AD4 - P1.1 Live Weather Alerts | n8n | whenever its n8n schedule fires | weather_events |
| AD4 P0.2 - Market Discovery | n8n | whenever its n8n schedule fires | bands, markets |
| AD4 P0.3 - Book + Volume Snapshot | n8n | whenever its n8n schedule fires | book_snapshots |
| AD4 P0.4 - Trade History | n8n | whenever its n8n schedule fires | derived_band_day_volume, derived_city_day_volume, trades_observed |
| AD4 P0.5 - Refresh Rules Text | n8n | whenever its n8n schedule fires | markets |
| AD4 P1.2 - NWS Monitor | n8n | whenever its n8n schedule fires | cities, live_weather, weather_events, weather_observations |
| AD4 P1.3 - NWS Forecast | n8n | whenever its n8n schedule fires | cities, weather_forecasts |
| AD4 P1.4 - NWS Gridpoint | n8n | whenever its n8n schedule fires | weather_forecast_features |
| AD4 P1.5 - Open-Meteo Global | n8n | whenever its n8n schedule fires | live_weather, weather_forecast_features, weather_forecasts |
| AD4 P2.2 - Paper Maintenance | n8n | whenever its n8n schedule fires | paper_activity |
When a page is empty
An empty panel is not a bug by default. It means one of three things, and every panel now tells you which:
- Not installed — the table does not exist. A SQL file has not been run. The panel names which one.
- No data yet — the table exists and nothing has filled it. The panel names the job and where its button is.
- Stale — it was filled and stopped. The job has failed or is switched off.
Setting it up, in order
- 1Run the SQL. In the Supabase SQL editor, run the files in
sql/in the order listed insql/INSTALL_ORDER.txt. They are all safe to run again, so if you lose your place, start over. If a page is red afterwards, runsql/ad4_98_ui_health.sql— it lists every missing table, the file that creates it, and the pages it breaks. - 2Set the keys. The web app needs
NEXT_PUBLIC_SUPABASE_URLandNEXT_PUBLIC_SUPABASE_ANON_KEY. GitHub Actions needsSUPABASE_URLandSUPABASE_SERVICE_KEYas repository secrets. See the safety section below — the two keys are not interchangeable. - 3Import the workflows. Import each file in
n8n/into n8n. Open its Config node and fill in your Supabase URL and the service key. Activate it, copy its Production webhook URL, and paste it on the Workflows page so the app can run it. - 4Collect for a while. Nothing can be learned from a day that has not finished. Let the collectors run for a couple of weeks. The Synthesis page shows each finding filling up toward the point where it is worth believing.
- 5Then learn. Press Learn from what has settled on Synthesis, or run the four learning Actions in order yourself. Only after that do the probabilities mean anything.
permission denied for table … (42501) means the database has not granted write access to the key the workflow is using. Run sql/ad4_38_grants.sql — it grants the write path back and then prints one row per table saying whether the service key can write it.Keys, and the one rule about them
Supabase gives you two keys and they are not interchangeable. Mixing them up is the single most expensive mistake available here.
Can read, cannot write. It is meant to be in the browser, which is why it goes in NEXT_PUBLIC_SUPABASE_ANON_KEY. Anyone who opens the site can see it, and that is fine.
Can do anything, including delete everything. It belongs in exactly two places: the GitHub secret SUPABASE_SERVICE_KEY, and the Config node inside n8n.
NEXT_PUBLIC_ is compiled into the JavaScript the browser downloads. Putting the service key there publishes it to everyone who opens the site. There is no way to un-publish it — the key has to be rotated. The app refuses to send a request at all if it detects a secret key in the browser, and says so at the top of every page.The same rule covers the GitHub token used by the Relearn workflow: it lives in n8n, and the button on Synthesis calls n8n rather than GitHub. A page that could start a build would be a page carrying a credential.
Words used here
- Bucket (band)
- One temperature range you can bet on, like 72–73°F. A market is a row of them and exactly one wins.
- Edge
- The gap between what the desk thinks a bucket is worth and what it costs. 5 points means the desk says 45% and the market charges 40¢.
- Net edge
- The same gap after fees and after the price moves against you as you buy. This is the only one that means anything.
- The book
- The list of prices people are actually offering. A big order eats through it and pays worse than the headline price.
- Depth
- How much money you can put in before the price moves against you by a given amount. Thin markets have almost none.
- Peak window
- The hours around local solar afternoon when the day's maximum is made. Before it, the day is undecided; after it, it is done.
- Sigma (σ)
- How unusual today is for that city, in its own terms. +2σ is a genuinely hot day for that city, whether that is Chicago or Beirut.
- Bias
- A forecast being wrong in the same direction every time. Fixable — you subtract it. Different from error, which is being wrong in random directions.
- Calibration
- Whether a stated probability is honest. If everything called 70% happens about 70% of the time, the model is calibrated.
- Persistence
- Guessing today will be like yesterday. It is free and surprisingly good, so it is the bar any model has to beat.
- Settled
- The day is over, the market has paid out, and the result is written down. Nothing can be learned from a day until it settles.
- Paper trade
- A trade written down but not placed. Everything here is paper.