Files
Quant_Code/5.课程代码/4.Stock-Prediction-Models/使用文档/Stock-Prediction-Models-master/agent/9.double-recurrent-q-learning-agent.ipynb
zhoujie2104231 2757a4d0d2 chore: 添加Stock-Prediction-Models项目文件
添加了Stock-Prediction-Models项目的多个文件,包括数据集、模型代码、README文档和CSS样式文件。这些文件用于股票预测模型的训练和展示,涵盖了LSTM、GRU等深度学习模型的应用。
2025-04-27 16:28:06 +08:00

599 lines
75 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import tensorflow as tf\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"sns.set()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Date</th>\n",
" <th>Open</th>\n",
" <th>High</th>\n",
" <th>Low</th>\n",
" <th>Close</th>\n",
" <th>Adj Close</th>\n",
" <th>Volume</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>2016-11-02</td>\n",
" <td>778.200012</td>\n",
" <td>781.650024</td>\n",
" <td>763.450012</td>\n",
" <td>768.700012</td>\n",
" <td>768.700012</td>\n",
" <td>1872400</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2016-11-03</td>\n",
" <td>767.250000</td>\n",
" <td>769.950012</td>\n",
" <td>759.030029</td>\n",
" <td>762.130005</td>\n",
" <td>762.130005</td>\n",
" <td>1943200</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2016-11-04</td>\n",
" <td>750.659973</td>\n",
" <td>770.359985</td>\n",
" <td>750.560974</td>\n",
" <td>762.020020</td>\n",
" <td>762.020020</td>\n",
" <td>2134800</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>2016-11-07</td>\n",
" <td>774.500000</td>\n",
" <td>785.190002</td>\n",
" <td>772.549988</td>\n",
" <td>782.520020</td>\n",
" <td>782.520020</td>\n",
" <td>1585100</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>2016-11-08</td>\n",
" <td>783.400024</td>\n",
" <td>795.632996</td>\n",
" <td>780.190002</td>\n",
" <td>790.510010</td>\n",
" <td>790.510010</td>\n",
" <td>1350800</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Date Open High Low Close Adj Close \\\n",
"0 2016-11-02 778.200012 781.650024 763.450012 768.700012 768.700012 \n",
"1 2016-11-03 767.250000 769.950012 759.030029 762.130005 762.130005 \n",
"2 2016-11-04 750.659973 770.359985 750.560974 762.020020 762.020020 \n",
"3 2016-11-07 774.500000 785.190002 772.549988 782.520020 782.520020 \n",
"4 2016-11-08 783.400024 795.632996 780.190002 790.510010 790.510010 \n",
"\n",
" Volume \n",
"0 1872400 \n",
"1 1943200 \n",
"2 2134800 \n",
"3 1585100 \n",
"4 1350800 "
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.read_csv('../dataset/GOOG-year.csv')\n",
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from collections import deque\n",
"import random\n",
"\n",
"class Model:\n",
" def __init__(self, input_size, output_size, layer_size, learning_rate, name):\n",
" with tf.variable_scope(name):\n",
" self.X = tf.placeholder(tf.float32, (None, None, input_size))\n",
" self.Y = tf.placeholder(tf.float32, (None, output_size))\n",
" cell = tf.nn.rnn_cell.LSTMCell(layer_size, state_is_tuple = False)\n",
" self.hidden_layer = tf.placeholder(tf.float32, (None, 2 * layer_size))\n",
" self.rnn,self.last_state = tf.nn.dynamic_rnn(inputs=self.X,cell=cell,\n",
" dtype=tf.float32,\n",
" initial_state=self.hidden_layer)\n",
" self.logits = tf.layers.dense(self.rnn[:,-1], output_size)\n",
" self.cost = tf.reduce_sum(tf.square(self.Y - self.logits))\n",
" self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)\n",
" \n",
"class Agent:\n",
"\n",
" LEARNING_RATE = 0.003\n",
" BATCH_SIZE = 32\n",
" LAYER_SIZE = 256\n",
" OUTPUT_SIZE = 3\n",
" EPSILON = 0.5\n",
" DECAY_RATE = 0.005\n",
" MIN_EPSILON = 0.1\n",
" GAMMA = 0.99\n",
" MEMORIES = deque()\n",
" COPY = 1000\n",
" T_COPY = 0\n",
" MEMORY_SIZE = 300\n",
" \n",
" def __init__(self, state_size, window_size, trend, skip):\n",
" self.state_size = state_size\n",
" self.window_size = window_size\n",
" self.half_window = window_size // 2\n",
" self.trend = trend\n",
" self.skip = skip\n",
" tf.reset_default_graph()\n",
" self.INITIAL_FEATURES = np.zeros((4, self.state_size))\n",
" self.model = Model(self.state_size, self.OUTPUT_SIZE, self.LAYER_SIZE, self.LEARNING_RATE,\n",
" 'real_model')\n",
" self.model_negative = Model(self.state_size, self.OUTPUT_SIZE, self.LAYER_SIZE, self.LEARNING_RATE,\n",
" 'negative_model')\n",
" self.sess = tf.InteractiveSession()\n",
" self.sess.run(tf.global_variables_initializer())\n",
" self.trainable = tf.trainable_variables()\n",
" \n",
" def _assign(self, from_name, to_name):\n",
" from_w = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=from_name)\n",
" to_w = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=to_name)\n",
" for i in range(len(from_w)):\n",
" assign_op = to_w[i].assign(from_w[i])\n",
" self.sess.run(assign_op)\n",
"\n",
" def _memorize(self, state, action, reward, new_state, dead, rnn_state):\n",
" self.MEMORIES.append((state, action, reward, new_state, dead, rnn_state))\n",
" if len(self.MEMORIES) > self.MEMORY_SIZE:\n",
" self.MEMORIES.popleft()\n",
"\n",
" def _select_action(self, state):\n",
" if np.random.rand() < self.EPSILON:\n",
" action = np.random.randint(self.OUTPUT_SIZE)\n",
" else:\n",
" action = self.get_predicted_action([state])\n",
" return action\n",
"\n",
" def _construct_memories(self, replay):\n",
" states = np.array([a[0] for a in replay])\n",
" new_states = np.array([a[3] for a in replay])\n",
" init_values = np.array([a[-1] for a in replay])\n",
" Q = self.sess.run(self.model.logits, feed_dict={self.model.X:states, \n",
" self.model.hidden_layer:init_values})\n",
" Q_new = self.sess.run(self.model.logits, feed_dict={self.model.X:new_states, \n",
" self.model.hidden_layer:init_values})\n",
" Q_new_negative = self.sess.run(self.model_negative.logits, \n",
" feed_dict={self.model_negative.X:new_states, \n",
" self.model_negative.hidden_layer:init_values})\n",
" replay_size = len(replay)\n",
" X = np.empty((replay_size, 4, self.state_size))\n",
" Y = np.empty((replay_size, self.OUTPUT_SIZE))\n",
" INIT_VAL = np.empty((replay_size, 2 * self.LAYER_SIZE))\n",
" for i in range(replay_size):\n",
" state_r, action_r, reward_r, new_state_r, dead_r, rnn_memory = replay[i]\n",
" target = Q[i]\n",
" target[action_r] = reward_r\n",
" if not dead_r:\n",
" target[action_r] += self.GAMMA * Q_new_negative[i, np.argmax(Q_new[i])]\n",
" X[i] = state_r\n",
" Y[i] = target\n",
" INIT_VAL[i] = rnn_memory\n",
" return X, Y, INIT_VAL\n",
" \n",
" def get_state(self, t):\n",
" window_size = self.window_size + 1\n",
" d = t - window_size + 1\n",
" block = self.trend[d : t + 1] if d >= 0 else -d * [self.trend[0]] + self.trend[0 : t + 1]\n",
" res = []\n",
" for i in range(window_size - 1):\n",
" res.append(block[i + 1] - block[i])\n",
" return np.array(res)\n",
" \n",
" def buy(self, initial_money):\n",
" starting_money = initial_money\n",
" states_sell = []\n",
" states_buy = []\n",
" inventory = []\n",
" state = self.get_state(0)\n",
" init_value = np.zeros((1, 2 * self.LAYER_SIZE))\n",
" for k in range(self.INITIAL_FEATURES.shape[0]):\n",
" self.INITIAL_FEATURES[k,:] = state\n",
" for t in range(0, len(self.trend) - 1, self.skip):\n",
" action, last_state = self.sess.run([self.model.logits,self.model.last_state],\n",
" feed_dict={self.model.X:[self.INITIAL_FEATURES],\n",
" self.model.hidden_layer:init_value})\n",
" action, init_value = np.argmax(action[0]), last_state\n",
" next_state = self.get_state(t + 1)\n",
" \n",
" if action == 1 and initial_money >= self.trend[t]:\n",
" inventory.append(self.trend[t])\n",
" initial_money -= self.trend[t]\n",
" states_buy.append(t)\n",
" print('day %d: buy 1 unit at price %f, total balance %f'% (t, self.trend[t], initial_money))\n",
" \n",
" elif action == 2 and len(inventory):\n",
" bought_price = inventory.pop(0)\n",
" initial_money += self.trend[t]\n",
" states_sell.append(t)\n",
" try:\n",
" invest = ((close[t] - bought_price) / bought_price) * 100\n",
" except:\n",
" invest = 0\n",
" print(\n",
" 'day %d, sell 1 unit at price %f, investment %f %%, total balance %f,'\n",
" % (t, close[t], invest, initial_money)\n",
" )\n",
" \n",
" new_state = np.append([self.get_state(t + 1)], self.INITIAL_FEATURES[:3, :], axis = 0)\n",
" self.INITIAL_FEATURES = new_state\n",
" invest = ((initial_money - starting_money) / starting_money) * 100\n",
" total_gains = initial_money - starting_money\n",
" return states_buy, states_sell, total_gains, invest\n",
" \n",
" \n",
" def train(self, iterations, checkpoint, initial_money):\n",
" for i in range(iterations):\n",
" total_profit = 0\n",
" inventory = []\n",
" state = self.get_state(0)\n",
" starting_money = initial_money\n",
" init_value = np.zeros((1, 2 * self.LAYER_SIZE))\n",
" for k in range(self.INITIAL_FEATURES.shape[0]):\n",
" self.INITIAL_FEATURES[k,:] = state\n",
" for t in range(0, len(self.trend) - 1, self.skip):\n",
" if (self.T_COPY + 1) % self.COPY == 0:\n",
" self._assign('real_model', 'negative_model')\n",
" \n",
" if np.random.rand() < self.EPSILON:\n",
" action = np.random.randint(self.OUTPUT_SIZE)\n",
" else:\n",
" action, last_state = self.sess.run([self.model.logits,\n",
" self.model.last_state],\n",
" feed_dict={self.model.X:[self.INITIAL_FEATURES],\n",
" self.model.hidden_layer:init_value})\n",
" action, init_value = np.argmax(action[0]), last_state\n",
" \n",
" next_state = self.get_state(t + 1)\n",
" \n",
" if action == 1 and starting_money >= self.trend[t]:\n",
" inventory.append(self.trend[t])\n",
" starting_money -= self.trend[t]\n",
" \n",
" elif action == 2 and len(inventory) > 0:\n",
" bought_price = inventory.pop(0)\n",
" total_profit += self.trend[t] - bought_price\n",
" starting_money += self.trend[t]\n",
" \n",
" invest = ((starting_money - initial_money) / initial_money)\n",
" new_state = np.append([self.get_state(t + 1)], self.INITIAL_FEATURES[:3, :], axis = 0)\n",
" \n",
" self._memorize(self.INITIAL_FEATURES, action, invest, new_state, \n",
" starting_money < initial_money, init_value[0])\n",
" self.INITIAL_FEATURES = new_state\n",
" batch_size = min(len(self.MEMORIES), self.BATCH_SIZE)\n",
" replay = random.sample(self.MEMORIES, batch_size)\n",
" X, Y, INIT_VAL = self._construct_memories(replay)\n",
" \n",
" cost, _ = self.sess.run([self.model.cost, self.model.optimizer], \n",
" feed_dict={self.model.X: X, self.model.Y:Y,\n",
" self.model.hidden_layer: INIT_VAL})\n",
" self.T_COPY += 1\n",
" self.EPSILON = self.MIN_EPSILON + (1.0 - self.MIN_EPSILON) * np.exp(-self.DECAY_RATE * i)\n",
" if (i+1) % checkpoint == 0:\n",
" print('epoch: %d, total rewards: %f.3, cost: %f, total money: %f'%(i + 1, total_profit, cost,\n",
" starting_money))"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:<tensorflow.python.ops.rnn_cell_impl.LSTMCell object at 0x7fb85fd10940>: Using a concatenated state is slower and will soon be deprecated. Use state_is_tuple=True.\n",
"WARNING:tensorflow:<tensorflow.python.ops.rnn_cell_impl.LSTMCell object at 0x7fb85f9de7b8>: Using a concatenated state is slower and will soon be deprecated. Use state_is_tuple=True.\n",
"epoch: 10, total rewards: 1305.274912.3, cost: 0.402263, total money: 777.284860\n",
"epoch: 20, total rewards: 582.070375.3, cost: 0.782595, total money: 804.650331\n",
"epoch: 30, total rewards: 420.380369.3, cost: 1.481925, total money: 80.210326\n",
"epoch: 40, total rewards: 1502.554748.3, cost: 0.343374, total money: 2823.564757\n",
"epoch: 50, total rewards: 589.170222.3, cost: 0.370314, total money: 6597.640193\n",
"epoch: 60, total rewards: 1069.864985.3, cost: 0.733583, total money: 10052.755000\n",
"epoch: 70, total rewards: 900.360168.3, cost: 0.154633, total money: 8866.610168\n",
"epoch: 80, total rewards: 625.559509.3, cost: 0.573019, total money: 9652.999511\n",
"epoch: 90, total rewards: 966.905028.3, cost: 0.080430, total money: 6971.785033\n",
"epoch: 100, total rewards: 784.169802.3, cost: 0.568819, total money: 10784.169802\n",
"epoch: 110, total rewards: 658.149963.3, cost: 0.052230, total money: 9641.509948\n",
"epoch: 120, total rewards: 615.210201.3, cost: 0.802322, total money: 9595.940181\n",
"epoch: 130, total rewards: 623.289978.3, cost: 0.278659, total money: 10623.289978\n",
"epoch: 140, total rewards: 595.960078.3, cost: 0.094435, total money: 10595.960078\n",
"epoch: 150, total rewards: 594.979550.3, cost: 0.360762, total money: 1819.289547\n",
"epoch: 160, total rewards: 794.614687.3, cost: 1.058314, total money: 3118.034730\n",
"epoch: 170, total rewards: 1225.854981.3, cost: 0.226553, total money: 5322.584961\n",
"epoch: 180, total rewards: 1099.610169.3, cost: 0.275357, total money: 6189.200135\n",
"epoch: 190, total rewards: 857.554813.3, cost: 0.417154, total money: 7946.004825\n",
"epoch: 200, total rewards: 1049.100096.3, cost: 0.839669, total money: 3317.970090\n"
]
}
],
"source": [
"close = df.Close.values.tolist()\n",
"initial_money = 10000\n",
"window_size = 30\n",
"skip = 1\n",
"batch_size = 32\n",
"agent = Agent(state_size = window_size, \n",
" window_size = window_size, \n",
" trend = close, \n",
" skip = skip)\n",
"agent.train(iterations = 200, checkpoint = 10, initial_money = initial_money)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"day 0: buy 1 unit at price 768.700012, total balance 9231.299988\n",
"day 1, sell 1 unit at price 762.130005, investment -0.854691 %, total balance 9993.429993,\n",
"day 3: buy 1 unit at price 782.520020, total balance 9210.909973\n",
"day 4, sell 1 unit at price 790.510010, investment 1.021059 %, total balance 10001.419983,\n",
"day 5: buy 1 unit at price 785.309998, total balance 9216.109985\n",
"day 6, sell 1 unit at price 762.559998, investment -2.896945 %, total balance 9978.669983,\n",
"day 7: buy 1 unit at price 754.020020, total balance 9224.649963\n",
"day 8, sell 1 unit at price 736.080017, investment -2.379248 %, total balance 9960.729980,\n",
"day 13: buy 1 unit at price 769.200012, total balance 9191.529968\n",
"day 16, sell 1 unit at price 761.679993, investment -0.977642 %, total balance 9953.209961,\n",
"day 19: buy 1 unit at price 758.039978, total balance 9195.169983\n",
"day 20, sell 1 unit at price 747.919983, investment -1.335021 %, total balance 9943.089966,\n",
"day 24: buy 1 unit at price 771.190002, total balance 9171.899964\n",
"day 28: buy 1 unit at price 796.099976, total balance 8375.799988\n",
"day 29: buy 1 unit at price 797.070007, total balance 7578.729981\n",
"day 31: buy 1 unit at price 790.799988, total balance 6787.929993\n",
"day 32, sell 1 unit at price 794.200012, investment 2.983702 %, total balance 7582.130005,\n",
"day 33, sell 1 unit at price 796.419983, investment 0.040197 %, total balance 8378.549988,\n",
"day 35, sell 1 unit at price 791.260010, investment -0.728919 %, total balance 9169.809998,\n",
"day 36, sell 1 unit at price 789.909973, investment -0.112546 %, total balance 9959.719971,\n",
"day 38: buy 1 unit at price 785.049988, total balance 9174.669983\n",
"day 41: buy 1 unit at price 786.140015, total balance 8388.529968\n",
"day 42, sell 1 unit at price 786.900024, investment 0.235658 %, total balance 9175.429992,\n",
"day 43, sell 1 unit at price 794.020020, investment 1.002367 %, total balance 9969.450012,\n",
"day 44: buy 1 unit at price 806.150024, total balance 9163.299988\n",
"day 46, sell 1 unit at price 804.789978, investment -0.168709 %, total balance 9968.089966,\n",
"day 47: buy 1 unit at price 807.909973, total balance 9160.179993\n",
"day 49, sell 1 unit at price 807.880005, investment -0.003709 %, total balance 9968.059998,\n",
"day 51: buy 1 unit at price 806.070007, total balance 9161.989991\n",
"day 52: buy 1 unit at price 802.174988, total balance 8359.815003\n",
"day 54: buy 1 unit at price 819.309998, total balance 7540.505005\n",
"day 55, sell 1 unit at price 823.869995, investment 2.208243 %, total balance 8364.375000,\n",
"day 56: buy 1 unit at price 835.669983, total balance 7528.705017\n",
"day 57: buy 1 unit at price 832.150024, total balance 6696.554993\n",
"day 58, sell 1 unit at price 823.309998, investment 2.634713 %, total balance 7519.864991,\n",
"day 59, sell 1 unit at price 802.320007, investment -2.073695 %, total balance 8322.184998,\n",
"day 61, sell 1 unit at price 795.695007, investment -4.783584 %, total balance 9117.880005,\n",
"day 62, sell 1 unit at price 798.530029, investment -4.040136 %, total balance 9916.410034,\n",
"day 68: buy 1 unit at price 813.669983, total balance 9102.740051\n",
"day 69, sell 1 unit at price 819.239990, investment 0.684554 %, total balance 9921.980041,\n",
"day 76: buy 1 unit at price 831.330017, total balance 9090.650024\n",
"day 77: buy 1 unit at price 828.640015, total balance 8262.010009\n",
"day 79, sell 1 unit at price 823.210022, investment -0.976747 %, total balance 9085.220031,\n",
"day 81, sell 1 unit at price 830.630005, investment 0.240151 %, total balance 9915.850036,\n",
"day 86: buy 1 unit at price 838.679993, total balance 9077.170043\n",
"day 88: buy 1 unit at price 845.539978, total balance 8231.630065\n",
"day 89, sell 1 unit at price 845.619995, investment 0.827491 %, total balance 9077.250060,\n",
"day 91, sell 1 unit at price 848.780029, investment 0.383193 %, total balance 9926.030089,\n",
"day 95: buy 1 unit at price 829.590027, total balance 9096.440062\n",
"day 96, sell 1 unit at price 817.580017, investment -1.447704 %, total balance 9914.020079,\n",
"day 97: buy 1 unit at price 814.429993, total balance 9099.590086\n",
"day 101: buy 1 unit at price 831.500000, total balance 8268.090086\n",
"day 102: buy 1 unit at price 829.559998, total balance 7438.530088\n",
"day 104, sell 1 unit at price 834.570007, investment 2.472897 %, total balance 8273.100095,\n",
"day 105, sell 1 unit at price 831.409973, investment -0.010827 %, total balance 9104.510068,\n",
"day 106, sell 1 unit at price 827.880005, investment -0.202516 %, total balance 9932.390073,\n",
"day 108: buy 1 unit at price 824.729980, total balance 9107.660093\n",
"day 109, sell 1 unit at price 823.349976, investment -0.167328 %, total balance 9931.010069,\n",
"day 114: buy 1 unit at price 838.210022, total balance 9092.800047\n",
"day 117, sell 1 unit at price 862.760010, investment 2.928859 %, total balance 9955.560057,\n",
"day 121: buy 1 unit at price 905.960022, total balance 9049.600035\n",
"day 122: buy 1 unit at price 912.570007, total balance 8137.030028\n",
"day 124: buy 1 unit at price 927.039978, total balance 7209.990050\n",
"day 125: buy 1 unit at price 931.659973, total balance 6278.330077\n",
"day 130, sell 1 unit at price 930.599976, investment 2.719762 %, total balance 7208.930053,\n",
"day 131, sell 1 unit at price 932.219971, investment 2.153256 %, total balance 8141.150024,\n",
"day 132, sell 1 unit at price 937.080017, investment 1.083021 %, total balance 9078.230041,\n",
"day 133, sell 1 unit at price 943.000000, investment 1.217185 %, total balance 10021.230041,\n",
"day 137: buy 1 unit at price 941.859985, total balance 9079.370056\n",
"day 138, sell 1 unit at price 948.820007, investment 0.738966 %, total balance 10028.190063,\n",
"day 142: buy 1 unit at price 975.880005, total balance 9052.310058\n",
"day 143: buy 1 unit at price 964.859985, total balance 8087.450073\n",
"day 144: buy 1 unit at price 966.950012, total balance 7120.500061\n",
"day 145, sell 1 unit at price 975.599976, investment -0.028695 %, total balance 8096.100037,\n",
"day 146, sell 1 unit at price 983.679993, investment 1.950543 %, total balance 9079.780030,\n",
"day 147: buy 1 unit at price 976.570007, total balance 8103.210023\n",
"day 148: buy 1 unit at price 980.940002, total balance 7122.270021\n",
"day 150, sell 1 unit at price 949.830017, investment -1.770515 %, total balance 8072.100038,\n",
"day 151: buy 1 unit at price 942.900024, total balance 7129.200014\n",
"day 152, sell 1 unit at price 953.400024, investment -2.372588 %, total balance 8082.600038,\n",
"day 153: buy 1 unit at price 950.760010, total balance 7131.840028\n",
"day 154, sell 1 unit at price 942.309998, investment -3.938060 %, total balance 8074.150026,\n",
"day 155, sell 1 unit at price 939.780029, investment -0.330894 %, total balance 9013.930055,\n",
"day 156, sell 1 unit at price 957.369995, investment 0.695232 %, total balance 9971.300050,\n",
"day 159: buy 1 unit at price 957.090027, total balance 9014.210023\n",
"day 160: buy 1 unit at price 965.590027, total balance 8048.619996\n",
"day 161, sell 1 unit at price 952.270020, investment -0.503611 %, total balance 9000.890016,\n",
"day 162: buy 1 unit at price 927.330017, total balance 8073.559999\n",
"day 163: buy 1 unit at price 940.489990, total balance 7133.070009\n",
"day 165: buy 1 unit at price 908.729980, total balance 6224.340029\n",
"day 167: buy 1 unit at price 911.710022, total balance 5312.630007\n",
"day 169, sell 1 unit at price 918.590027, investment -4.867490 %, total balance 6231.220034,\n",
"day 170, sell 1 unit at price 928.799988, investment 0.158516 %, total balance 7160.020022,\n",
"day 173, sell 1 unit at price 947.159973, investment 0.709203 %, total balance 8107.179995,\n",
"day 174: buy 1 unit at price 955.989990, total balance 7151.190005\n",
"day 175: buy 1 unit at price 953.419983, total balance 6197.770022\n",
"day 176: buy 1 unit at price 965.400024, total balance 5232.369998\n",
"day 177, sell 1 unit at price 970.890015, investment 6.840320 %, total balance 6203.260013,\n",
"day 178: buy 1 unit at price 968.150024, total balance 5235.109989\n",
"day 179: buy 1 unit at price 972.919983, total balance 4262.190006\n",
"day 180: buy 1 unit at price 980.340027, total balance 3281.849979\n",
"day 181, sell 1 unit at price 950.700012, investment 4.276578 %, total balance 4232.549991,\n",
"day 182, sell 1 unit at price 947.799988, investment -0.856704 %, total balance 5180.349979,\n",
"day 184, sell 1 unit at price 941.530029, investment -1.247085 %, total balance 6121.880008,\n",
"day 185, sell 1 unit at price 930.500000, investment -3.615084 %, total balance 7052.380008,\n",
"day 186: buy 1 unit at price 930.830017, total balance 6121.549991\n",
"day 190: buy 1 unit at price 929.359985, total balance 5192.190006\n",
"day 191, sell 1 unit at price 926.789978, investment -4.272070 %, total balance 6118.979984,\n",
"day 192, sell 1 unit at price 922.900024, investment -5.141220 %, total balance 7041.880008,\n",
"day 193, sell 1 unit at price 907.239990, investment -7.456600 %, total balance 7949.119998,\n",
"day 196: buy 1 unit at price 922.219971, total balance 7026.900027\n",
"day 198: buy 1 unit at price 910.979980, total balance 6115.920047\n",
"day 199, sell 1 unit at price 910.669983, investment -2.165813 %, total balance 7026.590030,\n",
"day 200, sell 1 unit at price 906.659973, investment -2.442542 %, total balance 7933.250003,\n",
"day 201, sell 1 unit at price 924.690002, investment 0.267835 %, total balance 8857.940005,\n",
"day 204, sell 1 unit at price 915.890015, investment 0.538984 %, total balance 9773.830020,\n",
"day 205: buy 1 unit at price 913.809998, total balance 8860.020022\n",
"day 206, sell 1 unit at price 921.289978, investment 0.818549 %, total balance 9781.310000,\n",
"day 209: buy 1 unit at price 937.340027, total balance 8843.969973\n",
"day 210: buy 1 unit at price 928.450012, total balance 7915.519961\n",
"day 211, sell 1 unit at price 927.809998, investment -1.016710 %, total balance 8843.329959,\n",
"day 212: buy 1 unit at price 935.950012, total balance 7907.379947\n",
"day 214, sell 1 unit at price 929.080017, investment 0.067856 %, total balance 8836.459964,\n",
"day 216, sell 1 unit at price 935.090027, investment -0.091884 %, total balance 9771.549991,\n",
"day 217: buy 1 unit at price 925.109985, total balance 8846.440006\n",
"day 219, sell 1 unit at price 915.000000, investment -1.092841 %, total balance 9761.440006,\n",
"day 220: buy 1 unit at price 921.809998, total balance 8839.630008\n",
"day 221: buy 1 unit at price 931.580017, total balance 7908.049991\n",
"day 222: buy 1 unit at price 932.450012, total balance 6975.599979\n",
"day 226, sell 1 unit at price 944.489990, investment 2.460376 %, total balance 7920.089969,\n",
"day 227: buy 1 unit at price 949.500000, total balance 6970.589969\n",
"day 229, sell 1 unit at price 953.270020, investment 2.328303 %, total balance 7923.859989,\n",
"day 230: buy 1 unit at price 957.789978, total balance 6966.070011\n",
"day 231: buy 1 unit at price 951.679993, total balance 6014.390018\n",
"day 232: buy 1 unit at price 969.960022, total balance 5044.429996\n",
"day 233, sell 1 unit at price 978.890015, investment 4.980428 %, total balance 6023.320011,\n",
"day 234: buy 1 unit at price 977.000000, total balance 5046.320011\n",
"day 237, sell 1 unit at price 987.830017, investment 4.036863 %, total balance 6034.150028,\n",
"day 239, sell 1 unit at price 992.000000, investment 3.571767 %, total balance 7026.150028,\n",
"day 240, sell 1 unit at price 992.179993, investment 4.255632 %, total balance 8018.330021,\n",
"day 243, sell 1 unit at price 988.200012, investment 1.880489 %, total balance 9006.530033,\n",
"day 244, sell 1 unit at price 968.450012, investment -0.875127 %, total balance 9974.980045,\n"
]
}
],
"source": [
"states_buy, states_sell, total_gains, invest = agent.buy(initial_money = initial_money)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1080x360 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure(figsize = (15,5))\n",
"plt.plot(close, color='r', lw=2.)\n",
"plt.plot(close, '^', markersize=10, color='m', label = 'buying signal', markevery = states_buy)\n",
"plt.plot(close, 'v', markersize=10, color='k', label = 'selling signal', markevery = states_sell)\n",
"plt.title('total gains %f, total investment %f%%'%(total_gains, invest))\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}