Upload 66 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +4 -0
- Frozen Lake Comparing Q and Double Q Learning Stochastic.ipynb +0 -0
- Frozen Lake Comparison Q and Double Q Learnings Deterministic.ipynb +0 -0
- Frozen Lake Double Q Learning Deterministic Environment.ipynb +0 -0
- Frozen Lake Double Q Learning Stochastic Environment.ipynb +0 -0
- Frozen Lake Q Learning for Determinitic Environment.ipynb +0 -0
- Frozen Lake Q Learning for Stochastic Environment.ipynb +0 -0
- Lawn Mower Comparison SARSA and Double Q Learnings Deterministic.ipynb +101 -0
- Lawn Mower Double Q Learning Deterministic Environment.ipynb +0 -0
- Lawn Mower N Step Bootstrapping Deterministic.ipynb +0 -0
- Lawn Mower SARSA Deterministic Environment.ipynb +0 -0
- NVDA.csv +505 -0
- README.md +246 -3
- Squirrel Maze Double Q Learning Deterministic Environment.ipynb +0 -0
- Squirrel Maze Double Q Learning StochasticEnvironment.ipynb +0 -0
- Squirrel Maze Q Learning Deterministic Environment.ipynb +0 -0
- Squirrel Maze Q Learning Stochastic Environment.ipynb +0 -0
- Stock Trading Q Learning Environment.ipynb +0 -0
- environments/Frozen Lake Grid World Defining Deterministic and Stochastic Environment.ipynb +0 -0
- environments/Lawn Mower Grid World Defining Deterministic Environment.ipynb +0 -0
- environments/Squirrel Maze Grid World Defining Deterministic and Stochastic Environment.ipynb +0 -0
- environments/Stock Trading Environment.ipynb +445 -0
- images/Cartoon_green_texture_grass.jpg +3 -0
- images/acorn.png +0 -0
- images/agent_flag_winner.png +0 -0
- images/agent_gems_lottery.png +0 -0
- images/agent_grid_cross.png +0 -0
- images/agent_hole_drown.png +0 -0
- images/frozen_lake.jpg +0 -0
- images/house.png +0 -0
- images/hunter.png +0 -0
- images/icons8-battery-64.png +0 -0
- images/icons8-cross-100.png +0 -0
- images/icons8-drown-100.png +0 -0
- images/icons8-flag-100.png +0 -0
- images/icons8-gems-100.png +0 -0
- images/icons8-goal-50.png +0 -0
- images/icons8-grid-100.png +0 -0
- images/icons8-hole-100.png +0 -0
- images/icons8-lawn-mower-100.png +0 -0
- images/icons8-money-100.png +0 -0
- images/icons8-rocks-53.png +0 -0
- images/icons8-skateboard-100.png +0 -0
- images/icons8-trophy-100.png +0 -0
- images/lawnmower_battery_bolt.png +0 -0
- images/lawnmower_goal_win.png +0 -0
- images/lawnmower_grid_cross.png +0 -0
- images/lawnmower_rocks_boom.png +0 -0
- images/squirrel.png +0 -0
- images/squirrel_acorn.jpg +0 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
images/Cartoon_green_texture_grass.jpg filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
reports/Frozen_Lake_Report.pdf filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
reports/Lawn_Mower_Report.pdf filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
reports/Squirrel_Maze_Report.pdf filter=lfs diff=lfs merge=lfs -text
|
Frozen Lake Comparing Q and Double Q Learning Stochastic.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Frozen Lake Comparison Q and Double Q Learnings Deterministic.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Frozen Lake Double Q Learning Deterministic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Frozen Lake Double Q Learning Stochastic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Frozen Lake Q Learning for Determinitic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Frozen Lake Q Learning for Stochastic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Lawn Mower Comparison SARSA and Double Q Learnings Deterministic.ipynb
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"# Comparing SARSA And Double Q Learning"
|
| 8 |
+
]
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"cell_type": "markdown",
|
| 12 |
+
"metadata": {},
|
| 13 |
+
"source": [
|
| 14 |
+
"## Lawn Mower"
|
| 15 |
+
]
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"cell_type": "code",
|
| 19 |
+
"execution_count": null,
|
| 20 |
+
"metadata": {},
|
| 21 |
+
"outputs": [],
|
| 22 |
+
"source": [
|
| 23 |
+
"# SARSA Training Loop\n",
|
| 24 |
+
"sarsa_rewards = []\n",
|
| 25 |
+
"for episode in range(total_episodes):\n",
|
| 26 |
+
" state, _ = env.reset()\n",
|
| 27 |
+
" state_index = env.obs_space_to_index(state)\n",
|
| 28 |
+
" total_rewards = 0\n",
|
| 29 |
+
" total_steps = 0\n",
|
| 30 |
+
" action = env.action_space.sample() if np.random.uniform(0, 1) < epsilon else np.argmax(qt[state_index])\n",
|
| 31 |
+
" while True:\n",
|
| 32 |
+
" next_state, reward, terminated, truncated, _ = env.step(action)\n",
|
| 33 |
+
" total_steps += 1 \n",
|
| 34 |
+
" next_strt_idx = env.obs_space_to_index(next_state)\n",
|
| 35 |
+
" next_action = env.action_space.sample() if np.random.uniform(0, 1) < epsilon else np.argmax(qt[next_strt_idx])\n",
|
| 36 |
+
" qt[state_index, action] = qt[state_index, action] + alpha * (reward + gamma * qt[next_strt_idx, next_action] - qt[state_index, action])\n",
|
| 37 |
+
" state_index, action = next_strt_idx, next_action\n",
|
| 38 |
+
" total_rewards += reward\n",
|
| 39 |
+
" if terminated or truncated:\n",
|
| 40 |
+
" break\n",
|
| 41 |
+
" sarsa_rewards.append(total_rewards)\n",
|
| 42 |
+
"\n",
|
| 43 |
+
"\n",
|
| 44 |
+
"# Double Q-learning Training Loop\n",
|
| 45 |
+
"double_q_rewards = []\n",
|
| 46 |
+
"for episode in range(total_episodes):\n",
|
| 47 |
+
" state, _ = env.reset()\n",
|
| 48 |
+
" state_index = env.obs_space_to_index(state)\n",
|
| 49 |
+
" total_rewards = 0\n",
|
| 50 |
+
" total_steps = 0\n",
|
| 51 |
+
" while True:\n",
|
| 52 |
+
" total_steps += 1\n",
|
| 53 |
+
" action = env.action_space.sample() if np.random.uniform(0, 1) < epsilon else np.argmax((qt1[state_index] + qt2[state_index]) / 2)\n",
|
| 54 |
+
" next_state, reward, terminated, truncated, _ = env.step(action)\n",
|
| 55 |
+
" next_strt_idx = env.obs_space_to_index(next_state)\n",
|
| 56 |
+
" if np.random.uniform(0, 1) < 0.5:\n",
|
| 57 |
+
" qt1[state_index, action] += alpha * (reward + gamma * qt2[next_strt_idx, np.argmax(qt1[next_strt_idx])] - qt1[state_index, action])\n",
|
| 58 |
+
" else:\n",
|
| 59 |
+
" qt2[state_index, action] += alpha * (reward + gamma * qt1[next_strt_idx, np.argmax(qt2[next_strt_idx])] - qt2[state_index, action])\n",
|
| 60 |
+
" state_index = next_strt_idx\n",
|
| 61 |
+
" total_rewards += reward\n",
|
| 62 |
+
" if terminated or truncated or total_steps >= max_timestamp:\n",
|
| 63 |
+
" break\n",
|
| 64 |
+
" double_q_rewards.append(total_rewards)\n"
|
| 65 |
+
]
|
| 66 |
+
},
|
| 67 |
+
{
|
| 68 |
+
"cell_type": "code",
|
| 69 |
+
"execution_count": null,
|
| 70 |
+
"metadata": {},
|
| 71 |
+
"outputs": [
|
| 72 |
+
{
|
| 73 |
+
"data": {
|
| 74 |
+
"image/png": "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zZtRq1YtXV5orzFaQm12tNfL/fv3o3HjxvD09ETlypWxatUqg+9z6tQpJCYmwsvLCxUqVMAnn3yC5cuXUzsgESjYeYb9+uuvqFy5Mpo1ayZq+VdffRXTpk1D/fr18eWXXyIxMREzZsxA//79DZa9dOkSXnrpJXTr1g0zZszAw4cP0a1bN6xZswbjx4/HwIED8eGHH+Ly5cvo168f1Go17/MqlQodO3ZEeHg4Zs2ahQYNGuD999/X3dS15s2bh+effx4fffQRPv30U8jlcvTt2xe//fabQZr+/PNPjB8/Hi+++CLmzZuHSpUqCX7PkSNHYvHixejduzcWLVqEiRMnwsvLi9dGZMWKFejXrx9kMhlmzJiB4cOHY9OmTWjRogUvENF+l+TkZISEhOCLL75AYmIiZs+eLap68IMPPsDo0aMRFRWF2bNno3fv3vj666/RoUMHFBUVAQDmzp2LF154AQCwePFirF69Gr169TK6zooVK2LXrl24efOm2e0DQGpqKi5duoQBAwbAw8MDvXr1wpo1a0R9FoDuIhwUFMRLA6AJGPPy8kStZ926dfDx8UHXrl3RuHFjVKlSRXQ6Dh8+jH/++Qf9+/fH/PnzMXLkSOzatQutW7cW3P6YMWNw8uRJvP/++3j99dfx66+/GtyUp02bhqlTp6Ju3br4/PPPUblyZXTo0AGPHz8WlSZTYmJikJiYiIMHDyInJweAprq1devWWL16NVJSUvD5558jICAAQ4YMwbx586zelthzTV9GRgaaNm2KnTt34o033tBVoQ4bNgxz5841+dmtW7dCpVJh0KBBRpcZNGgQiouLDQIGsaZPn45BgwYhLi4Oc+bMwbhx47Br1y60atWKd45qj8HXX38dCxYsQHJyMhYsWCCYtuLiYiQnJyMsLAxffPEFevfurZu3f/9+jBo1Cv3798esWbOQn5+P3r174/79+2bTeunSJfTp0wft27fH7NmzERQUhCFDhvCC51u3bukC6smTJ2P8+PFYs2ZNqfb9M8W5BUvEWbKzsxkA1qNHD1HLnzhxggFgr776Km/6xIkTGQD2559/6qZVrFiRAWD//POPbtr27dsZAObl5cWuXbumm/71118zAOyvv/7STRs8eDADwMaMGaObplarWZcuXZiHhwevqiYvL4+XnsLCQlarVi3Wtm1b3nQATCqVsn///dfgu0GveD4gIECweoG7jbCwMFarVi1eVdiWLVsYADZt2jSD7/LRRx/x1vH888+zBg0aGN0GY4xlZmYyDw8P1qFDB6ZSqXTTtUX83377rW6athhfTDXWsmXLGADm4eHB2rRpw6ZOncr27dvH2wbXG2+8waKjo5larWaMMfbHH38wAOz48eO85bTVWDt37mR3795lN27cYD/++CMLDQ1lSqWS3bhxg7f8oEGDGAAWFBTEXnjhBfbFF1+ws2fPGk137dq1WUpKiu7/KVOmsHLlyrGioiKz31n/OGGMsQMHDjAAbNWqVQbfISkpSfd9GWNs/PjxTCaTsaysLMZYyb7p0qULb7kpU6YwAKWqxtIaO3YsA8BOnjzJGGNs7ty5DAD77rvvdMsUFhayhIQE5uvry3JychhjjP31118G5xRjjKWlpTEAbPny5bpplpxr+ufJsGHDWGRkJLt37x5vO/3792cBAQGCea41btw4wWOI69ixYwwAmzBhgtFltPSrsa5evcpkMhmbPn06b7nTp08zuVzOmy6UzhkzZjCJRMK7Vmnz6t133zVYXns+Xbp0STft5MmTBtV02uOLWw2svV7u3btXNy0zM5MplUr21ltv6aaNGTOGSSQSXp7dv3+fBQcHG6yTGKKSnWeU9mnRz89P1PK///47ABg0mHzrrbcAwKAkpWbNmkhISND936RJEwBA27ZtERMTYzD9ypUrBtvkPklri4kLCwuxc+dO3XQvLy/d3w8fPkR2djZatmxpUOUEAImJiahZs6aZbwoEBgYiNTUVt2/fFpx/5MgRZGZmYtSoUbwGt126dEF8fLxgqdLIkSN5/7ds2VLwO3Pt3LkThYWFGDduHKTSklN1+PDh8Pf3F9yOGK+88gq2bduG1q1bY//+/fj444/RsmVLxMXFGVQLFRcX4/vvv8eLL76o69rbtm1bhIWFGS1VSUpKQmhoKKKjo9GnTx/4+Pjgl19+QYUKFXjLLV++HF999RViY2Px008/YeLEiahRowbatWtnUHVx6tQpnD59GgMGDNBNGzBgAO7du4ft27eb/c7c46SoqAj3799H1apVERgYKHisjBgxgteVuWXLllCpVLh27RqAkn0zZswY3nLjxo0zmxaxtF3CHz16BEBzDkZERPDyQKFQ4M0330Rubi727Nlj9bbEnGtcjDFs3LgR3bp1A2MM9+7d0/0kJycj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",
|
| 75 |
+
"text/plain": [
|
| 76 |
+
"<Figure size 640x480 with 1 Axes>"
|
| 77 |
+
]
|
| 78 |
+
},
|
| 79 |
+
"metadata": {},
|
| 80 |
+
"output_type": "display_data"
|
| 81 |
+
}
|
| 82 |
+
],
|
| 83 |
+
"source": [
|
| 84 |
+
"plt.plot(sarsa_rewards, label='SARSA')\n",
|
| 85 |
+
"plt.plot(double_q_rewards, label='Double Q-learning')\n",
|
| 86 |
+
"plt.xlabel('Episode')\n",
|
| 87 |
+
"plt.ylabel('Total Reward')\n",
|
| 88 |
+
"plt.legend()\n",
|
| 89 |
+
"plt.title('Comparison of SARSA and Double Q-learning')\n",
|
| 90 |
+
"plt.show()"
|
| 91 |
+
]
|
| 92 |
+
}
|
| 93 |
+
],
|
| 94 |
+
"metadata": {
|
| 95 |
+
"language_info": {
|
| 96 |
+
"name": "python"
|
| 97 |
+
}
|
| 98 |
+
},
|
| 99 |
+
"nbformat": 4,
|
| 100 |
+
"nbformat_minor": 2
|
| 101 |
+
}
|
Lawn Mower Double Q Learning Deterministic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Lawn Mower N Step Bootstrapping Deterministic.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Lawn Mower SARSA Deterministic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
NVDA.csv
ADDED
|
@@ -0,0 +1,505 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Date,Open,High,Low,Close,Adj Close,Volume
|
| 2 |
+
2021-02-01,130.532501,132.707504,129.027496,132.369995,132.130936,21720400
|
| 3 |
+
2021-02-02,133.987503,135.720001,132.854996,135.567505,135.322693,22044000
|
| 4 |
+
2021-02-03,136.360001,139.317505,135.164993,135.304993,135.060638,24540800
|
| 5 |
+
2021-02-04,135.309998,136.735001,133.377502,136.642502,136.395737,20134000
|
| 6 |
+
2021-02-05,137.250000,137.372498,135.457504,135.910004,135.664551,16915200
|
| 7 |
+
2021-02-08,137.272507,144.737503,137.272507,144.387497,144.126740,43462400
|
| 8 |
+
2021-02-09,143.407501,145.832504,142.225006,142.632507,142.374908,28756000
|
| 9 |
+
2021-02-10,144.632507,149.050003,143.414993,147.642502,147.375854,48535200
|
| 10 |
+
2021-02-11,149.802505,152.722504,149.250000,152.507507,152.232056,45082800
|
| 11 |
+
2021-02-12,150.500000,152.912506,147.750000,149.612503,149.342300,37475600
|
| 12 |
+
2021-02-16,150.642502,153.725006,149.500000,153.302505,153.025620,32196000
|
| 13 |
+
2021-02-17,151.710007,152.235001,147.800003,149.059998,148.790787,27475600
|
| 14 |
+
2021-02-18,147.289993,148.732498,145.750000,148.289993,148.022171,23386800
|
| 15 |
+
2021-02-19,150.244995,151.770004,148.467499,149.264999,148.995422,27172400
|
| 16 |
+
2021-02-22,147.747498,151.332504,143.250000,143.557495,143.298218,32588400
|
| 17 |
+
2021-02-23,140.752502,142.387497,133.895004,141.419998,141.164597,39178000
|
| 18 |
+
2021-02-24,141.227493,145.067505,137.559998,144.990005,144.728119,44832000
|
| 19 |
+
2021-02-25,140.455002,143.747498,132.162506,133.074997,132.834641,82443600
|
| 20 |
+
2021-02-26,137.524994,138.544998,133.610001,137.145004,136.897324,50093200
|
| 21 |
+
2021-03-01,138.750000,139.250000,135.532501,138.417496,138.167511,35318400
|
| 22 |
+
2021-03-02,139.000000,139.205002,133.960007,134.062500,133.820374,26411600
|
| 23 |
+
2021-03-03,134.262497,134.514999,127.987503,128.047501,127.816238,37759200
|
| 24 |
+
2021-03-04,128.007507,129.750000,120.837502,123.702499,123.479088,57334400
|
| 25 |
+
2021-03-05,125.500000,125.500000,116.792503,124.614998,124.389938,54284000
|
| 26 |
+
2021-03-08,124.500000,124.712502,115.665001,115.932503,115.723129,54311200
|
| 27 |
+
2021-03-09,121.302498,126.167503,120.592499,125.202499,125.019524,52182400
|
| 28 |
+
2021-03-10,128.404999,129.800003,124.574997,124.682503,124.500282,38437600
|
| 29 |
+
2021-03-11,129.500000,130.462494,127.345001,129.934998,129.745087,29991600
|
| 30 |
+
2021-03-12,126.482498,128.887497,125.900002,128.559998,128.372116,24396400
|
| 31 |
+
2021-03-15,128.647507,132.067505,127.672501,131.912506,131.719727,22198800
|
| 32 |
+
2021-03-16,133.565002,135.125000,131.167496,132.912506,132.718262,27212800
|
| 33 |
+
2021-03-17,130.397507,134.532501,129.895004,133.412506,133.217529,24386400
|
| 34 |
+
2021-03-18,131.365005,131.839996,127.169998,127.224998,127.039055,29389600
|
| 35 |
+
2021-03-19,127.500000,129.214996,126.125000,128.457504,128.269760,29920800
|
| 36 |
+
2021-03-22,129.127502,133.945007,129.067505,131.862503,131.669769,29780400
|
| 37 |
+
2021-03-23,132.542496,133.445007,130.212494,130.707504,130.516479,22204800
|
| 38 |
+
2021-03-24,131.512497,131.592499,126.367500,126.430000,126.245224,24584000
|
| 39 |
+
2021-03-25,124.995003,127.147499,122.720001,125.352501,125.169296,29514400
|
| 40 |
+
2021-03-26,125.544998,128.562500,123.735001,128.392502,128.204849,36396800
|
| 41 |
+
2021-03-29,128.202499,130.625000,127.000000,129.482498,129.293243,27352000
|
| 42 |
+
2021-03-30,128.419998,129.752502,127.050003,128.717499,128.529388,20020400
|
| 43 |
+
2021-03-31,130.154999,134.705002,129.824997,133.482498,133.287399,31477600
|
| 44 |
+
2021-04-01,135.722504,138.699997,135.112503,138.117493,137.915634,30827600
|
| 45 |
+
2021-04-05,138.675003,140.139999,137.330002,139.875000,139.670563,25567200
|
| 46 |
+
2021-04-06,139.997498,140.542496,137.735001,138.615005,138.412399,19174400
|
| 47 |
+
2021-04-07,138.807495,142.434998,137.115005,141.434998,141.228287,25128400
|
| 48 |
+
2021-04-08,142.527496,144.714996,142.490005,143.169998,142.960770,24441600
|
| 49 |
+
2021-04-09,142.139999,144.080002,141.750000,144.000000,143.789536,19517200
|
| 50 |
+
2021-04-12,142.897507,153.524994,141.392502,152.089996,151.867706,86932400
|
| 51 |
+
2021-04-13,152.315002,157.000000,151.257507,156.794998,156.565842,67621200
|
| 52 |
+
2021-04-14,156.250000,157.205002,152.274994,152.770004,152.546722,38550000
|
| 53 |
+
2021-04-15,156.625000,162.142502,156.315002,161.372498,161.136642,59848000
|
| 54 |
+
2021-04-16,160.529999,161.657501,158.652496,159.125000,158.892441,33520800
|
| 55 |
+
2021-04-19,155.365005,158.074997,152.330002,153.617493,153.392975,40442000
|
| 56 |
+
2021-04-20,153.232498,154.970001,149.630005,151.712494,151.490768,33413200
|
| 57 |
+
2021-04-21,151.187500,153.625000,151.022507,153.604996,153.380493,21677600
|
| 58 |
+
2021-04-22,153.750000,154.384995,147.835007,148.502502,148.285477,27778800
|
| 59 |
+
2021-04-23,149.342499,153.350006,149.002502,152.652496,152.429398,22750000
|
| 60 |
+
2021-04-26,151.850006,154.789993,151.250000,154.779999,154.553787,19779600
|
| 61 |
+
2021-04-27,155.785004,156.705002,153.544998,153.817505,153.592712,16457200
|
| 62 |
+
2021-04-28,153.645004,155.322495,152.154999,152.767502,152.544220,20941600
|
| 63 |
+
2021-04-29,154.000000,154.365005,150.714996,153.247498,153.023514,17319600
|
| 64 |
+
2021-04-30,151.744995,153.649994,149.970001,150.095001,149.875626,20191200
|
| 65 |
+
2021-05-03,151.250000,152.467499,147.875000,148.367493,148.150665,20391200
|
| 66 |
+
2021-05-04,146.372498,146.375000,140.102493,143.512497,143.302734,40532400
|
| 67 |
+
2021-05-05,147.089996,148.134995,143.875000,144.585007,144.373672,29202400
|
| 68 |
+
2021-05-06,144.952499,145.712494,142.179993,145.229996,145.017761,19338000
|
| 69 |
+
2021-05-07,148.082504,149.707504,146.717499,148.122498,147.905991,22932800
|
| 70 |
+
2021-05-10,147.872498,148.059998,142.500000,142.657501,142.449005,26890400
|
| 71 |
+
2021-05-11,138.250000,143.547501,137.500000,143.062500,142.853424,28558400
|
| 72 |
+
2021-05-12,140.095001,142.602493,137.092499,137.585007,137.383926,30340800
|
| 73 |
+
2021-05-13,140.337494,140.807495,134.589996,136.652496,136.452759,28540400
|
| 74 |
+
2021-05-14,138.899994,143.279999,137.485001,142.429993,142.221848,25861600
|
| 75 |
+
2021-05-17,141.570007,141.692505,138.535004,141.654999,141.447968,21698000
|
| 76 |
+
2021-05-18,142.669998,144.042496,140.039993,140.157501,139.952667,18625600
|
| 77 |
+
2021-05-19,135.664993,140.794998,135.432495,140.657501,140.451935,34400000
|
| 78 |
+
2021-05-20,143.024994,146.837494,142.705002,146.125000,145.911438,32159200
|
| 79 |
+
2021-05-21,151.637497,152.220001,148.695007,149.917496,149.698380,67299200
|
| 80 |
+
2021-05-24,152.125000,157.449997,151.759995,156.119995,155.891830,55481600
|
| 81 |
+
2021-05-25,157.660004,158.184998,154.824997,156.477493,156.248810,43540800
|
| 82 |
+
2021-05-26,157.342499,157.937500,155.862503,157.000000,156.770554,37044000
|
| 83 |
+
2021-05-27,156.997498,157.500000,154.600006,154.880005,154.653656,58147600
|
| 84 |
+
2021-05-28,155.009995,162.774994,155.009995,162.445007,162.207581,64453600
|
| 85 |
+
2021-06-01,162.699997,163.882507,159.032501,162.645004,162.407303,47280400
|
| 86 |
+
2021-06-02,162.522507,169.187500,162.354996,167.782501,167.537277,59416800
|
| 87 |
+
2021-06-03,167.007507,172.589996,165.830002,169.697495,169.449478,58000800
|
| 88 |
+
2021-06-04,171.125000,176.610001,170.955002,175.782501,175.525589,61712000
|
| 89 |
+
2021-06-07,175.712494,178.125000,171.927505,176.190002,175.932495,57575600
|
| 90 |
+
2021-06-08,175.272507,176.214996,172.509995,174.570007,174.314865,32384800
|
| 91 |
+
2021-06-09,175.157501,175.750000,172.557495,173.582504,173.368530,38165600
|
| 92 |
+
2021-06-10,173.500000,174.919998,171.759995,174.250000,174.035202,28777200
|
| 93 |
+
2021-06-11,174.794998,179.392502,174.437500,178.252502,178.032776,41630800
|
| 94 |
+
2021-06-14,179.059998,180.395004,176.627502,180.187500,179.965408,32137600
|
| 95 |
+
2021-06-15,179.149994,180.162506,177.279999,177.884995,177.665726,24303200
|
| 96 |
+
2021-06-16,177.907501,179.547501,175.845001,178.102493,177.882965,30712400
|
| 97 |
+
2021-06-17,177.744995,188.350006,177.562500,186.572495,186.342499,80965600
|
| 98 |
+
2021-06-18,187.839996,193.750000,185.839996,186.387497,186.157745,96885600
|
| 99 |
+
2021-06-21,184.352493,185.365005,178.227493,184.272507,184.045349,67238400
|
| 100 |
+
2021-06-22,184.714996,189.637497,183.860001,188.867493,188.634674,58014400
|
| 101 |
+
2021-06-23,190.077499,191.527496,189.077499,190.572495,190.337585,33235600
|
| 102 |
+
2021-06-24,192.277496,194.199997,190.882507,192.054993,191.818268,32092400
|
| 103 |
+
2021-06-25,192.804993,193.455002,188.945007,190.309998,190.075409,27836400
|
| 104 |
+
2021-06-28,193.612503,200.787506,193.190002,199.850006,199.603668,49543600
|
| 105 |
+
2021-06-29,198.824997,200.987503,196.570007,200.267502,200.020630,36763200
|
| 106 |
+
2021-06-30,199.992493,201.625000,198.637497,200.024994,199.778442,32656800
|
| 107 |
+
2021-07-01,201.250000,204.559998,200.190002,202.119995,201.870850,48013600
|
| 108 |
+
2021-07-02,204.402496,205.052505,202.877502,204.869995,204.617462,34276400
|
| 109 |
+
2021-07-06,207.375000,208.419998,203.502502,206.985001,206.729858,44670800
|
| 110 |
+
2021-07-07,208.535004,208.750000,203.320007,203.717499,203.466400,41842800
|
| 111 |
+
2021-07-08,198.565002,201.330002,197.007507,199.027496,198.782150,50330000
|
| 112 |
+
2021-07-09,199.625000,200.802505,197.542496,200.502502,200.255371,29662400
|
| 113 |
+
2021-07-12,202.399994,205.327499,201.877502,205.125000,204.872147,32198400
|
| 114 |
+
2021-07-13,204.005005,204.612503,201.139999,202.500000,202.250397,29070800
|
| 115 |
+
2021-07-14,203.577499,204.177505,197.527496,198.414993,198.170395,38010000
|
| 116 |
+
2021-07-15,198.117493,198.470001,188.585007,189.662506,189.428726,55056400
|
| 117 |
+
2021-07-16,190.304993,191.570007,180.729996,181.610001,181.386124,68822400
|
| 118 |
+
2021-07-19,179.152496,190.419998,178.654999,187.797501,187.565994,74906000
|
| 119 |
+
2021-07-20,187.300003,188.380005,181.639999,186.119995,185.890564,43468700
|
| 120 |
+
2021-07-21,188.820007,195.270004,187.419998,194.100006,193.860748,37101700
|
| 121 |
+
2021-07-22,196.419998,198.869995,192.759995,195.940002,195.698486,32382600
|
| 122 |
+
2021-07-23,196.559998,197.000000,192.500000,195.580002,195.338928,19567200
|
| 123 |
+
2021-07-26,193.110001,194.419998,189.139999,192.940002,192.702164,20394300
|
| 124 |
+
2021-07-27,192.649994,196.220001,187.410004,192.080002,191.843231,24886300
|
| 125 |
+
2021-07-28,193.190002,196.460007,189.949997,195.029999,194.789581,20219100
|
| 126 |
+
2021-07-29,195.190002,198.529999,193.279999,196.619995,196.377640,19078100
|
| 127 |
+
2021-07-30,194.179993,196.300003,192.630005,194.990005,194.749664,18349700
|
| 128 |
+
2021-08-02,197.000000,199.610001,193.610001,197.500000,197.256561,21744400
|
| 129 |
+
2021-08-03,197.399994,202.220001,192.199997,198.149994,197.905731,30181100
|
| 130 |
+
2021-08-04,199.899994,203.179993,198.279999,202.740005,202.490112,23130900
|
| 131 |
+
2021-08-05,205.000000,207.330002,203.419998,206.369995,206.115585,21143500
|
| 132 |
+
2021-08-06,205.240005,205.699997,202.100006,203.660004,203.408966,17849700
|
| 133 |
+
2021-08-09,204.460007,205.080002,201.429993,202.949997,202.699844,14644300
|
| 134 |
+
2021-08-10,203.220001,204.300003,198.350006,199.360001,199.114258,17923800
|
| 135 |
+
2021-08-11,200.429993,200.490005,194.300003,196.990005,196.747192,18592500
|
| 136 |
+
2021-08-12,198.699997,200.289993,196.199997,199.050003,198.804657,15165200
|
| 137 |
+
2021-08-13,199.050003,202.139999,198.509995,201.880005,201.631149,18306300
|
| 138 |
+
2021-08-16,201.350006,202.869995,194.529999,199.500000,199.254089,21087600
|
| 139 |
+
2021-08-17,196.850006,197.699997,192.669998,194.580002,194.340164,20458500
|
| 140 |
+
2021-08-18,195.000000,196.339996,190.000000,190.399994,190.165298,28591300
|
| 141 |
+
2021-08-19,194.940002,204.949997,187.619995,197.979996,197.735962,76655500
|
| 142 |
+
2021-08-20,199.910004,208.649994,199.330002,208.160004,207.903412,67574100
|
| 143 |
+
2021-08-23,209.710007,219.970001,209.500000,219.580002,219.309341,57580700
|
| 144 |
+
2021-08-24,217.529999,219.589996,215.350006,217.929993,217.661362,29729900
|
| 145 |
+
2021-08-25,217.369995,224.699997,217.220001,222.130005,221.856186,34770100
|
| 146 |
+
2021-08-26,222.000000,223.399994,217.899994,220.679993,220.407974,23794000
|
| 147 |
+
2021-08-27,221.839996,227.220001,221.669998,226.360001,226.080978,30472200
|
| 148 |
+
2021-08-30,228.300003,230.429993,225.509995,226.880005,226.600342,26258000
|
| 149 |
+
2021-08-31,226.949997,226.949997,221.199997,223.850006,223.613495,25985000
|
| 150 |
+
2021-09-01,224.850006,226.970001,223.570007,224.410004,224.172913,20176700
|
| 151 |
+
2021-09-02,225.179993,225.929993,222.949997,223.960007,223.723389,18783400
|
| 152 |
+
2021-09-03,223.250000,229.860001,222.000000,228.429993,228.188660,28053200
|
| 153 |
+
2021-09-07,228.330002,228.990005,225.220001,226.619995,226.380569,19810700
|
| 154 |
+
2021-09-08,225.130005,226.100006,219.770004,223.389999,223.153992,25443400
|
| 155 |
+
2021-09-09,223.119995,225.380005,221.309998,221.770004,221.535706,19685600
|
| 156 |
+
2021-09-10,223.479996,226.259995,222.699997,224.779999,224.542511,24837600
|
| 157 |
+
2021-09-13,226.839996,229.639999,218.580002,221.520004,221.285965,29750000
|
| 158 |
+
2021-09-14,222.750000,224.100006,220.860001,222.419998,222.185013,19975500
|
| 159 |
+
2021-09-15,223.089996,223.669998,219.660004,223.410004,223.173965,16653800
|
| 160 |
+
2021-09-16,221.830002,222.770004,219.270004,222.419998,222.185013,15603300
|
| 161 |
+
2021-09-17,223.000000,223.210007,218.300003,219.000000,218.768600,29450300
|
| 162 |
+
2021-09-20,211.460007,214.330002,206.619995,211.130005,210.906937,34944000
|
| 163 |
+
2021-09-21,214.169998,214.250000,209.500000,212.460007,212.235550,20468800
|
| 164 |
+
2021-09-22,213.660004,219.600006,211.960007,219.410004,219.178192,26872600
|
| 165 |
+
2021-09-23,221.399994,225.350006,218.899994,224.820007,224.582474,24855500
|
| 166 |
+
2021-09-24,220.699997,221.490005,218.610001,220.809998,220.576706,21765500
|
| 167 |
+
2021-09-27,217.100006,217.990005,213.250000,216.600006,216.371155,24521500
|
| 168 |
+
2021-09-28,212.139999,214.190002,206.509995,206.990005,206.771317,34306900
|
| 169 |
+
2021-09-29,209.399994,210.169998,204.669998,205.169998,204.953232,21839400
|
| 170 |
+
2021-09-30,207.679993,210.660004,206.880005,207.160004,206.941116,22100900
|
| 171 |
+
2021-10-01,207.500000,208.589996,202.029999,207.419998,207.200851,24097800
|
| 172 |
+
2021-10-04,205.039993,205.419998,195.550003,197.320007,197.111526,34563500
|
| 173 |
+
2021-10-05,199.500000,206.479996,198.539993,204.509995,204.293915,27928200
|
| 174 |
+
2021-10-06,201.199997,207.199997,200.800003,207.000000,206.781296,29720200
|
| 175 |
+
2021-10-07,210.919998,213.220001,209.720001,210.750000,210.527328,25691900
|
| 176 |
+
2021-10-08,211.009995,212.059998,207.750000,208.309998,208.089905,15125800
|
| 177 |
+
2021-10-11,205.750000,210.630005,205.110001,206.949997,206.731354,16338800
|
| 178 |
+
2021-10-12,208.279999,210.570007,205.279999,206.710007,206.491623,16213400
|
| 179 |
+
2021-10-13,209.179993,209.899994,207.130005,209.389999,209.168747,18065200
|
| 180 |
+
2021-10-14,212.880005,217.550003,211.220001,217.460007,217.230255,24358900
|
| 181 |
+
2021-10-15,218.100006,219.309998,216.619995,218.619995,218.389008,22699400
|
| 182 |
+
2021-10-18,217.490005,222.910004,216.440002,222.220001,221.985214,18949400
|
| 183 |
+
2021-10-19,222.759995,223.789993,220.369995,222.899994,222.664505,16147300
|
| 184 |
+
2021-10-20,223.050003,224.330002,219.820007,221.029999,220.796463,14627600
|
| 185 |
+
2021-10-21,220.970001,227.110001,220.830002,226.919998,226.680252,18759000
|
| 186 |
+
2021-10-22,228.229996,231.300003,225.610001,227.259995,227.019897,24938400
|
| 187 |
+
2021-10-25,229.729996,233.550003,227.699997,231.660004,231.415253,23023500
|
| 188 |
+
2021-10-26,239.889999,252.589996,239.240005,247.169998,246.908844,48589800
|
| 189 |
+
2021-10-27,244.740005,250.899994,242.820007,244.509995,244.251663,24599000
|
| 190 |
+
2021-10-28,248.779999,249.500000,245.229996,249.410004,249.146500,23420400
|
| 191 |
+
2021-10-29,250.009995,257.089996,250.000000,255.669998,255.399887,29250300
|
| 192 |
+
2021-11-01,256.489990,258.940002,252.270004,258.269989,257.997101,26574000
|
| 193 |
+
2021-11-02,258.220001,266.779999,258.000000,264.010010,263.731049,29411200
|
| 194 |
+
2021-11-03,266.700012,267.839996,262.350006,265.980011,265.698975,23991000
|
| 195 |
+
2021-11-04,272.290009,313.649994,271.179993,298.010010,297.695160,115363100
|
| 196 |
+
2021-11-05,301.869995,314.000000,294.100006,297.519989,297.205658,85126000
|
| 197 |
+
2021-11-08,301.489990,311.000000,299.070007,308.040009,307.714539,50310100
|
| 198 |
+
2021-11-09,322.820007,323.100006,299.640015,306.570007,306.246094,64674600
|
| 199 |
+
2021-11-10,293.559998,308.500000,287.779999,294.589996,294.278748,63620600
|
| 200 |
+
2021-11-11,304.679993,305.899994,297.769989,303.899994,303.578918,33217200
|
| 201 |
+
2021-11-12,300.100006,306.799988,296.299988,303.899994,303.578918,41305400
|
| 202 |
+
2021-11-15,305.519989,306.440002,292.470001,300.250000,299.932800,38490900
|
| 203 |
+
2021-11-16,297.589996,303.899994,297.059998,302.029999,301.710907,26448400
|
| 204 |
+
2021-11-17,304.179993,305.089996,288.000000,292.609985,292.300842,42850800
|
| 205 |
+
2021-11-18,323.670013,327.600006,313.209991,316.750000,316.415344,78171100
|
| 206 |
+
2021-11-19,322.429993,330.880005,319.049988,329.850006,329.501526,53386700
|
| 207 |
+
2021-11-22,335.170013,346.470001,319.000000,319.559998,319.222351,75433500
|
| 208 |
+
2021-11-23,315.350006,323.600006,308.799988,317.459991,317.124603,53216300
|
| 209 |
+
2021-11-24,314.609985,328.549988,309.279999,326.739990,326.394775,43516200
|
| 210 |
+
2021-11-26,326.000000,327.100006,313.500000,315.029999,314.697144,28306900
|
| 211 |
+
2021-11-29,323.660004,334.119995,320.359985,333.760010,333.407379,45496400
|
| 212 |
+
2021-11-30,331.690002,333.529999,318.640015,326.760010,326.414795,62206600
|
| 213 |
+
2021-12-01,332.190002,332.890015,313.799988,314.350006,314.056305,48436800
|
| 214 |
+
2021-12-02,312.140015,324.779999,310.250000,321.260010,320.959869,47289000
|
| 215 |
+
2021-12-03,320.000000,321.290009,301.299988,306.929993,306.643250,54432500
|
| 216 |
+
2021-12-06,298.799988,302.410004,280.380005,300.369995,300.089355,65893800
|
| 217 |
+
2021-12-07,309.570007,324.489990,306.510010,324.269989,323.967072,59305300
|
| 218 |
+
2021-12-08,319.989990,322.899994,314.209991,318.260010,317.962677,47555100
|
| 219 |
+
2021-12-09,317.339996,322.049988,304.279999,304.899994,304.615143,48850700
|
| 220 |
+
2021-12-10,311.500000,313.049988,298.609985,301.980011,301.697906,48882500
|
| 221 |
+
2021-12-13,302.489990,302.940002,281.160004,281.609985,281.346893,59834400
|
| 222 |
+
2021-12-14,276.989990,286.779999,272.500000,283.369995,283.105286,66703500
|
| 223 |
+
2021-12-15,284.000000,305.000000,278.380005,304.589996,304.305450,69829700
|
| 224 |
+
2021-12-16,311.519989,311.600006,280.929993,283.869995,283.604797,70736600
|
| 225 |
+
2021-12-17,279.850006,289.220001,277.600006,278.010010,277.750305,71375800
|
| 226 |
+
2021-12-20,273.049988,281.440002,271.450012,277.190002,276.931061,46184700
|
| 227 |
+
2021-12-21,283.739990,291.200012,274.010010,290.750000,290.478394,52438500
|
| 228 |
+
2021-12-22,288.910004,295.549988,284.489990,294.000000,293.725342,39518400
|
| 229 |
+
2021-12-23,297.549988,300.589996,294.309998,296.399994,296.123108,34302200
|
| 230 |
+
2021-12-27,296.600006,310.869995,296.399994,309.450012,309.160919,40368600
|
| 231 |
+
2021-12-28,313.119995,313.299988,300.119995,303.220001,302.936676,42059100
|
| 232 |
+
2021-12-29,302.730011,305.480011,293.660004,300.010010,299.729736,34313900
|
| 233 |
+
2021-12-30,298.269989,304.570007,295.399994,295.859985,295.583588,30886400
|
| 234 |
+
2021-12-31,296.739990,300.299988,293.309998,294.109985,293.835205,26653000
|
| 235 |
+
2022-01-03,298.149994,307.109985,297.850006,301.209991,300.928589,39154700
|
| 236 |
+
2022-01-04,302.769989,304.679993,283.489990,292.899994,292.626373,52715400
|
| 237 |
+
2022-01-05,289.489990,294.160004,275.329987,276.040009,275.782135,49806400
|
| 238 |
+
2022-01-06,276.399994,284.380005,270.649994,281.779999,281.516754,45418600
|
| 239 |
+
2022-01-07,281.410004,284.220001,270.570007,272.470001,272.215454,40993900
|
| 240 |
+
2022-01-10,265.809998,274.690002,256.440002,274.000000,273.744049,59468100
|
| 241 |
+
2022-01-11,273.230011,280.649994,268.390015,278.170013,277.910126,40408900
|
| 242 |
+
2022-01-12,280.670013,285.950012,276.079987,279.989990,279.728424,38341300
|
| 243 |
+
2022-01-13,283.790009,284.799988,264.980011,265.750000,265.501740,54017100
|
| 244 |
+
2022-01-14,263.000000,271.970001,262.100006,269.420013,269.168304,39583200
|
| 245 |
+
2022-01-18,262.600006,266.380005,257.700012,259.029999,258.787994,42427000
|
| 246 |
+
2022-01-19,260.790009,265.429993,250.520004,250.669998,250.435822,48831500
|
| 247 |
+
2022-01-20,253.039993,255.789993,240.779999,241.500000,241.274384,43518100
|
| 248 |
+
2022-01-21,235.070007,248.229996,232.630005,233.740005,233.521652,71895800
|
| 249 |
+
2022-01-24,223.300003,233.800003,208.880005,233.720001,233.501663,91398200
|
| 250 |
+
2022-01-25,225.460007,229.429993,220.000000,223.240005,223.031448,66461600
|
| 251 |
+
2022-01-26,232.399994,240.570007,223.000000,227.720001,227.507263,75595900
|
| 252 |
+
2022-01-27,235.679993,239.949997,216.750000,219.440002,219.234985,57335300
|
| 253 |
+
2022-01-28,220.119995,228.580002,212.960007,228.399994,228.186615,54377400
|
| 254 |
+
2022-01-31,231.820007,245.089996,230.520004,244.860001,244.631256,56468000
|
| 255 |
+
2022-02-01,251.039993,251.449997,238.899994,246.380005,246.149826,51892500
|
| 256 |
+
2022-02-02,257.940002,258.170013,245.529999,252.419998,252.184189,54341900
|
| 257 |
+
2022-02-03,244.580002,250.770004,237.800003,239.479996,239.256256,41017800
|
| 258 |
+
2022-02-04,239.720001,246.350006,236.320007,243.190002,242.962799,35482900
|
| 259 |
+
2022-02-07,243.720001,251.820007,242.020004,247.279999,247.048981,37686800
|
| 260 |
+
2022-02-08,243.589996,252.300003,239.800003,251.080002,250.845444,41035900
|
| 261 |
+
2022-02-09,256.220001,267.250000,253.529999,267.049988,266.800476,52428200
|
| 262 |
+
2022-02-10,259.950012,269.250000,256.000000,258.239990,257.998718,51320000
|
| 263 |
+
2022-02-11,259.160004,261.519989,237.729996,239.490005,239.266251,60547200
|
| 264 |
+
2022-02-14,239.339996,248.750000,237.550003,242.669998,242.443283,44042400
|
| 265 |
+
2022-02-15,249.490005,265.450012,247.839996,264.950012,264.702484,69986900
|
| 266 |
+
2022-02-16,262.589996,265.820007,255.520004,265.109985,264.862305,73267600
|
| 267 |
+
2022-02-17,256.299988,257.850006,241.649994,245.070007,244.841064,81059500
|
| 268 |
+
2022-02-18,246.679993,249.860001,231.000000,236.419998,236.199142,76125500
|
| 269 |
+
2022-02-22,230.350006,240.639999,230.000000,233.899994,233.681488,63342200
|
| 270 |
+
2022-02-23,238.020004,241.550003,223.009995,223.869995,223.660858,56651100
|
| 271 |
+
2022-02-24,210.149994,238.000000,208.899994,237.479996,237.258133,73580100
|
| 272 |
+
2022-02-25,237.210007,242.169998,233.809998,241.570007,241.344330,52886600
|
| 273 |
+
2022-02-28,239.919998,246.649994,237.070007,243.850006,243.622192,47731900
|
| 274 |
+
2022-03-01,242.910004,243.770004,231.320007,234.770004,234.550690,41205600
|
| 275 |
+
2022-03-02,237.559998,244.089996,234.149994,242.199997,242.014954,38964200
|
| 276 |
+
2022-03-03,242.619995,243.259995,234.690002,237.139999,236.958817,36509500
|
| 277 |
+
2022-03-04,233.839996,236.800003,224.820007,229.360001,229.184769,43141500
|
| 278 |
+
2022-03-07,228.169998,230.330002,213.300003,213.520004,213.356873,45082100
|
| 279 |
+
2022-03-08,213.089996,223.729996,206.500000,215.139999,214.975632,55746700
|
| 280 |
+
2022-03-09,223.869995,232.199997,222.470001,230.139999,229.964157,49274200
|
| 281 |
+
2022-03-10,225.309998,227.880005,218.820007,226.580002,226.406906,42806600
|
| 282 |
+
2022-03-11,230.220001,231.449997,220.460007,221.000000,220.831161,36720900
|
| 283 |
+
2022-03-14,218.690002,222.619995,211.589996,213.300003,213.137039,38535400
|
| 284 |
+
2022-03-15,215.179993,230.380005,213.220001,229.729996,229.554474,49199600
|
| 285 |
+
2022-03-16,235.000000,245.970001,231.720001,244.960007,244.772858,67142200
|
| 286 |
+
2022-03-17,241.199997,248.419998,239.059998,247.660004,247.470795,47194100
|
| 287 |
+
2022-03-18,247.990005,265.690002,246.240005,264.529999,264.327911,73071900
|
| 288 |
+
2022-03-21,265.070007,271.519989,259.670013,267.339996,267.135742,59172700
|
| 289 |
+
2022-03-22,267.269989,272.380005,260.720001,265.239990,265.037354,54700700
|
| 290 |
+
2022-03-23,261.260010,266.119995,255.750000,256.339996,256.144165,50212000
|
| 291 |
+
2022-03-24,261.660004,283.200012,259.070007,281.500000,281.284912,87737900
|
| 292 |
+
2022-03-25,278.859985,283.579987,272.709991,276.920013,276.708435,57901600
|
| 293 |
+
2022-03-28,277.559998,282.500000,272.059998,282.190002,281.974426,42549400
|
| 294 |
+
2022-03-29,286.950012,289.459991,279.799988,286.559998,286.341064,48898400
|
| 295 |
+
2022-03-30,283.040009,284.959991,275.029999,276.899994,276.688446,46348700
|
| 296 |
+
2022-03-31,277.820007,282.480011,272.700012,272.859985,272.651489,52344000
|
| 297 |
+
2022-04-01,273.750000,274.959991,262.670013,267.119995,266.915894,51723500
|
| 298 |
+
2022-04-04,267.279999,275.579987,266.130005,273.600006,273.390961,39712000
|
| 299 |
+
2022-04-05,272.540009,273.190002,258.200012,259.309998,259.111877,43661500
|
| 300 |
+
2022-04-06,249.339996,253.000000,240.029999,244.070007,243.883530,70383300
|
| 301 |
+
2022-04-07,244.410004,247.220001,234.779999,242.080002,241.895050,55799200
|
| 302 |
+
2022-04-08,239.169998,239.229996,230.619995,231.190002,231.013382,52478100
|
| 303 |
+
2022-04-11,222.139999,223.199997,216.600006,219.169998,219.002548,57520700
|
| 304 |
+
2022-04-12,225.369995,227.250000,212.820007,215.039993,214.875687,66225800
|
| 305 |
+
2022-04-13,217.279999,225.000000,214.550003,222.029999,221.860367,51694300
|
| 306 |
+
2022-04-14,225.050003,227.770004,211.630005,212.580002,212.417587,56909700
|
| 307 |
+
2022-04-18,212.000000,220.880005,210.789993,217.830002,217.663589,52570100
|
| 308 |
+
2022-04-19,217.199997,223.729996,213.139999,221.979996,221.810394,51278100
|
| 309 |
+
2022-04-20,225.169998,226.699997,212.000000,214.820007,214.655884,46897400
|
| 310 |
+
2022-04-21,217.089996,223.919998,200.000000,201.830002,201.675797,65620900
|
| 311 |
+
2022-04-22,203.029999,204.860001,195.000000,195.149994,195.000900,62471300
|
| 312 |
+
2022-04-25,192.020004,199.449997,190.960007,199.020004,198.867950,64156600
|
| 313 |
+
2022-04-26,197.179993,197.880005,186.699997,187.880005,187.736465,65314300
|
| 314 |
+
2022-04-27,185.979996,191.669998,182.899994,184.149994,184.009308,49946000
|
| 315 |
+
2022-04-28,189.669998,200.369995,184.899994,197.820007,197.668884,57032700
|
| 316 |
+
2022-04-29,194.020004,201.279999,185.169998,185.470001,185.328308,50043500
|
| 317 |
+
2022-05-02,185.410004,195.740005,183.910004,195.330002,195.180771,57204900
|
| 318 |
+
2022-05-03,194.000000,198.250000,191.330002,196.020004,195.870255,47575100
|
| 319 |
+
2022-05-04,199.229996,204.000000,187.509995,203.339996,203.184631,64885500
|
| 320 |
+
2022-05-05,198.669998,199.250000,185.000000,188.440002,188.296036,62633100
|
| 321 |
+
2022-05-06,187.360001,195.119995,179.899994,186.750000,186.607315,63329700
|
| 322 |
+
2022-05-09,180.339996,182.550003,168.270004,169.500000,169.370499,64445500
|
| 323 |
+
2022-05-10,176.889999,181.979996,170.250000,175.949997,175.815567,76147400
|
| 324 |
+
2022-05-11,173.470001,177.529999,165.679993,166.300003,166.172943,67016700
|
| 325 |
+
2022-05-12,162.190002,167.880005,155.669998,161.750000,161.626434,70872800
|
| 326 |
+
2022-05-13,167.880005,179.279999,165.929993,177.059998,176.924728,67043700
|
| 327 |
+
2022-05-16,175.089996,177.880005,171.059998,172.639999,172.508118,52144600
|
| 328 |
+
2022-05-17,180.740005,183.710007,176.339996,181.770004,181.631134,58583000
|
| 329 |
+
2022-05-18,177.050003,181.179993,168.639999,169.380005,169.250595,54516100
|
| 330 |
+
2022-05-19,169.369995,176.869995,167.339996,171.240005,171.109177,62131000
|
| 331 |
+
2022-05-20,173.320007,174.100006,157.550003,166.940002,166.812469,73910500
|
| 332 |
+
2022-05-23,162.740005,169.149994,161.789993,168.979996,168.850891,63988900
|
| 333 |
+
2022-05-24,165.100006,165.970001,157.800003,161.539993,161.416580,58855000
|
| 334 |
+
2022-05-25,160.199997,171.110001,160.000000,169.750000,169.620316,78113200
|
| 335 |
+
2022-05-26,160.360001,180.919998,160.220001,178.509995,178.373596,99657500
|
| 336 |
+
2022-05-27,181.860001,188.809998,181.000000,188.110001,187.966293,73837900
|
| 337 |
+
2022-05-31,189.800003,192.000000,183.500000,186.720001,186.577362,66410000
|
| 338 |
+
2022-06-01,187.240005,190.529999,181.220001,183.199997,183.060028,54451400
|
| 339 |
+
2022-06-02,182.919998,196.190002,181.979996,195.919998,195.770309,64865600
|
| 340 |
+
2022-06-03,190.820007,193.320007,185.220001,187.199997,187.056976,59877900
|
| 341 |
+
2022-06-06,191.389999,193.369995,185.639999,187.860001,187.716476,42240600
|
| 342 |
+
2022-06-07,184.720001,190.000000,181.880005,189.259995,189.115387,38891400
|
| 343 |
+
2022-06-08,187.990005,191.800003,185.350006,186.479996,186.376907,36325200
|
| 344 |
+
2022-06-09,184.809998,189.330002,180.410004,180.479996,180.380234,39557400
|
| 345 |
+
2022-06-10,176.000000,176.970001,168.690002,169.740005,169.646179,46524800
|
| 346 |
+
2022-06-13,160.000000,163.119995,156.059998,156.470001,156.383514,60415300
|
| 347 |
+
2022-06-14,157.309998,160.660004,154.119995,158.360001,158.272461,46968000
|
| 348 |
+
2022-06-15,160.949997,168.679993,159.259995,165.270004,165.178650,56393600
|
| 349 |
+
2022-06-16,158.600006,159.419998,154.009995,156.009995,155.923767,54574900
|
| 350 |
+
2022-06-17,156.479996,159.949997,153.279999,158.800003,158.712219,63033400
|
| 351 |
+
2022-06-21,164.750000,170.080002,164.070007,165.660004,165.568436,48308900
|
| 352 |
+
2022-06-22,162.259995,166.619995,161.800003,163.600006,163.509583,43713500
|
| 353 |
+
2022-06-23,165.190002,165.850006,158.529999,162.250000,162.160309,46368000
|
| 354 |
+
2022-06-24,165.000000,171.399994,163.100006,171.259995,171.165329,47215300
|
| 355 |
+
2022-06-27,173.119995,173.300003,166.259995,168.690002,168.596756,42796800
|
| 356 |
+
2022-06-28,169.000000,172.020004,159.449997,159.820007,159.731674,46114900
|
| 357 |
+
2022-06-29,158.139999,158.199997,151.699997,155.419998,155.334091,48235200
|
| 358 |
+
2022-06-30,153.610001,155.669998,148.619995,151.589996,151.506210,68607000
|
| 359 |
+
2022-07-01,148.990005,150.630005,143.919998,145.229996,145.149719,57761000
|
| 360 |
+
2022-07-05,141.750000,149.710007,140.550003,149.639999,149.557297,65139700
|
| 361 |
+
2022-07-06,150.100006,153.190002,147.889999,151.300003,151.216370,52906600
|
| 362 |
+
2022-07-07,154.559998,159.449997,153.889999,158.580002,158.492355,49290300
|
| 363 |
+
2022-07-08,154.300003,160.369995,153.889999,158.380005,158.292465,46797200
|
| 364 |
+
2022-07-11,155.259995,155.270004,150.380005,151.520004,151.436249,43732100
|
| 365 |
+
2022-07-12,152.679993,154.309998,148.770004,150.820007,150.736649,45848300
|
| 366 |
+
2022-07-13,145.899994,153.750000,144.649994,151.639999,151.556183,52191800
|
| 367 |
+
2022-07-14,151.080002,154.729996,147.279999,153.720001,153.635025,45623500
|
| 368 |
+
2022-07-15,156.589996,157.820007,154.449997,157.619995,157.532867,38593500
|
| 369 |
+
2022-07-18,163.020004,168.970001,160.020004,161.009995,160.920990,67051700
|
| 370 |
+
2022-07-19,164.860001,171.100006,161.720001,169.919998,169.826080,70236600
|
| 371 |
+
2022-07-20,169.470001,179.330002,168.009995,178.070007,177.971573,76053800
|
| 372 |
+
2022-07-21,178.850006,181.440002,175.449997,180.500000,180.400223,55704900
|
| 373 |
+
2022-07-22,178.929993,179.669998,171.369995,173.190002,173.094269,53667100
|
| 374 |
+
2022-07-25,170.190002,171.240005,166.490005,170.240005,170.145905,48074800
|
| 375 |
+
2022-07-26,168.889999,169.190002,164.779999,165.330002,165.238617,39786500
|
| 376 |
+
2022-07-27,170.320007,179.360001,169.130005,177.899994,177.801666,56977600
|
| 377 |
+
2022-07-28,179.750000,181.399994,174.399994,179.839996,179.740585,47464600
|
| 378 |
+
2022-07-29,178.130005,182.440002,176.919998,181.630005,181.529602,43546000
|
| 379 |
+
2022-08-01,181.820007,188.460007,179.899994,184.410004,184.308075,47646900
|
| 380 |
+
2022-08-02,181.220001,189.380005,180.919998,185.259995,185.157593,48952700
|
| 381 |
+
2022-08-03,181.839996,189.679993,181.369995,188.929993,188.825562,41814600
|
| 382 |
+
2022-08-04,188.490005,192.740005,187.600006,192.149994,192.043777,40965200
|
| 383 |
+
2022-08-05,188.100006,192.289993,186.660004,189.889999,189.785034,38606800
|
| 384 |
+
2022-08-08,175.020004,182.389999,172.419998,177.929993,177.831635,98185900
|
| 385 |
+
2022-08-09,172.520004,174.470001,167.240005,170.860001,170.765564,66826300
|
| 386 |
+
2022-08-10,176.979996,181.179993,173.169998,180.970001,180.869980,59742200
|
| 387 |
+
2022-08-11,181.309998,187.070007,178.759995,179.419998,179.320831,50932700
|
| 388 |
+
2022-08-12,181.600006,187.179993,179.529999,187.089996,186.986588,47809400
|
| 389 |
+
2022-08-15,187.009995,191.639999,186.130005,190.320007,190.214813,45766600
|
| 390 |
+
2022-08-16,189.199997,191.419998,185.009995,188.789993,188.685623,45124000
|
| 391 |
+
2022-08-17,185.229996,186.880005,181.449997,183.350006,183.248657,44679900
|
| 392 |
+
2022-08-18,183.009995,188.649994,181.830002,187.729996,187.626221,41544700
|
| 393 |
+
2022-08-19,184.059998,185.199997,177.699997,178.490005,178.391342,44158800
|
| 394 |
+
2022-08-22,174.899994,175.580002,169.660004,170.339996,170.245850,40959300
|
| 395 |
+
2022-08-23,169.889999,174.649994,169.699997,171.809998,171.715027,36998600
|
| 396 |
+
2022-08-24,170.119995,174.059998,168.949997,172.220001,172.124802,52266100
|
| 397 |
+
2022-08-25,168.440002,179.470001,168.330002,179.130005,179.030991,77069100
|
| 398 |
+
2022-08-26,178.570007,179.240005,162.369995,162.600006,162.510117,76912700
|
| 399 |
+
2022-08-29,160.199997,163.380005,157.669998,158.009995,157.922653,49613200
|
| 400 |
+
2022-08-30,159.600006,160.389999,151.820007,154.679993,154.594498,53018100
|
| 401 |
+
2022-08-31,153.839996,155.399994,149.589996,150.940002,150.856567,57371000
|
| 402 |
+
2022-09-01,142.089996,143.800003,132.699997,139.369995,139.292969,117886500
|
| 403 |
+
2022-09-02,141.000000,141.710007,135.910004,136.470001,136.394562,74315700
|
| 404 |
+
2022-09-06,137.309998,137.789993,133.509995,134.649994,134.575577,53575100
|
| 405 |
+
2022-09-07,135.630005,138.380005,133.460007,137.139999,137.104919,51265700
|
| 406 |
+
2022-09-08,134.589996,140.080002,133.690002,139.899994,139.864212,62487300
|
| 407 |
+
2022-09-09,141.570007,144.740005,141.259995,143.869995,143.833191,48661200
|
| 408 |
+
2022-09-12,143.690002,145.470001,141.979996,145.050003,145.012909,48415900
|
| 409 |
+
2022-09-13,138.020004,139.220001,130.990005,131.309998,131.276413,71495600
|
| 410 |
+
2022-09-14,132.539993,132.899994,129.130005,131.279999,131.246429,58850700
|
| 411 |
+
2022-09-15,130.149994,132.330002,127.900002,129.289993,129.256927,52362500
|
| 412 |
+
2022-09-16,127.419998,132.119995,126.169998,131.979996,131.946243,67075100
|
| 413 |
+
2022-09-19,130.119995,134.630005,130.100006,133.820007,133.785782,56968500
|
| 414 |
+
2022-09-20,132.149994,134.830002,130.570007,131.759995,131.726288,52481800
|
| 415 |
+
2022-09-21,132.130005,140.309998,131.100006,132.610001,132.576080,80767900
|
| 416 |
+
2022-09-22,130.699997,131.490005,124.279999,125.610001,125.577873,75916200
|
| 417 |
+
2022-09-23,124.199997,126.110001,122.570000,125.160004,125.127991,66330900
|
| 418 |
+
2022-09-26,124.910004,126.589996,122.139999,122.279999,122.248726,54734300
|
| 419 |
+
2022-09-27,125.070000,127.360001,122.580002,124.129997,124.098251,55385400
|
| 420 |
+
2022-09-28,124.099998,128.229996,123.540001,127.360001,127.327423,54241400
|
| 421 |
+
2022-09-29,124.480003,125.000000,119.459999,122.199997,122.168739,53276300
|
| 422 |
+
2022-09-30,120.870003,126.330002,120.750000,121.389999,121.358955,56563800
|
| 423 |
+
2022-10-03,123.470001,126.779999,121.050003,125.120003,125.088005,54747800
|
| 424 |
+
2022-10-04,128.789993,132.199997,128.789993,131.669998,131.636322,58418200
|
| 425 |
+
2022-10-05,129.110001,133.210007,126.209999,132.089996,132.056213,50713100
|
| 426 |
+
2022-10-06,132.199997,136.559998,131.029999,131.300003,131.266418,64415700
|
| 427 |
+
2022-10-07,125.050003,126.699997,120.220001,120.760002,120.729118,67247800
|
| 428 |
+
2022-10-10,120.370003,121.239998,114.080002,116.699997,116.670151,69869900
|
| 429 |
+
2022-10-11,115.610001,118.459999,112.830002,115.860001,115.830368,66748200
|
| 430 |
+
2022-10-12,115.790001,117.349998,113.449997,115.000000,114.970589,49259000
|
| 431 |
+
2022-10-13,109.709999,120.779999,108.129997,119.599998,119.569412,85010300
|
| 432 |
+
2022-10-14,120.570000,121.110001,112.040001,112.269997,112.241280,71343200
|
| 433 |
+
2022-10-17,115.180000,119.480003,115.169998,118.879997,118.849594,58077400
|
| 434 |
+
2022-10-18,123.440002,124.919998,116.180000,119.669998,119.639389,65936200
|
| 435 |
+
2022-10-19,118.790001,123.500000,118.339996,120.510002,120.479179,52313100
|
| 436 |
+
2022-10-20,121.129997,127.690002,121.050003,121.940002,121.908813,65239800
|
| 437 |
+
2022-10-21,120.980003,124.980003,118.870003,124.660004,124.628120,60949400
|
| 438 |
+
2022-10-24,125.080002,127.099998,120.639999,125.989998,125.957771,51745700
|
| 439 |
+
2022-10-25,126.940002,133.000000,126.639999,132.610001,132.576080,50548200
|
| 440 |
+
2022-10-26,128.690002,133.880005,127.080002,128.960007,128.927017,53295300
|
| 441 |
+
2022-10-27,136.300003,138.380005,131.220001,131.759995,131.726288,58311300
|
| 442 |
+
2022-10-28,131.039993,138.500000,130.610001,138.339996,138.304611,52104000
|
| 443 |
+
2022-10-31,137.779999,138.380005,132.970001,134.970001,134.935486,48634100
|
| 444 |
+
2022-11-01,138.110001,139.250000,135.190002,135.429993,135.395355,43281700
|
| 445 |
+
2022-11-02,138.500000,142.100006,132.110001,132.190002,132.156189,67262800
|
| 446 |
+
2022-11-03,130.429993,137.809998,129.559998,134.210007,134.175674,50006500
|
| 447 |
+
2022-11-04,139.860001,142.289993,136.970001,141.559998,141.523788,61257600
|
| 448 |
+
2022-11-07,142.279999,144.119995,139.539993,143.009995,142.973419,41006100
|
| 449 |
+
2022-11-08,148.009995,148.910004,142.160004,146.020004,145.982651,59529200
|
| 450 |
+
2022-11-09,141.619995,142.110001,137.589996,137.759995,137.724762,45441400
|
| 451 |
+
2022-11-10,148.000000,157.729996,145.470001,157.500000,157.459717,70081900
|
| 452 |
+
2022-11-11,158.070007,163.889999,154.820007,163.270004,163.228241,65548700
|
| 453 |
+
2022-11-14,162.179993,165.399994,159.220001,162.949997,162.908325,52785200
|
| 454 |
+
2022-11-15,167.220001,169.979996,163.820007,166.660004,166.617371,54587600
|
| 455 |
+
2022-11-16,161.619995,163.619995,158.729996,159.100006,159.059311,64954700
|
| 456 |
+
2022-11-17,157.149994,162.660004,155.350006,156.770004,156.729904,71089400
|
| 457 |
+
2022-11-18,159.660004,160.020004,151.199997,154.089996,154.050583,49207200
|
| 458 |
+
2022-11-21,151.470001,154.770004,150.800003,153.169998,153.130829,40473900
|
| 459 |
+
2022-11-22,153.279999,160.580002,151.220001,160.380005,160.338989,47286600
|
| 460 |
+
2022-11-23,160.979996,165.270004,160.479996,165.190002,165.147751,42724100
|
| 461 |
+
2022-11-25,163.179993,164.869995,161.720001,162.699997,162.658386,16793400
|
| 462 |
+
2022-11-28,160.259995,163.570007,157.250000,158.270004,158.229523,30374100
|
| 463 |
+
2022-11-29,158.270004,159.320007,155.199997,156.389999,156.350006,29838400
|
| 464 |
+
2022-11-30,156.970001,169.300003,155.970001,169.229996,169.229996,56529800
|
| 465 |
+
2022-12-01,169.990005,172.649994,166.350006,171.350006,171.350006,47097700
|
| 466 |
+
2022-12-02,166.589996,169.330002,164.449997,168.759995,168.759995,37138900
|
| 467 |
+
2022-12-05,166.789993,169.949997,164.720001,166.100006,166.100006,35225500
|
| 468 |
+
2022-12-06,165.300003,165.729996,158.190002,159.869995,159.869995,35269400
|
| 469 |
+
2022-12-07,157.720001,161.860001,156.669998,161.199997,161.199997,37238800
|
| 470 |
+
2022-12-08,162.729996,171.789993,159.589996,171.690002,171.690002,51545600
|
| 471 |
+
2022-12-09,171.600006,175.830002,169.750000,170.009995,170.009995,46533800
|
| 472 |
+
2022-12-12,170.369995,175.380005,167.970001,175.350006,175.350006,45732800
|
| 473 |
+
2022-12-13,185.309998,187.899994,177.110001,180.720001,180.720001,65658900
|
| 474 |
+
2022-12-14,179.869995,182.520004,174.199997,176.740005,176.740005,49688800
|
| 475 |
+
2022-12-15,171.460007,173.199997,167.000000,169.520004,169.520004,47854200
|
| 476 |
+
2022-12-16,168.639999,170.410004,164.100006,165.710007,165.710007,47823200
|
| 477 |
+
2022-12-19,165.720001,166.089996,161.449997,162.539993,162.539993,35403900
|
| 478 |
+
2022-12-20,160.639999,163.100006,158.520004,160.850006,160.850006,40326000
|
| 479 |
+
2022-12-21,161.139999,166.270004,161.020004,165.009995,165.009995,32502500
|
| 480 |
+
2022-12-22,160.940002,161.380005,148.820007,153.389999,153.389999,56504500
|
| 481 |
+
2022-12-23,151.960007,153.389999,148.830002,152.059998,152.059998,34932600
|
| 482 |
+
2022-12-27,150.740005,151.000000,140.559998,141.210007,141.210007,46490200
|
| 483 |
+
2022-12-28,139.270004,142.619995,138.839996,140.360001,140.360001,35106600
|
| 484 |
+
2022-12-29,144.020004,146.830002,142.270004,146.029999,146.029999,35492300
|
| 485 |
+
2022-12-30,143.339996,146.289993,142.330002,146.139999,146.139999,31027300
|
| 486 |
+
2023-01-03,148.509995,149.960007,140.960007,143.149994,143.149994,40127700
|
| 487 |
+
2023-01-04,145.669998,148.529999,142.410004,147.490005,147.490005,43132400
|
| 488 |
+
2023-01-05,144.910004,145.639999,141.479996,142.649994,142.649994,38916800
|
| 489 |
+
2023-01-06,144.740005,150.100006,140.339996,148.589996,148.589996,40482300
|
| 490 |
+
2023-01-09,152.839996,160.559998,151.410004,156.279999,156.279999,50423100
|
| 491 |
+
2023-01-10,155.070007,159.619995,154.720001,159.089996,159.089996,38410100
|
| 492 |
+
2023-01-11,158.399994,160.279999,155.630005,160.009995,160.009995,35328500
|
| 493 |
+
2023-01-12,161.000000,166.369995,154.919998,165.110001,165.110001,55140900
|
| 494 |
+
2023-01-13,162.779999,169.220001,161.649994,168.990005,168.990005,44693500
|
| 495 |
+
2023-01-17,168.990005,177.279999,168.990005,177.020004,177.020004,51110200
|
| 496 |
+
2023-01-18,176.669998,178.729996,172.820007,173.770004,173.770004,43962400
|
| 497 |
+
2023-01-19,170.360001,171.970001,167.309998,167.649994,167.649994,45293200
|
| 498 |
+
2023-01-20,170.110001,178.559998,168.250000,178.389999,178.389999,56401600
|
| 499 |
+
2023-01-23,180.639999,192.449997,178.179993,191.929993,191.929993,65516300
|
| 500 |
+
2023-01-24,188.270004,194.949997,188.199997,192.649994,192.649994,49620400
|
| 501 |
+
2023-01-25,189.130005,193.699997,185.800003,193.229996,193.229996,44953700
|
| 502 |
+
2023-01-26,197.009995,201.660004,192.779999,198.020004,198.020004,48953500
|
| 503 |
+
2023-01-27,194.619995,206.279999,194.050003,203.649994,203.649994,54163300
|
| 504 |
+
2023-01-30,199.500000,201.399994,191.500000,191.619995,191.619995,48861100
|
| 505 |
+
2023-01-31,191.695007,196.869995,189.500000,195.369995,195.369995,49801658
|
README.md
CHANGED
|
@@ -1,3 +1,246 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Defining and Solving Reinforcement Learning Environments
|
| 2 |
+
|
| 3 |
+
## 📋 Project Description
|
| 4 |
+
|
| 5 |
+
This project involves defining and solving various reinforcement learning (RL) environments using SARSA and tabular methods such as Q-learning and Double Q-learning. We explore both deterministic and stochastic environments across different scenarios: Frozen Lake, Lawn Mower, and Squirrel Maze. And we apply these techniques to a stock trading environment to demonstrate the versatility of these algorithms.
|
| 6 |
+
|
| 7 |
+
## 💻 Team Members
|
| 8 |
+
|
| 9 |
+
- Charvi Kusuma [GitHub](https://github.com/kcharvi)
|
| 10 |
+
- Tarun Reddi [GitHub](https://github.com/REDDITARUN)
|
| 11 |
+
|
| 12 |
+
## 🎯 Objective
|
| 13 |
+
|
| 14 |
+
The primary objective is for the agent to learn a policy that maximizes the cumulative reward over time in various grid-world environments. Each environment is designed with unique states, actions, and rewards to test the robustness of RL algorithms.
|
| 15 |
+
|
| 16 |
+
## 📁 Repository Structure
|
| 17 |
+
|
| 18 |
+
- `environments/`: Source code for the environments.
|
| 19 |
+
- `images/`: Images used in the environments.
|
| 20 |
+
- `models/`: Saved models and results.
|
| 21 |
+
- `reports/`: Project reports and documentation.
|
| 22 |
+
- `README.md`: Project overview and instructions.
|
| 23 |
+
|
| 24 |
+
## 📚 Environments
|
| 25 |
+
|
| 26 |
+
<p align="center">
|
| 27 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/d7cd08e0-7fb2-4329-8738-286438f1d198" alt="Lawn Mower" width="200"/>
|
| 28 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/47d729b0-c885-4e94-8b73-4b6aef995a6e" alt="Squirrel Maze" width="200"/>
|
| 29 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/d2bfc794-e84a-4c51-b75a-b9b44a2f4646" alt="Frozen Lake" width="200"/>
|
| 30 |
+
</p>
|
| 31 |
+
<p align="center">
|
| 32 |
+
<b>Lawn Mower</b> <b>Squirrel Maze</b> <b>Frozen Lake</b>
|
| 33 |
+
</p>
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
### 1. Frozen Lake
|
| 39 |
+
|
| 40 |
+
The Frozen Lake environment is a 4x4 grid where the agent (a skater) must navigate from the start to the goal while avoiding holes and collecting gems.
|
| 41 |
+
|
| 42 |
+
#### Key Features:
|
| 43 |
+
|
| 44 |
+
- **States**: Positions on the grid, including start, goal, holes, and gems.
|
| 45 |
+
- **Actions**: Move left, right, up, or down.
|
| 46 |
+
- **Rewards**: Positive rewards for reaching the goal and collecting gems; negative rewards for falling into holes or moving away from the goal.
|
| 47 |
+
|
| 48 |
+
### 2. Lawn Mower
|
| 49 |
+
|
| 50 |
+
The Lawn Mower environment simulates a mower navigating a lawn to cut grass while avoiding obstacles.
|
| 51 |
+
|
| 52 |
+
#### Key Features:
|
| 53 |
+
|
| 54 |
+
- **States**: Grid positions representing lawn mower agent, battery and rock locations along with goal state.
|
| 55 |
+
- **Actions**: Move left, right, up, or down.
|
| 56 |
+
- **Rewards**: Positive rewards for reaching battery; negative rewards for hitting obstacles.
|
| 57 |
+
|
| 58 |
+
### 3. Squirrel Maze
|
| 59 |
+
|
| 60 |
+
The Squirrel Maze environment involves a squirrel navigating a grid to collect acorns and avoid hunters.
|
| 61 |
+
|
| 62 |
+
#### Key Features:
|
| 63 |
+
|
| 64 |
+
- **States**: Positions on the grid, including start, acorns, hunters, and home.
|
| 65 |
+
- **Actions**: Move left, right, up, or down.
|
| 66 |
+
- **Rewards**: Positive rewards for collecting acorns and reaching home; negative rewards for encountering hunters.
|
| 67 |
+
|
| 68 |
+
### 4. Stock Trading
|
| 69 |
+
|
| 70 |
+
The Stock Trading environment simulates trading in a stock market, where the agent learns to buy and sell stocks to maximize profit.
|
| 71 |
+
|
| 72 |
+
#### Key Features:
|
| 73 |
+
|
| 74 |
+
- **States**: Market conditions and portfolio status.
|
| 75 |
+
- **Actions**: Buy, sell, hold.
|
| 76 |
+
- **Rewards**: Profit or loss from trades.
|
| 77 |
+
|
| 78 |
+
## ❗Importance of This Project
|
| 79 |
+
|
| 80 |
+
1. **Technical Proficiency with Algorithms Implemented**: The project involves the implementation of advanced RL algorithms such as Q-learning and Double Q-learning, a quick start to understand and apply sophisticated reinforcement learning techniques. The custom design of multiple RL environments (Frozen Lake, Lawn Mower, Squirrel Maze, and Stock Trading) gives the capability to create and manipulate simulations, an essential skill in many AI and data science roles.
|
| 81 |
+
|
| 82 |
+
2. **Problem-Solving Skills with Deterministic and Stochastic Approaches and Reward Optimization**: By addressing both deterministic and stochastic environments, the project improves our ability to tackle uncertainty and variability, which are common in real-world scenarios. The strategic design of reward systems to guide agent behavior gives an understanding of optimization and objective-driven development.
|
| 83 |
+
|
| 84 |
+
3. **Data Analysis and Visualization**: Detailed analysis and comparison of different algorithms provide insights and gives us the ability to draw meaningful conclusions from data. The use of matplotlib for environment visualization and results plotting enhances our proficiency in presenting data clearly and effectively.
|
| 85 |
+
|
| 86 |
+
4. **Versatility with ease of Extending Application to Diverse Domains**: The application of RL to both grid-world scenarios and a stock trading environment gives the versatility and ability to adapt RL techniques to various domains, from robotics to finance.
|
| 87 |
+
|
| 88 |
+
5. **Innovation and Creativity with Custom Environments**: Creating unique environments like Lawn Mower and Squirrel Maze increases our creativity and ability to think outside the box, essential for innovation in technology roles. The inclusion of safety measures ensures ethical considerations are addressed, reflecting a responsible approach to AI development.
|
| 89 |
+
|
| 90 |
+
## 🌟 Features
|
| 91 |
+
|
| 92 |
+
- **Defining RL Environments - Frozen Lake, Law Mower, Squirrel Maze and Stock Trading**: Detailed creation of both deterministic and stochastic environments.
|
| 93 |
+
- **SARSA Implementation**: Step by Step solving with SARSA algorithm.
|
| 94 |
+
- **Q-Learning Implementation**: In-depth application of Q-learning to solve creative environments.
|
| 95 |
+
- **Other Tabular Method - Double Q Learning**: Exploration of different tabular methods for RL problem-solving.
|
| 96 |
+
- **Stock Trading Environment**: Unique application of Q-learning in a simulated stock trading scenario.
|
| 97 |
+
- **Comprehensive Analysis**: Extensive evaluation and comparison of different RL methods.
|
| 98 |
+
|
| 99 |
+
## 📈 Results Overview
|
| 100 |
+
|
| 101 |
+
### Frozen Lake
|
| 102 |
+
|
| 103 |
+
- **Deterministic Q-Learning**: Showed a smooth decrease in epsilon and a steady increase in total rewards per episode, stabilizing at higher values indicating effective learning.
|
| 104 |
+
- **Stochastic Q-Learning**: Demonstrated more fluctuations in rewards due to randomness, with epsilon decay less smooth compared to deterministic.
|
| 105 |
+
- **Deterministic Double Q-Learning**: Performed slightly better than Q-Learning, with higher and more stable rewards.
|
| 106 |
+
- **Stochastic Double Q-Learning**: Similar fluctuations as stochastic Q-Learning, but generally showed better performance over time.
|
| 107 |
+
|
| 108 |
+
1. Epsilon Decay Plot
|
| 109 |
+
|
| 110 |
+
- **Description**: This plot shows how the epsilon value decreases over episodes, indicating the agent's transition from exploration to exploitation.
|
| 111 |
+
|
| 112 |
+

|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
2. Total Rewards per Episode
|
| 116 |
+
|
| 117 |
+
- **Description**: This plot illustrates the cumulative rewards obtained by the agent in each episode, showing the learning progress over time.
|
| 118 |
+
|
| 119 |
+

|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
3. Q-Learning vs. Double Q-Learning Comparison
|
| 123 |
+
|
| 124 |
+
- **Description**: A comparison of the performance of Q-Learning and Double Q-Learning algorithms in the Frozen Lake environment.
|
| 125 |
+
|
| 126 |
+

|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
### Lawn Mower
|
| 130 |
+
|
| 131 |
+
- **SARSA**: Steady increase in rewards indicating effective policy learning. Performance might vary if adapted to stochastic environments.
|
| 132 |
+
- **Double Q-Learning**: Achieved higher rewards compared to SARSA, showing improved learning efficiency. Potential for robust policy in stochastic environments.
|
| 133 |
+
- **N-Step Bootstrapping**: Outperformed SARSA with a steady increase in rewards, showing the benefit of multi-step updates. Can handle stochasticity with more robustness.
|
| 134 |
+
|
| 135 |
+
1. Epsilon Decay Plot
|
| 136 |
+
|
| 137 |
+
<p align="center">
|
| 138 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/7c856c99-c183-4200-afdc-043da83758d1" alt="SARSA Epsilon Decay" width="300"/>
|
| 139 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/6c034df0-fc1a-45b9-a44d-c6bffe493308" alt="Q Learning Epsilon Decay" width="300"/>
|
| 140 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/eaef9a85-7b21-40cd-b877-854b048ecd59" alt="Double Q Epsilon Decay" width="300"/>
|
| 141 |
+
</p>
|
| 142 |
+
<p align="center">
|
| 143 |
+
<b>SARSA Epsilon Decay</b> <b>Q Learning Epsilon Decay</b> <b>Double Q Epsilon Decay</b>
|
| 144 |
+
</p>
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
3. Total Rewards per Episode
|
| 148 |
+
|
| 149 |
+
<p align="center">
|
| 150 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/66611548-edf9-427f-8ff5-71b8810f95bf" alt="SARSA Total Rewards" width="300"/>
|
| 151 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/1eca5c95-087a-40c5-bb30-95c05249d548" alt="Q Learning Total Rewards" width="300"/>
|
| 152 |
+
<img src="https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/0d8f5d2a-d265-4fa2-ab2a-095689921ec7" alt="Double Q Total Rewards" width="300"/>
|
| 153 |
+
</p>
|
| 154 |
+
<p align="center">
|
| 155 |
+
<b>SARSA Total Rewards</b> <b>Q Learning Total Rewards</b> <b>Double Q Total Rewards</b>
|
| 156 |
+
</p>
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
5. SARSA vs. Double Q-Learning Comparison
|
| 160 |
+
|
| 161 |
+

|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
### Squirrel Maze
|
| 165 |
+
|
| 166 |
+
- **Deterministic Q-Learning**: Showed steady increase in rewards with a smooth epsilon decay.
|
| 167 |
+
- **Stochastic Q-Learning**: High variance in rewards due to environment randomness, less smooth epsilon decay.
|
| 168 |
+
- **Deterministic Double Q-Learning**: Higher and more stable rewards compared to Q-Learning, better handling of state-action space.
|
| 169 |
+
- **Stochastic Double Q-Learning**: High variance similar to stochastic Q-Learning, but occasionally higher peaks in rewards.
|
| 170 |
+
|
| 171 |
+
1. Epsilon Decay Plot
|
| 172 |
+
|
| 173 |
+

|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
2. Total Rewards per Episode
|
| 177 |
+
|
| 178 |
+

|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
3. Comparison
|
| 182 |
+
|
| 183 |
+
| Algorithm | Environment | Model Variation | Max Reward (Episode) | Episode 1000 Reward | Epsilon Decay Trend |
|
| 184 |
+
| --- | --- | --- | --- | --- | --- |
|
| 185 |
+
| Q-learning | Deterministic | Base Model | 400+ | 390 | Slow Decline |
|
| 186 |
+
| Q-learning | Deterministic | Hyperparameter Tuning (Max Timestamp, Decay Rate: 20, 0.75) | 800+ | 765 | Slow Decline |
|
| 187 |
+
| Q-learning | Deterministic | Hyperparameter Tuning (Max Timestamp, Decay Rate: 20, 0.995) | 800+ | 765 | Slow Decline |
|
| 188 |
+
| Q-learning | Stochastic | Base Model | 400+ | 305 | Slow Decline |
|
| 189 |
+
| Q-learning | Stochastic | Hyperparameter Tuning (Max Timestamp, Decay Rate: 20, 0.995) | 800+ | 660 | Slow Decline |
|
| 190 |
+
| Double Q-learning | Deterministic | Base Model | 400 | - | - |
|
| 191 |
+
| Double Q-learning | Stochastic | Base Model | 400+ | - | - |
|
| 192 |
+
|
| 193 |
+
### Stock Trading
|
| 194 |
+
|
| 195 |
+
- **Q-Learning**: Demonstrated gradual increase in account value over episodes with expected fluctuations, indicating effective learning despite market volatility. Can be adapted to stochastic market conditions, reflecting real-world market dynamics, useful in algorithmic trading.
|
| 196 |
+
|
| 197 |
+
1. Epsilon Decay Plot
|
| 198 |
+
|
| 199 |
+

|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
2. Total Rewards per Episode
|
| 203 |
+
|
| 204 |
+

|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
3. Account Value Over Time
|
| 208 |
+
|
| 209 |
+
- **Description**: This plot shows how the agent's account value changes over time, indicating the profitability of the trading strategy.
|
| 210 |
+
|
| 211 |
+

|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
### Summary of Results for Each Environment
|
| 215 |
+
|
| 216 |
+
| Environment | Algorithm | Deterministic Environment Results | Stochastic Environment Results |
|
| 217 |
+
| ----------------- | -------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
| 218 |
+
| **Frozen Lake** | Q-Learning | - Epsilon Decay: Smooth exponential decay | - Epsilon Decay: Fluctuating due to randomness |
|
| 219 |
+
| | | - Total Rewards per Episode: Gradually increasing, stable at higher values | - Total Rewards per Episode: Fluctuating with occasional high rewards |
|
| 220 |
+
| | Double Q-Learning | - Epsilon Decay: Smooth exponential decay | - Epsilon Decay: Fluctuating due to randomness |
|
| 221 |
+
| | | - Total Rewards per Episode: Gradually increasing, slightly higher than Q-Learning | - Total Rewards per Episode: Fluctuating, generally lower than deterministic |
|
| 222 |
+
| | | - Comparison: Double Q-Learning performs slightly better in stable environments | - Comparison: More variance observed, with occasional high rewards |
|
| 223 |
+
| **Lawn Mower** | SARSA | - Total Rewards per Episode: Increasing steadily | - Performance might vary if adapted to stochastic |
|
| 224 |
+
| | Double Q-Learning | - Total Rewards per Episode: Higher rewards compared to SARSA | - Potential for robust policy in stochastic environment |
|
| 225 |
+
| | N-Step Bootstrapping | - Total Rewards per Episode: Steady increase, higher than SARSA | - Can handle stochasticity with more robustness |
|
| 226 |
+
| | | - Comparison: Double Q-Learning achieves better long-term rewards | - Higher variance expected with stochastic adjustments |
|
| 227 |
+
| **Squirrel Maze** | Q-Learning | - Epsilon Decay: Smooth exponential decay | - Epsilon Decay: Fluctuating due to randomness |
|
| 228 |
+
| | | - Total Rewards per Episode: Increasing steadily | - Total Rewards per Episode: Fluctuating with high variance |
|
| 229 |
+
| | Double Q-Learning | - Epsilon Decay: Smooth exponential decay | - Epsilon Decay: Fluctuating due to randomness |
|
| 230 |
+
| | | - Total Rewards per Episode: Higher and more stable compared to Q-Learning | - Total Rewards per Episode: Fluctuating, generally lower than deterministic |
|
| 231 |
+
| | | - Comparison: Double Q-Learning shows better reward dynamics | - Comparison: High variance with occasional peaks in rewards |
|
| 232 |
+
| **Stock Trading** | Q-Learning | - Epsilon Decay: Smooth exponential decay | - Adapts well to deterministic trading strategies |
|
| 233 |
+
| | | - Total Rewards per Episode: Initial fluctuations, eventually stabilizing | - Can be adapted to stochastic market conditions |
|
| 234 |
+
| | | - Evaluation: Account value increases over time with fluctuations | - Reflects real-world market dynamics, useful in algorithmic trading |
|
| 235 |
+
|
| 236 |
+
## 🖥️ Technologies Used
|
| 237 |
+
|
| 238 |
+
- Python
|
| 239 |
+
- Gymnasium Library
|
| 240 |
+
- Matplotlib (for visualizations)
|
| 241 |
+
- Various RL Algorithms
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
### 🚨Academic Integrity Disclaimer🚨
|
| 245 |
+
|
| 246 |
+
This project in this repository is intended solely as an inspiration for your future projects and should be referenced accordingly. It is not meant for students to fulfill their academic project requirements. If a student uses this project for such purposes, the creators are not responsible. The student will be solely accountable for violating academic integrity. We explicitly state that this repository should not be used to meet academic requirements. Therefore, any academic integrity issues should be addressed with the student, not the creators.
|
Squirrel Maze Double Q Learning Deterministic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Squirrel Maze Double Q Learning StochasticEnvironment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Squirrel Maze Q Learning Deterministic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Squirrel Maze Q Learning Stochastic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Stock Trading Q Learning Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
environments/Frozen Lake Grid World Defining Deterministic and Stochastic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
environments/Lawn Mower Grid World Defining Deterministic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
environments/Squirrel Maze Grid World Defining Deterministic and Stochastic Environment.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
environments/Stock Trading Environment.ipynb
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"## Defining Stock Trading Environment"
|
| 8 |
+
]
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"cell_type": "markdown",
|
| 12 |
+
"metadata": {},
|
| 13 |
+
"source": [
|
| 14 |
+
"Task:\n",
|
| 15 |
+
"\n",
|
| 16 |
+
"In this part, you need to apply a Q-learning agent that you implemented in Part 2.1 to learn the trends in stock price and perform a series of trades over a period of time to end up with a profit. You can modify your Q-learning code, if needed."
|
| 17 |
+
]
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"cell_type": "code",
|
| 21 |
+
"execution_count": null,
|
| 22 |
+
"metadata": {},
|
| 23 |
+
"outputs": [
|
| 24 |
+
{
|
| 25 |
+
"name": "stdout",
|
| 26 |
+
"output_type": "stream",
|
| 27 |
+
"text": [
|
| 28 |
+
"Collecting gymnasium\n",
|
| 29 |
+
" Downloading gymnasium-0.29.1-py3-none-any.whl.metadata (10 kB)\n",
|
| 30 |
+
"Requirement already satisfied: numpy>=1.21.0 in c:\\users\\91740\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.8_qbz5n2kfra8p0\\localcache\\local-packages\\python38\\site-packages (from gymnasium) (1.24.3)\n",
|
| 31 |
+
"Requirement already satisfied: cloudpickle>=1.2.0 in c:\\users\\91740\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.8_qbz5n2kfra8p0\\localcache\\local-packages\\python38\\site-packages (from gymnasium) (3.0.0)\n",
|
| 32 |
+
"Requirement already satisfied: typing-extensions>=4.3.0 in c:\\users\\91740\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.8_qbz5n2kfra8p0\\localcache\\local-packages\\python38\\site-packages (from gymnasium) (4.5.0)\n",
|
| 33 |
+
"Collecting farama-notifications>=0.0.1 (from gymnasium)\n",
|
| 34 |
+
" Downloading Farama_Notifications-0.0.4-py3-none-any.whl (2.5 kB)\n",
|
| 35 |
+
"Requirement already satisfied: importlib-metadata>=4.8.0 in c:\\users\\91740\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.8_qbz5n2kfra8p0\\localcache\\local-packages\\python38\\site-packages (from gymnasium) (6.9.0)\n",
|
| 36 |
+
"Requirement already satisfied: zipp>=0.5 in c:\\users\\91740\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.8_qbz5n2kfra8p0\\localcache\\local-packages\\python38\\site-packages (from importlib-metadata>=4.8.0->gymnasium) (3.17.0)\n",
|
| 37 |
+
"Downloading gymnasium-0.29.1-py3-none-any.whl (953 kB)\n",
|
| 38 |
+
" ---------------------------------------- 0.0/953.9 kB ? eta -:--:--\n",
|
| 39 |
+
" ---- ----------------------------------- 102.4/953.9 kB 2.0 MB/s eta 0:00:01\n",
|
| 40 |
+
" ----------------------------- ---------- 696.3/953.9 kB 7.3 MB/s eta 0:00:01\n",
|
| 41 |
+
" ---------------------------------------- 953.9/953.9 kB 8.6 MB/s eta 0:00:00\n",
|
| 42 |
+
"Installing collected packages: farama-notifications, gymnasium\n",
|
| 43 |
+
"Successfully installed farama-notifications-0.0.4 gymnasium-0.29.1\n"
|
| 44 |
+
]
|
| 45 |
+
}
|
| 46 |
+
],
|
| 47 |
+
"source": [
|
| 48 |
+
"!pip install gymnasium"
|
| 49 |
+
]
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"cell_type": "code",
|
| 53 |
+
"execution_count": null,
|
| 54 |
+
"metadata": {},
|
| 55 |
+
"outputs": [],
|
| 56 |
+
"source": [
|
| 57 |
+
"# Imports\n",
|
| 58 |
+
"import gymnasium\n",
|
| 59 |
+
"from gymnasium import spaces\n",
|
| 60 |
+
"import math\n",
|
| 61 |
+
"import matplotlib.pyplot as plt\n",
|
| 62 |
+
"import numpy as np\n",
|
| 63 |
+
"import pandas as pd"
|
| 64 |
+
]
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"cell_type": "code",
|
| 68 |
+
"execution_count": null,
|
| 69 |
+
"metadata": {},
|
| 70 |
+
"outputs": [],
|
| 71 |
+
"source": [
|
| 72 |
+
"# Defining the Stock Trading Environment.\n",
|
| 73 |
+
"\"\"\"DON'T MAKE ANY CHANGES TO THE ENVIRONMENT.\"\"\"\n",
|
| 74 |
+
"\n",
|
| 75 |
+
"\n",
|
| 76 |
+
"class StockTradingEnvironment(gymnasium.Env):\n",
|
| 77 |
+
" \"\"\"This class implements the Stock Trading environment.\"\"\"\n",
|
| 78 |
+
"\n",
|
| 79 |
+
" def __init__(self, file_path, train=True, number_of_days_to_consider=10):\n",
|
| 80 |
+
" \"\"\"This method initializes the environment.\n",
|
| 81 |
+
"\n",
|
| 82 |
+
" :param file_path: - Path of the CSV file containing the historical stock data.\n",
|
| 83 |
+
" :param train: - Boolean indicating whether the goal is to train or test the performance of the agent.\n",
|
| 84 |
+
" :param number_of_days_to_consider = Integer representing the number of days the for which the agent\n",
|
| 85 |
+
" considers the trend in stock price to make a decision.\"\"\"\n",
|
| 86 |
+
"\n",
|
| 87 |
+
" self.file_path = file_path\n",
|
| 88 |
+
" self.stock_data = pd.read_csv(self.file_path)\n",
|
| 89 |
+
" self.train = train\n",
|
| 90 |
+
"\n",
|
| 91 |
+
" # Splitting the data into train and test datasets.\n",
|
| 92 |
+
" self.training_stock_data = self.stock_data.iloc[:int(0.8 * len(self.stock_data))]\n",
|
| 93 |
+
" self.testing_stock_data = self.stock_data.iloc[int(0.8 * len(self.stock_data)):].reset_index()\n",
|
| 94 |
+
"\n",
|
| 95 |
+
" self.observation_space = spaces.Discrete(4)\n",
|
| 96 |
+
" self.action_space = spaces.Discrete(3)\n",
|
| 97 |
+
"\n",
|
| 98 |
+
" self.investment_capital = 100000 # This defines the investment capital that the agent starts with.\n",
|
| 99 |
+
" self.number_of_shares = 0 # This defines number of shares currently held by the agent.\n",
|
| 100 |
+
" self.stock_value = 0 # This defines the value of the stock currently held by the agent.\n",
|
| 101 |
+
" self.book_value = 0 # This defines the total value for which the agent bought the shares.\n",
|
| 102 |
+
" # This defines the agent's total account value.\n",
|
| 103 |
+
" self.total_account_value = self.investment_capital + self.stock_value\n",
|
| 104 |
+
" # List to store the total account value over training or evaluation.\n",
|
| 105 |
+
" self.total_account_value_list = []\n",
|
| 106 |
+
" # This defines the number of days for which the agent considers the data before taking an action.\n",
|
| 107 |
+
" self.number_of_days_to_consider = number_of_days_to_consider\n",
|
| 108 |
+
" # The maximum timesteps the agent will take before the episode ends.\n",
|
| 109 |
+
" if self.train:\n",
|
| 110 |
+
" self.max_timesteps = len(self.training_stock_data) - self.number_of_days_to_consider\n",
|
| 111 |
+
" else:\n",
|
| 112 |
+
" self.max_timesteps = len(self.testing_stock_data) - self.number_of_days_to_consider\n",
|
| 113 |
+
" # Initializing the number of steps taken to 0.\n",
|
| 114 |
+
" self.timestep = 0\n",
|
| 115 |
+
" self.reset()\n",
|
| 116 |
+
"\n",
|
| 117 |
+
" def reset(self):\n",
|
| 118 |
+
" \"\"\"This method resets the environment and returns the observation.\n",
|
| 119 |
+
"\n",
|
| 120 |
+
" :returns observation: - Integer in the range of 0 to 3 representing the four possible observations that the\n",
|
| 121 |
+
" agent can receive. The observation depends upon whether the price increased on average\n",
|
| 122 |
+
" in the number of days the agent considers, and whether the agent already has the stock\n",
|
| 123 |
+
" or not.\n",
|
| 124 |
+
"\n",
|
| 125 |
+
" info: - info: - A dictionary that can be used to provide additional implementation information.\"\"\"\n",
|
| 126 |
+
"\n",
|
| 127 |
+
" self.investment_capital = 100000 # This defines the investment capital that the agent starts with.\n",
|
| 128 |
+
" self.number_of_shares = 0 # This defines number of shares currently held by the agent.\n",
|
| 129 |
+
" self.stock_value = 0 # This defines the value of the stock currently held by the agent.\n",
|
| 130 |
+
" self.book_value = 0 # This defines the total value for which the agent bought the shares.\n",
|
| 131 |
+
" # This defines the agent's total account value.\n",
|
| 132 |
+
" self.total_account_value = self.investment_capital + self.stock_value\n",
|
| 133 |
+
" # List to store the total account value over training or evaluation.\n",
|
| 134 |
+
" self.total_account_value_list = []\n",
|
| 135 |
+
" # Initializing the number of steps taken to 0.\n",
|
| 136 |
+
" self.timestep = 0\n",
|
| 137 |
+
"\n",
|
| 138 |
+
" # Getting the observation vector.\n",
|
| 139 |
+
" if self.train:\n",
|
| 140 |
+
" # If the task is to train the agent the maximum timesteps will be equal to the number of days considered\n",
|
| 141 |
+
" # subtracted from the length of the training stock data.\n",
|
| 142 |
+
" self.max_timesteps = len(self.training_stock_data) - self.number_of_days_to_consider\n",
|
| 143 |
+
"\n",
|
| 144 |
+
" # Calculating whether the price increased or decreased/remained the same on the majority of days the agent\n",
|
| 145 |
+
" # considers.\n",
|
| 146 |
+
" price_increase_list = []\n",
|
| 147 |
+
" for i in range(self.number_of_days_to_consider):\n",
|
| 148 |
+
" if self.training_stock_data['Close'][self.timestep + 1 + i] \\\n",
|
| 149 |
+
" - self.training_stock_data['Close'][self.timestep + i] > 0:\n",
|
| 150 |
+
" price_increase_list.append(1)\n",
|
| 151 |
+
" else:\n",
|
| 152 |
+
" price_increase_list.append(0)\n",
|
| 153 |
+
"\n",
|
| 154 |
+
" if (np.sum(price_increase_list) / self.number_of_days_to_consider) >= 0.5:\n",
|
| 155 |
+
" price_increase = True\n",
|
| 156 |
+
" else:\n",
|
| 157 |
+
" price_increase = False\n",
|
| 158 |
+
"\n",
|
| 159 |
+
" stock_held = False\n",
|
| 160 |
+
"\n",
|
| 161 |
+
" # Observation vector that will be passed to the agent.\n",
|
| 162 |
+
" observation = [price_increase, stock_held]\n",
|
| 163 |
+
"\n",
|
| 164 |
+
" else:\n",
|
| 165 |
+
" # If the task is to evaluate the trained agent's performance the maximum timesteps will be equal to the\n",
|
| 166 |
+
" # number of days considered subtracted from the length of the testing stock data.\n",
|
| 167 |
+
" self.max_timesteps = len(self.testing_stock_data) - self.number_of_days_to_consider\n",
|
| 168 |
+
"\n",
|
| 169 |
+
" # Calculating whether the price increased or decreased/remained the same on the majority of days the agent\n",
|
| 170 |
+
" # considers.\n",
|
| 171 |
+
" price_increase_list = []\n",
|
| 172 |
+
" for i in range(self.number_of_days_to_consider):\n",
|
| 173 |
+
" if self.testing_stock_data['Close'][self.timestep + 1 + i] \\\n",
|
| 174 |
+
" - self.testing_stock_data['Close'][self.timestep + i] > 0:\n",
|
| 175 |
+
" price_increase_list.append(1)\n",
|
| 176 |
+
" else:\n",
|
| 177 |
+
" price_increase_list.append(0)\n",
|
| 178 |
+
"\n",
|
| 179 |
+
" if (np.sum(price_increase_list) / self.number_of_days_to_consider) >= 0.5:\n",
|
| 180 |
+
" price_increase = True\n",
|
| 181 |
+
" else:\n",
|
| 182 |
+
" price_increase = False\n",
|
| 183 |
+
"\n",
|
| 184 |
+
" stock_held = False\n",
|
| 185 |
+
"\n",
|
| 186 |
+
" # Observation vector.\n",
|
| 187 |
+
" observation = [price_increase, stock_held]\n",
|
| 188 |
+
"\n",
|
| 189 |
+
" if np.array_equal(observation, [True, False]):\n",
|
| 190 |
+
" observation = 0\n",
|
| 191 |
+
" if np.array_equal(observation, [True, True]):\n",
|
| 192 |
+
" observation = 1\n",
|
| 193 |
+
" if np.array_equal(observation, [False, False]):\n",
|
| 194 |
+
" observation = 2\n",
|
| 195 |
+
" if np.array_equal(observation, [False, True]):\n",
|
| 196 |
+
" observation = 3\n",
|
| 197 |
+
"\n",
|
| 198 |
+
" info = None\n",
|
| 199 |
+
"\n",
|
| 200 |
+
" return observation, info\n",
|
| 201 |
+
"\n",
|
| 202 |
+
" def step(self, action):\n",
|
| 203 |
+
" \"\"\"This method implements what happens when the agent takes the action to Buy/Sell/Hold.\n",
|
| 204 |
+
"\n",
|
| 205 |
+
" :param action: - Integer in the range 0 to 2 inclusive.\n",
|
| 206 |
+
"\n",
|
| 207 |
+
" :returns observation: - Integer in the range of 0 to 3 representing the four possible observations that the\n",
|
| 208 |
+
" agent can receive. The observation depends upon whether the price increased on average\n",
|
| 209 |
+
" in the number of days the agent considers, and whether the agent already has the stock\n",
|
| 210 |
+
" or not.\n",
|
| 211 |
+
" reward: - Integer/Float value that's used to measure the performance of the agent.\n",
|
| 212 |
+
" terminated: - Boolean describing whether the episode has terminated.\n",
|
| 213 |
+
" truncated: - Boolean describing whether a truncation condition outside the scope of the MDP is satisfied.\n",
|
| 214 |
+
" info: - A dictionary that can be used to provide additional implementation information.\"\"\"\n",
|
| 215 |
+
"\n",
|
| 216 |
+
" # We give the agent a penalty for taking actions such as buying a stock when the agent doesn't have the\n",
|
| 217 |
+
" # investment capital and selling a stock when the agent doesn't have any shares.\n",
|
| 218 |
+
" penalty = 0\n",
|
| 219 |
+
"\n",
|
| 220 |
+
" if self.train:\n",
|
| 221 |
+
" if action == 0: # Buy\n",
|
| 222 |
+
" if self.number_of_shares > 0:\n",
|
| 223 |
+
" penalty = -10\n",
|
| 224 |
+
" # Determining the number of shares the agent can buy.\n",
|
| 225 |
+
" number_of_shares_to_buy = math.floor(self.investment_capital / self.training_stock_data[\n",
|
| 226 |
+
" 'Open'][self.timestep + self.number_of_days_to_consider])\n",
|
| 227 |
+
" # Adding to the number of shares the agent has.\n",
|
| 228 |
+
" self.number_of_shares += number_of_shares_to_buy\n",
|
| 229 |
+
"\n",
|
| 230 |
+
" # Computing the stock value, book value, investment capital and reward.\n",
|
| 231 |
+
" if number_of_shares_to_buy > 0:\n",
|
| 232 |
+
" self.stock_value +=\\\n",
|
| 233 |
+
" self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 234 |
+
" * number_of_shares_to_buy\n",
|
| 235 |
+
" self.book_value += \\\n",
|
| 236 |
+
" self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider]\\\n",
|
| 237 |
+
" * number_of_shares_to_buy\n",
|
| 238 |
+
" self.investment_capital -= \\\n",
|
| 239 |
+
" self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 240 |
+
" * number_of_shares_to_buy\n",
|
| 241 |
+
"\n",
|
| 242 |
+
" reward = 1 + penalty\n",
|
| 243 |
+
"\n",
|
| 244 |
+
" else:\n",
|
| 245 |
+
" # Computing the stock value and reward.\n",
|
| 246 |
+
" self.stock_value = \\\n",
|
| 247 |
+
" self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 248 |
+
" * self.number_of_shares\n",
|
| 249 |
+
" reward = -10\n",
|
| 250 |
+
"\n",
|
| 251 |
+
" if action == 1: # Sell\n",
|
| 252 |
+
" # Computing the investment capital, sell value and reward.\n",
|
| 253 |
+
" self.investment_capital += \\\n",
|
| 254 |
+
" self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 255 |
+
" * self.number_of_shares\n",
|
| 256 |
+
" sell_value = self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 257 |
+
" * self.number_of_shares\n",
|
| 258 |
+
"\n",
|
| 259 |
+
" if self.book_value > 0:\n",
|
| 260 |
+
" reward = (sell_value - self.book_value) / self.book_value * 100\n",
|
| 261 |
+
" else:\n",
|
| 262 |
+
" reward = -10\n",
|
| 263 |
+
"\n",
|
| 264 |
+
" self.number_of_shares = 0\n",
|
| 265 |
+
" self.stock_value = 0\n",
|
| 266 |
+
" self.book_value = 0\n",
|
| 267 |
+
"\n",
|
| 268 |
+
" if action == 2: # Hold\n",
|
| 269 |
+
" # Computing the stock value and reward.\n",
|
| 270 |
+
" self.stock_value = self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 271 |
+
" * self.number_of_shares\n",
|
| 272 |
+
"\n",
|
| 273 |
+
" if self.book_value > 0:\n",
|
| 274 |
+
" reward = (self.stock_value - self.book_value) / self.book_value * 100\n",
|
| 275 |
+
" else:\n",
|
| 276 |
+
" reward = -1\n",
|
| 277 |
+
"\n",
|
| 278 |
+
" else:\n",
|
| 279 |
+
" if action == 0: # Buy\n",
|
| 280 |
+
" if self.number_of_shares > 0:\n",
|
| 281 |
+
" penalty = -10\n",
|
| 282 |
+
" # Determining the number of shares the agent can buy.\n",
|
| 283 |
+
" number_of_shares_to_buy = math.floor(self.investment_capital / self.testing_stock_data[\n",
|
| 284 |
+
" 'Open'][self.timestep + self.number_of_days_to_consider])\n",
|
| 285 |
+
" # Adding to the number of shares the agent has.\n",
|
| 286 |
+
" self.number_of_shares += number_of_shares_to_buy\n",
|
| 287 |
+
"\n",
|
| 288 |
+
" # Computing the stock value, book value, investment capital and reward.\n",
|
| 289 |
+
" if number_of_shares_to_buy > 0:\n",
|
| 290 |
+
" self.stock_value += \\\n",
|
| 291 |
+
" self.testing_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 292 |
+
" * number_of_shares_to_buy\n",
|
| 293 |
+
" self.book_value += \\\n",
|
| 294 |
+
" self.testing_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 295 |
+
" * number_of_shares_to_buy\n",
|
| 296 |
+
" self.investment_capital -= \\\n",
|
| 297 |
+
" self.testing_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 298 |
+
" * number_of_shares_to_buy\n",
|
| 299 |
+
"\n",
|
| 300 |
+
" reward = 1 + penalty\n",
|
| 301 |
+
"\n",
|
| 302 |
+
" else:\n",
|
| 303 |
+
" # Computing the stock value and reward.\n",
|
| 304 |
+
" self.stock_value = self.training_stock_data['Open'][\n",
|
| 305 |
+
" self.timestep + self.number_of_days_to_consider] * self.number_of_shares\n",
|
| 306 |
+
" reward = -10\n",
|
| 307 |
+
"\n",
|
| 308 |
+
" if action == 1: # Sell\n",
|
| 309 |
+
" # Computing the investment capital, sell value and reward.\n",
|
| 310 |
+
" self.investment_capital += \\\n",
|
| 311 |
+
" self.testing_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 312 |
+
" * self.number_of_shares\n",
|
| 313 |
+
" sell_value = self.training_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 314 |
+
" * self.number_of_shares\n",
|
| 315 |
+
"\n",
|
| 316 |
+
" if self.book_value > 0:\n",
|
| 317 |
+
" reward = (sell_value - self.book_value) / self.book_value * 100\n",
|
| 318 |
+
" else:\n",
|
| 319 |
+
" reward = -10\n",
|
| 320 |
+
"\n",
|
| 321 |
+
" self.number_of_shares = 0\n",
|
| 322 |
+
" self.stock_value = 0\n",
|
| 323 |
+
" self.book_value = 0\n",
|
| 324 |
+
"\n",
|
| 325 |
+
" if action == 2: # Hold\n",
|
| 326 |
+
" # Computing the stock value and reward.\n",
|
| 327 |
+
" self.stock_value = self.testing_stock_data['Open'][self.timestep + self.number_of_days_to_consider] \\\n",
|
| 328 |
+
" * self.number_of_shares\n",
|
| 329 |
+
"\n",
|
| 330 |
+
" if self.book_value > 0:\n",
|
| 331 |
+
" reward = (self.stock_value - self.book_value) / self.book_value * 100\n",
|
| 332 |
+
" else:\n",
|
| 333 |
+
" reward = -1\n",
|
| 334 |
+
"\n",
|
| 335 |
+
" # Determining if the agent currently has shares of the stock or not.\n",
|
| 336 |
+
" if self.number_of_shares > 0:\n",
|
| 337 |
+
" stock_held = True\n",
|
| 338 |
+
" else:\n",
|
| 339 |
+
" stock_held = False\n",
|
| 340 |
+
"\n",
|
| 341 |
+
" # Getting the observation vector.\n",
|
| 342 |
+
" if self.train:\n",
|
| 343 |
+
" # If the task is to train the agent the maximum timesteps will be equal to the number of days considered\n",
|
| 344 |
+
" # subtracted from the length of the training stock data.\n",
|
| 345 |
+
" self.max_timesteps = len(self.training_stock_data) - self.number_of_days_to_consider\n",
|
| 346 |
+
"\n",
|
| 347 |
+
" # Calculating whether the price increased or decreased/remained the same on the majority of days the agent\n",
|
| 348 |
+
" # considers.\n",
|
| 349 |
+
" price_increase_list = []\n",
|
| 350 |
+
" for i in range(self.number_of_days_to_consider):\n",
|
| 351 |
+
" if self.training_stock_data['Close'][self.timestep + 1 + i] \\\n",
|
| 352 |
+
" - self.training_stock_data['Close'][self.timestep + i] > 0:\n",
|
| 353 |
+
" price_increase_list.append(1)\n",
|
| 354 |
+
" else:\n",
|
| 355 |
+
" price_increase_list.append(0)\n",
|
| 356 |
+
"\n",
|
| 357 |
+
" if (np.sum(price_increase_list) / self.number_of_days_to_consider) >= 0.5:\n",
|
| 358 |
+
" price_increase = True\n",
|
| 359 |
+
" else:\n",
|
| 360 |
+
" price_increase = False\n",
|
| 361 |
+
"\n",
|
| 362 |
+
" # Observation vector.\n",
|
| 363 |
+
" observation = [price_increase, stock_held]\n",
|
| 364 |
+
"\n",
|
| 365 |
+
" else:\n",
|
| 366 |
+
" # If the task is to evaluate the trained agent's performance the maximum timesteps will be equal to the\n",
|
| 367 |
+
" # number of days considered subtracted from the length of the testing stock data.\n",
|
| 368 |
+
" self.max_timesteps = len(self.testing_stock_data) - self.number_of_days_to_consider\n",
|
| 369 |
+
"\n",
|
| 370 |
+
" # Calculating whether the price increased or decreased/remained the same on the majority of days the agent\n",
|
| 371 |
+
" # considers.\n",
|
| 372 |
+
" price_increase_list = []\n",
|
| 373 |
+
" for i in range(self.number_of_days_to_consider):\n",
|
| 374 |
+
" if self.testing_stock_data['Close'][self.timestep + 1 + i] \\\n",
|
| 375 |
+
" - self.testing_stock_data['Close'][self.timestep + i] > 0:\n",
|
| 376 |
+
" price_increase_list.append(1)\n",
|
| 377 |
+
" else:\n",
|
| 378 |
+
" price_increase_list.append(0)\n",
|
| 379 |
+
"\n",
|
| 380 |
+
" if (np.sum(price_increase_list) / self.number_of_days_to_consider) >= 0.5:\n",
|
| 381 |
+
" price_increase = True\n",
|
| 382 |
+
" else:\n",
|
| 383 |
+
" price_increase = False\n",
|
| 384 |
+
"\n",
|
| 385 |
+
" # Observation vector.\n",
|
| 386 |
+
" observation = [price_increase, stock_held]\n",
|
| 387 |
+
"\n",
|
| 388 |
+
" self.timestep += 1 # Increasing the number of steps taken by the agent by 1.\n",
|
| 389 |
+
"\n",
|
| 390 |
+
" if np.array_equal(observation, [True, False]):\n",
|
| 391 |
+
" observation = 0\n",
|
| 392 |
+
" if np.array_equal(observation, [True, True]):\n",
|
| 393 |
+
" observation = 1\n",
|
| 394 |
+
" if np.array_equal(observation, [False, False]):\n",
|
| 395 |
+
" observation = 2\n",
|
| 396 |
+
" if np.array_equal(observation, [False, True]):\n",
|
| 397 |
+
" observation = 3\n",
|
| 398 |
+
"\n",
|
| 399 |
+
" # Computing the total account value.\n",
|
| 400 |
+
" self.total_account_value = self.investment_capital + self.stock_value\n",
|
| 401 |
+
" # Appending the total account value of the list to plot the graph.\n",
|
| 402 |
+
" self.total_account_value_list.append(self.total_account_value)\n",
|
| 403 |
+
"\n",
|
| 404 |
+
" # The episode terminates when the maximum timesteps have been reached.\n",
|
| 405 |
+
" terminated = True if (self.timestep >= self.max_timesteps) \\\n",
|
| 406 |
+
" else False\n",
|
| 407 |
+
" truncated = False\n",
|
| 408 |
+
" info = {}\n",
|
| 409 |
+
"\n",
|
| 410 |
+
" return observation, reward, terminated, truncated, info\n",
|
| 411 |
+
"\n",
|
| 412 |
+
" def render(self, mode='human'):\n",
|
| 413 |
+
" \"\"\"This method renders the agent's total account value over time.\n",
|
| 414 |
+
"\n",
|
| 415 |
+
" :param mode: 'human' renders to the current display or terminal and returns nothing.\"\"\"\n",
|
| 416 |
+
"\n",
|
| 417 |
+
" plt.figure(figsize=(15, 10))\n",
|
| 418 |
+
" plt.plot(self.total_account_value_list, color='lightseagreen', linewidth=7)\n",
|
| 419 |
+
" plt.xlabel('Days', fontsize=32)\n",
|
| 420 |
+
" plt.ylabel('Total Account Value', fontsize=32)\n",
|
| 421 |
+
" plt.title('Total Account Value over Time', fontsize=38)\n",
|
| 422 |
+
" plt.grid()\n",
|
| 423 |
+
" plt.show()"
|
| 424 |
+
]
|
| 425 |
+
},
|
| 426 |
+
{
|
| 427 |
+
"cell_type": "code",
|
| 428 |
+
"execution_count": null,
|
| 429 |
+
"metadata": {},
|
| 430 |
+
"outputs": [],
|
| 431 |
+
"source": [
|
| 432 |
+
"# NOTE: You can adjust the parameter 'number_of_days_to_consider'\n",
|
| 433 |
+
"\n",
|
| 434 |
+
"stock_trading_environment = StockTradingEnvironment('./NVDA.csv', number_of_days_to_consider=10)"
|
| 435 |
+
]
|
| 436 |
+
}
|
| 437 |
+
],
|
| 438 |
+
"metadata": {
|
| 439 |
+
"language_info": {
|
| 440 |
+
"name": "python"
|
| 441 |
+
}
|
| 442 |
+
},
|
| 443 |
+
"nbformat": 4,
|
| 444 |
+
"nbformat_minor": 2
|
| 445 |
+
}
|
images/Cartoon_green_texture_grass.jpg
ADDED
|
Git LFS Details
|
images/acorn.png
ADDED
|
images/agent_flag_winner.png
ADDED
|
images/agent_gems_lottery.png
ADDED
|
images/agent_grid_cross.png
ADDED
|
images/agent_hole_drown.png
ADDED
|
images/frozen_lake.jpg
ADDED
|
images/house.png
ADDED
|
images/hunter.png
ADDED
|
images/icons8-battery-64.png
ADDED
|
|
images/icons8-cross-100.png
ADDED
|
|
images/icons8-drown-100.png
ADDED
|
|
images/icons8-flag-100.png
ADDED
|
|
images/icons8-gems-100.png
ADDED
|
|
images/icons8-goal-50.png
ADDED
|
|
images/icons8-grid-100.png
ADDED
|
|
images/icons8-hole-100.png
ADDED
|
|
images/icons8-lawn-mower-100.png
ADDED
|
|
images/icons8-money-100.png
ADDED
|
|
images/icons8-rocks-53.png
ADDED
|
|
images/icons8-skateboard-100.png
ADDED
|
|
images/icons8-trophy-100.png
ADDED
|
|
images/lawnmower_battery_bolt.png
ADDED
|
images/lawnmower_goal_win.png
ADDED
|
images/lawnmower_grid_cross.png
ADDED
|
images/lawnmower_rocks_boom.png
ADDED
|
images/squirrel.png
ADDED
|
images/squirrel_acorn.jpg
ADDED
|