{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e8501022-fcc2-4413-8d96-a808daf447da",
   "metadata": {},
   "source": [
    "# Backtesting with [**vectorbt**](https://github.com/polakowo/vectorbt)\n",
    "* Data Acquisition (**yfinance**)\n",
    "* Statistical and Technical Analysis (**pandas_ta**)\n",
    "* Backtesting Analysis and Results (**vectorbt**)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f4f31b7-b37c-482c-a65b-d3cb21fd57f0",
   "metadata": {},
   "source": [
    "### Initializations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "208299e0-da6e-4631-85f8-c10e7a499792",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Package Versions:\n",
      "Numpy v1.20.2\n",
      "Pandas v1.2.4\n",
      "vectorbt >= v0.18.1\n",
      "\n",
      "Pandas TA v0.2.89b0\n",
      "To install the Latest Version:\n",
      "$ pip install -U git+https://github.com/twopirllc/pandas-ta\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import asyncio\n",
    "import itertools\n",
    "from datetime import datetime\n",
    "\n",
    "from IPython import display\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import pandas_ta as ta\n",
    "import vectorbt as vbt\n",
    "\n",
    "import plotly.graph_objects as go\n",
    "\n",
    "print(\"Package Versions:\")\n",
    "print(f\"Numpy v{np.__version__}\")\n",
    "print(f\"Pandas v{pd.__version__}\")\n",
    "print(f\"vectorbt >= v0.18.1\")\n",
    "print(f\"\\nPandas TA v{ta.version}\\nTo install the Latest Version:\\n$ pip install -U git+https://github.com/twopirllc/pandas-ta\\n\")\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4f0ed8c-a6d4-4843-877c-a200e47fc9d0",
   "metadata": {},
   "source": [
    "# **vectorbt** Theme and Portfolio Settings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "35f829c2-1890-443f-9608-c1ba0893226c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Portfolio Settings [Initial]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Value</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Option</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>call_seq</th>\n",
       "      <td>default</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>init_cash</th>\n",
       "      <td>100.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>size</th>\n",
       "      <td>inf</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>size_type</th>\n",
       "      <td>shares</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>signal_size_type</th>\n",
       "      <td>shares</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>fees</th>\n",
       "      <td>0.0025</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>fixed_fees</th>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>slippage</th>\n",
       "      <td>0.0025</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>reject_prob</th>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min_size</th>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max_size</th>\n",
       "      <td>inf</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>allow_partial</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>raise_reject</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>close_first</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>accumulate</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>log</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>conflict_mode</th>\n",
       "      <td>ignore</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>signal_direction</th>\n",
       "      <td>longonly</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>order_direction</th>\n",
       "      <td>all</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cash_sharing</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>row_wise</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>use_numba</th>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>seed</th>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>freq</th>\n",
       "      <td>1D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>incl_unrealized</th>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>use_filled_close</th>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>subplots</th>\n",
       "      <td>[orders, trade_returns, cum_returns]</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                 Value\n",
       "Option                                                \n",
       "call_seq                                       default\n",
       "init_cash                                        100.0\n",
       "size                                               inf\n",
       "size_type                                       shares\n",
       "signal_size_type                                shares\n",
       "fees                                            0.0025\n",
       "fixed_fees                                         0.0\n",
       "slippage                                        0.0025\n",
       "reject_prob                                        0.0\n",
       "min_size                                           0.0\n",
       "max_size                                           inf\n",
       "allow_partial                                    False\n",
       "raise_reject                                     False\n",
       "close_first                                      False\n",
       "accumulate                                       False\n",
       "log                                              False\n",
       "conflict_mode                                   ignore\n",
       "signal_direction                              longonly\n",
       "order_direction                                    all\n",
       "cash_sharing                                     False\n",
       "row_wise                                         False\n",
       "use_numba                                         True\n",
       "seed                                              None\n",
       "freq                                                1D\n",
       "incl_unrealized                                  False\n",
       "use_filled_close                                  True\n",
       "subplots          [orders, trade_returns, cum_returns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cheight, cwidth = 500, 1000 # Adjust as needed for Chart Height and Width\n",
    "vbt.settings.set_theme(\"dark\") # Options: \"light\" (Default), \"dark\" (my fav), \"seaborn\"\n",
    "\n",
    "# Must be set\n",
    "vbt.settings.portfolio[\"freq\"] = \"1D\" # Daily\n",
    "\n",
    "# Predefine vectorbt Portfolio settings\n",
    "# vbt.settings.portfolio[\"init_cash\"] = 100\n",
    "vbt.settings.portfolio[\"fees\"] = 0.0025 # 0.25%\n",
    "vbt.settings.portfolio[\"slippage\"] = 0.0025 # 0.25%\n",
    "# vbt.settings.portfolio[\"size\"] = 100\n",
    "# vbt.settings.portfolio[\"accumulate\"] = False\n",
    "vbt.settings.portfolio[\"allow_partial\"] = False\n",
    "\n",
    "pf_settings = pd.DataFrame(vbt.settings.portfolio.items(), columns=[\"Option\", \"Value\"])\n",
    "pf_settings.set_index(\"Option\", inplace=True)\n",
    "\n",
    "print(f\"Portfolio Settings [Initial]\")\n",
    "pf_settings"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc8fc1e3-f3cc-487c-b11f-7df03eb64420",
   "metadata": {},
   "source": [
    "## Helper Methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d292b3b0-9186-4cf0-b618-64c6c9d8c1db",
   "metadata": {},
   "outputs": [],
   "source": [
    "def combine_stats(pf: vbt.portfolio.base.Portfolio, ticker: str, strategy: str, mode: int = 0):\n",
    "    header = pd.Series({\n",
    "        \"Run Time\": ta.get_time(full=False, to_string=True),\n",
    "        \"Mode\": \"LIVE\" if mode else \"TEST\",\n",
    "        \"Strategy\": strategy,\n",
    "        \"Direction\": vbt.settings.portfolio[\"signal_direction\"],\n",
    "        \"Symbol\": ticker.upper(),\n",
    "        \"Fees [%]\": 100 * vbt.settings.portfolio[\"fees\"],\n",
    "        \"Slippage [%]\": 100 * vbt.settings.portfolio[\"slippage\"],\n",
    "        \"Accumulate\": vbt.settings.portfolio[\"accumulate\"],\n",
    "    })\n",
    "    rstats = pf.returns_stats().dropna(axis=0).T\n",
    "    stats = pf.stats().dropna(axis=0).T\n",
    "    joint = pd.concat([header, stats, rstats])\n",
    "    return joint[~joint.index.duplicated(keep=\"first\")]\n",
    "\n",
    "def earliest_common_index(d: dict):\n",
    "    \"\"\"Returns index of the earliest common index of all DataFrames in the dict\"\"\"\n",
    "    min_date = None\n",
    "    for df in d.values():\n",
    "        if min_date is None:\n",
    "            min_date = df.index[0]\n",
    "        elif min_date < df.index[0]:\n",
    "            min_date = df.index[0]\n",
    "    return min_date\n",
    "\n",
    "def dl(tickers: list, same_start: bool = False, **kwargs):\n",
    "    if isinstance(tickers, str):\n",
    "        tickers = [tickers]\n",
    "    \n",
    "    if not isinstance(tickers, list) or len(tickers) == 0:\n",
    "        print(\"Must be a non-empty list of tickers or symbols\")\n",
    "        return\n",
    "\n",
    "    if \"limit\" in kwargs and kwargs[\"limit\"] and len(tickers) > kwargs[\"limit\"]:\n",
    "        from itertools import islice            \n",
    "        tickers = list(islice(tickers, kwargs[\"limit\"]))\n",
    "        print(f\"[!] Too many assets to compare. Using the first {kwargs['limit']}: {', '.join(tickers)}\")\n",
    "\n",
    "    print(f\"[i] Downloading: {', '.join(tickers)}\")\n",
    "\n",
    "    received = {}\n",
    "    if len(tickers):\n",
    "        _df = pd.DataFrame()\n",
    "        for ticker in tickers:\n",
    "            received[ticker] = _df.ta.ticker(ticker, **kwargs)\n",
    "            print(f\"[+] {ticker}{received[ticker].shape} {ta.get_time(full=False, to_string=True)}\")\n",
    "    \n",
    "    if same_start and len(tickers) > 1:\n",
    "        earliestci = earliest_common_index(received)\n",
    "        print(f\"[i] Earliest Common Date: {earliestci}\")\n",
    "        result = {ticker:df[df.index > earliestci].copy() for ticker,df in received.items()}\n",
    "    else:\n",
    "        result = received\n",
    "    print(f\"[*] Download Complete\\n\")\n",
    "    return result\n",
    "\n",
    "def dtmask(df: pd.DataFrame, start: datetime, end: datetime):\n",
    "    return df.loc[(df.index >= start) & (df.index <= end), :].copy()\n",
    "\n",
    "def show_data(d: dict):\n",
    "    [print(f\"{t}[{df.index[0]} - {df.index[-1]}]: {df.shape} {df.ta.time_range:.2f} years\") for t,df in d.items()]\n",
    "    \n",
    "def trade_table(pf: vbt.portfolio.base.Portfolio, k: int = 1, total_fees: bool = False):\n",
    "    if not isinstance(pf, vbt.portfolio.base.Portfolio): return\n",
    "    k = int(k) if isinstance(k, int) and k > 0 else 1\n",
    "\n",
    "    df = pf.trades.records[[\"status\", \"direction\", \"size\", \"entry_price\", \"exit_price\", \"return\", \"pnl\", \"entry_fees\", \"exit_fees\"]]\n",
    "    if total_fees:\n",
    "        df[\"total_fees\"] = df[\"entry_fees\"] + df[\"exit_fees\"]\n",
    "\n",
    "    print(f\"\\nLast {k} of {df.shape[0]} Trades\\n{df.tail(k)}\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5296f5e7-6752-43f4-b47d-d359da0d0145",
   "metadata": {},
   "source": [
    "# Data Acquisition"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c770d31-a015-49f2-b1ad-5bced3520d55",
   "metadata": {},
   "source": [
    "#### Specify Symbols for Benchmarks and Assets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "edf274ec-9813-469b-b1e5-129a4e8fe7ed",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tickers by index #\n",
      "====================================================================================================\n",
      "Benchmarks: 0: SPY, 1: QQQ\n",
      "    Assets: 0: AAPL, 1: TSLA, 2: TWTR\n",
      "       All: 0: SPY, 1: QQQ, 2: AAPL, 3: TSLA, 4: TWTR\n"
     ]
    }
   ],
   "source": [
    "benchmark_tickers = [\"SPY\", \"QQQ\"]\n",
    "asset_tickers = [\"AAPL\", \"TSLA\", \"TWTR\"]\n",
    "all_tickers = benchmark_tickers + asset_tickers\n",
    "\n",
    "print(\"Tickers by index #\")\n",
    "print(\"=\"*100)\n",
    "print(f\"Benchmarks: {', '.join([f'{k}: {v}' for k,v in enumerate(benchmark_tickers)])}\")\n",
    "print(f\"    Assets: {', '.join([f'{k}: {v}' for k,v in enumerate(asset_tickers)])}\")\n",
    "print(f\"       All: {', '.join([f'{k}: {v}' for k,v in enumerate(all_tickers)])}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c4c7072a-2c93-4a40-81b4-e18563f81e44",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Selected Benchmark | Asset: SPY | TWTR\n"
     ]
    }
   ],
   "source": [
    "benchmark = benchmark_tickers[0] # Change index for different benchmark\n",
    "asset = asset_tickers[2] # Change index for different symbol\n",
    "print(f\"Selected Benchmark | Asset: {benchmark} | {asset}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "57a1ded8-fe41-4416-8a54-ac94e9306975",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[i] Downloading: SPY, QQQ\n",
      "[+] SPY(7149, 7) Saturday June 19, 2021, NYSE: 7:58:24\n",
      "[+] QQQ(5607, 7) Saturday June 19, 2021, NYSE: 7:58:27\n",
      "[*] Download Complete\n",
      "\n"
     ]
    }
   ],
   "source": [
    "benchmarks = dl(benchmark_tickers, lc_cols=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "eeb57c0a-677a-4fcf-8a0f-08338c04bf03",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[i] Downloading: AAPL, TSLA, TWTR\n",
      "[+] AAPL(10216, 7) Saturday June 19, 2021, NYSE: 7:58:30\n",
      "[+] TSLA(2763, 7) Saturday June 19, 2021, NYSE: 7:58:32\n",
      "[+] TWTR(1916, 7) Saturday June 19, 2021, NYSE: 7:58:34\n",
      "[*] Download Complete\n",
      "\n"
     ]
    }
   ],
   "source": [
    "assets = dl(asset_tickers, lc_cols=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68d36f39-b55b-4ff6-9b73-ec7e6cf9e502",
   "metadata": {},
   "source": [
    "### Define Testing Dates and Ranges"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f3b1fafb-e0e6-41b8-85af-4b8a78a00c85",
   "metadata": {},
   "outputs": [],
   "source": [
    "start_date = datetime(2005, 1, 1) # Adjust as needed\n",
    "end_date = datetime(2010, 1, 1)   # Adjust as needed"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf392c49-9325-4cd5-81c3-ac7285bb7100",
   "metadata": {},
   "source": [
    "### Select and Benchmark and Asset to Backtest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "844bec64-4547-414f-8c89-00d66f08f5d4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Available Data:\n",
      "====================================================================================================\n",
      "Benchmarks: SPY, QQQ\n",
      "Assets: AAPL, TSLA, TWTR\n"
     ]
    }
   ],
   "source": [
    "print(\"Available Data:\")\n",
    "print(\"=\"*100)\n",
    "print(f\"Benchmarks: {', '.join(benchmarks.keys())}\")\n",
    "print(f\"Assets: {', '.join(assets.keys())}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d1fea600-8460-441a-b933-94fbd2456930",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Analysis of: SPY and AAPL from 2005-01-01 00:00:00 to 2010-01-01 00:00:00\n"
     ]
    }
   ],
   "source": [
    "benchmark_name = \"SPY\" # Select a Benchmark\n",
    "asset_name = \"AAPL\" # Select an Asset\n",
    "\n",
    "benchmarkdf = benchmarks[benchmark_name]\n",
    "assetdf     = assets[asset_name]\n",
    "\n",
    "# Set True if you want to constrain Data between start_date & end_date\n",
    "common_range = True\n",
    "if common_range:\n",
    "    crs = f\" from {start_date} to {end_date}\"\n",
    "    benchmarkdf = dtmask(benchmarkdf, start_date, end_date)\n",
    "    assetdf = dtmask(assetdf, start_date, end_date)\n",
    "\n",
    "# Update DataFrame names\n",
    "benchmarkdf.name = benchmark_name\n",
    "assetdf.name = asset_name\n",
    "print(f\"Analysis of: {benchmarkdf.name} and {assetdf.name}{crs if common_range else ''}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e0c3328-783c-4cf2-82fe-d8772948289a",
   "metadata": {},
   "source": [
    "#### Sanity Check"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5449cbc0-8050-4b1b-9357-eac975fbbb3c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>volume</th>\n",
       "      <th>dividends</th>\n",
       "      <th>stock splits</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2005-01-03</th>\n",
       "      <td>88.048860</td>\n",
       "      <td>88.193728</td>\n",
       "      <td>86.846484</td>\n",
       "      <td>87.136215</td>\n",
       "      <td>55748000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-04</th>\n",
       "      <td>87.252088</td>\n",
       "      <td>87.310035</td>\n",
       "      <td>85.788956</td>\n",
       "      <td>86.071442</td>\n",
       "      <td>69167600</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-05</th>\n",
       "      <td>86.006247</td>\n",
       "      <td>86.375654</td>\n",
       "      <td>85.470248</td>\n",
       "      <td>85.477493</td>\n",
       "      <td>65667300</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-06</th>\n",
       "      <td>85.788945</td>\n",
       "      <td>86.303215</td>\n",
       "      <td>85.658567</td>\n",
       "      <td>85.912079</td>\n",
       "      <td>47814700</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-07</th>\n",
       "      <td>86.172847</td>\n",
       "      <td>86.361172</td>\n",
       "      <td>85.564411</td>\n",
       "      <td>85.788956</td>\n",
       "      <td>55847700</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>89.876815</td>\n",
       "      <td>90.205268</td>\n",
       "      <td>89.724602</td>\n",
       "      <td>90.109138</td>\n",
       "      <td>39677500</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>90.445592</td>\n",
       "      <td>90.517689</td>\n",
       "      <td>89.980945</td>\n",
       "      <td>90.301392</td>\n",
       "      <td>87508500</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-29</th>\n",
       "      <td>90.533684</td>\n",
       "      <td>90.549703</td>\n",
       "      <td>90.165173</td>\n",
       "      <td>90.173180</td>\n",
       "      <td>80572500</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-30</th>\n",
       "      <td>89.908834</td>\n",
       "      <td>90.245300</td>\n",
       "      <td>89.860763</td>\n",
       "      <td>90.141151</td>\n",
       "      <td>73138400</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-31</th>\n",
       "      <td>90.341438</td>\n",
       "      <td>90.365476</td>\n",
       "      <td>89.235905</td>\n",
       "      <td>89.275963</td>\n",
       "      <td>90637900</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1259 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                 open       high        low      close    volume  dividends  \\\n",
       "date                                                                          \n",
       "2005-01-03  88.048860  88.193728  86.846484  87.136215  55748000        0.0   \n",
       "2005-01-04  87.252088  87.310035  85.788956  86.071442  69167600        0.0   \n",
       "2005-01-05  86.006247  86.375654  85.470248  85.477493  65667300        0.0   \n",
       "2005-01-06  85.788945  86.303215  85.658567  85.912079  47814700        0.0   \n",
       "2005-01-07  86.172847  86.361172  85.564411  85.788956  55847700        0.0   \n",
       "...               ...        ...        ...        ...       ...        ...   \n",
       "2009-12-24  89.876815  90.205268  89.724602  90.109138  39677500        0.0   \n",
       "2009-12-28  90.445592  90.517689  89.980945  90.301392  87508500        0.0   \n",
       "2009-12-29  90.533684  90.549703  90.165173  90.173180  80572500        0.0   \n",
       "2009-12-30  89.908834  90.245300  89.860763  90.141151  73138400        0.0   \n",
       "2009-12-31  90.341438  90.365476  89.235905  89.275963  90637900        0.0   \n",
       "\n",
       "            stock splits  \n",
       "date                      \n",
       "2005-01-03             0  \n",
       "2005-01-04             0  \n",
       "2005-01-05             0  \n",
       "2005-01-06             0  \n",
       "2005-01-07             0  \n",
       "...                  ...  \n",
       "2009-12-24             0  \n",
       "2009-12-28             0  \n",
       "2009-12-29             0  \n",
       "2009-12-30             0  \n",
       "2009-12-31             0  \n",
       "\n",
       "[1259 rows x 7 columns]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "benchmarkdf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "3adaeb5e-dfc4-4eed-970f-f465035c7a89",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>volume</th>\n",
       "      <th>dividends</th>\n",
       "      <th>stock splits</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2005-01-03</th>\n",
       "      <td>0.994723</td>\n",
       "      <td>0.999791</td>\n",
       "      <td>0.961248</td>\n",
       "      <td>0.971844</td>\n",
       "      <td>691992000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-04</th>\n",
       "      <td>0.979521</td>\n",
       "      <td>1.005318</td>\n",
       "      <td>0.966930</td>\n",
       "      <td>0.981825</td>\n",
       "      <td>1096810400</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-05</th>\n",
       "      <td>0.989809</td>\n",
       "      <td>1.001940</td>\n",
       "      <td>0.983514</td>\n",
       "      <td>0.990424</td>\n",
       "      <td>680433600</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-06</th>\n",
       "      <td>0.993034</td>\n",
       "      <td>0.996720</td>\n",
       "      <td>0.972458</td>\n",
       "      <td>0.991192</td>\n",
       "      <td>705555200</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2005-01-07</th>\n",
       "      <td>0.998101</td>\n",
       "      <td>1.069197</td>\n",
       "      <td>0.994263</td>\n",
       "      <td>1.063362</td>\n",
       "      <td>2227450400</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>6.251186</td>\n",
       "      <td>6.429309</td>\n",
       "      <td>6.245044</td>\n",
       "      <td>6.419788</td>\n",
       "      <td>500889200</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>6.502094</td>\n",
       "      <td>6.570578</td>\n",
       "      <td>6.437294</td>\n",
       "      <td>6.498715</td>\n",
       "      <td>644565600</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-29</th>\n",
       "      <td>6.530040</td>\n",
       "      <td>6.532804</td>\n",
       "      <td>6.410268</td>\n",
       "      <td>6.421631</td>\n",
       "      <td>445205600</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-30</th>\n",
       "      <td>6.413338</td>\n",
       "      <td>6.510692</td>\n",
       "      <td>6.397369</td>\n",
       "      <td>6.499636</td>\n",
       "      <td>412084400</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-31</th>\n",
       "      <td>6.545397</td>\n",
       "      <td>6.552154</td>\n",
       "      <td>6.466470</td>\n",
       "      <td>6.471691</td>\n",
       "      <td>352410800</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1259 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                open      high       low     close      volume  dividends  \\\n",
       "date                                                                        \n",
       "2005-01-03  0.994723  0.999791  0.961248  0.971844   691992000        0.0   \n",
       "2005-01-04  0.979521  1.005318  0.966930  0.981825  1096810400        0.0   \n",
       "2005-01-05  0.989809  1.001940  0.983514  0.990424   680433600        0.0   \n",
       "2005-01-06  0.993034  0.996720  0.972458  0.991192   705555200        0.0   \n",
       "2005-01-07  0.998101  1.069197  0.994263  1.063362  2227450400        0.0   \n",
       "...              ...       ...       ...       ...         ...        ...   \n",
       "2009-12-24  6.251186  6.429309  6.245044  6.419788   500889200        0.0   \n",
       "2009-12-28  6.502094  6.570578  6.437294  6.498715   644565600        0.0   \n",
       "2009-12-29  6.530040  6.532804  6.410268  6.421631   445205600        0.0   \n",
       "2009-12-30  6.413338  6.510692  6.397369  6.499636   412084400        0.0   \n",
       "2009-12-31  6.545397  6.552154  6.466470  6.471691   352410800        0.0   \n",
       "\n",
       "            stock splits  \n",
       "date                      \n",
       "2005-01-03           0.0  \n",
       "2005-01-04           0.0  \n",
       "2005-01-05           0.0  \n",
       "2005-01-06           0.0  \n",
       "2005-01-07           0.0  \n",
       "...                  ...  \n",
       "2009-12-24           0.0  \n",
       "2009-12-28           0.0  \n",
       "2009-12-29           0.0  \n",
       "2009-12-30           0.0  \n",
       "2009-12-31           0.0  \n",
       "\n",
       "[1259 rows x 7 columns]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assetdf"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a71574b2-5e32-45d1-beb9-48a0cb4eadfe",
   "metadata": {},
   "source": [
    "## Creating Trading Signals for **vectorbt**\n",
    "**vectorbt** can create a Backtest using ```vbt.Portfolio.from_signals(*args, **kwargs)``` based on trends can you define with **Pandas TA**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19c0ab8b-fcbe-4a07-9a77-e904b970e6ca",
   "metadata": {},
   "source": [
    "### Trend Creation\n",
    "A **Trend** is the result of some calculation or condition of one or more indicators. For simplicity, a _Trend_ is either ```True``` or ```1``` and _No Trend_ is ```False``` or ```0```. Using the **Hello World** of Trends, the **Golden/Death Cross**, it's Trend is _Long_ when ```long = ma(close, 50) > ma(close, 200) ``` and _Short_ when ```short = ma(close, 50) < ma(close, 200) ```. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "775842c7-ea0e-42a0-b287-cc56487520c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Example Long Trends for the selected Asset\n",
    "# * Uncomment others for exploration or replace them with your own TA Trend Strategy\n",
    "def trends(df: pd.DataFrame, mamode: str = \"sma\", fast: int = 50, slow: int = 200):\n",
    "    return ta.ma(mamode, df.close, length=fast) > ta.ma(mamode, df.close, length=slow) # SMA(fast) > SMA(slow) \"Golden/Death Cross\"\n",
    "#     return ta.increasing(ta.ma(mamode, df.close, length=fast)) # Increasing MA(fast)\n",
    "#     return ta.macd(df.close, fast, slow).iloc[:,1] > 0 # MACD Histogram is positive"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eab7e842-0cc9-420a-a22e-069ecc86e879",
   "metadata": {},
   "source": [
    "### Display Trends"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "8c13e23e-6c2a-47e9-94b8-90dcb79f9191",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "trend_kwargs = {\"mamode\": \"sma\", \"fast\": 50, \"slow\": 200}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ef5a755c-ce2b-4bb1-a72f-51f5afbf537a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:title={'center':'SPY Trends'}, xlabel='date'>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 8272 characters]\n",
      "text/plain": [
       "<Figure size 1152x72 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmark_trends = trends(benchmarkdf, **trend_kwargs)\n",
    "benchmark_trends.copy().astype(int).plot(figsize=(16, 1), kind=\"area\", color=[\"green\"], alpha=0.45, title=f\"{benchmarkdf.name} Trends\", grid=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "bc51e2ca-8784-48a5-a55e-8f32212b9560",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:title={'center':'AAPL Trends'}, xlabel='date'>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 9196 characters]\n",
      "text/plain": [
       "<Figure size 1152x72 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "asset_trends = trends(assetdf, **trend_kwargs)\n",
    "asset_trends.copy().astype(int).plot(figsize=(16, 1), kind=\"area\", color=[\"green\"], alpha=0.45, title=f\"{assetdf.name} Trends\", grid=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba1888d0-10a9-44d4-bc8a-b8ea1c1faa0e",
   "metadata": {},
   "source": [
    "### **Trend Signals** \n",
    "Given a _Trend_, **Trend Signals** returns the _Trend_, _Trades_, _Entries_ and _Exits_ as boolean integers. When ```asbool=True```, it returns _Trends_, _Entries_ and _Exits_ as boolean values which is helpful when combined with the [**vectorbt**](https://github.com/polakowo/vectorbt) backtesting package."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "75bd0f52-ebe0-4fe1-b8e0-475320d3557f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>TS_Trends</th>\n",
       "      <th>TS_Trades</th>\n",
       "      <th>TS_Entries</th>\n",
       "      <th>TS_Exits</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-29</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-30</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-31</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            TS_Trends  TS_Trades  TS_Entries  TS_Exits\n",
       "date                                                  \n",
       "2009-12-24       True          0       False     False\n",
       "2009-12-28       True          0       False     False\n",
       "2009-12-29       True          0       False     False\n",
       "2009-12-30       True          0       False     False\n",
       "2009-12-31       True          0       False     False"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# trade_offset = 0 for Live Signals (close is last price)\n",
    "# trade_offset = 1 for Backtesting\n",
    "LIVE = 0\n",
    "\n",
    "benchmark_signals = assetdf.ta.tsignals(benchmark_trends, asbool=True, trade_offset=LIVE, append=True)\n",
    "benchmark_signals.tail()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "3fceb4ec-b564-47fc-9568-301d1e517440",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>TS_Trends</th>\n",
       "      <th>TS_Trades</th>\n",
       "      <th>TS_Entries</th>\n",
       "      <th>TS_Exits</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-29</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-30</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-31</th>\n",
       "      <td>True</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            TS_Trends  TS_Trades  TS_Entries  TS_Exits\n",
       "date                                                  \n",
       "2009-12-24       True          0       False     False\n",
       "2009-12-28       True          0       False     False\n",
       "2009-12-29       True          0       False     False\n",
       "2009-12-30       True          0       False     False\n",
       "2009-12-31       True          0       False     False"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asset_signals = assetdf.ta.tsignals(asset_trends, asbool=True, trade_offset=LIVE, append=True)\n",
    "asset_signals.tail()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58fee2e0-dc54-45cd-89e7-939c0646e1cd",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "5155f6c5-2256-4abd-8945-3201e3963613",
   "metadata": {},
   "source": [
    "## Creating **vectorbt** Portfolios\n",
    "* [**vectorbt** Portfolio Options](https://polakowo.io/vectorbt/docs/portfolio/base.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40085839-77af-4cf8-ad94-25ed5a9a8bc1",
   "metadata": {},
   "source": [
    "### Buy 'N Hold Portfolios with their Single Trade and Performance Statistics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "237cbd18-dfc5-4982-bc5c-2427cfa2ab6d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Last 1 of 1 Trades\n",
      "   status  direction      size  entry_price  exit_price    return       pnl  \\\n",
      "0       0          0  1.141912    87.354056   89.275963  0.019501  1.945272   \n",
      "\n",
      "   entry_fees  exit_fees  \n",
      "0    0.249377        0.0  \n",
      "\n",
      "None\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/kj/Documents/GitHub/pandas-ta/env/lib/python3.9/site-packages/vectorbt/portfolio/trades.py:252: RuntimeWarning: invalid value encountered in true_divide\n",
      "  return self.wrapper.wrap_reduced(win_count / total_count, group_by=group_by, **wrap_kwargs)\n",
      "/Users/kj/Documents/GitHub/pandas-ta/env/lib/python3.9/site-packages/vectorbt/portfolio/trades.py:252: RuntimeWarning: invalid value encountered in true_divide\n",
      "  return self.wrapper.wrap_reduced(win_count / total_count, group_by=group_by, **wrap_kwargs)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Run Time                  Saturday June 19, 2021, NYSE: 7:58:39\n",
       "Mode                                                       TEST\n",
       "Strategy                                           Buy and Hold\n",
       "Direction                                              longonly\n",
       "Symbol                                                      SPY\n",
       "Fees [%]                                                   0.25\n",
       "Slippage [%]                                               0.25\n",
       "Accumulate                                                False\n",
       "Start                                       2005-01-03 00:00:00\n",
       "End                                         2009-12-31 00:00:00\n",
       "Duration                                     1259 days 00:00:00\n",
       "Init. Cash                                                100.0\n",
       "Total Profit                                           1.945272\n",
       "Total Return [%]                                       1.945272\n",
       "Benchmark Return [%]                                   2.455635\n",
       "Position Coverage [%]                                     100.0\n",
       "Max. Drawdown [%]                                     55.189436\n",
       "Avg. Drawdown [%]                                      2.615867\n",
       "Max. Drawdown Duration                        562 days 00:00:00\n",
       "Avg. Drawdown Duration               24 days 01:55:11.999999999\n",
       "Num. Trades                                                   0\n",
       "Gross Exposure                                              1.0\n",
       "Sharpe Ratio                                           0.163325\n",
       "Sortino Ratio                                          0.231223\n",
       "Calmar Ratio                                           0.010149\n",
       "Annual Return [%]                                      0.560106\n",
       "Annual Volatility [%]                                 28.894472\n",
       "Omega Ratio                                            1.028442\n",
       "Skew                                                   0.426804\n",
       "Kurtosis                                              14.956038\n",
       "Tail Ratio                                              0.88191\n",
       "Common Sense Ratio                                      0.88685\n",
       "Value at Risk                                         -0.022291\n",
       "Alpha                                                 -0.001443\n",
       "Beta                                                   1.000002\n",
       "dtype: object"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Benchmark Buy and Hold (BnH) Strategy\n",
    "benchmarkpf_bnh = vbt.Portfolio.from_holding(benchmarkdf.close)\n",
    "print(trade_table(benchmarkpf_bnh))\n",
    "combine_stats(benchmarkpf_bnh, benchmarkdf.name, \"Buy and Hold\", LIVE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "79667a6e-cd9b-424e-bec8-02435a8e38d3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Last 1 of 1 Trades\n",
      "   status  direction        size  entry_price  exit_price    return  \\\n",
      "0       0          0  102.384595     0.974274    6.471691  5.640079   \n",
      "\n",
      "         pnl  entry_fees  exit_fees  \n",
      "0  562.60143    0.249377        0.0  \n",
      "\n",
      "None\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/kj/Documents/GitHub/pandas-ta/env/lib/python3.9/site-packages/vectorbt/portfolio/trades.py:252: RuntimeWarning: invalid value encountered in true_divide\n",
      "  return self.wrapper.wrap_reduced(win_count / total_count, group_by=group_by, **wrap_kwargs)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Run Time                  Saturday June 19, 2021, NYSE: 7:58:52\n",
       "Mode                                                       TEST\n",
       "Strategy                                           Buy and Hold\n",
       "Direction                                              longonly\n",
       "Symbol                                                     AAPL\n",
       "Fees [%]                                                   0.25\n",
       "Slippage [%]                                               0.25\n",
       "Accumulate                                                False\n",
       "Start                                       2005-01-03 00:00:00\n",
       "End                                         2009-12-31 00:00:00\n",
       "Duration                                     1259 days 00:00:00\n",
       "Init. Cash                                                100.0\n",
       "Total Profit                                          562.60143\n",
       "Total Return [%]                                      562.60143\n",
       "Benchmark Return [%]                                 565.918578\n",
       "Position Coverage [%]                                     100.0\n",
       "Max. Drawdown [%]                                     60.866748\n",
       "Avg. Drawdown [%]                                      6.076352\n",
       "Max. Drawdown Duration                        457 days 00:00:00\n",
       "Avg. Drawdown Duration               22 days 17:32:18.461538461\n",
       "Num. Trades                                                   0\n",
       "Gross Exposure                                              1.0\n",
       "Sharpe Ratio                                           1.329387\n",
       "Sortino Ratio                                          1.982724\n",
       "Calmar Ratio                                           1.199638\n",
       "Annual Return [%]                                     73.018058\n",
       "Annual Volatility [%]                                 51.088459\n",
       "Omega Ratio                                            1.209774\n",
       "Skew                                                    -0.0376\n",
       "Kurtosis                                               3.435275\n",
       "Tail Ratio                                             1.037861\n",
       "Common Sense Ratio                                     1.795687\n",
       "Value at Risk                                         -0.041247\n",
       "Alpha                                                  -0.00145\n",
       "Beta                                                    1.00001\n",
       "dtype: object"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Asset Buy and Hold (BnH) Strategy\n",
    "assetpf_bnh = vbt.Portfolio.from_holding(assetdf.close)\n",
    "print(trade_table(assetpf_bnh))\n",
    "combine_stats(assetpf_bnh, assetdf.name, \"Buy and Hold\", LIVE)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6549488f-31df-4de3-a6b8-0034b4be591a",
   "metadata": {},
   "source": [
    "### Signal Portfolios with their Last 'k' Trades and Performance Statistics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "ab11d9a6-05a3-49e5-9c2c-d339e26e9b23",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Last 5 of 3 Trades\n",
      "   status  direction      size  entry_price  exit_price    return        pnl  \\\n",
      "0       1          0  1.139340    87.551210   93.911126  0.067461   6.729240   \n",
      "1       1          0  1.094141    97.302877  112.341527  0.149169  15.880955   \n",
      "2       0          0  1.677572    72.905618   89.275963  0.222042  27.156674   \n",
      "\n",
      "   entry_fees  exit_fees  \n",
      "0    0.249377   0.267492  \n",
      "1    0.266158   0.307294  \n",
      "2    0.305761   0.000000  \n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Run Time                  Saturday June 19, 2021, NYSE: 7:58:53\n",
       "Mode                                                       TEST\n",
       "Strategy                                          Long Strategy\n",
       "Direction                                              longonly\n",
       "Symbol                                                      SPY\n",
       "Fees [%]                                                   0.25\n",
       "Slippage [%]                                               0.25\n",
       "Accumulate                                                False\n",
       "Start                                       2005-01-03 00:00:00\n",
       "End                                         2009-12-31 00:00:00\n",
       "Duration                                     1259 days 00:00:00\n",
       "Init. Cash                                                100.0\n",
       "Total Profit                                          49.766868\n",
       "Total Return [%]                                      49.766868\n",
       "Benchmark Return [%]                                   2.455635\n",
       "Position Coverage [%]                                 52.819698\n",
       "Max. Drawdown [%]                                     10.131765\n",
       "Avg. Drawdown [%]                                      1.723872\n",
       "Max. Drawdown Duration                        451 days 00:00:00\n",
       "Avg. Drawdown Duration               17 days 20:34:17.142857143\n",
       "Num. Trades                                                   2\n",
       "Win Rate [%]                                              100.0\n",
       "Best Trade [%]                                        14.916866\n",
       "Worst Trade [%]                                        6.746063\n",
       "Avg. Trade [%]                                        10.831464\n",
       "Max. Trade Duration                           335 days 00:00:00\n",
       "Avg. Trade Duration                           264 days 00:00:00\n",
       "Expectancy                                            11.305097\n",
       "SQN                                                    2.470596\n",
       "Gross Exposure                                         0.528197\n",
       "Sharpe Ratio                                           1.009581\n",
       "Sortino Ratio                                          1.431911\n",
       "Calmar Ratio                                           1.226146\n",
       "Annual Return [%]                                     12.423018\n",
       "Annual Volatility [%]                                 12.357496\n",
       "Omega Ratio                                            1.224227\n",
       "Skew                                                  -0.412954\n",
       "Kurtosis                                               6.272176\n",
       "Tail Ratio                                             1.032277\n",
       "Common Sense Ratio                                     1.160517\n",
       "Value at Risk                                         -0.010296\n",
       "Alpha                                                  0.122838\n",
       "Beta                                                   0.182612\n",
       "dtype: object"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Benchmark Portfolio from Trade Signals\n",
    "benchmarkpf_signals = vbt.Portfolio.from_signals(\n",
    "    benchmarkdf.close,\n",
    "    entries=benchmark_signals.TS_Entries,\n",
    "    exits=benchmark_signals.TS_Exits,\n",
    ")\n",
    "trade_table(benchmarkpf_signals, k=5)\n",
    "combine_stats(benchmarkpf_signals, benchmarkdf.name, \"Long Strategy\", LIVE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d8eaf793-f18b-41e1-92d2-d27baa166371",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Last 5 of 4 Trades\n",
      "   status  direction       size  entry_price  exit_price    return        pnl  \\\n",
      "0       1          0  60.628049     1.645288    1.772486  0.072117   7.193697   \n",
      "1       1          0  45.848650     2.332160    3.704574  0.582002  62.231414   \n",
      "2       1          0  29.257588     5.776368    3.885621 -0.331506 -56.025411   \n",
      "3       0          0  30.748240     3.678809    6.471691  0.756681  85.593399   \n",
      "\n",
      "   entry_fees  exit_fees  \n",
      "0    0.249377   0.268656  \n",
      "1    0.267316   0.424624  \n",
      "2    0.422507   0.284210  \n",
      "3    0.282792   0.000000  \n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Run Time                  Saturday June 19, 2021, NYSE: 7:58:54\n",
       "Mode                                                       TEST\n",
       "Strategy                                          Long Strategy\n",
       "Direction                                              longonly\n",
       "Symbol                                                     AAPL\n",
       "Fees [%]                                                   0.25\n",
       "Slippage [%]                                               0.25\n",
       "Accumulate                                                False\n",
       "Start                                       2005-01-03 00:00:00\n",
       "End                                         2009-12-31 00:00:00\n",
       "Duration                                     1259 days 00:00:00\n",
       "Init. Cash                                                100.0\n",
       "Total Profit                                          98.993099\n",
       "Total Return [%]                                      98.993099\n",
       "Benchmark Return [%]                                 565.918578\n",
       "Position Coverage [%]                                 62.271644\n",
       "Max. Drawdown [%]                                     59.898137\n",
       "Avg. Drawdown [%]                                      6.193394\n",
       "Max. Drawdown Duration                        506 days 00:00:00\n",
       "Avg. Drawdown Duration                         32 days 01:30:00\n",
       "Num. Trades                                                   3\n",
       "Win Rate [%]                                          66.666667\n",
       "Best Trade [%]                                        58.200243\n",
       "Worst Trade [%]                                       -33.15062\n",
       "Avg. Trade [%]                                        10.753768\n",
       "Max. Trade Duration                           363 days 00:00:00\n",
       "Avg. Trade Duration                           207 days 08:00:00\n",
       "Expectancy                                             4.466566\n",
       "SQN                                                    0.130735\n",
       "Gross Exposure                                         0.622716\n",
       "Sharpe Ratio                                           0.739016\n",
       "Sortino Ratio                                           1.08289\n",
       "Calmar Ratio                                            0.36859\n",
       "Annual Return [%]                                     22.077862\n",
       "Annual Volatility [%]                                 35.543979\n",
       "Omega Ratio                                            1.140899\n",
       "Skew                                                   0.024374\n",
       "Kurtosis                                               4.672291\n",
       "Tail Ratio                                             1.095481\n",
       "Common Sense Ratio                                     1.337339\n",
       "Value at Risk                                         -0.029217\n",
       "Alpha                                                 -0.063652\n",
       "Beta                                                   0.482566\n",
       "dtype: object"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Asset Portfolio from Trade Signals\n",
    "assetpf_signals = vbt.Portfolio.from_signals(\n",
    "    assetdf.close,\n",
    "    entries=asset_signals.TS_Entries,\n",
    "    exits=asset_signals.TS_Exits,\n",
    ")\n",
    "trade_table(assetpf_signals, k=5)\n",
    "combine_stats(assetpf_signals, assetdf.name, \"Long Strategy\", LIVE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "056574e2-0e68-4055-92ba-d8893e153619",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "297ff72d-9e7b-483d-a7eb-8b39fa585e41",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "758ab259-f6f8-4dfc-8c2d-5aaf429cea42",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "79249c48-7cb6-41a1-ad8d-4aa928d7cd90",
   "metadata": {},
   "source": [
    "## Buy and Hold Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "f386b63d-38f0-401a-ae0e-48bfb65e561a",
   "metadata": {},
   "outputs": [],
   "source": [
    "vbt.settings.set_theme(\"seaborn\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "000dbee0-dd23-45b9-b298-5e9805e99dd5",
   "metadata": {},
   "source": [
    "### Benchmark"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "8d3be988-8ab0-4160-8954-2e5989b3c75f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 75140 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_bnh.trades.plot(title=f\"{benchmarkdf.name} | Trades\", height=cheight, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "de6ef303-a1a8-4ff9-8722-4e50cdde28d9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 48244 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_bnh.value().vbt.plot(title=f\"{benchmarkdf.name} | Equity Curve\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "f38fa715-186c-40fb-aecb-177c39480600",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 46908 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_bnh.drawdown().vbt.plot(title=f\"{benchmarkdf.name} | Drawdown\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "aab9e899-5115-4395-bc1a-c79e75a87583",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 23148 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_bnh.trades.plot_pnl(title=f\"{benchmarkdf.name} | PnL\", height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "4612fa22-363c-4351-9748-1204c26817f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 50144 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_bnh.active_returns().vbt.plot(title=f\"{benchmarkdf.name} | Active Returns\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "61e0a14e-72ef-49fd-a610-7a7f2a47ec59",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26260 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_bnh.cash().vbt.plot(title=f\"{benchmarkdf.name} | Cash\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "8ff2049b-7d65-4ee3-aeda-f246d3f78990",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 18196 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "total_assetfees = benchmarkpf_bnh.trades.records_readable[\"Entry Fees\"] + benchmarkpf_bnh.trades.records_readable[\"Exit Fees\"]\n",
    "total_assetfees.vbt.plot(title=f\"{benchmarkdf.name} | Total Fees\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1763326-6e9d-476b-978c-9ef0f4230023",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "d2ee8078-2c50-456b-91b7-bce90ab837d7",
   "metadata": {},
   "source": [
    "### Asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "39d91c0e-85aa-41d1-8be4-db4950fbd072",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 70612 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_bnh.trades.plot(title=f\"{assetdf.name} | Trades\", height=cheight, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "e8b1c77d-b699-4531-8226-bc9c33a465eb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 46564 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_bnh.value().vbt.plot(title=f\"{assetdf.name} | Equity Curve\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "3afeecfb-6732-4811-9bbc-d731705096df",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 52936 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_bnh.drawdown().vbt.plot(title=f\"{assetdf.name} | Drawdown\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "0b66f1f8-1155-4759-aba0-b3762dfca7d8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 24704 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_bnh.trades.plot_pnl(title=f\"{assetdf.name} | PnL\", height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "f1b5e490-b99b-4613-be46-72b41076a45f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 57136 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_bnh.active_returns().vbt.plot(title=f\"{assetdf.name} | Active Returns\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "061f2fbe-b6c0-49e6-8523-d2a895609427",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 26284 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_bnh.cash().vbt.plot(title=f\"{assetdf.name} | Cash\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "e9968dcd-f488-4093-816d-059488617a1f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 18020 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "total_assetfees = assetpf_bnh.trades.records_readable[\"Entry Fees\"] + assetpf_bnh.trades.records_readable[\"Exit Fees\"]\n",
    "total_assetfees.vbt.plot(title=f\"{assetdf.name} | Total Fees\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c4ac309d-b834-43c0-b99e-05458f5eba55",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "698c7cd9-dec0-42c0-90e1-edf6cf43113e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "2f1db047-adfc-4095-9c58-c782fd0085d1",
   "metadata": {},
   "source": [
    "## Signal Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "26f2e079-ffc7-4047-908f-3badf0ce94fe",
   "metadata": {},
   "outputs": [],
   "source": [
    "vbt.settings.set_theme(\"dark\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56c982d5-f6a1-4ed0-94b4-97b492cea01f",
   "metadata": {},
   "source": [
    "### Benchmark"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "a7c9675c-0019-490f-a230-689aecba1c0f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 79540 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_signals.trades.plot(title=f\"{benchmarkdf.name} | Trades\", height=cheight, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "d7aba265-f0d9-4377-810c-23877e849ee4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 41608 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_signals.value().vbt.plot(title=f\"{benchmarkdf.name} | Equity Curve\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "59fbacad-e920-4b1d-81de-34dbb4fe772a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 49348 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_signals.drawdown().vbt.plot(title=f\"{benchmarkdf.name} | Drawdown\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "efa2a030-d345-4253-82cd-d41644ab3d19",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 31852 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_signals.trades.plot_pnl(title=f\"{benchmarkdf.name} | PnL\", height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "0152d91e-c129-4e10-897f-fc9f832bbb5e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 53356 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_signals.active_returns().vbt.plot(title=f\"{benchmarkdf.name} | Active Returns\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "7b3ea536-cb90-4eef-aa3d-d37a0639a6f2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 38948 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "benchmarkpf_signals.cash().vbt.plot(title=f\"{benchmarkdf.name} | Cash\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "6305826c-d02c-4d3c-b754-1623f3e1f37f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 28684 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "total_assetfees = benchmarkpf_signals.trades.records_readable[\"Entry Fees\"] + benchmarkpf_signals.trades.records_readable[\"Exit Fees\"]\n",
    "total_assetfees.vbt.plot(title=f\"{benchmarkdf.name} | Total Fees\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de460913-d69d-4fe1-8d5f-21f107c334e9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "aac6ae83-46b5-447c-99ed-0d30fd64cb0f",
   "metadata": {},
   "source": [
    "### Asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "d52dc534-ba16-4dc6-a8ab-fa358e3b1e7a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 78408 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_signals.trades.plot(title=f\"{assetdf.name} | Trades\", height=cheight, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "46e75cf4-78ea-46ff-a9e4-bd56c9d946e8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 45112 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_signals.value().vbt.plot(title=f\"{assetdf.name} | Equity Curve\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "153347c4-d673-498e-b14e-cdbdf4753562",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 46752 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_signals.drawdown().vbt.plot(title=f\"{assetdf.name} | Drawdown\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "57cfbcaa-2796-4161-815f-54a74c4379cd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 35052 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_signals.trades.plot_pnl(title=f\"{assetdf.name} | PnL\", height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "812803e3-5448-4f59-81ce-20ed154f1ac7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 54904 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_signals.active_returns().vbt.plot(title=f\"{assetdf.name} | Active Returns\", trace_kwargs=dict(name=\"%\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "7c8bc78b-7d7b-40e7-a4e0-817389efbc36",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 40984 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "assetpf_signals.cash().vbt.plot(title=f\"{assetdf.name} | Cash\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "e492d13a-4493-4dc9-a5c5-7e0727a36746",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 32944 characters]"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "total_assetfees = assetpf_signals.trades.records_readable[\"Entry Fees\"] + assetpf_signals.trades.records_readable[\"Exit Fees\"]\n",
    "total_assetfees.vbt.plot(title=f\"{assetdf.name} | Total Fees\", trace_kwargs=dict(name=u\"\\u00A4\"), height=cheight // 2, width=cwidth).show_png()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8821f5db-c6ff-4b62-b65c-44319077e88d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "1343a6b8-8e70-426e-9b58-a091b114b465",
   "metadata": {},
   "source": [
    "# Disclaimer\n",
    "* All investments involve risk, and the past performance of a security, industry, sector, market, financial product, trading strategy, or individual’s trading does not guarantee future results or returns. Investors are fully responsible for any investment decisions they make. Such decisions should be based solely on an evaluation of their financial circumstances, investment objectives, risk tolerance, and liquidity needs.\n",
    "\n",
    "* Any opinions, news, research, analyses, prices, or other information offered is provided as general market commentary, and does not constitute investment advice. I will not accept liability for any loss or damage, including without limitation any loss of profit, which may arise directly or indirectly from use of or reliance on such information."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
