Teen-Different commited on
Commit
12a6c8d
·
verified ·
1 Parent(s): a988eeb

Upload 66 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +4 -0
  2. Frozen Lake Comparing Q and Double Q Learning Stochastic.ipynb +0 -0
  3. Frozen Lake Comparison Q and Double Q Learnings Deterministic.ipynb +0 -0
  4. Frozen Lake Double Q Learning Deterministic Environment.ipynb +0 -0
  5. Frozen Lake Double Q Learning Stochastic Environment.ipynb +0 -0
  6. Frozen Lake Q Learning for Determinitic Environment.ipynb +0 -0
  7. Frozen Lake Q Learning for Stochastic Environment.ipynb +0 -0
  8. Lawn Mower Comparison SARSA and Double Q Learnings Deterministic.ipynb +101 -0
  9. Lawn Mower Double Q Learning Deterministic Environment.ipynb +0 -0
  10. Lawn Mower N Step Bootstrapping Deterministic.ipynb +0 -0
  11. Lawn Mower SARSA Deterministic Environment.ipynb +0 -0
  12. NVDA.csv +505 -0
  13. README.md +246 -3
  14. Squirrel Maze Double Q Learning Deterministic Environment.ipynb +0 -0
  15. Squirrel Maze Double Q Learning StochasticEnvironment.ipynb +0 -0
  16. Squirrel Maze Q Learning Deterministic Environment.ipynb +0 -0
  17. Squirrel Maze Q Learning Stochastic Environment.ipynb +0 -0
  18. Stock Trading Q Learning Environment.ipynb +0 -0
  19. environments/Frozen Lake Grid World Defining Deterministic and Stochastic Environment.ipynb +0 -0
  20. environments/Lawn Mower Grid World Defining Deterministic Environment.ipynb +0 -0
  21. environments/Squirrel Maze Grid World Defining Deterministic and Stochastic Environment.ipynb +0 -0
  22. environments/Stock Trading Environment.ipynb +445 -0
  23. images/Cartoon_green_texture_grass.jpg +3 -0
  24. images/acorn.png +0 -0
  25. images/agent_flag_winner.png +0 -0
  26. images/agent_gems_lottery.png +0 -0
  27. images/agent_grid_cross.png +0 -0
  28. images/agent_hole_drown.png +0 -0
  29. images/frozen_lake.jpg +0 -0
  30. images/house.png +0 -0
  31. images/hunter.png +0 -0
  32. images/icons8-battery-64.png +0 -0
  33. images/icons8-cross-100.png +0 -0
  34. images/icons8-drown-100.png +0 -0
  35. images/icons8-flag-100.png +0 -0
  36. images/icons8-gems-100.png +0 -0
  37. images/icons8-goal-50.png +0 -0
  38. images/icons8-grid-100.png +0 -0
  39. images/icons8-hole-100.png +0 -0
  40. images/icons8-lawn-mower-100.png +0 -0
  41. images/icons8-money-100.png +0 -0
  42. images/icons8-rocks-53.png +0 -0
  43. images/icons8-skateboard-100.png +0 -0
  44. images/icons8-trophy-100.png +0 -0
  45. images/lawnmower_battery_bolt.png +0 -0
  46. images/lawnmower_goal_win.png +0 -0
  47. images/lawnmower_grid_cross.png +0 -0
  48. images/lawnmower_rocks_boom.png +0 -0
  49. images/squirrel.png +0 -0
  50. 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
- license: mit
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> &nbsp;&nbsp;&nbsp;&nbsp; <b>Squirrel Maze</b> &nbsp;&nbsp;&nbsp;&nbsp; <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
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/ef84589b-9b5d-47ab-8ac2-5c093ff96d9e)
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
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/bdf10023-f9a4-4aee-8b39-6975288589bc)
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
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/9681d2f8-6546-4f62-9d7c-6528f865472a)
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> &nbsp;&nbsp;&nbsp;&nbsp; <b>Q Learning Epsilon Decay</b> &nbsp;&nbsp;&nbsp;&nbsp; <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> &nbsp;&nbsp;&nbsp;&nbsp; <b>Q Learning Total Rewards</b> &nbsp;&nbsp;&nbsp;&nbsp; <b>Double Q Total Rewards</b>
156
+ </p>
157
+
158
+
159
+ 5. SARSA vs. Double Q-Learning Comparison
160
+
161
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/bf78cf38-86a1-4fca-8f48-d35a65945fa9)
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
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/0063a9d5-4083-4337-ad09-9498abb604f5)
174
+
175
+
176
+ 2. Total Rewards per Episode
177
+
178
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/e1361577-49c8-4ee6-94a1-0d2cba7b034c)
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
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/7bbacddf-d9f7-429c-b781-4f5a85648071)
200
+
201
+
202
+ 2. Total Rewards per Episode
203
+
204
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/a8e5efa8-559b-4457-b1e8-fac392a73b54)
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
+ ![image](https://github.com/REDDITARUN/Defining-and-Solving-Reinforcement-Learning-Environments/assets/53268025/70f9baa4-4fe1-43fa-95c3-522d9a436014)
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

  • SHA256: e181666181880d5caa5d096a33e3cec8ab21104b8d1504f58ae32dd1e4531b00
  • Pointer size: 132 Bytes
  • Size of remote file: 2.92 MB
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