{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "nwaAZRu1NTiI"
},
"source": [
"# Policy Gradient\n",
"\n",
"\n",
"#### This version implements Policy Gradient using a custom enviroment (Unit 4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install talib-binary\n",
"!pip install yfinance"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"id": "LNXxxKojNTiL"
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"from tensorflow.keras import layers, Model, Input\n",
"from tensorflow.keras.utils import to_categorical\n",
"import tensorflow.keras.backend as K\n",
"\n",
"import gym\n",
"from gym import spaces\n",
"from gym.utils import seeding\n",
"from gym import wrappers\n",
"\n",
"from tqdm.notebook import tqdm\n",
"from collections import deque\n",
"import numpy as np\n",
"import random\n",
"from matplotlib import pyplot as plt\n",
"from sklearn.preprocessing import MinMaxScaler\n",
"import joblib\n",
"import talib as ta\n",
"import yfinance as yf\n",
"import pandas as pd\n",
"\n",
"import io\n",
"import base64\n",
"from IPython.display import HTML, Video\n"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"# custom model to be able to run a custom loss with parameters\n",
"class CustomModel(tf.keras.Model):\n",
" def custom_loss(self,y, y_pred, d_returns):\n",
" log_like = y * K.log(y_pred)\n",
" # K.print_tensor(d_returns)\n",
" return K.sum(-log_like * d_returns )\n",
" \n",
" def train_step(self, data):\n",
" # Unpack the data. Its structure depends on your model and\n",
" # on what you pass to `fit()`.\n",
" if len(data) == 3:\n",
" x, y, sample_weight = data\n",
" else:\n",
" sample_weight = None\n",
" x, y = data\n",
"\n",
" # check if we passed the d_return\n",
" if isinstance(x, tuple):\n",
" x, d_return = x\n",
"\n",
" with tf.GradientTape() as tape:\n",
" y_pred = self(x, training=True) # Forward pass\n",
" # Compute the loss value.\n",
" y = tf.cast(y, tf.float32)\n",
" loss = self.custom_loss(y, y_pred, d_return)\n",
"\n",
" # Compute gradients\n",
" trainable_vars = self.trainable_variables\n",
" gradients = tape.gradient(loss, trainable_vars)\n",
"\n",
" # Update weights\n",
" self.optimizer.apply_gradients(zip(gradients, trainable_vars))\n",
"\n",
" # Update the metrics.\n",
" # Metrics are configured in `compile()`.\n",
" self.compiled_metrics.update_state(y, y_pred, sample_weight=sample_weight)\n",
"\n",
" # Return a dict mapping metric names to current value.\n",
" # Note that it will include the loss (tracked in self.metrics).\n",
" return {m.name: m.result() for m in self.metrics}"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"class Policy:\n",
" def __init__(self, env=None, action_size=2):\n",
"\n",
" self.action_size = action_size\n",
"\n",
" # Hyperparameters\n",
" self.gamma = 0.95 # Discount rate\n",
"\n",
" self.learning_rate = 1e-3\n",
" \n",
" # Construct DQN models\n",
" self.env = env\n",
" self.action_size = action_size\n",
" self.action_space = [i for i in range(action_size)]\n",
" print(\"action space\",self.action_space)\n",
" # self.saved_log_probs = None\n",
" self.model= self._build_model()\n",
" self.model.summary()\n",
"\n",
"\n",
" def _build_model(self):\n",
" x = Input(shape=(4,), name='x_input')\n",
" # y_true = Input( shape=(2,), name='y_true' )\n",
" d_returns = Input(shape=[1], name='d_returns')\n",
"\n",
" l = layers.Dense(16, activation = 'relu')(x)\n",
" l = layers.Dense(16, activation = 'relu')(l)\n",
" y_pred = layers.Dense(self.action_size, activation = 'softmax', name='y_pred')(l)\n",
" \n",
" optimizer = tf.keras.optimizers.Adam(learning_rate=self.learning_rate)\n",
"\n",
" # model_train = Model( inputs=[x], outputs=[y_pred], name='train_only' )\n",
" model_train = CustomModel( inputs=x, outputs=y_pred, name='train_only' )\n",
" # model_predict = Model( inputs=x, outputs=y_pred, name='predict_only' )\n",
" model_train.compile(loss=None, optimizer=optimizer, metrics = ['accuracy'])\n",
" # use run_eagerly to print values inside the loss function to debug\n",
" # model_train.compile(loss=None, optimizer=optimizer, metrics = ['accuracy'], run_eagerly = True)\n",
"\n",
" return model_train\n",
"\n",
" def act(self, state):\n",
" probs = self.model.predict(np.array([state]), verbose=0)[0]\n",
" action = np.random.choice(self.action_space, p=probs)\n",
"\n",
" return action\n",
"\n",
" # this implements the reinforce \n",
" def learn(self, n_training_episodes=None, max_t=None, print_every=100):\n",
" # Help us to calculate the score during the training\n",
" scores_deque = deque(maxlen=100)\n",
" scores = []\n",
" # Line 3 of pseudocode\n",
" for i_episode in range(1, n_training_episodes+1):\n",
" # saved_log_probs = []\n",
" saved_actions = []\n",
" saved_state = []\n",
" rewards = []\n",
" state = self.env.reset()\n",
" # Line 4 of pseudocode\n",
" for t in range(max_t):\n",
" saved_state.append(state)\n",
" action = self.act(state)\n",
" # action, log_prob = self.act(state)\n",
" # saved_log_probs.append(log_prob)\n",
" saved_actions.append(action)\n",
" state, reward, done, _ = self.env.step(action)\n",
" rewards.append(reward)\n",
" if done:\n",
" break \n",
" scores_deque.append(sum(rewards))\n",
" scores.append(sum(rewards))\n",
" \n",
" # Line 6 of pseudocode: calculate the return\n",
" returns = deque(maxlen=max_t) \n",
" n_steps = len(rewards) \n",
" # Compute the discounted returns at each timestep,\n",
" # as \n",
" # the sum of the gamma-discounted return at time t (G_t) + the reward at time t\n",
" #\n",
" # In O(N) time, where N is the number of time steps\n",
" # (this definition of the discounted return G_t follows the definition of this quantity \n",
" # shown at page 44 of Sutton&Barto 2017 2nd draft)\n",
" # G_t = r_(t+1) + r_(t+2) + ...\n",
" \n",
" # Given this formulation, the returns at each timestep t can be computed \n",
" # by re-using the computed future returns G_(t+1) to compute the current return G_t\n",
" # G_t = r_(t+1) + gamma*G_(t+1)\n",
" # G_(t-1) = r_t + gamma* G_t\n",
" # (this follows a dynamic programming approach, with which we memorize solutions in order \n",
" # to avoid computing them multiple times)\n",
" \n",
" # This is correct since the above is equivalent to (see also page 46 of Sutton&Barto 2017 2nd draft)\n",
" # G_(t-1) = r_t + gamma*r_(t+1) + gamma*gamma*r_(t+2) + ...\n",
" \n",
" \n",
" ## Given the above, we calculate the returns at timestep t as: \n",
" # gamma[t] * return[t] + reward[t]\n",
" #\n",
" ## We compute this starting from the last timestep to the first, in order\n",
" ## to employ the formula presented above and avoid redundant computations that would be needed \n",
" ## if we were to do it from first to last.\n",
" \n",
" ## Hence, the queue \"returns\" will hold the returns in chronological order, from t=0 to t=n_steps\n",
" ## thanks to the appendleft() function which allows to append to the position 0 in constant time O(1)\n",
" ## a normal python list would instead require O(N) to do this.\n",
" for t in range(n_steps)[::-1]:\n",
" disc_return_t = (returns[0] if len(returns)>0 else 0)\n",
" returns.appendleft( self.gamma*disc_return_t + rewards[t] ) \n",
" \n",
" ## standardization of the returns is employed to make training more stable\n",
" eps = np.finfo(np.float32).eps.item()\n",
" ## eps is the smallest representable float, which is \n",
" # added to the standard deviation of the returns to avoid numerical instabilities \n",
" returns = np.array(returns)\n",
" returns = (returns - returns.mean()) / (returns.std() + eps)\n",
" # self.saved_log_probs = saved_log_probs\n",
" \n",
" # Line 7:\n",
" saved_state = np.array(saved_state)\n",
" # print(\"Saved state\", saved_state, saved_state.shape)\n",
" saved_actions = np.array(to_categorical(saved_actions, num_classes=self.action_size))\n",
" # print(\"Saved actions\", saved_actions, saved_actions.shape)\n",
" returns = returns.reshape(-1,1)\n",
" # print(\"Returns\", returns, returns.shape)\n",
" # this is the trick part, we send a tuple so the CustomModel is able to split the x and use \n",
" # the returns inside to calculate the custom loss\n",
" self.model.train_on_batch(x=(saved_state,returns), y=saved_actions)\n",
"\n",
" # policy_loss = []\n",
" # for action, log_prob, disc_return in zip(saved_actions, saved_log_probs, returns):\n",
" # policy_loss.append(-log_prob * disc_return)\n",
" # policy_loss = torch.cat(policy_loss).sum()\n",
" \n",
" # # Line 8: PyTorch prefers gradient descent \n",
" # optimizer.zero_grad()\n",
" # policy_loss.backward()\n",
" # optimizer.step()\n",
" \n",
" if i_episode % print_every == 0:\n",
" print('Episode {}\\tAverage Score: {:.2f}'.format(i_episode, np.mean(scores_deque)))\n",
" \n",
" return scores\n",
"\n",
"\n",
" #\n",
" # Loads a saved model\n",
" #\n",
" def load(self, name):\n",
" self.model = tf.keras.models.load_model(name)\n",
" # self.scaler = joblib.load(name+\".scaler\") \n",
"\n",
" #\n",
" # Saves parameters of a trained model\n",
" #\n",
" def save(self, name):\n",
" self.model.save(name)\n",
" # joblib.dump(self.scaler, name+\".scaler\") \n",
"\n",
" def play(self, state):\n",
" # state = self._get_scaled_state(state)\n",
" return np.argmax(self.model.predict(np.array([state]), verbose=0)[0])"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"from enum import Enum\n",
"class Actions(Enum):\n",
" Sell = 0\n",
" Buy = 1\n",
" Do_nothing = 2\n",
"\n",
"class CustTradingEnv(gym.Env):\n",
"\n",
" def __init__(self, df, max_steps=0, seed=8, random_start=True, scaler=None):\n",
" self.seed(seed=seed)\n",
" self.df = df\n",
" if scaler is None:\n",
" self.scaler = MinMaxScaler()\n",
" else:\n",
" self.scaler = scaler\n",
" self.prices, self.signal_features = self._process_data()\n",
"\n",
" # spaces\n",
" self.action_space = spaces.Discrete(3)\n",
" self.observation_space = spaces.Box(low=0, high=1, shape=(1,) , dtype=np.float64)\n",
"\n",
" # episode\n",
" self._start_tick = 0\n",
" self._end_tick = 0\n",
" self._done = None\n",
" self._current_tick = None\n",
" self._last_trade_tick = None\n",
" self._position = None\n",
" self._position_history = None\n",
" self._total_reward = None\n",
" self._total_profit = None\n",
" self._first_rendering = None\n",
" self.history = None\n",
" self._max_steps = max_steps\n",
" self._start_episode_tick = None\n",
" self._trade_history = None\n",
" self._random_start = random_start\n",
"\n",
"\n",
" def reset(self):\n",
" self._done = False\n",
" if self._random_start:\n",
" self._start_episode_tick = np.random.randint(1,high=len(self.df)- self._max_steps )\n",
" self._end_tick = self._start_episode_tick + self._max_steps\n",
" else:\n",
" self._start_episode_tick = 1\n",
" self._end_tick = len(self.df)-1\n",
"\n",
" self._current_tick = self._start_episode_tick\n",
" self._last_trade_tick = self._current_tick - 1\n",
" self._position = 0\n",
" self._position_history = []\n",
" # self._position_history = (self.window_size * [None]) + [self._position]\n",
" self._total_reward = 0.\n",
" self._total_profit = 0.\n",
" self._trade_history = []\n",
" self.history = {}\n",
" return self._get_observation()\n",
"\n",
"\n",
" def step(self, action):\n",
" self._done = False\n",
" self._current_tick += 1\n",
"\n",
" if self._current_tick == self._end_tick:\n",
" self._done = True\n",
"\n",
" step_reward = self._calculate_reward(action)\n",
" self._total_reward += step_reward\n",
"\n",
" observation = self._get_observation()\n",
" info = dict(\n",
" total_reward = self._total_reward,\n",
" total_profit = self._total_profit,\n",
" position = self._position,\n",
" action = action\n",
" )\n",
" self._update_history(info)\n",
"\n",
" return observation, step_reward, self._done, info\n",
"\n",
" def seed(self, seed=None):\n",
" self.np_random, seed = seeding.np_random(seed)\n",
" return [seed]\n",
" \n",
" def _get_observation(self):\n",
" return self.signal_features[self._current_tick]\n",
"\n",
" def _update_history(self, info):\n",
" if not self.history:\n",
" self.history = {key: [] for key in info.keys()}\n",
"\n",
" for key, value in info.items():\n",
" self.history[key].append(value)\n",
"\n",
"\n",
" def render(self, mode='human'):\n",
" window_ticks = np.arange(len(self._position_history))\n",
" prices = self.prices[self._start_episode_tick:self._end_tick+1]\n",
" plt.plot(prices)\n",
"\n",
" open_buy = []\n",
" close_buy = []\n",
" open_sell = []\n",
" close_sell = []\n",
" do_nothing = []\n",
"\n",
" for i, tick in enumerate(window_ticks):\n",
" if self._position_history[i] == 1:\n",
" open_buy.append(tick)\n",
" elif self._position_history[i] == 2 :\n",
" close_buy.append(tick)\n",
" elif self._position_history[i] == 3 :\n",
" open_sell.append(tick)\n",
" elif self._position_history[i] == 4 :\n",
" close_sell.append(tick)\n",
" elif self._position_history[i] == 0 :\n",
" do_nothing.append(tick)\n",
"\n",
" plt.plot(open_buy, prices[open_buy], 'go', marker=\"^\")\n",
" plt.plot(close_buy, prices[close_buy], 'go', marker=\"v\")\n",
" plt.plot(open_sell, prices[open_sell], 'ro', marker=\"v\")\n",
" plt.plot(close_sell, prices[close_sell], 'ro', marker=\"^\")\n",
" \n",
" plt.plot(do_nothing, prices[do_nothing], 'yo')\n",
"\n",
" plt.suptitle(\n",
" \"Total Reward: %.6f\" % self._total_reward + ' ~ ' +\n",
" \"Total Profit: %.6f\" % self._total_profit\n",
" )\n",
"\n",
" def _calculate_reward(self, action):\n",
" step_reward = 0\n",
"\n",
" current_price = self.prices[self._current_tick]\n",
" last_price = self.prices[self._current_tick - 1]\n",
" price_diff = current_price - last_price\n",
"\n",
" penalty = -1 * last_price * 0.01\n",
" # OPEN BUY - 1\n",
" if action == Actions.Buy.value and self._position == 0:\n",
" self._position = 1\n",
" step_reward += price_diff\n",
" self._last_trade_tick = self._current_tick - 1\n",
" self._position_history.append(1)\n",
"\n",
" elif action == Actions.Buy.value and self._position > 0:\n",
" step_reward += penalty\n",
" self._position_history.append(-1)\n",
" # CLOSE SELL - 4\n",
" elif action == Actions.Buy.value and self._position < 0:\n",
" self._position = 0\n",
" step_reward += -1 * (self.prices[self._current_tick -1] - self.prices[self._last_trade_tick]) \n",
" self._total_profit += step_reward\n",
" self._position_history.append(4)\n",
" self._trade_history.append(step_reward)\n",
"\n",
" # OPEN SELL - 3\n",
" elif action == Actions.Sell.value and self._position == 0:\n",
" self._position = -1\n",
" step_reward += -1 * price_diff\n",
" self._last_trade_tick = self._current_tick - 1\n",
" self._position_history.append(3)\n",
" # CLOSE BUY - 2\n",
" elif action == Actions.Sell.value and self._position > 0:\n",
" self._position = 0\n",
" step_reward += self.prices[self._current_tick -1] - self.prices[self._last_trade_tick] \n",
" self._total_profit += step_reward\n",
" self._position_history.append(2)\n",
" self._trade_history.append(step_reward)\n",
" elif action == Actions.Sell.value and self._position < 0:\n",
" step_reward += penalty\n",
" self._position_history.append(-1)\n",
"\n",
" # DO NOTHING - 0\n",
" elif action == Actions.Do_nothing.value and self._position > 0:\n",
" step_reward += price_diff\n",
" self._position_history.append(0)\n",
" elif action == Actions.Do_nothing.value and self._position < 0:\n",
" step_reward += -1 * price_diff\n",
" self._position_history.append(0)\n",
" elif action == Actions.Do_nothing.value and self._position == 0:\n",
" step_reward += -1 * abs(price_diff)\n",
" self._position_history.append(0)\n",
"\n",
" return step_reward\n",
"\n",
" def get_scaler(self):\n",
" return self.scaler\n",
"\n",
" def set_scaler(self, scaler):\n",
" self.scaler = scaler\n",
" \n",
" def _process_data(self):\n",
" timeperiod = 14\n",
" self.df = self.df.copy()\n",
" \n",
" self.df['mfi_r'] = ta.MFI(self.df['High'], self.df['Low'], self.df['Close'],self.df['Volume'], timeperiod=timeperiod)\n",
" _, self.df['stoch_d_r'] = ta.STOCH(self.df['High'], self.df['Low'], self.df['Close'], fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)\n",
" self.df['adx_r'] = ta.ADX(self.df['High'], self.df['Low'], self.df['Close'], timeperiod=timeperiod)\n",
" self.df['p_di'] = ta.PLUS_DI(self.df['High'], self.df['Low'], self.df['Close'], timeperiod=timeperiod)\n",
" self.df['m_di'] = ta.MINUS_DI(self.df['High'], self.df['Low'], self.df['Close'], timeperiod=timeperiod)\n",
" self.df['di'] = np.where( self.df['p_di'] > self.df['m_di'], 1, 0)\n",
"\n",
" self.df = self.df.dropna()\n",
" # self.df['di_s']=self.df['di']\n",
" # self.df['mfi_s']=self.df['mfi_r']\n",
" # self.df['stoch_d_s']=self.df['stoch_d_r']\n",
" # self.df['adx_s']=self.df['adx_r']\n",
"\n",
" self.df[['di_s','mfi_s','stoch_d_s','adx_s']] = self.scaler.fit_transform(self.df[['di','mfi_r','stoch_d_r','adx_r']])\n",
"\n",
" def f1(row):\n",
" row['state'] = [row['di_s'], row['mfi_s'], row['stoch_d_s'], row['adx_s']]\n",
" return row\n",
"\n",
" self.df = self.df.apply(f1, axis=1 )\n",
"\n",
" prices = self.df.loc[:, 'Close'].to_numpy()\n",
" # print(self.df.head(30))\n",
"\n",
" signal_features = np.stack(self.df.loc[:, 'state'].to_numpy())\n",
"\n",
" return prices, signal_features"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3067\n",
"1918\n"
]
}
],
"source": [
"# Get data\n",
"eth_usd = yf.Ticker(\"ETH-USD\")\n",
"eth = eth_usd.history(period=\"max\")\n",
"\n",
"btc_usd = yf.Ticker(\"BTC-USD\")\n",
"btc = btc_usd.history(period=\"max\")\n",
"print(len(btc))\n",
"print(len(eth))\n",
"\n",
"btc_train = eth[-3015:-200]\n",
"# btc_test = eth[-200:]\n",
"eth_train = eth[-1864:-200]\n",
"eth_test = eth[-200:]\n",
"# len(eth_train)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"action space [0, 1, 2]\n",
"Model: \"train_only\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" x_input (InputLayer) [(None, 4)] 0 \n",
" \n",
" dense_22 (Dense) (None, 16) 80 \n",
" \n",
" dense_23 (Dense) (None, 16) 272 \n",
" \n",
" y_pred (Dense) (None, 3) 51 \n",
" \n",
"=================================================================\n",
"Total params: 403\n",
"Trainable params: 403\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n",
"Episode 100\tAverage Score: -180.05\n",
"Episode 200\tAverage Score: -164.72\n",
"Episode 300\tAverage Score: -81.03\n",
"Episode 400\tAverage Score: -117.40\n",
"Episode 500\tAverage Score: -182.76\n",
"Episode 600\tAverage Score: -92.27\n",
"Episode 700\tAverage Score: -207.78\n",
"Episode 800\tAverage Score: -232.02\n",
"Episode 900\tAverage Score: -29.72\n",
"Episode 1000\tAverage Score: -44.37\n",
"Episode 1100\tAverage Score: -60.61\n",
"Episode 1200\tAverage Score: -67.30\n",
"Episode 1300\tAverage Score: -36.28\n",
"Episode 1400\tAverage Score: -60.42\n",
"Episode 1500\tAverage Score: -93.99\n",
"Episode 1600\tAverage Score: -70.92\n",
"Episode 1700\tAverage Score: -88.01\n",
"Episode 1800\tAverage Score: -21.69\n",
"Episode 1900\tAverage Score: -66.15\n",
"Episode 2000\tAverage Score: -96.49\n",
"Episode 2100\tAverage Score: -33.40\n",
"Episode 2200\tAverage Score: -25.62\n",
"Episode 2300\tAverage Score: -46.25\n",
"Episode 2400\tAverage Score: -63.88\n",
"Episode 2500\tAverage Score: -29.43\n",
"Episode 2600\tAverage Score: -19.85\n",
"Episode 2700\tAverage Score: -53.53\n",
"Episode 2800\tAverage Score: -42.98\n",
"Episode 2900\tAverage Score: -50.12\n",
"Episode 3000\tAverage Score: -27.25\n"
]
}
],
"source": [
"# create env\n",
"max_steps = 20 \n",
"env = CustTradingEnv(df=eth_train, max_steps=max_steps)\n",
"\n",
"model = Policy(env=env, action_size=3)\n",
"# model.learn(total_steps=6_000)\n",
"\n",
"model.learn(n_training_episodes=3000, max_t=20, print_every=100)\n",
"# model.learn(n_training_episodes=1000, max_t=1000, print_every=100)\n",
"env.close()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.save(\"./alt/fin_rl_policy_gradient_v1\")\n",
"joblib.dump(env.get_scaler(),\"./alt/fin_rl_policy_gradient_v1.h5_scaler\")\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"def evaluate_agent(env, max_steps, n_eval_episodes, model, random=False):\n",
" \"\"\"\n",
" Evaluate the agent for ``n_eval_episodes`` episodes and returns average reward and std of reward.\n",
" :param env: The evaluation environment\n",
" :param n_eval_episodes: Number of episode to evaluate the agent\n",
" :param model: The DQN model\n",
" \"\"\"\n",
" episode_rewards = []\n",
" episode_profits = []\n",
" for episode in tqdm(range(n_eval_episodes), disable=random):\n",
" state = env.reset()\n",
" step = 0\n",
" done = False\n",
" total_rewards_ep = 0\n",
" total_profit_ep = 0\n",
" \n",
" for step in range(max_steps):\n",
" # Take the action (index) that have the maximum expected future reward given that state\n",
" if random:\n",
" action = env.action_space.sample()\n",
" else:\n",
" action = model.play(state)\n",
" # print(action)\n",
" \n",
" new_state, reward, done, info = env.step(action)\n",
" total_rewards_ep += reward\n",
" \n",
" if done:\n",
" break\n",
" state = new_state\n",
"\n",
" episode_rewards.append(total_rewards_ep)\n",
" episode_profits.append(env.history['total_profit'][-1])\n",
" # print(env.history)\n",
" # env.render()\n",
" # assert 0\n",
"\n",
" mean_reward = np.mean(episode_rewards)\n",
" std_reward = np.std(episode_rewards)\n",
" mean_profit = np.mean(episode_profits)\n",
" std_profit = np.std(episode_profits)\n",
"\n",
" return mean_reward, std_reward, mean_profit, std_profit"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "f0eff2ef3b0a4e12a23709db72722a25",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/1000 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(-154.3092699572754, 175.74654447090296, 87.62391918945312, 124.92244937767752)"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mThe Kernel crashed while executing code in the the current cell or a previous cell. Please review the code in the cell(s) to identify a possible cause of the failure. Click here for more info. View Jupyter log for further details."
]
}
],
"source": [
"max_steps = 20 \n",
"env_test = CustTradingEnv(df=eth_test, max_steps=max_steps, random_start=True, scaler=env.get_scaler())\n",
"n_eval_episodes = 1000\n",
"\n",
"evaluate_agent(env_test, max_steps, n_eval_episodes, model)"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a7b0edb264fe43edbe5cea55fac21688",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/1 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(-1782.8878674316418, 0.0, 381.1708984375, 0.0)"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# trade sequentially \n",
"max_steps = len(eth_test)\n",
"env_test = CustTradingEnv(df=eth_test, max_steps=max_steps, random_start=False, scaler=env.get_scaler())\n",
"n_eval_episodes = 1\n",
"\n",
"evaluate_agent(env_test, max_steps, n_eval_episodes, model)"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential_18\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" dense_72 (Dense) (None, 256) 1280 \n",
" \n",
" dense_73 (Dense) (None, 128) 32896 \n",
" \n",
" dense_74 (Dense) (None, 64) 8256 \n",
" \n",
" dense_75 (Dense) (None, 3) 195 \n",
" \n",
"=================================================================\n",
"Total params: 42,627\n",
"Trainable params: 42,627\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"# load model and scaler from file\n",
"max_steps = 20 \n",
"scaler_l = joblib.load(\"./alt/fin_rl_dqn_v1.h5_scaler\")\n",
"env_l = CustTradingEnv(df=eth_test, max_steps=max_steps, scaler=scaler_l, random_start=False)\n",
"\n",
"model_l = DQN(env=env_l, replay_buffer_size=10_000)\n",
"model_l.load(\"./alt/fin_rl_dqn_v1\")"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5af7f535b81047198bff5776f994ed8c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/1 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(-1782.8878674316418, 0.0, 381.1708984375, 0.0)"
]
},
"execution_count": 82,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# trade sequentially the loaded model and env\n",
"max_steps = len(eth_test)\n",
"n_eval_episodes = 1\n",
"evaluate_agent(env_l, max_steps, n_eval_episodes, model_l)"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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iIiIiIxDCuZERERERETGIQVzIiIiIiIi45CCORERERERkXFIwZyIiIiIiMg4pGBORERERERkHFIwJyIiIiIiMg4pmBMRERERERmHFMyJiIiIiIiMQwrmRERERERExiEFcyIiIiIiIuOQgjkREREREZFxSMGciIiIiIjIOKRgTkREREREZBxSMCciIiIiIjIOKZgTEREREREZhxTMiYiIiIiIjEMK5kRERERERMYhBXMiIiIiIiLjkII5ERERERGRcUjBnIiIiIiIyDikYE5ERERERGQcUjAnIiIiIiIyDimYExERERERGYcUzImIiIiIiIxDCbFuwEByc3PtrFmzYt0MERERERGRmHjjjTeqrLV53ZfHfTA3a9YstmzZEutmiIiIiIiIxIQx5lhvy9XNUkREREREZBxSMCciIiIiIjIOKZgTEREREREZhwYM5owx040xLxhj9hhjdhljvuguzzbGPGuMOeD+mxWxz9eMMQeNMfuMMVdFLD/HGPOWu+6nxhgzNi9LRERERERkYhtMZq4D+LK1djGwFvicMWYJ8FXgeWvtfOB592fcdTcAS4F3AHcbY7zusf4buBWY7z7eMYqvRUREREREZNIYMJiz1pZaa990n9cDe4Ai4DrgV+5mvwKud59fBzxorW211h4BDgJrjDGFQLq1doO11gK/jthHREREREREhmBIY+aMMbOAVcAmYIq1thScgA/IdzcrAk5E7FbsLityn3dfLiIiIiIiIkM06GDOGJMKPAzcZq2t62/TXpbZfpb3dq5bjTFbjDFbKisrB9tEERERERGRSWNQwZwxxocTyP3WWvt/7uJyt+sk7r8V7vJiYHrE7tOAEnf5tF6W92Ct/bm1drW1dnVeXo+JzkVERERERCa9wVSzNMAvgT3W2h9HrHoM+Kj7/KPAnyKW32CMSTTGzMYpdLLZ7YpZb4xZ6x7z5oh9REREREREZAgSBrHNhcBNwFvGmG3usq8D3wceMsZ8AjgOfADAWrvLGPMQsBunEubnrLVBd7/PAPcDScCT7kNERERERESGyDiFJePX6tWr7ZYtW2LdDJGYsNayu7SOJYXpaFpGERERkcnJGPOGtXZ19+VDqmYpItH1v5uP866fvsLLB6pi3RQRERERiTMK5kTiVE1TGz98eh8AT+4sjXFrRERERCTeKJgTiVP/9sx+6prbWT4tg2d2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",
"text/plain": [
"