{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 📘 Fincept Notebook — Your First Watchlist & Returns\n",
    "\n",
    "**Trading · Beginner · ~12 min · Standard library only**\n",
    "\n",
    "A *watchlist* is just a handful of tickers you track. In this notebook we attach a short price history to each, compute the returns and risk that every trader looks at first, and rank the names on a clean leaderboard — all with Python's standard library, no extra packages.\n",
    "\n",
    "**What you'll learn**\n",
    "- Turn daily closing prices into daily returns and a cumulative return\n",
    "- Measure average return and volatility with the `statistics` module\n",
    "- Rank a watchlist by performance and by risk, and read a leaderboard\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. The watchlist\n",
    "\n",
    "Our watchlist holds four tickers, each with twelve daily closing prices (oldest first). In a real terminal these would stream from a data feed; here we embed them so every cell runs offline and deterministically.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {"fincept_title": "Define watchlist"},
   "outputs": [],
   "source": [
    "WATCHLIST = {\n",
    "    \"AAPL\": [188.0, 189.5, 191.2, 190.1, 192.8, 195.0, 194.2, 196.5, 198.0, 197.1, 199.4, 201.0],\n",
    "    \"MSFT\": [410.0, 412.5, 411.0, 415.8, 418.2, 416.0, 420.5, 422.1, 419.7, 423.4, 425.0, 427.8],\n",
    "    \"TSLA\": [240.0, 235.5, 244.0, 238.2, 250.1, 246.8, 255.0, 248.3, 260.5, 254.0, 249.7, 262.4],\n",
    "    \"KO\":   [60.1, 60.3, 60.0, 60.5, 60.4, 60.7, 60.6, 60.9, 61.0, 60.8, 61.2, 61.1],\n",
    "}\n",
    "\n",
    "print(\"Watchlist — 12 daily closes per ticker (oldest -> newest)\")\n",
    "print(\"=\" * 58)\n",
    "for ticker, closes in WATCHLIST.items():\n",
    "    print(f\"{ticker:<5} first={closes[0]:>7.2f}  last={closes[-1]:>7.2f}  n={len(closes)}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Daily returns and cumulative return\n",
    "\n",
    "A **simple daily return** is the percentage change from one close to the next: `(today − yesterday) / yesterday`. The **cumulative return** is the total gain over the whole window, `last / first − 1`. These are the two numbers a trader checks first.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {"fincept_title": "Compute returns"},
   "outputs": [],
   "source": [
    "WATCHLIST = {\n",
    "    \"AAPL\": [188.0, 189.5, 191.2, 190.1, 192.8, 195.0, 194.2, 196.5, 198.0, 197.1, 199.4, 201.0],\n",
    "    \"MSFT\": [410.0, 412.5, 411.0, 415.8, 418.2, 416.0, 420.5, 422.1, 419.7, 423.4, 425.0, 427.8],\n",
    "    \"TSLA\": [240.0, 235.5, 244.0, 238.2, 250.1, 246.8, 255.0, 248.3, 260.5, 254.0, 249.7, 262.4],\n",
    "    \"KO\":   [60.1, 60.3, 60.0, 60.5, 60.4, 60.7, 60.6, 60.9, 61.0, 60.8, 61.2, 61.1],\n",
    "}\n",
    "\n",
    "def daily_returns(closes):\n",
    "    return [(closes[i] - closes[i - 1]) / closes[i - 1] for i in range(1, len(closes))]\n",
    "\n",
    "print(\"Daily returns (%) per ticker\")\n",
    "print(\"=\" * 70)\n",
    "for ticker, closes in WATCHLIST.items():\n",
    "    rets = daily_returns(closes)\n",
    "    cum = closes[-1] / closes[0] - 1\n",
    "    pretty = \"  \".join(f\"{r * 100:+5.2f}\" for r in rets)\n",
    "    print(f\"{ticker:<5} {pretty}\")\n",
    "    print(f\"      cumulative return over window: {cum * 100:+6.2f}%\")\n",
    "    print()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Average return and volatility\n",
    "\n",
    "Return alone tells you nothing about *risk*. **Volatility** — the spread of the daily returns — does. We use `statistics.mean` for the average daily return and `statistics.pstdev` (population standard deviation) for volatility. Higher volatility means a bumpier ride for the same average gain.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {"fincept_title": "Mean & volatility"},
   "outputs": [],
   "source": [
    "import statistics\n",
    "\n",
    "WATCHLIST = {\n",
    "    \"AAPL\": [188.0, 189.5, 191.2, 190.1, 192.8, 195.0, 194.2, 196.5, 198.0, 197.1, 199.4, 201.0],\n",
    "    \"MSFT\": [410.0, 412.5, 411.0, 415.8, 418.2, 416.0, 420.5, 422.1, 419.7, 423.4, 425.0, 427.8],\n",
    "    \"TSLA\": [240.0, 235.5, 244.0, 238.2, 250.1, 246.8, 255.0, 248.3, 260.5, 254.0, 249.7, 262.4],\n",
    "    \"KO\":   [60.1, 60.3, 60.0, 60.5, 60.4, 60.7, 60.6, 60.9, 61.0, 60.8, 61.2, 61.1],\n",
    "}\n",
    "\n",
    "def daily_returns(closes):\n",
    "    return [(closes[i] - closes[i - 1]) / closes[i - 1] for i in range(1, len(closes))]\n",
    "\n",
    "print(f\"{'Ticker':<8}{'Mean daily':>12}{'Volatility':>12}{'Cumulative':>12}\")\n",
    "print(\"=\" * 44)\n",
    "for ticker, closes in WATCHLIST.items():\n",
    "    rets = daily_returns(closes)\n",
    "    mean_r = statistics.mean(rets)\n",
    "    vol = statistics.pstdev(rets)\n",
    "    cum = closes[-1] / closes[0] - 1\n",
    "    print(f\"{ticker:<8}{mean_r * 100:>11.3f}%{vol * 100:>11.3f}%{cum * 100:>11.2f}%\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. The leaderboard\n",
    "\n",
    "Finally we rank the watchlist two ways: by **cumulative return** (who made the most) and by **volatility** (who was calmest). The best name combines a high return with low risk — but those two rarely come together, which is the whole game of investing.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {"fincept_title": "Leaderboard"},
   "outputs": [],
   "source": [
    "import statistics\n",
    "\n",
    "WATCHLIST = {\n",
    "    \"AAPL\": [188.0, 189.5, 191.2, 190.1, 192.8, 195.0, 194.2, 196.5, 198.0, 197.1, 199.4, 201.0],\n",
    "    \"MSFT\": [410.0, 412.5, 411.0, 415.8, 418.2, 416.0, 420.5, 422.1, 419.7, 423.4, 425.0, 427.8],\n",
    "    \"TSLA\": [240.0, 235.5, 244.0, 238.2, 250.1, 246.8, 255.0, 248.3, 260.5, 254.0, 249.7, 262.4],\n",
    "    \"KO\":   [60.1, 60.3, 60.0, 60.5, 60.4, 60.7, 60.6, 60.9, 61.0, 60.8, 61.2, 61.1],\n",
    "}\n",
    "\n",
    "def daily_returns(closes):\n",
    "    return [(closes[i] - closes[i - 1]) / closes[i - 1] for i in range(1, len(closes))]\n",
    "\n",
    "stats = {}\n",
    "for ticker, closes in WATCHLIST.items():\n",
    "    rets = daily_returns(closes)\n",
    "    stats[ticker] = {\"cum\": closes[-1] / closes[0] - 1, \"vol\": statistics.pstdev(rets)}\n",
    "\n",
    "by_return = sorted(stats.items(), key=lambda kv: kv[1][\"cum\"], reverse=True)\n",
    "by_vol = sorted(stats.items(), key=lambda kv: kv[1][\"vol\"])  # calmest first\n",
    "\n",
    "print(\"LEADERBOARD — best total return\")\n",
    "print(\"=\" * 40)\n",
    "for rank, (ticker, s) in enumerate(by_return, 1):\n",
    "    print(f\"  #{rank}  {ticker:<5} {s['cum'] * 100:+6.2f}%\")\n",
    "\n",
    "print()\n",
    "print(\"LEADERBOARD — lowest volatility (calmest)\")\n",
    "print(\"=\" * 40)\n",
    "for rank, (ticker, s) in enumerate(by_vol, 1):\n",
    "    print(f\"  #{rank}  {ticker:<5} {s['vol'] * 100:5.3f}% daily\")\n",
    "\n",
    "top = by_return[0][0]\n",
    "calm = by_vol[0][0]\n",
    "print()\n",
    "print(f\"Top performer: {top}.  Calmest name: {calm}.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "*— Fincept Notebook · part of Fincept Terminal. Edit any cell and press Ctrl+Enter to run.*\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"},
  "language_info": {"name": "python"}
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
