{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# DQN On Foreign Exchange Market\n", "## Load dataset" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19", "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5" }, "outputs": [], "source": [ "# This Python 3 environment comes with many helpful analytics libraries installed\n", "# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n", "# For example, here's several helpful packages to load in\n", "\n", "import random\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import os\n", "\n", "from keras.models import Sequential\n", "from keras.layers import Dense\n", "from keras.optimizers import Adam\n", "\n", "from collections import deque\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Flags for the debuging purposes are presented here." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# If this flag is set, each step of the environment's state will be printed\n", "ENVIRONMENT_DEBUG = False" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0", "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TarihŞimdiAçılışYüksekDüşükFark %
0NaT5.08395,09245,11515,06120.35
1NaT5.06604,99245,09444,95911.42
2NaT4.99504,91365,01834,90861.64
3NaT4.91424,88454,93244,87340.65
4NaT4.88234,84594,91044,84070.52
5NaT4.85724,85544,85844,85440.09
6NaT4.85294,86444,88304,8340-0.25
7NaT4.86494,77054,88454,76601.93
8NaT4.77284,88834,89244,7728-2.32
9NaT4.88614,74154,94034,73453.09
\n", "
" ], "text/plain": [ " Tarih Şimdi Açılış Yüksek Düşük Fark %\n", "0 NaT 5.0839 5,0924 5,1151 5,0612 0.35\n", "1 NaT 5.0660 4,9924 5,0944 4,9591 1.42\n", "2 NaT 4.9950 4,9136 5,0183 4,9086 1.64\n", "3 NaT 4.9142 4,8845 4,9324 4,8734 0.65\n", "4 NaT 4.8823 4,8459 4,9104 4,8407 0.52\n", "5 NaT 4.8572 4,8554 4,8584 4,8544 0.09\n", "6 NaT 4.8529 4,8644 4,8830 4,8340 -0.25\n", "7 NaT 4.8649 4,7705 4,8845 4,7660 1.93\n", "8 NaT 4.7728 4,8883 4,8924 4,7728 -2.32\n", "9 NaT 4.8861 4,7415 4,9403 4,7345 3.09" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds = pd.read_csv(\n", " \"https://static-1300131294.cos.ap-shanghai.myqcloud.com/data/deep-learning/dqn/USD_TRY%20Gemi%20Verileri.csv\"\n", ")\n", "ds[\"Tarih\"] = pd.to_datetime(ds[\"Tarih\"], format='%d/%m/%Y', errors=\"coerce\")\n", "ds[\"Şimdi\"] = pd.to_numeric(ds[\"Şimdi\"].str.replace(\",\", \".\"), errors=\"coerce\")\n", "ds[\"Fark %\"] = ds[\"Fark %\"].str.replace(\"%\", \"\")\n", "ds[\"Fark %\"] = ds[\"Fark %\"].str.replace(\",\", \".\")\n", "\n", "ds.head(10)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "The reverse version of the data will be used. It is expected to make the learning stronger since from 2002 to this date, usd is increasing with respect to try." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkAAAAGdCAYAAAD60sxaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAlN0lEQVR4nO3df3TT9b3H8VdCaVooCaMtDaUBdEMpP6SzrCW6O4Z0VmWbvYMj61QYduI2ZG5FlApSudPTOxkTGChDt4sOEOx+eJBx8bKiw60dYOmcLcg8ZygopojYpoK0pf3cPzyNRgq2QKDN5/k4J8fDN5/vJ9+3LeRpSKrDGGMEAABgEefFvgAAAIALjQACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYJ2Yi30BF0Nra6sOHTqkPn36yOFwXOzLAQAAHWCMUUNDg1JTU+V0nttrOFYG0KFDh+Tz+S72ZQAAgLNw8OBBpaWlndMeVgZQnz59JH30L9Dtdl/kqwEAAB0RDAbl8/lCz+PnwsoAavtrL7fbTQABANDNnI+3r/AmaAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWuSABtGLFCg0ZMkRxcXHKzs7Wzp07z7i+tLRUw4YNU1xcnEaNGqXNmzefdu33v/99ORwOLVmy5DxfNQAAiFYRD6ANGzaosLBQxcXF2r17t0aPHq3c3FwdPny43fXl5eXKz89XQUGBqqqqlJeXp7y8PFVXV5+y9o9//KP+/ve/KzU1NdJjAACAKBLxAPrFL36h22+/XdOnT9fw4cO1cuVK9erVS7/5zW/aXb906VJdd911mjNnjtLT0/XTn/5UV155pZYvXx627u2339asWbO0du1a9ezZM9JjAACAKBLRAGpqalJlZaVycnI+fkCnUzk5OaqoqGj3nIqKirD1kpSbmxu2vrW1VbfeeqvmzJmjESNGfOZ1NDY2KhgMht0AAIC9IhpAR44cUUtLi1JSUsKOp6SkKBAItHtOIBD4zPU/+9nPFBMTox/96Ecduo6SkhJ5PJ7QzefzdXISAAAQTbrdp8AqKyu1dOlSrV69Wg6Ho0PnFBUVqb6+PnQ7ePBghK8SAAB0ZRENoKSkJPXo0UO1tbVhx2tra+X1ets9x+v1nnH9Sy+9pMOHD2vQoEGKiYlRTEyM3nzzTc2ePVtDhgxpd0+XyyW32x12AwAA9opoAMXGxiozM1NlZWWhY62trSorK5Pf72/3HL/fH7ZekrZu3Rpaf+utt+qf//yn/vGPf4RuqampmjNnjp5//vnIDQMAAKJGTKQfoLCwUNOmTdOYMWOUlZWlJUuW6NixY5o+fbokaerUqRo4cKBKSkokSXfddZfGjRunxYsXa+LEiVq/fr1efvllrVq1SpKUmJioxMTEsMfo2bOnvF6vLr/88kiPAwAAokDEA2jKlCl69913tWDBAgUCAWVkZGjLli2hNzofOHBATufHL0RdddVVWrdunebPn6/77rtPQ4cO1bPPPquRI0dG+lIBAIAlHMYYc7Ev4kILBoPyeDyqr6/n/UAAAHQT5/P5u9t9CgwAAOBcEUAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArHNBAmjFihUaMmSI4uLilJ2drZ07d55xfWlpqYYNG6a4uDiNGjVKmzdvDt3X3Nyse++9V6NGjVLv3r2VmpqqqVOn6tChQ5EeAwAARImIB9CGDRtUWFio4uJi7d69W6NHj1Zubq4OHz7c7vry8nLl5+eroKBAVVVVysvLU15enqqrqyVJx48f1+7du3X//fdr9+7d+sMf/qB9+/bpm9/8ZqRHAQAAUcJhjDGRfIDs7Gx96Utf0vLlyyVJra2t8vl8mjVrlubOnXvK+ilTpujYsWPatGlT6NjYsWOVkZGhlStXtvsYu3btUlZWlt58800NGjToM68pGAzK4/Govr5ebrf7LCcDAAAX0vl8/o7oK0BNTU2qrKxUTk7Oxw/odConJ0cVFRXtnlNRURG2XpJyc3NPu16S6uvr5XA41Ldv33bvb2xsVDAYDLsBAAB7RTSAjhw5opaWFqWkpIQdT0lJUSAQaPecQCDQqfUnTpzQvffeq/z8/NPWYElJiTweT+jm8/nOYhoAABAtuvWnwJqbm3XTTTfJGKPHHnvstOuKiopUX18fuh08ePACXiUAAOhqYiK5eVJSknr06KHa2tqw47W1tfJ6ve2e4/V6O7S+LX7efPNNbdu27Yx/F+hyueRyuc5yCgAAEG0i+gpQbGysMjMzVVZWFjrW2tqqsrIy+f3+ds/x+/1h6yVp69atYevb4uf111/Xn//8ZyUmJkZmAAAAEJUi+gqQJBUWFmratGkaM2aMsrKytGTJEh07dkzTp0+XJE2dOlUDBw5USUmJJOmuu+7SuHHjtHjxYk2cOFHr16/Xyy+/rFWrVkn6KH4mT56s3bt3a9OmTWppaQm9P6hfv36KjY2N9EgAAKCbi3gATZkyRe+++64WLFigQCCgjIwMbdmyJfRG5wMHDsjp/PiFqKuuukrr1q3T/Pnzdd9992no0KF69tlnNXLkSEnS22+/rY0bN0qSMjIywh7rhRde0Fe/+tVIjwQAALq5iP8coK6InwMEAED3021+DhAAAEBXRAABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsM4FCaAVK1ZoyJAhiouLU3Z2tnbu3HnG9aWlpRo2bJji4uI0atQobd68Oex+Y4wWLFigAQMGKD4+Xjk5OXr99dcjOQIAAIgiEQ+gDRs2qLCwUMXFxdq9e7dGjx6t3NxcHT58uN315eXlys/PV0FBgaqqqpSXl6e8vDxVV1eH1jz88MNatmyZVq5cqR07dqh3797Kzc3ViRMnIj0OAACIAg5jjInkA2RnZ+tLX/qSli9fLklqbW2Vz+fTrFmzNHfu3FPWT5kyRceOHdOmTZtCx8aOHauMjAytXLlSxhilpqZq9uzZuvvuuyVJ9fX1SklJ0erVq/Xtb3/7M68pGAzK4/Govr5ebrf7PE0KAAAi6Xw+f0f0FaCmpiZVVlYqJyfn4wd0OpWTk6OKiop2z6moqAhbL0m5ubmh9fv371cgEAhb4/F4lJ2dfdo9GxsbFQwGw24AAMBeEQ2gI0eOqKWlRSkpKWHHU1JSFAgE2j0nEAiccX3bPzuzZ0lJiTweT+jm8/nOah4AABAdrPgUWFFRkerr60O3gwcPXuxLAgAAF1FEAygpKUk9evRQbW1t2PHa2lp5vd52z/F6vWdc3/bPzuzpcrnkdrvDbgAAwF4RDaDY2FhlZmaqrKwsdKy1tVVlZWXy+/3tnuP3+8PWS9LWrVtD6y+55BJ5vd6wNcFgUDt27DjtngAAAJ8UE+kHKCws1LRp0zRmzBhlZWVpyZIlOnbsmKZPny5Jmjp1qgYOHKiSkhJJ0l133aVx48Zp8eLFmjhxotavX6+XX35Zq1atkiQ5HA79+Mc/1oMPPqihQ4fqkksu0f3336/U1FTl5eVFehwAABAFIh5AU6ZM0bvvvqsFCxYoEAgoIyNDW7ZsCb2J+cCBA3I6P34h6qqrrtK6des0f/583XfffRo6dKieffZZjRw5MrTmnnvu0bFjxzRjxgzV1dXpy1/+srZs2aK4uLhIjwMAAKJAxH8OUFfEzwECAKD76TY/BwgAAKArIoAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWCdiAXT06FHdfPPNcrvd6tu3rwoKCvTBBx+c8ZwTJ05o5syZSkxMVEJCgiZNmqTa2trQ/a+88ory8/Pl8/kUHx+v9PR0LV26NFIjAACAKBWxALr55ptVU1OjrVu3atOmTdq+fbtmzJhxxnN+8pOf6LnnnlNpaan+8pe/6NChQ/rWt74Vur+yslL9+/fXmjVrVFNTo3nz5qmoqEjLly+P1BgAACAKOYwx5nxvunfvXg0fPly7du3SmDFjJElbtmzRDTfcoLfeekupqamnnFNfX6/k5GStW7dOkydPliS99tprSk9PV0VFhcaOHdvuY82cOVN79+7Vtm3bOnx9wWBQHo9H9fX1crvdZzEhAAC40M7n83dEXgGqqKhQ3759Q/EjSTk5OXI6ndqxY0e751RWVqq5uVk5OTmhY8OGDdOgQYNUUVFx2seqr69Xv379zt/FAwCAqBcTiU0DgYD69+8f/kAxMerXr58CgcBpz4mNjVXfvn3DjqekpJz2nPLycm3YsEF/+tOfzng9jY2NamxsDP06GAx2YAoAABCtOvUK0Ny5c+VwOM54e+211yJ1rWGqq6t14403qri4WNdee+0Z15aUlMjj8YRuPp/vglwjAADomjr1CtDs2bP13e9+94xrLr30Unm9Xh0+fDjs+MmTJ3X06FF5vd52z/N6vWpqalJdXV3Yq0C1tbWnnLNnzx5NmDBBM2bM0Pz58z/zuouKilRYWBj6dTAYJIIAALBYpwIoOTlZycnJn7nO7/errq5OlZWVyszMlCRt27ZNra2tys7ObveczMxM9ezZU2VlZZo0aZIkad++fTpw4ID8fn9oXU1Nja655hpNmzZNDz30UIeu2+VyyeVydWgtAACIfhH5FJgkXX/99aqtrdXKlSvV3Nys6dOna8yYMVq3bp0k6e2339aECRP01FNPKSsrS5L0gx/8QJs3b9bq1avldrs1a9YsSR+910f66K+9rrnmGuXm5mrRokWhx+rRo0eHwqwNnwIDAKD7OZ/P3xF5E7QkrV27VnfeeacmTJggp9OpSZMmadmyZaH7m5ubtW/fPh0/fjx07JFHHgmtbWxsVG5urh599NHQ/b/73e/07rvvas2aNVqzZk3o+ODBg/XGG29EahQAABBlIvYKUFfGK0AAAHQ/Xf7nAAEAAHRlBBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6xBAAADAOhELoKNHj+rmm2+W2+1W3759VVBQoA8++OCM55w4cUIzZ85UYmKiEhISNGnSJNXW1ra79r333lNaWpocDofq6uoiMAEAAIhWEQugm2++WTU1Ndq6das2bdqk7du3a8aMGWc85yc/+Ymee+45lZaW6i9/+YsOHTqkb33rW+2uLSgo0BVXXBGJSwcAAFHOYYwx53vTvXv3avjw4dq1a5fGjBkjSdqyZYtuuOEGvfXWW0pNTT3lnPr6eiUnJ2vdunWaPHmyJOm1115Tenq6KioqNHbs2NDaxx57TBs2bNCCBQs0YcIEvf/+++rbt2+Hry8YDMrj8ai+vl5ut/vchgUAABfE+Xz+jsgrQBUVFerbt28ofiQpJydHTqdTO3bsaPecyspKNTc3KycnJ3Rs2LBhGjRokCoqKkLH9uzZo//6r//SU089JaezY5ff2NioYDAYdgMAAPaKSAAFAgH1798/7FhMTIz69eunQCBw2nNiY2NPeSUnJSUldE5jY6Py8/O1aNEiDRo0qMPXU1JSIo/HE7r5fL7ODQQAAKJKpwJo7ty5cjgcZ7y99tprkbpWFRUVKT09Xbfcckunz6uvrw/dDh48GKErBAAA3UFMZxbPnj1b3/3ud8+45tJLL5XX69Xhw4fDjp88eVJHjx6V1+tt9zyv16umpibV1dWFvQpUW1sbOmfbtm169dVX9bvf/U6S1Pb2paSkJM2bN08LFy5sd2+XyyWXy9WREQEAgAU6FUDJyclKTk7+zHV+v191dXWqrKxUZmampI/ipbW1VdnZ2e2ek5mZqZ49e6qsrEyTJk2SJO3bt08HDhyQ3++XJP3+97/Xhx9+GDpn165duu222/TSSy/p85//fGdGAQAAFutUAHVUenq6rrvuOt1+++1auXKlmpubdeedd+rb3/526BNgb7/9tiZMmKCnnnpKWVlZ8ng8KigoUGFhofr16ye3261Zs2bJ7/eHPgH26cg5cuRI6PE68ykwAABgt4gEkCStXbtWd955pyZMmCCn06lJkyZp2bJlofubm5u1b98+HT9+PHTskUceCa1tbGxUbm6uHn300UhdIgAAsFREfg5QV8fPAQIAoPvp8j8HCAAAoCsjgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdQggAABgHQIIAABYhwACAADWIYAAAIB1CCAAAGAdAggAAFiHAAIAANYhgAAAgHUIIAAAYB0CCAAAWIcAAgAA1iGAAACAdWIu9gVcDMYYSVIwGLzIVwIAADqq7Xm77Xn8XFgZQA0NDZIkn893ka8EAAB0VkNDgzwezznt4TDnI6O6mdbWVh06dEh9+vSRw+E4r3sHg0H5fD4dPHhQbrf7vO7dFTBf9xftMzJf9xftMzLf2TPGqKGhQampqXI6z+1dPFa+AuR0OpWWlhbRx3C73VH5jd2G+bq/aJ+R+bq/aJ+R+c7Oub7y04Y3QQMAAOsQQAAAwDoE0HnmcrlUXFwsl8t1sS8lIpiv+4v2GZmv+4v2GZmva7DyTdAAAMBuvAIEAACsQwABAADrEEAAAMA6BBAAALBO1AfQihUrNGTIEMXFxSk7O1s7d+4Mu3/VqlX66le/KrfbLYfDobq6ug7te+DAAU2cOFG9evVS//79NWfOHJ08eTJ0/zvvvKPvfOc7uuyyy+R0OvXjH//4vOwrSS+++KKuvPJKuVwuJScnKykpKWrm++tf/6qrr75aiYmJio+PV0pKivr16xc180lSY2Oj5s2bp8GDB8vlcikxMTGqvobSR7/v0tPTQ1/D5OTkbjPfj370I2VmZsrlcikjI+OU+1988UXdeOONGjBggHr37q20tLSomu+NN96Qw+E45TZgwIComVGSnn/+eY0dO1Z9+vRRQkKCevfuLZfL1eXne+WVV5Sfny+fz6f4+Hilp6dr6dKlYWs+ve/48eMvyvPgH/7wB33ta19TcnKy3G63/H6/nn/++c/c95///Kf+4z/+Q3FxcfL5fHr44YdPWVNaWqphw4YpLi5Oo0aN0ubNmzt0zZ8U1QG0YcMGFRYWqri4WLt379bo0aOVm5urw4cPh9YcP35c1113ne67774O79vS0qKJEyeqqalJ5eXlevLJJ7V69WotWLAgtKaxsVHJycmaP3++Ro8efd723b9/vyZOnKjx48erpKREdXV1Onr0qJYtWxYV8/Xu3Vt33nmntm/frkWLFuno0aM6duyY5s6dGxXzSdJNN92ksrIy/frXv9bixYvV0NCgGTNmRM336GOPPaaioiI98MAD+tnPfqajR4+qoaFBixcv7vLztbnttts0ZcqUdu8rLy/XFVdcod///vcqKSlRIBDQe++9p1/84hdRMV+bP//5z3rnnXe0cuVKxcbG6qc//Wm3+B7tyIz79+/XjTfeqGuuuUYPPfSQmpqalJaWpksvvbTLz1dZWan+/ftrzZo1qqmp0bx581RUVKTly5e3u++gQYP00ksvXZTnwe3bt+trX/uaNm/erMrKSo0fP17f+MY3VFVVddp9g8Ggrr32Wg0ePFiVlZVatGiRHnjgAa1atSq0pry8XPn5+SooKFBVVZXy8vKUl5en6urqDl+/JMlEsaysLDNz5szQr1taWkxqaqopKSk5Ze0LL7xgJJn333//M/fdvHmzcTqdJhAIhI499thjxu12m8bGxlPWjxs3ztx1113nZd977rnHjBgxImy+KVOmmNzc3KiY75Pa5vvP//xPc8stt0TFfP/7v/9rPB6Pee+998JmbBMNM/r9fnP33XeHzVdYWGiuvvrqLj/fJxUXF5vRo0efcU3bfDfccIOZPn16VMy3f/9+I8lUVVUZY7rf9+gnnW7G0tJSExMTY1paWkLzbdy40TgcDnPixIluM1+bH/7wh2b8+PHt3tenTx9zxRVXhH59sb5+bYYPH24WLlx42vsfffRR87nPfS5sj3vvvddcfvnloV/fdNNNZuLEiWHnZWdnmzvuuOMzr/uTovYVoKamJlVWVionJyd0zOl0KicnRxUVFee0d0VFhUaNGqWUlJTQsdzcXAWDQdXU1ER034qKCuXk5ITNl5ubq4qKiqiYr03bfJdeeqnKy8s1bty4qJhv48aNGjNmjB5++GGlpqZq586dOnjwoD788ENJ0fE92tjYqLi4uLDv0fj4eO3cuVMtLS1der7O+OR89fX16tevX5f/+nXGN7/5TSUnJ2vnzp1h/z+naJgxMzNTTqdTjz/+uCorK+X3+/Xb3/5WOTk5crlc3W6+tu+/T2tqalJDQ4MGDRoUOnYxv36tra1qaGho91o/ue9XvvIVxcbGhu27b98+vf/++6E1n3xub1vT2ZmiNoCOHDmilpaWsC+OJKWkpCgQCJzT3oFAoN192+6L5L5taz45X0pKioLBoD788MNuP1+bwYMHq6WlRXfffbdmzpyp733ve6H13Xm+f//73/rrX/+q6upqPf7445KknTt36oc//GHYOd15xtzcXD3xxBPatm2bWlpadPToUT3xxBNqbm7WkSNHuvR8ndH2e7C6ulq7du3S9OnTQ9fRnedLSEjQ4sWLVVpaqieffFKSVFJSoo0bN4ZdS3ee8ZJLLtH//d//ad68eWppadEtt9yit956S88880zoOrrLfOXl5dqwYYNmzJhxyn1HjhyRJPXq1euU67gY8/385z/XBx98oJtuuumc9j3dms7OFLUBdL5cf/31SkhIUEJCgkaMGHGxL+e866rz/fGPf5Qk3XPPPVqyZImefvrps9qnq83X2toqh8OhtWvX6otf/KKkj96w+eSTT4ZeBeqsrjbj/fffr+uvv15f//rXJUn33nuvpk2bJumj//rsrK4236c9+OCDevzxx8/62rrafElJSSosLFR2dnboDcTXXXedFi1adNZ7drUZA4GAbr/99tAT8YoVKxQbG6vJkyfLnMX/HOFizVddXa0bb7xRxcXFuvbaayP2OOdjvnXr1mnhwoV65pln1L9///N8hWcn5mJfQKQkJSWpR48eqq2tDTteW1srr9fb4X2eeOKJ0BNTz549JUler/eUd9G3PU5n9v60juzr9XpVW1sbNt/7778vt9ut+Pj4bj9fmyuvvFI9evTQ2LFjlZCQoAceeED5+fndfr4BAwZo4MCB8ng8io+PV48ePZSQkCBjjN566y0NHTq0288YHx+v3/zmN/rlL38pj8ejX/3qV6qtrVWfPn2UnJzcpefrjD179kj66M22U6dODbuOaJhP+vjPUZ/Pp+eeey7sWrrzjCtWrJDH49GSJUu0atUqpaamas2aNfL5fNqxY0e3mG/Pnj2aMGGCZsyYofnz57e7JikpSdJHb3L+9HVcyPnWr1+v733veyotLT3lr64+re057kz7nm5NZ/+9Ru0rQLGxscrMzFRZWVnoWGtrq8rKyuT3+zu8z8CBA/WFL3xBX/jCFzR48GBJkt/v16uvvhr2LvqtW7fK7XZr+PDhZ33NHdnX7/errKwsbL6tW7fK7/dHxXxtPjlfa2urGhsbo2K+q6++WocOHdIHH3wQmnHLli1yOp1KS0uLihnb9O7dW5mZmXrhhRe0fv360CtCXXm+jnrxxReVl5enwYMHq0ePHqHjXf3r11lt36N/+9vfNGDAAEnRMePx48fldDrD/pxp+zqePHmyy89XU1Oj8ePHa9q0aXrooYdOuy42NlZ9+vTRwYMHQ8cu9Nfv6aef1vTp0/X0009r4sSJn/lYfr9f27dvV3Nzc9i+l19+uT73uc+F1nzyub1tTWdmkhTdnwJbv369cblcZvXq1WbPnj1mxowZpm/fvmHvWn/nnXdMVVWVefzxx40ks337dlNVVRX6lE57Tp48aUaOHGmuvfZa849//MNs2bLFJCcnm6KiorB1VVVVpqqqymRmZprvfOc7pqqqytTU1JzTvv/+979Nr169zJw5c8zixYtNTEyMcTgcZtWqVVEx3/Lly83GjRvNv/71L/PII4+YmJgYExcXZ+64446omK+hocGkpaWZyZMnm5qaGlNcXGwcDof5yle+EjXfo/v27TO//e1vzb/+9S/z4IMPGqfTaXr37m22bt3a5eczxpjXX3/dVFVVmTvuuMNcdtlloT3aPpWybds206tXL1NUVGRWrlxpXC6XWbp0qSkvL4+K+VavXm3WrVtn9u7da/bu3WumTJliJJmCgoJu8T3akRnLysqMw+EwCxcuNI888oiJjY01I0eONKmpqea2227r0vO9+uqrJjk52dxyyy3mnXfeCd0OHz7c7r6XXHKJcTqdZuHChWbjxo0X9Ou3du1aExMTY1asWBF2rXV1dafdt66uzqSkpJhbb73VVFdXm/Xr15tevXqZX/3qV6E1f/vb30xMTIz5+c9/bvbu3WuKi4tNz549zauvvnrafdsT1QFkjDG//OUvzaBBg0xsbKzJysoyf//738PuLy4uNpJOuf3P//zPGfd94403zPXXX2/i4+NNUlKSmT17tmlubg5b096+gwcPPud9X3jhBZORkWFiY2NNYmKiSUxMjJr5li1bZkaMGGF69epl3G63SUtLM/369Yua+YwxZu/evSYnJ8fEx8ebtLQ0M378eOPz+aJmxj179piMjAwTHx9v3G63GTVqlElNTe02840bN67d8/bv32+MMWbatGnt3u9wOKJivtWrV5v09PTQ78GsrCxz2223das/Rz9rRmOMefrpp80Xv/hF07t3b5OQkGDi4+NNz549u/x8p7uWT5/T3hpJF3S+030dpk2bdsZ9X3nlFfPlL3/ZuFwuM3DgQPPf//3fp6x55plnzGWXXWZiY2PNiBEjzJ/+9Kcz7tkehzFn8Y4vAACAbixq3wMEAABwOgQQAACwDgEEAACsQwABAADrEEAAAMA6BBAAALAOAQQAAKxDAAEAAOsQQAAAwDoEEAAAsA4BBAAArEMAAQAA6/w/Z2N1hO6Dgk8AAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "X = ds[\"Şimdi\"]\n", "Y = ds[\"Tarih\"]\n", "X = np.array(X).reshape((len(X), 1))\n", "Y = np.array(Y).reshape((len(Y), 1))\n", "fig = plt.figure()\n", "ax = fig.add_subplot(111)\n", "ax.plot_date(Y, X, \".\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4000, 207)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Split train and test data\n", "\n", "date_split = 4000\n", "train = ds[:date_split]\n", "test = ds[date_split:]\n", "len(train), len(test)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Define envireonment" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "class Environment:\n", " def __init__(self, data, tl, history_t=10):\n", " self.data = data\n", " self.history_t = history_t\n", " self.tl_start = tl\n", " self.reset()\n", "\n", " def reset(self):\n", " self.tl = self.tl_start\n", " self.usd = 0\n", " self.done = False\n", " self.profits = 0\n", " self.current_position = \"none\"\n", " self.history = [self.data.iloc[x, :][\"Fark %\"] for x in range(self.history_t)]\n", " self.t = self.history_t\n", " self.last_tl = 0\n", " return self.history\n", "\n", " def step(self, act):\n", " reward = 0\n", " if act == 0: # Hold\n", " self.current_position = self.current_position\n", " elif act == 1: # Buy\n", " if self.current_position == \"none\":\n", " self.current_position = \"long\"\n", " # Buy usd\n", "\n", " self.last_tl = self.tl\n", " self.usd = self.tl / (self.data.iloc[self.t, :][\"Şimdi\"])\n", " self.tl = 0\n", " else:\n", " self.current_position = self.current_position\n", "\n", " else: # sell\n", " if self.current_position == \"long\":\n", " self.current_position = \"none\"\n", " # Sell usd\n", "\n", " self.tl = self.usd * (self.data.iloc[self.t, :][\"Şimdi\"])\n", " self.usd = 0\n", " self.profits = self.profits + (self.tl - self.last_tl)\n", "\n", " if (self.tl - self.last_tl) > 0:\n", " reward = 1\n", " else:\n", " reward = -1\n", " else:\n", " self.current_position = self.current_position\n", "\n", " # et next time\n", " self.t += 1\n", " # print(\"history before: \",self.history)\n", " self.history.pop(0)\n", " self.history.append(self.data.iloc[self.t, :][\"Fark %\"])\n", " # print(\"history after: \",self.history)\n", "\n", " # print(\"reward: \",reward)\n", "\n", " if ENVIRONMENT_DEBUG == True:\n", " print(\n", " \"t: \",\n", " (self.t - self.history_t),\n", " \" reward: \",\n", " reward,\n", " \" profits: \",\n", " self.profits,\n", " \" current position: \",\n", " self.current_position,\n", " \" done: \",\n", " self.done,\n", " )\n", "\n", " if self.t == (len(self.data) - 1):\n", " self.done = True\n", " print(\n", " \"Total steps: \",\n", " (self.t - self.history_t),\n", " \" TotalProfit: \",\n", " self.profits,\n", " \" done: \",\n", " self.done,\n", " )\n", "\n", " return self.history, reward, self.done, self.profits # obs, reward, done" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Agent class" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# Deep Q-learning Agent\n", "class DQNAgent:\n", " def __init__(self, state_size, action_size, hidden_layer_size):\n", " self.state_size = state_size\n", " self.action_size = action_size\n", " self.hidden_layer_size = hidden_layer_size\n", " self.memory = deque(maxlen=2000)\n", " self.gamma = 0.95 # discount rate\n", " self.epsilon = 1.0 # exploration rate\n", " self.epsilon_min = 0.01\n", " self.epsilon_decay = 0.995\n", " self.learning_rate = 0.001\n", " self.model = self._build_model()\n", "\n", " def _build_model(self):\n", " # Neural Net for Deep-Q learning Model\n", " model = Sequential()\n", " model.add(\n", " Dense(self.hidden_layer_size, input_dim=self.state_size, activation=\"relu\")\n", " )\n", " model.add(Dense(self.hidden_layer_size, activation=\"relu\"))\n", " model.add(Dense(self.action_size, activation=\"linear\"))\n", " model.compile(loss=\"mse\", optimizer=Adam(learning_rate=self.learning_rate))\n", " return model\n", "\n", " def remember(self, state, action, reward, next_state, done):\n", " self.memory.append((state, action, reward, next_state, done))\n", "\n", " def act(self, state):\n", " state = np.array(state).astype(float)\n", " state = np.reshape(state, [1, self.state_size])\n", " if np.random.rand() <= self.epsilon:\n", " return random.randrange(self.action_size)\n", " act_values = self.model.predict(state)\n", " return np.argmax(act_values[0]) # returns action\n", "\n", " def act_greedy(self, state):\n", " state = np.array(state).astype(float)\n", " state = np.reshape(state, [1, self.state_size])\n", " act_values = self.model.predict(state)\n", " return np.argmax(act_values[0]) # returns action\n", "\n", " def replay(self, batch_size):\n", " minibatch = random.sample(self.memory, batch_size)\n", " for state, action, reward, next_state, done in minibatch:\n", " target = reward\n", " if not done:\n", " target = reward + self.gamma * np.amax(\n", " self.model.predict(next_state)[0]\n", " )\n", " target_f = self.model.predict(state)\n", " target_f[0][action] = target\n", " self.model.fit(state, target_f, epochs=1, verbose=0)\n", " if self.epsilon > self.epsilon_min:\n", " self.epsilon *= self.epsilon_decay" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Train the DQN" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WARNING:tensorflow:From d:\\conda\\envs\\py39\\lib\\site-packages\\keras\\src\\backend.py:873: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", "\n", "Total steps: 3909 TotalProfit: -36.91076629230869 done: True\n", "1/1 [==============================] - 1s 603ms/step\n", "1/1 [==============================] - 0s 126ms/step\n", "WARNING:tensorflow:From d:\\conda\\envs\\py39\\lib\\site-packages\\keras\\src\\utils\\tf_utils.py:492: The name tf.ragged.RaggedTensorValue is deprecated. Please use tf.compat.v1.ragged.RaggedTensorValue instead.\n", "\n", "1/1 [==============================] - 0s 148ms/step\n", "1/1 [==============================] - 0s 82ms/step\n", "1/1 [==============================] - 0s 79ms/step\n", "1/1 [==============================] - 0s 239ms/step\n", "1/1 [==============================] - 0s 147ms/step\n", "1/1 [==============================] - 0s 136ms/step\n", "1/1 [==============================] - 0s 110ms/step\n", "1/1 [==============================] - 0s 140ms/step\n", "1/1 [==============================] - 0s 110ms/step\n", "1/1 [==============================] - 0s 116ms/step\n", "1/1 [==============================] - 0s 207ms/step\n", "1/1 [==============================] - 0s 91ms/step\n", "1/1 [==============================] - 0s 224ms/step\n", "1/1 [==============================] - 0s 203ms/step\n", "1/1 [==============================] - 0s 142ms/step\n", "1/1 [==============================] - 0s 93ms/step\n", "1/1 [==============================] - 0s 73ms/step\n", "1/1 [==============================] - 0s 112ms/step\n", "1/1 [==============================] - 0s 112ms/step\n", "1/1 [==============================] - 0s 247ms/step\n", "1/1 [==============================] - 0s 195ms/step\n", "1/1 [==============================] - 0s 126ms/step\n", "1/1 [==============================] - 0s 219ms/step\n", "1/1 [==============================] - 0s 133ms/step\n", "1/1 [==============================] - 0s 92ms/step\n", "1/1 [==============================] - 0s 93ms/step\n", "1/1 [==============================] - 0s 157ms/step\n", "1/1 [==============================] - 0s 196ms/step\n", "1/1 [==============================] - 0s 172ms/step\n", "1/1 [==============================] - 0s 176ms/step\n", "1/1 [==============================] - 0s 163ms/step\n", "1/1 [==============================] - 0s 113ms/step\n", "1/1 [==============================] - 0s 116ms/step\n", "1/1 [==============================] - 0s 155ms/step\n", "1/1 [==============================] - 0s 188ms/step\n", "1/1 [==============================] - 0s 147ms/step\n", "1/1 [==============================] - 0s 101ms/step\n", "1/1 [==============================] - 0s 162ms/step\n", "1/1 [==============================] - 0s 181ms/step\n", "1/1 [==============================] - 0s 150ms/step\n", "1/1 [==============================] - 0s 123ms/step\n", "1/1 [==============================] - 0s 127ms/step\n", "1/1 [==============================] - 0s 154ms/step\n", "1/1 [==============================] - 0s 183ms/step\n", "1/1 [==============================] - 0s 215ms/step\n", "1/1 [==============================] - 0s 63ms/step\n", "1/1 [==============================] - 0s 149ms/step\n", "1/1 [==============================] - 0s 122ms/step\n", "1/1 [==============================] - 0s 90ms/step\n", "1/1 [==============================] - 0s 135ms/step\n", "1/1 [==============================] - 0s 157ms/step\n", "1/1 [==============================] - 0s 123ms/step\n", "1/1 [==============================] - 0s 142ms/step\n", "1/1 [==============================] - 0s 126ms/step\n", "1/1 [==============================] - 0s 177ms/step\n", "1/1 [==============================] - 0s 202ms/step\n", "1/1 [==============================] - 0s 67ms/step\n", "1/1 [==============================] - 0s 153ms/step\n", "1/1 [==============================] - 0s 89ms/step\n", "1/1 [==============================] - 0s 99ms/step\n", "1/1 [==============================] - 0s 131ms/step\n", "1/1 [==============================] - 0s 234ms/step\n" ] } ], "source": [ "if __name__ == \"__main__\":\n", " # macros\n", " EPISODES = 1\n", " STATE_SIZE = 90\n", "\n", " # profits list\n", " total_profits = []\n", "\n", " # initialize environment and the agent\n", " env = Environment(train, 100, STATE_SIZE) # 100tl, 60 history\n", " agent = DQNAgent(STATE_SIZE, 3, 100)\n", "\n", " # Iterate the game\n", " for e in range(EPISODES):\n", " # check if the buy and sell actions are taken\n", " actions_count = 0\n", "\n", " # reset state in the beginning of each game\n", " state = env.reset()\n", " state = np.reshape(state, [1, STATE_SIZE])\n", "\n", " # time_t represents each frame of the game\n", " # the more time_t the more score\n", " for time_t in range(5000):\n", " # Decide action\n", " action = agent.act(state)\n", "\n", " if (action == 1) or (action == 2):\n", " actions_count = actions_count + 1\n", "\n", " # Advance the game to the next frame based on the action.\n", " next_state, reward, done, profits = env.step(action)\n", " next_state = np.array(next_state, dtype=np.float32)\n", " next_state = np.reshape(next_state, [1, STATE_SIZE])\n", "\n", " # make rewards = profits (EXPERIMENTAL)\n", " reward = profits\n", "\n", " # Remember the previous state, action, reward, and done\n", " agent.remember(state, action, reward, next_state, done)\n", "\n", " # make next_state the new current state for the next frame.\n", " state = next_state\n", "\n", " # done becomes True when the game ends\n", " if done:\n", " total_profits.append(profits)\n", " # print the score and break out of the loop\n", " # print(\"number of actions taken other than hold in this iteration is \",actions_count,\"\\n\")\n", " # print(\"episode: {}/{}, score: {}\".format(e, EPISODES, time_t))\n", " break\n", " # train the agent with the experience of the episode\n", " agent.replay(32)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def plot_profits(total_profits):\n", " epoch_count = range(1, len(total_profits) + 1)\n", " fig = plt.figure(figsize=(30, 10))\n", " plt.plot(epoch_count, total_profits, \"b-\")\n", " plt.legend(\"Total Profits\")\n", " plt.xlabel(\"Epoch\")\n", " plt.ylabel(\"Total Profits\")\n", " plt.figure(figsize=(50, 10))\n", " plt.show();" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAACXAAAANBCAYAAABDYwRbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABY5UlEQVR4nOzdf5BdZZ3n8c/tTqebJHQH0x3SwQYJGhJcGShE7BgdMc6K4MaMZLe0MDFOhHGGLa1ImARKfrqAMDjLlMuu5TIEnc0s4hgkhFpJVAq3JiSkkLg7mMTdiEkghB/20i1EmiR99w/LW2Qg4Xbo5jHp16vqVPW955znfk///a7nVKrVajUAAAAAAAAAAAC86RpKDwAAAAAAAAAAADBSCbgAAAAAAAAAAAAKEXABAAAAAAAAAAAUIuACAAAAAAAAAAAoRMAFAAAAAAAAAABQiIALAAAAAAAAAACgEAEXAAAAAAAAAABAIQIuAAAAAAAAAACAQkaVHuBIMDAwkJ07d+boo49OpVIpPQ4AAAAAAAAAAFBYtVrNb37zm0yePDkNDQfeZ0vANQR27tyZrq6u0mMAAAAAAAAAAAB/YHbs2JG3vvWtBzwv4BoCRx99dJLf/bNbW1sLTwMAAAAAAAAAAJTW19eXrq6uWlt0IAKuIfD71ya2trYKuAAAAAAAAAAAgJrft0UHcuCXKwIAAAAAAAAAADCsBFwAAAAAAAAAAACFCLgAAAAAAAAAAAAKGVV6AAAAAAAAAAAA4MhTrVazd+/e7Nu3r/Qow6KxsTGjRo1KpVJ5Q+sIuAAAAAAAAAAAgCH18ssv56mnnsru3btLjzKsxowZk87OzowePfqQ1xBwAQAAAAAAAAAAQ2ZgYCCPP/54GhsbM3ny5IwePfoN71L1h6Zarebll1/Os88+m8cffzzveMc70tDQcEhrCbgAAAAAAAAAAIAh8/LLL2dgYCBdXV0ZM2ZM6XGGzVFHHZWmpqZs27YtL7/8clpaWg5pnUPLvgAAAAAAAAAAAA7iUHekOpwMxTMe+f8lAAAAAAAAAACAP1ACLgAAAAAAAAAAgEIEXAAAAAAAAAAAAIUIuAAAAAAAAAAAgBGvUqkc9Lj66quH5XdHDcuqAAAAAAAAAAAAh5Gnnnqq9vd3vvOdXHnlldmyZUvtu3Hjxg3L7wq4AAAAAAAAAACAYVWtJrt3l/ntMWOSSuX1r5s0aVLt77a2tlQqlf2+Gy4CLgAAAAAAAAAAYFjt3p0M0wZWr+uFF5KxY8v8dj0aSg9Qr9mzZ+f4449PS0tLOjs7M2/evOzcubN2/le/+tVrvnty3bp1B113+/btOe+88zJmzJhMnDgxl156afbu3TvcjwMAAAAAAAAAAHD47MB19tln5/LLL09nZ2eefPLJLF68OHPnzs3atWv3u+6HP/xh3vnOd9Y+T5gw4YBr7tu3L+edd14mTZqUtWvX5qmnnsr8+fPT1NSU66+/ftieBQAAAAAAAAAARpIxY363E1ap3/5DdtgEXIsWLar9fcIJJ2Tp0qWZM2dO9uzZk6amptq5CRMm1P3uydWrV+fnP/95fvjDH+bYY4/Naaedlq985StZsmRJrr766owePXrInwMAAAAAAAAAAEaaSuUP+zWGJR02r1B8pZ6enixfvjwzZszYL95KfveqxYkTJ2bmzJlZuXLlQdd56KGH8q53vSvHHnts7buPfOQj6evry2OPPXbA+/r7+9PX17ffAQAAAAAAAAAAMFiHVcC1ZMmSjB07NhMmTMj27dtzzz331M6NGzcuX/va1/Ld73439913X2bOnJk5c+YcNOLatWvXfvFWktrnXbt2HfC+G264IW1tbbWjq6vrDT4ZAAAAAAAAAAAwEhUNuJYuXZpKpXLQY/PmzbXrL7300jz66KNZvXp1GhsbM3/+/FSr1SRJe3t7vvSlL+Wss87KmWeema9+9av59Kc/nb/+678e8rkvu+yy9Pb21o4dO3YM+W8AAAAAAAAAAABHvlElf/ySSy7JggULDnrNlClTan+3t7envb09U6dOzfTp09PV1ZV169alu7v7Ne8966yzsmbNmgOuPWnSpDz88MP7fff000/Xzh1Ic3NzmpubDzo3AAAAAAAAAABweFqwYMHrdk1DpWjA1dHRkY6OjkO6d2BgIEnS399/wGs2btyYzs7OA57v7u7Oddddl2eeeSYTJ05MkqxZsyatra055ZRTDmkuAAAAAAAAAACAehUNuOq1fv36bNiwITNnzswxxxyTrVu35oorrshJJ51U233rW9/6VkaPHp3TTz89SbJixYrcfvvtue2222rr3H333bnssstqr2X81//6X+eUU07JvHnzctNNN2XXrl358pe/nIsvvtgOWwAAAAAAAAAAwLA7LAKuMWPG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lFOyYcOGvPvd706S/OAHP8i5556bJ554IpMnT65rlr6+vrS1taW3tzetra1D95AAAAAAAAAAAMBhqd6m6LDZgeuVenp6snz58syYMaMWZp1xxhlpaGjIsmXLsm/fvvT29ubv//7v8+EPf/g1460keeihhzJ+/PhavJUkH/7wh9PQ0JD169cf8Pf7+/vT19e33wEAAAAAAAAAADBYh1XAtWTJkowdOzYTJkzI9u3bc88999TOnXjiiVm9enUuv/zyNDc3Z/z48XniiSdy1113HXC9Xbt2ZeLEift9N2rUqLzlLW/Jrl27DnjfDTfckLa2ttrR1dX1xh8OAAAAAAAAAAAYcYoGXEuXLk2lUjnosXnz5tr1l156aR599NGsXr06jY2NmT9/fn7/Bshdu3blwgsvzGc+85ls2LAhDz74YEaPHp25c+dmqN8Sedlll6W3t7d27NixY0jXBwAAAAAAAAAARoZRJX/8kksuyYIFCw56zZQpU2p/t7e3p729PVOnTs306dPT1dWVdevWpbu7O7feemva2tpy00031a7/b//tv6Wrqyvr16/Pe9/73letPWnSpDzzzDP7fbd379709PRk0qRJB5ypubk5zc3NdT4lAAAAAAAAAADAaysacHV0dKSjo+OQ7h0YGEiS9Pf3J0l2796dhob9NxRrbGzc79p/qbu7O88//3weeeSRnHHGGUmSH//4xxkYGMhZZ511SHMBAAAAAAAAAADUq+grFOu1fv36/Kf/9J+ycePGbNu2LT/+8Y/zqU99KieddFK6u7uTJOedd142bNiQa6+9Nv/n//yf/PSnP81nP/vZnHDCCTn99NOTJA8//HCmTZuWJ598Mkkyffr0nHPOObnwwgvz8MMP55/+6Z/y7//9v88nP/nJTJ48udjzAgAAAAAAAAAAI8NhEXCNGTMmK1asyKxZs3LyySdn4cKFOfXUU/Pggw/WXmX4oQ99KP/wD/+Q73//+zn99NNzzjnnpLm5OT/4wQ9y1FFHJfndLl1btmzJnj17amsvX74806ZNy6xZs3Luuedm5syZ+eY3v1nkOQEAAAAAAAAAgJGlUq1Wq6WHONz19fWlra0tvb29aW1tLT0OAAAAAAAAAABQWL1N0WGxAxcAAAAAAAAAAMCRSMAFAAAAAAAAAABQiIALAAAAAAAAAACgEAEXAAAAAAAAAABAIQIuAAAAAAAAAACAQgRcAAAAAAAAAAAAhQi4AAAAAAAAAAAAChFwAQAAAAAAAAAAFCLgAgAAAAAAAAAAKETABQAAAAAAAAAAUIiACwAAAAAAAAAAoBABFwAAAAAAAAAAQCECLgAAAAAAAAAAgEIEXAAAAAAAAAAAAIUIuAAAAAAAAAAAAAoRcAEAAAAAAAAAABQi4AIAAAAAAAAAAChEwAUAAAAAAAAAAFCIgAsAAAAAAAAAAKAQARcAAAAAAAAAAEAhAi4AAAAAAAAAAIBCBFwAAAAAAAAAAACFCLgAAAAAAAAAAAAKEXABAAAAAAAAAAAUIuACAAAAAAAAAAAoRMAFAAAAAAAAAABQiIALAAAAAAAAAACgEAEXAAAAAAAAAABAIQIuAAAAAAAAAACAQgRcAAAAAAAAAAAAhQi4AAAAAAAAAAAAChFwAQAAAAAAAAAAFCLgAgAAAAAAAAAAKETABQAAAAAAAAAAUIiACwAAAAAAAAAAoBABFwAAAAAAAAAAQCECLgAAAAAAAAAAgEIEXAAAAAAAAAAAAIUIuAAAAAAAAAAAAAoRcAEAAAAAAAAAABQi4AIAAAAAAAAAAChEwAUAAAAAAAAAAFCIgAsAAAAAAAAAAKAQARcAAAAAAAAAAEAhAi4AAAAAAAAAAIBCBFwAAAAAAAAAAACFCLgAAAAAAAAAAAAKEXABAAAAAAAAAAAUIuACAAAAAAAAAAAoRMAFAAAAAAAAAABQiIALAAAAAAAAAACgEAEXAAAAAAAAAABAIQIuAAAAAAAAAACAQgRcAAAAAAAAAAAAhQi4AAAAAAAAAAAAChFwAQAAAAAAAAAAFCLgAgAAAAAAAAAAKETABQAAAAAAAAAAUIiACwAAAOD/t3fvQVqX9f/HX/cCLgsCInJSUfEw4BFBSJHGvqgTqJkYZjpoiJWSgIJjiiYe8NzBMFFS85RihCnoaEKERmkoKC5pIlqaBxCBLDmYhOz+/mjaXxsKZCwfYB+PmXtm78993fdeF/+8YebJ5wYAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCBbTMD1xS9+MbvssksaN26c9u3b59RTT83ChQtrrZk6dWoOOeSQNGvWLK1bt07//v3z5z//eZ2fu9tuu6VUKtV6XHvttXV4EgAAAAAAAAAAgH/aYgKu3r17Z+LEiZk/f34eeOCB/OlPf8oJJ5xQ8/rrr7+e4447LocffngqKyszderULF26NF/60pfW+9mjR4/OO++8U/MYNmxYXR4FAAAAAAAAAAAgSdKw6A1sqBEjRtT8vOuuu2bkyJHp169fVq9enUaNGuW5557LmjVrcuWVV6as7J9d2nnnnZfjjjuuZs0nadasWdq1a1fnZwAAAAAAAAAAAPh3W8wduP7de++9l/Hjx+fQQw+tCbMOOuiglJWV5c4778yaNWvy/vvv55577smRRx65zngrSa699tq0atUqXbt2zXe/+9189NFH61y/atWqLFu2rNYDAAAAAAAAAADgv7VFBVwXXHBBmjZtmlatWuXNN9/MQw89VPNax44d88tf/jIXXXRRysvLs9122+Xtt9/OxIkT1/mZZ599diZMmJAnnngiZ555Zq6++uqcf/7563zPNddckxYtWtQ8OnTosFHOBwAAAAAAAAAA1C+l6urq6qJ++ciRI3Pdddetc828efPSuXPnJMnSpUvz3nvv5Y033sjll1+eFi1a5JFHHkmpVMqiRYty2GGHpV+/fjn55JOzfPnyXHLJJWnYsGGmTZuWUqm0QXu64447cuaZZ2bFihUpLy//2DWrVq3KqlWrap4vW7YsHTp0yPvvv5/mzZtv4OkBAAAAAAAAAICt1bJly9KiRYv1NkWFBlxLlizJX/7yl3Wu2X333bPNNtusdf3tt99Ohw4d8rvf/S49e/bMqFGjMmXKlMyePXutNTNnzswhhxyyQXv6wx/+kP322y8vv/xyOnXqtEHv2dA/bAAAAAAAAAAAoH7Y0Kao4Sbc01pat26d1q1bf6r3VlVVJUnNnbA++OCDlJXV/kbIBg0a1Fq7ISorK1NWVpY2bdp8qn0BAAAAAAAAAABsqLL1LyneM888k7Fjx6aysjJvvPFGHn/88Zx88snZY4890rNnzyTJMccck9mzZ2f06NF59dVXM2fOnAwaNCi77rprunbtmiSZNWtWOnfunAULFiRJZs6cmTFjxmTu3Ll57bXXMn78+IwYMSKnnHJKWrZsWdh5AQAAAAAAAACA+mGLCLiaNGmSBx98MEcccUQ6deqUr33taznggAMyY8aMlJeXJ0kOP/zw3HfffZk8eXK6du2avn37pry8PFOmTElFRUWSf96la/78+Vm9enWSpLy8PBMmTMjnPve57LvvvrnqqqsyYsSI3HrrrYWdFQAAAAAAAAAAqD9K1dXV1UVvYku3od9XCQAAAAAAAAAA1A8b2hRtEXfgAgAAAAAAAAAA2BoJuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoiIALAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgDYvewNaguro6SbJs2bKCdwIAAAAAAAAAAGwO/tUS/ast+iQCro1g+fLlSZIOHToUvBMAAAAAAAAAAGBzsnz58rRo0eITXy9Vry/xYr2qqqqycOHCNGvWLKVSqejtANSpZcuWpUOHDnnrrbfSvHnzorcDQD1nLgGwuTGbANjcmE0AbG7MJqA+qa6uzvLly7PjjjumrKzsE9e5A9dGUFZWlp133rnobQBsUs2bN/eXagA2G+YSAJsbswmAzY3ZBMDmxmwC6ot13XnrXz457QIAAAAAAAAAAKBOCbgAAAAAAAAAAAAKIuAC4L9SXl6eSy+9NOXl5UVvBQDMJQA2O2YTAJsbswmAzY3ZBLC2UnV1dXXRmwAAAAAAAAAAAKiP3IELAAAAAAAAAACgIAIuAAAAAAAAAACAggi4AAAAAAAAAAAACiLgAgAAAAAAAAAAKIiAC6Ceu+mmm7LbbrulcePGOfjggzNr1qxPXLt69eqMHj06e+yxRxo3bpwuXbpkypQpa61bsGBBTjnllLRq1SoVFRXZf//98+yzz9blMQDYimzs2bRmzZqMGjUqHTt2TEVFRfbYY49cccUVqa6uruujALCF+81vfpNjjz02O+64Y0qlUiZPnrze9/z6179Ot27dUl5enj333DN33XXXWmv+m1kHAP+uLmbTNddckx49eqRZs2Zp06ZN+vXrl/nz59fNAQDY6tTVv5v+5dprr02pVMrw4cM32p4BNkcCLoB67Gc/+1nOPffcXHrppZkzZ066dOmSPn36ZPHixR+7/uKLL84tt9ySG2+8MS+99FIGDx6c448/Ps8//3zNmr/+9a/p1atXGjVqlMceeywvvfRSvv/976dly5ab6lgAbMHqYjZdd911GTduXMaOHZt58+bluuuuy3e+853ceOONm+pYAGyhVq5cmS5duuSmm27aoPWvv/56jjnmmPTu3TuVlZUZPnx4vv71r2fq1Kk1a/7bWQcA/64uZtOMGTMyZMiQPP3005k2bVpWr16dz3/+81m5cmVdHQOArUhdzKZ/mT17dm655ZYccMABG3vbAJudUrX/dg5Qbx188MHp0aNHxo4dmySpqqpKhw4dMmzYsIwcOXKt9TvuuGO+/e1vZ8iQITXX+vfvn4qKitx7771JkpEjR+app57Kb3/7201zCAC2KnUxm77whS+kbdu2uf322z9xDQCsT6lUyqRJk9KvX79PXHPBBRfk0UcfzYsvvlhz7aSTTsrf/va3mjtE/rezDgA+ycaaTf9pyZIladOmTWbMmJHDDjtsY28bgK3YxpxNK1asSLdu3XLzzTfnyiuvzIEHHpgxY8bU4e4BiuUOXAD11D/+8Y8899xzOfLII2uulZWV5cgjj8zMmTM/9j2rVq1K48aNa12rqKjIk08+WfP84YcfTvfu3fPlL385bdq0SdeuXXPbbbfVzSEA2KrU1Ww69NBDM3369LzyyitJkrlz5+bJJ5/MUUcdVQenAKA+mzlzZq05liR9+vSpmWOfZtYBwP9ifbPp47z//vtJku23375O9wZA/bShs2nIkCE55phj1loLsLUScAHUU0uXLs2aNWvStm3bWtfbtm2bRYsWfex7+vTpk+uvvz6vvvpqqqqqMm3atDz44IN55513ata89tprGTduXPbaa69MnTo13/zmN3P22Wfn7rvvrtPzALDlq6vZNHLkyJx00knp3LlzGjVqlK5du2b48OEZMGBAnZ4HgPpn0aJFHzvHli1blr///e+fatYBwP9ifbPpP1VVVWX48OHp1atX9ttvv021TQDqkQ2ZTRMmTMicOXNyzTXXFLFFgEIIuADYYDfccEP22muvdO7cOdtss02GDh2aQYMGpazs/4+TqqqqdOvWLVdffXW6du2aM844I9/4xjfyox/9qMCdA7C12pDZNHHixIwfPz733Xdf5syZk7vvvjvf+973xMUAAAD/YciQIXnxxRczYcKEorcCQD311ltv5Zxzzsn48ePXuvM+wNZMwAVQT+2www5p0KBB3n333VrX33333bRr1+5j39O6detMnjw5K1euzBtvvJGXX3452267bXbfffeaNe3bt88+++xT631777133nzzzY1/CAC2KnU1m771rW/V3IVr//33z6mnnpoRI0b4H3wAbHTt2rX72DnWvHnzVFRUfKpZBwD/i/XNpn83dOjQPPLII3niiSey8847b8ptAlCPrG82Pffcc1m8eHG6deuWhg0bpmHDhpkxY0Z++MMfpmHDhlmzZk1BOweoWwIugHpqm222yUEHHZTp06fXXKuqqsr06dPTs2fPdb63cePG2WmnnfLRRx/lgQceyHHHHVfzWq9evTJ//vxa61955ZXsuuuuG/cAAGx16mo2ffDBB7XuyJUkDRo0SFVV1cY9AAD1Xs+ePWvNsSSZNm1azRz7X2YdAHwa65tNSVJdXZ2hQ4dm0qRJefzxx9OxY8dNvU0A6pH1zaYjjjgiL7zwQiorK2se3bt3z4ABA1JZWZkGDRoUsW2AOtew6A0AUJxzzz03AwcOTPfu3fOZz3wmY8aMycqVKzNo0KAkyVe/+tXstNNONXcoeeaZZ7JgwYIceOCBWbBgQS677LJUVVXl/PPPr/nMESNG5NBDD83VV1+dE088MbNmzcqtt96aW2+9tZAzArBlqYvZdOyxx+aqq67KLrvskn333TfPP/98rr/++px++umFnBGALceKFSvyxz/+seb566+/nsrKymy//fbZZZddcuGFF2bBggX5yU9+kiQZPHhwxo4dm/PPPz+nn356Hn/88UycODGPPvpozWesb9YBwLrUxWwaMmRI7rvvvjz00ENp1qxZFi1alCRp0aLFWnfpAoD/tLFnU7NmzbLffvvV+h1NmzZNq1at1roOsDURcAHUY1/5yleyZMmSXHLJJVm0aFEOPPDATJkyJW3btk2SvPnmm7XuWPLhhx/m4osvzmuvvZZtt902Rx99dO65555st912NWt69OiRSZMm5cILL8zo0aPTsWPHjBkzJgMGDNjUxwNgC1QXs+nGG2/MqFGjctZZZ2Xx4sXZcccdc+aZZ+aSSy7Z1McDYAvz7LPPpnfv3jXPzz333CTJwIEDc9ddd+Wdd96p9XXxHTt2zKOPPpoRI0bkhhtuyM4775wf//jH6dOnT82a9c06AFiXuphN48aNS5L83//9X63fdeedd+a0006ru8MAsFWoi9kEUB+Vqqurq4veBAAAAAAAAAAAQH1Utv4lAAAAAAAAAAAA1AUBFwAAAAAAAAAAQEEEXAAAAAAAAAAAAAURcAEAAAAAAAAAABREwAUAAAAAAAAAAFAQARcAAAAAAAAAAEBBBFwAAAAAAAAAAAAFEXABAAAAQMFKpVImT55c9DYAAAAAKICACwAAAIB67bTTTkupVFrr0bdv36K3BgAAAEA90LDoDQAAAABA0fr27Zs777yz1rXy8vKCdgMAAABAfeIOXAAAAADUe+Xl5WnXrl2tR8uWLZP88+sNx40bl6OOOioVFRXZfffd8/Of/7zW+1944YUcfvjhqaioSKtWrXLGGWdkxYoVtdbccccd2XfffVNeXp727dtn6NChtV5funRpjj/++DRp0iR77bVXHn744bo9NAAAAACbBQEXAAAAAKzHqFGj0r9//8ydOzcDBgzISSedlHnz5iVJVq5cmT59+qRly5aZPXt27r///vzqV7+qFWiNGzcuQ4YMyRlnnJEXXnghDz/8cPbcc89av+Pyyy/PiSeemN///vc5+uijM2DAgLz33nub9JwAAAAAbHql6urq6qI3AQAAAABFOe2003LvvfemcePGta5fdNFFueiii1IqlTJ48OCMGzeu5rVDDjkk3bp1y80335zbbrstF1xwQd566600bdo0SfKLX/wixx57bBYuXJi2bdtmp512yqBBg3LllVd+7B5KpVIuvvjiXHHFFUn+GYVtu+22eeyxx9K3b986OjkAAAAAm4OGRW8AAAAAAIrWu3fvWoFWkmy//fY1P/fs2bPWaz179kxlZWWSZN68eenSpUtNvJUkvXr1SlVVVebPn59SqZSFCxfmiCOOWOceDjjggJqfmzZtmubNm2fx4sWf9kgAAAAAbCEEXAAAAADUe02bNl3rKw03loqKig1a16hRo1rPS6VSqqqq6mJLAAAAAGxGyoreAAAAAABs7p5++um1nu+9995Jkr333jtz587NypUra15/6qmnUlZWlk6dOqVZs2bZbbfdMn369E26ZwAAAAC2DO7ABQAAAEC9t2rVqixatKjWtYYNG2aHHXZIktx///3p3r17PvvZz2b8+PGZNWtWbr/99iTJgAEDcumll2bgwIG57LLLsmTJkgwbNiynnnpq2rZtmyS57LLLMnjw4LRp0yZHHXVUli9fnqeeeirDhg3btAcFAAAAYLMj4AIAAACg3psyZUrat29f61qnTp3y8ssvJ0kuv/zyTJgwIWeddVbat2+fn/70p9lnn32SJE2aNMnUqVNzzjnnpEePHmnSpEn69++f66+/vuazBg4cmA8//DA/+MEPct5552WHHXbICSecsOkOCAAAAMBmq1RdXV1d9CYAAAAAYHNVKpUyadKk9OvXr+itAAAAALAVKit6AwAAAAAAAAAAAPWVgAsAAAAAAAAAAKAgDYveAAAAAABszqqrq4veAgAAAABbMXfgAgAAAAAAAAAAKIiACwAAAAAAAAAAoCACLgAAAAAAAAAAgIIIuAAAAAAAAAAAAAoi4AIAAAAAAAAAACiIgAsAAAAAAAAAAKAgAi4AAAAAAAAAAICCCLgAAAAAAAAAAAAKIuACAAAAAAAAAAAoyP8DdQdcY3/TcYcAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_profits(total_profits)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now test the agent with real world data." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TarihŞimdiAçılışYüksekDüşükFark %
4206NaT1.62251,62101,67251,60900.06
4205NaT1.62451,61501,63451,60000.12
4204NaT1.61501,62501,67201,5850-0.58
4203NaT1.69001,62001,69501,62004.64
4202NaT1.66801,68701,71101,6450-1.30
4201NaT1.66151,66601,66951,6400-0.39
4200NaT1.68001,65301,71001,60801.11
4199NaT1.66601,67001,68101,6450-0.83
4198NaT1.67801,65901,69701,65500.72
4197NaT1.68501,67401,70101,66000.42
\n", "
" ], "text/plain": [ " Tarih Şimdi Açılış Yüksek Düşük Fark %\n", "4206 NaT 1.6225 1,6210 1,6725 1,6090 0.06\n", "4205 NaT 1.6245 1,6150 1,6345 1,6000 0.12\n", "4204 NaT 1.6150 1,6250 1,6720 1,5850 -0.58\n", "4203 NaT 1.6900 1,6200 1,6950 1,6200 4.64\n", "4202 NaT 1.6680 1,6870 1,7110 1,6450 -1.30\n", "4201 NaT 1.6615 1,6660 1,6695 1,6400 -0.39\n", "4200 NaT 1.6800 1,6530 1,7100 1,6080 1.11\n", "4199 NaT 1.6660 1,6700 1,6810 1,6450 -0.83\n", "4198 NaT 1.6780 1,6590 1,6970 1,6550 0.72\n", "4197 NaT 1.6850 1,6740 1,7010 1,6600 0.42" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test = test.iloc[::-1]\n", "test.head(10)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1/1 [==============================] - 0s 306ms/step\n", "1/1 [==============================] - 0s 122ms/step\n", "1/1 [==============================] - 0s 131ms/step\n", "1/1 [==============================] - 0s 98ms/step\n", "1/1 [==============================] - 0s 60ms/step\n", "1/1 [==============================] - 0s 110ms/step\n", "1/1 [==============================] - 0s 219ms/step\n", "1/1 [==============================] - 0s 155ms/step\n", "1/1 [==============================] - 0s 212ms/step\n", "1/1 [==============================] - 0s 89ms/step\n", "1/1 [==============================] - 0s 161ms/step\n", "1/1 [==============================] - 0s 197ms/step\n", "1/1 [==============================] - 0s 120ms/step\n", "1/1 [==============================] - 0s 137ms/step\n", "1/1 [==============================] - 0s 120ms/step\n", "1/1 [==============================] - 0s 100ms/step\n", "1/1 [==============================] - 0s 83ms/step\n", "1/1 [==============================] - 0s 146ms/step\n", "1/1 [==============================] - 0s 100ms/step\n", "1/1 [==============================] - 0s 150ms/step\n", "1/1 [==============================] - 0s 160ms/step\n", "1/1 [==============================] - 0s 191ms/step\n", "1/1 [==============================] - 0s 95ms/step\n", "1/1 [==============================] - 0s 140ms/step\n", "1/1 [==============================] - 0s 176ms/step\n", "1/1 [==============================] - 0s 307ms/step\n", "1/1 [==============================] - 0s 284ms/step\n", "1/1 [==============================] - 0s 109ms/step\n", "1/1 [==============================] - 0s 106ms/step\n", "1/1 [==============================] - 0s 93ms/step\n", "1/1 [==============================] - 0s 185ms/step\n", "1/1 [==============================] - 0s 148ms/step\n", "1/1 [==============================] - 0s 411ms/step\n", "1/1 [==============================] - 0s 326ms/step\n", "1/1 [==============================] - 0s 193ms/step\n", "1/1 [==============================] - 0s 331ms/step\n", "1/1 [==============================] - 0s 179ms/step\n", "1/1 [==============================] - 0s 111ms/step\n", "1/1 [==============================] - 0s 154ms/step\n", "1/1 [==============================] - 0s 83ms/step\n", "1/1 [==============================] - 0s 107ms/step\n", "1/1 [==============================] - 0s 220ms/step\n", "1/1 [==============================] - 0s 194ms/step\n", "1/1 [==============================] - 0s 360ms/step\n", "1/1 [==============================] - 0s 224ms/step\n", "1/1 [==============================] - 0s 133ms/step\n", "1/1 [==============================] - 0s 259ms/step\n", "1/1 [==============================] - 0s 326ms/step\n", "1/1 [==============================] - 0s 126ms/step\n", "1/1 [==============================] - 0s 232ms/step\n", "1/1 [==============================] - 0s 196ms/step\n", "1/1 [==============================] - 0s 81ms/step\n", "1/1 [==============================] - 0s 182ms/step\n", "1/1 [==============================] - 0s 168ms/step\n", "1/1 [==============================] - 0s 239ms/step\n", "1/1 [==============================] - 0s 221ms/step\n", "1/1 [==============================] - 0s 291ms/step\n", "1/1 [==============================] - 0s 181ms/step\n", "1/1 [==============================] - 0s 121ms/step\n", "1/1 [==============================] - 0s 163ms/step\n", "1/1 [==============================] - 0s 203ms/step\n", "1/1 [==============================] - 0s 145ms/step\n", "1/1 [==============================] - 0s 96ms/step\n", "1/1 [==============================] - 0s 150ms/step\n", "1/1 [==============================] - 0s 137ms/step\n", "1/1 [==============================] - 0s 178ms/step\n", "1/1 [==============================] - 0s 109ms/step\n", "1/1 [==============================] - 0s 437ms/step\n", "1/1 [==============================] - 0s 288ms/step\n", "1/1 [==============================] - 0s 230ms/step\n", "1/1 [==============================] - 0s 296ms/step\n", "1/1 [==============================] - 0s 207ms/step\n", "1/1 [==============================] - 0s 219ms/step\n", "1/1 [==============================] - 0s 143ms/step\n", "1/1 [==============================] - 0s 174ms/step\n", "1/1 [==============================] - 0s 182ms/step\n", "1/1 [==============================] - 0s 166ms/step\n", "1/1 [==============================] - 0s 142ms/step\n", "1/1 [==============================] - 0s 156ms/step\n", "1/1 [==============================] - 0s 97ms/step\n", "1/1 [==============================] - 0s 206ms/step\n", "1/1 [==============================] - 0s 139ms/step\n", "1/1 [==============================] - 0s 120ms/step\n", "1/1 [==============================] - 0s 118ms/step\n", "1/1 [==============================] - 0s 139ms/step\n", "1/1 [==============================] - 0s 181ms/step\n", "1/1 [==============================] - 0s 189ms/step\n", "1/1 [==============================] - 0s 147ms/step\n", "1/1 [==============================] - 0s 199ms/step\n", "1/1 [==============================] - 0s 173ms/step\n", "1/1 [==============================] - 0s 90ms/step\n", "1/1 [==============================] - 0s 447ms/step\n", "1/1 [==============================] - 0s 429ms/step\n", "1/1 [==============================] - 0s 283ms/step\n", "1/1 [==============================] - 0s 161ms/step\n", "1/1 [==============================] - 0s 145ms/step\n", "1/1 [==============================] - 0s 165ms/step\n", "1/1 [==============================] - 0s 106ms/step\n", "1/1 [==============================] - 0s 109ms/step\n", "1/1 [==============================] - 0s 105ms/step\n", "1/1 [==============================] - 0s 155ms/step\n", "1/1 [==============================] - 0s 68ms/step\n", "1/1 [==============================] - 0s 102ms/step\n", "1/1 [==============================] - 0s 180ms/step\n", "1/1 [==============================] - 0s 304ms/step\n", "1/1 [==============================] - 1s 565ms/step\n", "1/1 [==============================] - 0s 201ms/step\n", "1/1 [==============================] - 0s 407ms/step\n", "1/1 [==============================] - 0s 317ms/step\n", "1/1 [==============================] - 0s 177ms/step\n", "1/1 [==============================] - 0s 155ms/step\n", "1/1 [==============================] - 0s 142ms/step\n", "1/1 [==============================] - 0s 99ms/step\n", "1/1 [==============================] - 0s 149ms/step\n", "1/1 [==============================] - 0s 157ms/step\n", "1/1 [==============================] - 0s 99ms/step\n", "Total steps: 116 TotalProfit: -0.4191616766467092 done: True\n" ] } ], "source": [ "env_test = Environment(test, 100, STATE_SIZE) # 100tl, 60 history\n", "\n", "# Iterate the game\n", "for e in range(1):\n", " # check if the buy and sell actions are taken\n", " actions_count = 0\n", "\n", " # reset state in the beginning of each game\n", " state = env_test.reset()\n", " state = np.reshape(state, [1, STATE_SIZE])\n", "\n", " # time_t represents each frame of the game\n", " # the more time_t the more score\n", " for time_t in range(5000):\n", " # Decide action\n", " action = agent.act_greedy(state)\n", "\n", " if (action == 1) or (action == 2):\n", " actions_count = actions_count + 1\n", "\n", " # Advance the game to the next frame based on the action.\n", " next_state, reward, done, profits = env_test.step(action)\n", "\n", " next_state = np.reshape(next_state, [1, STATE_SIZE])\n", "\n", " # make rewards = profits (EXPERIMENTAL)\n", " reward = profits\n", "\n", " # Remember the previous state, action, reward, and done\n", " agent.remember(state, action, reward, next_state, done)\n", "\n", " # make next_state the new current state for the next frame.\n", " state = next_state\n", "\n", " # done becomes True when the game ends\n", " if done:\n", " break" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Acknowledgement\n", "Thanks to [emrebulbul23](https://www.kaggle.com/emrebulbul23) for creating [DQN on foreign exchange market](https://www.kaggle.com/code/emrebulbul23/dqn-on-foreign-exchange-market). It inspired the majority of the content in this article." ] } ], "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.18" } }, "nbformat": 4, "nbformat_minor": 1 }