{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# FinSight \u2014 explore the sample data\n",
    "\n",
    "A hands-on tour of the FinSight data platform. Everything here hits the\n",
    "**public, read-only API** \u2014 no account, no API key, no database access.\n",
    "Run it top to bottom in any Jupyter kernel, Google Colab, or Binder.\n",
    "\n",
    "What you'll pull, all live:\n",
    "- **NOAA weather** \u2014 forecasts, station observations, settled actuals\n",
    "- **Kalshi weather markets** \u2014 order books, trades, price history\n",
    "- **Calibration** \u2014 do the prices match reality? (settled ground truth)\n",
    "- **Opportunities** \u2014 today's ranked signals and locked cross-exchange arbs"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "import requests, pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "API = \"https://finsight.forestrat.ai\"\n",
    "\n",
    "def get(path, **params):\n",
    "    \"\"\"GET a public FinSight endpoint and return parsed JSON.\"\"\"\n",
    "    r = requests.get(API + path, params=params, timeout=30)\n",
    "    r.raise_for_status()\n",
    "    return r.json()\n",
    "\n",
    "print(\"connected to\", API)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 \u00b7 NOAA weather\n",
    "\n",
    "The ground truth behind the temperature markets: what the forecast said,\n",
    "what the stations measured, and what actually settled."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "# The 8 tracked cities, each with its latest forecast and last reading\n",
    "cities = pd.DataFrame(get(\"/data/noaa/cities\"))\n",
    "cities[[\"city\", \"forecast_date\", \"forecast_high\", \"forecast_low\", \"latest_temp_f\"]]"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "# Phoenix station observations over the last 24h\n",
    "obs = pd.DataFrame(get(\"/data/noaa/observations\", city=\"phoenix\", hours=24))\n",
    "obs[\"obs_ts\"] = pd.to_datetime(obs[\"obs_ts\"])\n",
    "obs = obs.sort_values(\"obs_ts\")\n",
    "\n",
    "plt.figure(figsize=(9, 3))\n",
    "plt.plot(obs[\"obs_ts\"], obs[\"temp_f\"], marker=\".\")\n",
    "plt.title(\"Phoenix \u2014 station temperature, last 24h\")\n",
    "plt.ylabel(\"\u00b0F\"); plt.grid(alpha=.3); plt.tight_layout(); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 \u00b7 A Kalshi weather market\n",
    "\n",
    "Pick a live daily-temperature market and pull its order book, recent\n",
    "trades, and price history \u2014 the same tape the backtester replays."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "# Grab a live temperature market straight from the dataset sampler,\n",
    "# which picks an active KXHIGHT*/KXLOWT* market that has a current book.\n",
    "sample = get(\"/v1/datasets/kalshi_weather/sample\")[\"sample\"]\n",
    "mid = sample[\"market_id\"]\n",
    "print(\"market:\", mid, \"\u2014\", (sample.get(\"market\") or {}).get(\"title\", \"\"))"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "# Current top of book\n",
    "book = get(f\"/data/kalshi/markets/{mid}/book\")\n",
    "pd.Series(book)"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "# Price history (5-min buckets over the last day) with the last few trades\n",
    "hist = pd.DataFrame(get(f\"/data/kalshi/markets/{mid}/price-history\", minutes=1440, bucket_seconds=300))\n",
    "if not hist.empty:\n",
    "    hist[\"t\"] = pd.to_datetime(hist[\"timestamp\"], unit=\"ms\", errors=\"coerce\")\n",
    "    plt.figure(figsize=(9, 3))\n",
    "    plt.plot(hist[\"t\"], hist[\"yes_mid\"])\n",
    "    plt.title(f\"{mid} \u2014 mid price\"); plt.ylabel(\"prob\"); plt.grid(alpha=.3)\n",
    "    plt.tight_layout(); plt.show()\n",
    "pd.DataFrame(get(f\"/data/kalshi/markets/{mid}/trades\", limit=5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 \u00b7 Is the market calibrated?\n",
    "\n",
    "When the market says 30%, does it happen 30% of the time? Measured against\n",
    "exchange-settled outcomes. Where the solid line sits below the diagonal,\n",
    "the market is overpricing that probability \u2014 the favourite\u2013longshot bias."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "cal = get(\"/v1/calibration/curve\")\n",
    "pts = pd.DataFrame(cal[\"points\"])\n",
    "print(f\"n={cal['sample_size']:,}  Brier={cal['brier_score']}  bias={cal['bias']}\")\n",
    "\n",
    "plt.figure(figsize=(5, 5))\n",
    "plt.plot([0, 1], [0, 1], \"--\", color=\"gray\", label=\"perfectly calibrated\")\n",
    "plt.plot(pts[\"predicted\"], pts[\"actual\"], marker=\"o\", label=\"actual\")\n",
    "plt.xlabel(\"market said\"); plt.ylabel(\"actually happened\")\n",
    "plt.title(\"Calibration\"); plt.legend(); plt.grid(alpha=.3)\n",
    "plt.tight_layout(); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4 \u00b7 Where to look today\n",
    "\n",
    "One ranked feed across every live market, plus the locked cross-exchange\n",
    "arbitrages (buy YES on one venue, NO on the other, for under $1)."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "opps = pd.DataFrame(get(\"/v1/opportunities\", per_kind=5)[\"opportunities\"])\n",
    "opps[[\"kind\", \"title\", \"detail\", \"score\"]].head(12)"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "arbs = get(\"/v1/arb\")[\"arbs\"]\n",
    "print(f\"{len(arbs)} locked arbs right now\")\n",
    "pd.json_normalize(arbs)[[\"question\", \"cost\", \"net_edge_cents\", \"executable_contracts\", \"max_profit_usd\"]] if arbs else \"none right now\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next steps\n",
    "\n",
    "- Full REST reference + Swagger: **https://finsight.forestrat.ai/data/docs**\n",
    "- Point an AI agent at the data over MCP: **https://finsight.forestrat.ai/connect**\n",
    "- Every endpoint here is read-only and needs no key. Go build."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}