Download code/gate.py from Elpriser/eu-price-forecast: direct link, hf CLI and curl.
- Browser
- Download file 4.78 kB
-
https://huggingface.co/Elpriser/eu-price-forecast/resolve/main/code/gate.py
- Command line
-
hf download hf://Elpriser/eu-price-forecast/code/gate.py
-
curl -L -o gate.py https://huggingface.co/Elpriser/eu-price-forecast/resolve/main/code/gate.py
4.78 kB
| """The three small JSON files that decide WHAT is published, and read them defensively. | |
| publish_gate.json (checked in; written by build_gate.py from the research backtest) zone -> the horizons that may be published | |
| accuracy_eu.json (checked in; same script) zone -> what the forecast is worth, per horizon | |
| calibration_eu.json (written by calibrate_bands.py, refreshed monthly) zone -> the P10 / P90 band offsets | |
| A file that is missing, unreadable or of another `version` is treated as ABSENT, and absent never means "publish anyway": without the gate | |
| nothing is published, without the accuracy block nothing is published (a forecast without its honest numbers is not shown), without the | |
| calibration the days are published without a band. A file in the first build's format (no `version`) is therefore harmless. | |
| """ | |
| import json | |
| import os | |
| VERSION = 2 | |
| LOW_GAIN = 0.10 # an improvement below this (in the whole backtest, the hold-out or since September 2026) is low confidence | |
| MIN_GAIN_VS_BEST_NAIVE = 0.05 | |
| def dumps_compact(obj, level=0): | |
| """JSON for files people review in a diff: a dict or list that holds only scalars (or lists of scalars) is one line, anything else is | |
| indented. Same content as json.dumps(obj, indent=1), a tenth of the lines.""" | |
| scalar = lambda v: not isinstance(v, (dict, list)) | |
| flat = lambda v: all(scalar(x) or (isinstance(x, list) and all(scalar(y) for y in x)) for x in (v.values() if isinstance(v, dict) else v)) | |
| if isinstance(obj, list) and all(scalar(x) for x in obj): | |
| return json.dumps(obj) | |
| if isinstance(obj, dict) and obj and flat(obj) and level >= 2: | |
| return json.dumps(obj) | |
| pad = " " * (level + 1) | |
| if isinstance(obj, dict): | |
| return "{\n" + ",\n".join(f"{pad}{json.dumps(k)}: {dumps_compact(v, level + 1)}" for k, v in obj.items()) + "\n" + " " * level + "}" | |
| if isinstance(obj, list): | |
| return "[\n" + ",\n".join(pad + dumps_compact(v, level + 1) for v in obj) + "\n" + " " * level + "]" | |
| return json.dumps(obj) | |
| def _load(path, version=VERSION): | |
| try: | |
| with open(path, encoding="utf-8") as f: | |
| v = json.load(f) | |
| except (OSError, ValueError): | |
| return None | |
| return v if isinstance(v, dict) and v.get("version") == version else None | |
| def load_gate(path): | |
| """{zone: {"recipe": 'ens'|'lgb', "fuel": [h...], "nofuel": [h...]}} or None.""" | |
| g = _load(path) | |
| z = g.get("zones") if g else None | |
| return z if isinstance(z, dict) and z else None | |
| def horizons(gate, zone, fuel_ok): | |
| """The set of horizons the gate lets this zone publish, in the fuel mode the run is in. A zone the gate does not list publishes nothing.""" | |
| e = (gate or {}).get(zone) | |
| if not isinstance(e, dict): | |
| return set() | |
| return {int(h) for h in e.get("fuel" if fuel_ok else "nofuel", [])} | |
| def load_accuracy(path): | |
| return _load(path) | |
| def accuracy_block(acc, zone, fuel_ok, hs): | |
| """The `accuracy` object of the published payload for the horizons `hs` actually published, or None when the file has no numbers for | |
| one of them (the whole zone is then not published: see published_horizons).""" | |
| z = ((acc or {}).get("zones") or {}).get(zone) | |
| if not z: | |
| return None | |
| cells = z.get("fuel" if fuel_ok else "nofuel") or {} | |
| by = {str(h): cells[str(h)] for h in sorted(hs) if str(h) in cells} | |
| if not by: | |
| return None | |
| return {"version": VERSION, "period": acc.get("period"), "baseline": acc.get("baseline"), "recent": acc.get("recent"), | |
| "fuel": bool(fuel_ok) and z.get("recipe") != "lgb", "showEur": bool(z.get("showEur")), "byHorizon": by} | |
| def published_horizons(gate, acc, zone, fuel_ok): | |
| """The horizons to publish: those the gate allows AND for which the accuracy file has numbers (an unmeasured horizon is not published).""" | |
| cells = (((acc or {}).get("zones") or {}).get(zone) or {}).get("fuel" if fuel_ok else "nofuel") or {} | |
| return {h for h in horizons(gate, zone, fuel_ok) if str(h) in cells} | |
| def load_calibration(path): | |
| """{"quantile": {zone: {h: {lo, hi}}}, "residual": {...}} or None.""" | |
| c = _load(path) | |
| if not c: | |
| return None | |
| return {k: (c.get(k) if isinstance(c.get(k), dict) else {}) for k in ("quantile", "residual")} | |
| def offsets(cal, kind, zone, h): | |
| """{'lo','hi'} for a zone and horizon, or None. A horizon without its own entry borrows the nearest horizon of the same zone (the cells | |
| are thin only at the edges of the horizon range), a zone without any returns None.""" | |
| z = ((cal or {}).get(kind) or {}).get(zone) or {} | |
| if str(h) in z: | |
| return z[str(h)] | |
| if not z: | |
| return None | |
| return z[min(z, key=lambda k: abs(int(k) - h))] | |