{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Strategy debugging example\n",
    "\n",
    "Debugging a strategy can be time-consuming. FreqTrade offers helper functions to visualize raw data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Change directory\n",
    "# Modify this cell to insure that the output shows the correct path.\n",
    "import os\n",
    "from pathlib import Path\n",
    "\n",
    "# Define all paths relative to the project root shown in the cell output\n",
    "project_root = \"somedir/freqtrade\"\n",
    "i=0\n",
    "try:\n",
    "    os.chdirdir(project_root)\n",
    "    assert Path('LICENSE').is_file()\n",
    "except:\n",
    "    while i<4 and (not Path('LICENSE').is_file()):\n",
    "        os.chdir(Path(Path.cwd(), '../'))\n",
    "        i+=1\n",
    "    project_root = Path.cwd()\n",
    "print(Path.cwd())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Customize these according to your needs.\n",
    "\n",
    "# Define some constants\n",
    "ticker_interval = \"5m\"\n",
    "# Name of the strategy class\n",
    "strategy_name = 'SampleStrategy'\n",
    "# Path to user data\n",
    "user_data_dir = 'user_data'\n",
    "# Location of the strategy\n",
    "strategy_location = Path(user_data_dir, 'strategies')\n",
    "# Location of the data\n",
    "data_location = Path(user_data_dir, 'data', 'binance')\n",
    "# Pair to analyze - Only use one pair here\n",
    "pair = \"BTC_USDT\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load data using values set above\n",
    "from pathlib import Path\n",
    "from freqtrade.data.history import load_pair_history\n",
    "\n",
    "candles = load_pair_history(datadir=data_location,\n",
    "                            ticker_interval=ticker_interval,\n",
    "                            pair=pair)\n",
    "\n",
    "# Confirm success\n",
    "print(\"Loaded \" + str(len(candles)) + f\" rows of data for {pair} from {data_location}\")\n",
    "candles.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load and run strategy\n",
    "* Rerun each time the strategy file is changed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Load strategy using values set above\n",
    "from freqtrade.resolvers import StrategyResolver\n",
    "strategy = StrategyResolver({'strategy': strategy_name,\n",
    "                            'user_data_dir': user_data_dir,\n",
    "                            'strategy_path': strategy_location}).strategy\n",
    "\n",
    "# Generate buy/sell signals using strategy\n",
    "df = strategy.analyze_ticker(candles, {'pair': pair})\n",
    "df.tail()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Display the trade details\n",
    "\n",
    "* Note that using `data.head()` would also work, however most indicators have some \"startup\" data at the top of the dataframe.\n",
    "* Some possible problems\n",
    "    * Columns with NaN values at the end of the dataframe\n",
    "    * Columns used in `crossed*()` functions with completely different units\n",
    "* Comparison with full backtest\n",
    "    * having 200 buy signals as output for one pair from `analyze_ticker()` does not necessarily mean that 200 trades will be made during backtesting.\n",
    "    * Assuming you use only one condition such as, `df['rsi'] < 30` as buy condition, this will generate multiple \"buy\" signals for each pair in sequence (until rsi returns > 29). The bot will only buy on the first of these signals (and also only if a trade-slot (\"max_open_trades\") is still available), or on one of the middle signals, as soon as a \"slot\" becomes available.  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Report results\n",
    "print(f\"Generated {df['buy'].sum()} buy signals\")\n",
    "data = df.set_index('date', drop=True)\n",
    "data.tail()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Feel free to submit an issue or Pull Request enhancing this document if you would like to share ideas on how to best analyze the data."
   ]
  }
 ],
 "metadata": {
  "file_extension": ".py",
  "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.7.3"
  },
  "mimetype": "text/x-python",
  "name": "python",
  "npconvert_exporter": "python",
  "pygments_lexer": "ipython3",
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  },
  "version": 3
 },
 "nbformat": 4,
 "nbformat_minor": 2
}