# Polymarket Weather Edge: Temperature Odds vs Forecast & METAR (`metallic_pastry/polymarket-weather-edge`) Actor

Price every Polymarket daily high/low temperature bracket against NWS and MET Norway forecasts plus live airport METAR reports, using the markets' own settlement rules. Edge per bracket, YES and NO. Open data, no login. Errors are free.

- **URL**: https://apify.com/metallic_pastry/polymarket-weather-edge.md
- **Developed by:** [Simon Liarsgård](https://apify.com/metallic_pastry) (community)
- **Categories:** Developer tools, Integrations, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 temperature event analyzeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Polymarket Weather Edge: Temperature Odds vs Forecast & METAR

**Price every bracket of Polymarket's daily high and low temperature markets against real weather data, the same way the markets settle, and see where the order book disagrees with the forecast.**

Polymarket lists daily "Highest temperature in NYC on October 30?" style markets for about 50 cities, each with around 11 brackets (`68-69°F`, `17°C`, `78°F or higher`, …). This Actor reads those markets, pulls the latest airport reports and forecasts for the station each market settles on, and returns a probability for every bracket next to its bid and ask. Open, public data only. No login, no browser.

**$0.003 per analyzed event (about $0.30 for 100 events). Invalid input, unsupported events and API errors are free.**

### Who it is for

- **Weather traders** who want a second opinion on every bracket before placing an order.
- **Same-day monitoring:** once the day has started, the observed high or low so far rules brackets in or out. Run it on a schedule and watch for markets that have not caught up yet.
- **Research and dashboards:** a tidy table of model vs. market for every city and day, ready for Sheets, a database or an AI agent through the Apify API or MCP.

### How it works

1. **Markets.** Open temperature events come from Polymarket's public Gamma API. The Actor reads the settlement station from each market's rules (for example `KLGA` for New York, `EGLC` for London).
2. **What has already happened.** For days that have started, it fetches that station's METAR reports from NOAA's Aviation Weather Center and applies the market rules: routine reports only (SPECI ignored), the precise tenths-of-a-degree value from the remarks when present, the station's local calendar day, and halves rounded up. The highest (or lowest) value so far is a hard floor (or ceiling) for the result.
3. **What is still to come.** For US airports it uses the National Weather Service gridpoint forecast, including the official daytime high and overnight low. MET Norway's global forecast is used everywhere and is the only forecast outside the US. Both are nudged toward the latest report, with the correction fading over the following hours.
4. **Probabilities.** The remaining-day extreme is modeled as a normal distribution around the forecast. Uncertainty grows with lead time and is wider when only the global model is available or the two forecasts disagree. Combined with the observed extreme, this gives the probability of every whole-degree outcome and so of every bracket.
5. **Edge.** For each bracket: `edgeBuyYes = probability - best ask` and `edgeBuyNo = best bid - probability` (buying NO costs `1 - best bid`). Brackets with edge at or above **Minimum edge** are listed as opportunities.

### How to use it

1. Pick **Cities** (or leave empty to scan everything) and how many **Days ahead** to cover. Or paste specific **event URLs**.
2. Optionally restrict to highs or lows and adjust **Minimum edge** and **Uncertainty multiplier**.
3. Click **Start**. A full scan of all open events usually takes under a minute.

```json
{
    "cities": ["nyc", "london", "chicago"],
    "kind": "both",
    "maxDaysAhead": 1,
    "minEdge": 0.05
}
```

### Output

One dataset item per event. The **Overview** view shows the essentials; **Detail** has everything, including every bracket.

```json
{
    "eventSlug": "highest-temperature-in-nyc-on-october-30-2026",
    "city": "New York City",
    "kind": "high",
    "date": "2026-10-30",
    "unit": "F",
    "station": "KLGA",
    "dayStatus": "upcoming",
    "observed": { "available": true, "reports": 0, "extremeSoFar": null },
    "forecast": { "nws": 69.7, "metno": 67.9, "expected": 69.7, "sigma": 1.64, "source": "nws", "leadHours": 21.1 },
    "modelFavorite": { "bracket": "70-71°F", "probability": 0.41 },
    "marketFavorite": { "bracket": "70-71°F", "price": 0.6 },
    "bestOpportunity": { "bracket": "70-71°F", "side": "NO", "price": 0.41, "modelProbability": 0.59, "edge": 0.18 },
    "brackets": [
        { "label": "70-71°F", "modelProbability": 0.41, "marketPrice": 0.6, "bestBid": 0.59, "bestAsk": 0.61, "edgeBuyYes": -0.2, "edgeBuyNo": 0.18 }
    ]
}
```

Also saved in the run's key-value store:

- `OPPORTUNITIES`: one flat, edge-sorted list of every bracket and side above the minimum edge across all events.
- `RUN_SUMMARY`: events found, analyzed, charged, errors and request counts.

`marketPrice` is the price Polymarket displays: the bid/ask midpoint, or the last trade when the spread is wider than 10 cents. Edges always use the executable bid and ask.

### Reading the results

- **Same-day markets are where the data is strongest.** Once the high is in, the remaining question is mostly settled by the reports.
- **Day-ahead edges are a disagreement, not a guarantee.** The market often prices information the public forecasts do not have yet, and a raw global model can run a degree cold or warm at a particular airport. Treat a large day-ahead edge as a prompt to look closer, especially outside the US where only the global forecast is available.
- The default uncertainty was checked against two weeks of settled events: day-ahead market favorites (about 51% implied) won about 57% of the time. Raise the **Uncertainty multiplier** if you want more cautious probabilities.
- Hong Kong settles on the Hong Kong Observatory daily extract, and a few cities settle on Weather Underground. Those items carry a note; Hong Kong is forecast-only.

### Pricing

Pay per event, nothing else:

| Event | Price |
|---|---|
| Temperature event analyzed | $0.003 |
| Actor start | $0.00005 |

Errors and skipped events are never charged. **Max events** caps what one run can analyze, and a run stops cleanly when it reaches the maximum total charge you set.

### Data sources and attribution

- Market data: Polymarket public Gamma API.
- Observations: NOAA Aviation Weather Center (aviationweather.gov), public domain.
- US forecasts: NOAA National Weather Service API (api.weather.gov), public domain.
- Global forecasts: weather data from MET Norway (api.met.no), licensed under CC BY 4.0.

The Actor sends an identifying User-Agent and stays well below each service's published rate limits. Add your own email in **Contact email** if you run it very often.

### Disclaimer

This Actor is not affiliated with, endorsed by or sponsored by Polymarket, NOAA, the National Weather Service or MET Norway. Probabilities come from a statistical model and public forecasts and can be wrong. Nothing here is financial advice. Prediction markets are restricted in some countries; check what applies to you before trading.

# Changelog

This Actor's version history is a separate document: https://apify.com/metallic_pastry/polymarket-weather-edge/changelog.md

# Actor input Schema

## `cities` (type: `array`):

City names or Polymarket slugs, e.g. nyc, london, chicago, hong-kong, buenos-aires. Leave empty to scan every open temperature event. Aliases like 'New York', 'LA' and 'HK' work.

## `eventUrls` (type: `array`):

Polymarket event URLs or slugs (e.g. https://polymarket.com/event/highest-temperature-in-nyc-on-october-30-2026). When set, only these events are analyzed and the date window is ignored. Invalid or unsupported entries return a free error item.

## `kind` (type: `string`):

Daily highest temperature markets, lowest temperature markets, or both.

## `maxDaysAhead` (type: `integer`):

0 = only today's markets (in each city's local time), 1 = today and tomorrow, up to 3. Same-day markets are where live reports matter most.

## `maxEvents` (type: `integer`):

Hard cap on events analyzed (and charged) per run. The highest-volume events go first.

## `minEdge` (type: `number`):

Only brackets where model probability beats the executable price by at least this much (0.05 = 5 percentage points) are listed as opportunities. All brackets are still returned per event.

## `sigmaMultiplier` (type: `number`):

Scales the forecast uncertainty. Above 1 = more cautious (flatter probabilities), below 1 = more confident.

## `useNws` (type: `boolean`):

For US airports, lead with the National Weather Service gridpoint forecast (official daytime high and overnight low). MET Norway is always used and is the only forecast outside the US.

## `contactEmail` (type: `string`):

NOAA and MET Norway ask callers to identify themselves. If you schedule frequent runs, adding your email to the User-Agent is courteous. It is only sent to those two APIs.

## Actor input object example

```json
{
  "cities": [
    "nyc",
    "london",
    "seoul"
  ],
  "eventUrls": [
    "highest-temperature-in-nyc-on-october-30-2026"
  ],
  "kind": "both",
  "maxDaysAhead": 1,
  "maxEvents": 50,
  "minEdge": 0.08,
  "sigmaMultiplier": 1.3,
  "useNws": true,
  "contactEmail": "you@example.com"
}
```

# Actor output Schema

## `overview` (type: `string`):

Default dataset, Overview view: observed extreme, forecast, model vs. market favorite and best edge per event.

## `detail` (type: `string`):

Default dataset, Detail view: all fields including every bracket's probability, prices and edges.

## `opportunities` (type: `string`):

OPPORTUNITIES record: every bracket and side with edge at or above minEdge across the run, sorted by edge.

## `runSummary` (type: `string`):

RUN_SUMMARY record: events found, analyzed, charged, errors and API request stats.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "cities": [
        "nyc",
        "london",
        "chicago"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("metallic_pastry/polymarket-weather-edge").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "cities": [
        "nyc",
        "london",
        "chicago",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("metallic_pastry/polymarket-weather-edge").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "cities": [
    "nyc",
    "london",
    "chicago"
  ]
}' |
apify call metallic_pastry/polymarket-weather-edge --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,metallic_pastry/polymarket-weather-edge"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1T4PhBzJULTrcl2Cg/builds/n5A23cehhJIHb7Wwh/openapi.json
