Simulates real Polymarket "Highest temperature in [City] on [Date]?" markets.
Uses live Wunderground data to find the best-value temperature bracket to bet on.
Vercel cron jobs check your positions against Polymarket prices every 30 minutes.
wxmarket/
├── app/
│ ├── page.tsx # Main React UI
│ ├── layout.tsx
│ ├── globals.css
│ ├── components/
│ │ ├── Header.tsx
│ │ ├── Sidebar.tsx
│ │ ├── MarketCard.tsx # 11-bin temperature bracket UI
│ │ ├── JobRunner.tsx # Job runner tab (manual + auto)
│ │ └── Portfolio.tsx
│ ├── hooks/
│ │ ├── useSession.ts # Stable localStorage session ID
│ │ └── usePortfolio.ts # Fetches state from Redis
│ ├── lib/
│ │ ├── types.ts
│ │ ├── constants.ts # Cities + Polymarket base URL
│ │ ├── redis.ts # Upstash Redis helpers
│ │ ├── weather.ts # Bin generation + fallback data
│ │ ├── polymarket.ts # Gamma API client
│ │ ├── analyze.ts # Fallback signal logic
│ │ └── job.ts # Core job: check positions vs PM
│ └── api/
│ ├── analyze/route.ts # POST — fetch weather + PM + signal
│ ├── trade/route.ts # POST — save trade to Redis
│ ├── portfolio/route.ts # GET — load full portfolio state
│ ├── check-positions/route.ts # POST — manual job trigger
│ └── cron/
│ ├── check-positions/route.ts # GET (cron, every 30 min)
│ └── daily-snapshot/route.ts # GET (cron, daily 2pm UTC)
├── vercel.json # Cron job schedule
└── .env.local.example
git clone <your-repo>
cd wxmarket
npm install- Go to console.upstash.com
- Create a new Redis database (pick the region closest to your Vercel deployment)
- Copy the REST URL and REST Token from the database details page
Copy .env.local.example to .env.local and fill in:
cp .env.local.example .env.localANTHROPIC_API_KEY=sk-ant-... # console.anthropic.com/settings/keys
UPSTASH_REDIS_REST_URL=https://... # from Upstash dashboard
UPSTASH_REDIS_REST_TOKEN=... # from Upstash dashboard
CRON_SECRET=some-random-string-here # any random string you choosenpm i -g vercel
vercelThen in the Vercel dashboard → Settings → Environment Variables, add the same 4 variables from your .env.local.
Important: The cron jobs require the
CRON_SECRETto also be set in Vercel's environment variables. Vercel automatically sendsAuthorization: Bearer <CRON_SECRET>to cron routes.
After deploying, go to your Vercel project → Cron Jobs tab.
You should see two jobs:
| Path | Schedule |
|---|---|
/api/cron/check-positions |
Every 30 minutes |
/api/cron/daily-snapshot |
Daily at 14:00 UTC |
To manually trigger a cron:
curl -H "Authorization: Bearer your-cron-secret" \
https://your-app.vercel.app/api/cron/check-positionsPolymarket lists "Highest temperature in [City] on [Date]?" markets with ~11 brackets of 2°F each (1°C for European cities). The market resolves to the bracket containing the official high temperature recorded at the city's designated airport weather station on Wunderground.
| City | Station |
|---|---|
| New York | KLGA (LaGuardia) |
| Chicago | KORD (O'Hare) |
| Miami | KMIA |
| Seattle | KSEA |
| Dallas | KDFW |
| Atlanta | KATL |
| London | EGLC (London City) |
| Paris | LFPG (CDG) |
| Toronto | CYYZ (Pearson) |
The model builds a normal distribution over the 11 brackets based on forecast high and uncertainty level (low/medium/high). The top bracket is recommended when:
- Model probability > Polymarket crowd price (positive edge)
- Forecast uncertainty is low (models agree)
Every 30 minutes, the Vercel cron hits /api/cron/check-positions, which loops over all active session IDs in Redis, calls the Polymarket Gamma API for each open position, and:
- Computes price drift (PM price − your entry price)
- Marks positions as won/lost when markets resolve
- Appends results to the session's job log in Redis
cp .env.local.example .env.local
# fill in the 4 env vars
npm run dev
# open http://localhost:3000To test cron jobs locally:
curl -H "Authorization: Bearer your-cron-secret" \
http://localhost:3000/api/cron/check-positions