From 97e4dd20724aa1249e7662b84ee6e0c59400c471 Mon Sep 17 00:00:00 2001 From: p-pl Date: Wed, 14 Sep 2022 10:23:54 +0000 Subject: [PATCH 1/3] Initial Reinforcementlearning version for ML --- .../notebooks/Bitcoin_Factory_RL.py | 801 +++++++++++++++++ .../ReadMeReinforcementLearning.md | 16 + .../notebooks/Bitcoin_Factory_RL.py | 806 +++++++----------- .../Forecast-Client/ForecastClient.js | 189 ++-- .../TS/Bot-Modules/Test-Client/TestClient.js | 63 +- .../Test-Server/ForecastCasesManager.js | 86 +- .../Test-Server/ForecastClientsManager.js | 1 + .../Test-Server/TestCasesManager.js | 32 +- .../TS/Bot-Modules/Test-Server/TestServer.js | 7 +- 9 files changed, 1426 insertions(+), 575 deletions(-) create mode 100644 Bitcoin-Factory/Forecast-Client/notebooks/Bitcoin_Factory_RL.py create mode 100644 Bitcoin-Factory/ReadMeReinforcementLearning.md diff --git a/Bitcoin-Factory/Forecast-Client/notebooks/Bitcoin_Factory_RL.py b/Bitcoin-Factory/Forecast-Client/notebooks/Bitcoin_Factory_RL.py new file mode 100644 index 0000000000..330fa6b634 --- /dev/null +++ b/Bitcoin-Factory/Forecast-Client/notebooks/Bitcoin_Factory_RL.py @@ -0,0 +1,801 @@ +#!/usr/bin/env python +# coding: utf-8 + +import random +import gym +from gym import spaces +import pandas as pd +import numpy as np +import matplotlib +import matplotlib.pyplot as plt +import time +import ray +import os +import sys +import math +import json +from typing import Dict, List, Optional, Union +from ray import tune +from ray.rllib.agents import ppo +from ray.tune import CLIReporter +from ray.tune import ProgressReporter +from ray.tune.registry import register_env +from ray.rllib.env.vector_env import VectorEnv #unused +from sklearn.model_selection import train_test_split +from sklearn import preprocessing +from sklearn.preprocessing import MinMaxScaler +from tabulate import tabulate + +location: str = "/tf/notebooks/" +instructions_file: str = "instructions.csv" +run_forcast: bool = False +res_dir: str = location + "/ray_results/" + + +if os.path.isfile(location+instructions_file): #Forecaster + run_forecast = True + + # Load the Instructions Dataset + instructions_dataset = pd.read_csv( + '/tf/notebooks/instructions.csv', + header=0, + sep=' ', + skipinitialspace=True + ) + + # what are we going to do in the current run? + ACTION_TO_TAKE = instructions_dataset.values[0][1] + + # name of the model file to load or save. + MODEL_FILE_NAME = instructions_dataset.values[1][1] + + FILENAME_parameters_dataset = instructions_dataset.values[2][1] + FILENAME_timeseries_dataset = instructions_dataset.values[3][1] + + res_dir = location + "/models/" + MODEL_FILE_NAME + "/" + + parameters = pd.read_csv( + '/tf/notebooks/'+FILENAME_parameters_dataset, + header=0, + sep=' ', + skipinitialspace=True + ) + df = pd.read_csv( + location+FILENAME_timeseries_dataset, + header=0, + index_col=None, + sep=' ', + skipinitialspace=True + ) + +else: #Testclient + parameters = pd.read_csv( + location+'parameters.csv', + sep=' ', + skipinitialspace=True, + ) + df = pd.read_csv( + location+'time-series.csv', + header=0, + index_col=None, + sep=' ', + skipinitialspace=True + ) + +if {'TIMESTEPS_TO_TRAIN'}.issubset(parameters.columns): + EXPERIMENT_NAME = "Trading_Signal_Predictor_RL_V01" + PERCENTAGE_OF_DATASET_FOR_TRAINING = 80 + TIMESTEPS_TO_TRAIN = parameters['TIMESTEPS_TO_TRAIN'][0] + OBSERVATION_WINDOW_SIZE = parameters['OBSERVATION_WINDOW_SIZE'][0] + INITIAL_QUOTE_ASSET = parameters['INITIAL_QUOTE_ASSET'][0] + INITIAL_BASE_ASSET = parameters['INITIAL_BASE_ASSET'][0] + TRADING_FEE = parameters['TRADING_FEE'][0] + ENV_VERSION = parameters['ENV_VERSION'][0] + ENV_NAME = parameters['ENV_NAME'][0] + EXPLORE_ON_EVAL = parameters['EXPLORE_ON_EVAL'][0] + + # Hyper-parameters, in case we want to really control them from the test server not from ray + ALGORITHM = parameters['ALGORITHM'][0] + ROLLOUT_FRAGMENT_LENGTH = parameters['ROLLOUT_FRAGMENT_LENGTH'][0] + TRAIN_BATCH_SIZE = parameters['TRAIN_BATCH_SIZE'][0] + SGD_MINIBATCH_SIZE = parameters['SGD_MINIBATCH_SIZE'][0] + BATCH_MODE = parameters['BATCH_MODE'][0] + #VF_CLIP_PARAM = parameters['VF_CLIP_PARAM'][0] + FC_SIZE = [parameters['FC_SIZE'][0]] + LEARNING_RATE = parameters['LEARNING_RATE'][0] + GAMMA = parameters['GAMMA'][0] + +else: + EXPERIMENT_NAME = "Trading_Signal_Predictor_RL_V01" + PERCENTAGE_OF_DATASET_FOR_TRAINING = 80 + TIMESTEPS_TO_TRAIN = int(parameters.values[2][4]) + OBSERVATION_WINDOW_SIZE = int(parameters.values[2][5]) + INITIAL_QUOTE_ASSET = int(parameters.values[2][6]) + INITIAL_BASE_ASSET = int(parameters.values[2][7]) + TRADING_FEE = float(parameters.values[2][8]) + ENV_NAME = str(parameters.values[2][9]) + ENV_VERSION = int(parameters.values[2][10]) + EXPLORE_ON_EVAL = str(parameters.values[2][12]) + + # Hyper-parameters, in case we want to really control them from the test server not from ray + ALGORITHM = str(parameters.values[2][13]) + ROLLOUT_FRAGMENT_LENGTH = int(parameters.values[2][14]) + TRAIN_BATCH_SIZE = int(parameters.values[2][15]) + SGD_MINIBATCH_SIZE = int(parameters.values[2][16]) + BATCH_MODE = str(parameters.values[2][17]) + #VF_CLIP_PARAM = parameters['VF_CLIP_PARAM'][0] + FC_SIZE = int(parameters.values[2][18]) + LEARNING_RATE = float(parameters.values[2][19]) + GAMMA = float(parameters.values[2][20]) + + +print(f'TIMESTEPS_TO_TRAIN: {TIMESTEPS_TO_TRAIN}\n') +print(f'OBSERVATION_WINDOW_SIZE: {OBSERVATION_WINDOW_SIZE}\n') +print(f'INITIAL_QUOTE_ASSET: {INITIAL_QUOTE_ASSET}\n') +print(f'INITIAL_BASE_ASSET: {INITIAL_BASE_ASSET}\n') +print(f'TRADING_FEE: {TRADING_FEE}\n') + +def prepare_data(df): + # renaming column labels as we wish, regardless what test server sends, hopefully he will maintain position + df.rename(columns={df.columns[0]: "date"}, inplace=True) + df.rename(columns={df.columns[1]: "high"}, inplace=True) + df.rename(columns={df.columns[2]: "low"}, inplace=True) + df.rename(columns={df.columns[3]: "close"}, inplace=True) + df.rename(columns={df.columns[4]: "open"}, inplace=True) + df.rename(columns={df.columns[5]: "volume"}, inplace=True) + + df['volume'] = np.int64(df['volume']) + df['date'] = pd.to_datetime(df['date'], unit='ms') + df.sort_values(by='date', ascending=True, inplace=True) + df.reset_index(drop=True, inplace=True) + df['date'] = df['date'].dt.strftime('%Y-%m-%d %I:%M %p') + + return df + +data = prepare_data(df) + +# Setup which data to use for training and which data to use for evaluation of RL Model +def split_data(data): + + X_train_test, X_valid = train_test_split(data, train_size=0.67, test_size=0.33, shuffle=False) + X_train, X_test = train_test_split(X_train_test, train_size=0.50, test_size=0.50, shuffle=False) + + return X_train, X_test, X_valid + +X_train, X_test, X_valid = split_data(data) + + +# Normalize the dataset subsets to make the model converge faster +scaler_type = MinMaxScaler + +def get_feature_scalers(X, scaler_type=scaler_type): + scalers = [] + for name in list(X.columns[X.columns != 'date']): + scalers.append(scaler_type().fit(X[name].values.reshape(-1, 1))) + return scalers + +def get_scaler_transforms(X, scalers): + X_scaled = [] + for name, scaler in zip(list(X.columns[X.columns != 'date']), scalers): + X_scaled.append(scaler.transform(X[name].values.reshape(-1, 1))) + X_scaled = pd.concat([pd.DataFrame(column, columns=[name]) for name, column in zip(list(X.columns[X.columns != 'date']), X_scaled)], axis='columns') + return X_scaled + +def scale_numpy_array(np_arr, scaler_type = scaler_type): + return scaler_type().fit_transform(np_arr, (-1,1)) + +def normalize_data(X_train, X_test, X_valid): + X_train_test = pd.concat([X_train, X_test], axis='index') + X_train_test_valid = pd.concat([X_train_test, X_valid], axis='index') + + X_train_test_dates = X_train_test[['date']] + X_train_test_valid_dates = X_train_test_valid[['date']] + + X_train_test = X_train_test.drop(columns=['date']) + X_train_test_valid = X_train_test_valid.drop(columns=['date']) + + train_test_scalers = get_feature_scalers(X_train_test, + scaler_type=scaler_type) + train_test_valid_scalers = get_feature_scalers(X_train_test_valid, + scaler_type=scaler_type) + + X_train_test_scaled = get_scaler_transforms(X_train_test, + train_test_scalers) + X_train_test_valid_scaled = get_scaler_transforms(X_train_test_valid, + train_test_scalers) + X_train_test_valid_scaled_leaking = get_scaler_transforms(X_train_test_valid, + train_test_valid_scalers) + + X_train_test_scaled = pd.concat([X_train_test_dates, + X_train_test_scaled], + axis='columns') + X_train_test_valid_scaled = pd.concat([X_train_test_valid_dates, + X_train_test_valid_scaled], + axis='columns') + X_train_test_valid_scaled_leaking = pd.concat([X_train_test_valid_dates, + X_train_test_valid_scaled_leaking], + axis='columns') + + X_train_scaled = X_train_test_scaled.iloc[:X_train.shape[0]] + X_test_scaled = X_train_test_scaled.iloc[X_train.shape[0]:] + X_valid_scaled = X_train_test_valid_scaled.iloc[X_train_test.shape[0]:] + X_valid_scaled_leaking = X_train_test_valid_scaled_leaking.iloc[X_train_test.shape[0]:] + + return (train_test_scalers, + train_test_valid_scalers, + X_train_scaled, + X_test_scaled, + X_valid_scaled, + X_valid_scaled_leaking) + +train_test_scalers, train_test_valid_scalers, X_train_scaled, X_test_scaled, X_valid_scaled, X_valid_scaled_leaking = normalize_data(X_train, X_test, X_valid) + +class SimpleTradingEnv(gym.Env): + + metadata = {'render.modes': ['live', 'human', 'portfolio', 'none']} + visualization = None + + def __init__(self, config=None): + + self.df_scaled = config.get("df_scaled").reset_index(drop=True) + self.df_normal = config.get("df_normal").reset_index(drop=True) + self.window_size = OBSERVATION_WINDOW_SIZE + self.prices, self.features = self._process_data(self.df_scaled) + # The shape of the observation is (window_size * features + environment_features) the environment_features are: quote_asset, base_asset, net_worth. The entire observation is flattened in a 1D np array. + # NOT USED ANYMORE, KEPT FOR REFERENCE + # self.obs_shape = ((OBSERVATION_WINDOW_SIZE * self.features.shape[1] + 3),) + + # The shape of the observation is number of candles to look back, and the number of features (candle_features) + 3 (quote_asset, base_asset, net_worth) + self.obs_shape = (OBSERVATION_WINDOW_SIZE, self.features.shape[1] + 3) + + # Action space + #self.action_space = spaces.Box(low=np.array([0, 0]), high=np.array([3.0, 1.0]), dtype=np.float32) + self.action_space = spaces.MultiDiscrete([3, 100]) + # Observation space + self.observation_space = spaces.Box(low=-1, high=1, shape=self.obs_shape, dtype=np.float32) + + # Initialize the episode environment + + self._start_candle = OBSERVATION_WINDOW_SIZE # We assume that the first observation is not the first row of the dataframe, in order to avoid the case where there are no calculated indicators. + self._end_candle = len(self.features) - 1 + self._trading_fee = config.get("trading_fee") + + self._quote_asset = None + self._base_asset = None + self._done = None + self._current_candle = None + self._net_worth = None + self._previous_net_worth = None + + # Array that will contain observation history needed for appending it to the observation space + # It will contain observations consisting of the net_worth, base_asset and quote_asset as list of floats + # Other features (OHLC + Indicators) will be appended to the current observation in the _get_observation method that takes the data directly from the available dataframe + self._obs_env_history = None + + # Render and analysis data + self._total_reward_accumulated = None + self.portfolio_history = None + self.trade_history = None + self.positions = None + self._first_rendering = None + + + def reset(self): + self._done = False + self._current_candle = self._start_candle + self._quote_asset = INITIAL_QUOTE_ASSET + self._base_asset = INITIAL_BASE_ASSET + self._net_worth = INITIAL_QUOTE_ASSET # at the begining our net worth is the initial quote asset + self._previous_net_worth = INITIAL_QUOTE_ASSET # at the begining our previous net worth is the initial quote asset + self._total_reward_accumulated = 0. + self._first_rendering = True + self.portfolio_history = [] + self.trade_history = [] + self.positions = [] + self._obs_env_history = [] + + self._initial_obs_data() + + return self._get_observation() + + def _take_action(self, action): + self._done = False + current_price = random.uniform( + self.df_normal.loc[self._current_candle, "low"], self.df_normal.loc[self._current_candle, "high"]) + + + action_type = action[0] + amount = action[1] / 100 + + if action_type == 0: # Buy + # Buy % assets + # Determine the maximum amount of quote asset that can be bought + available_amount_to_buy_with = self._quote_asset / current_price + # Buy only the amount that agent chose + assets_bought = available_amount_to_buy_with * amount + # Update the quote asset balance + self._quote_asset -= assets_bought * current_price + # Update the base asset + self._base_asset += assets_bought + # substract trading fee from base asset based on the amount bought + self._base_asset -= self._trading_fee * assets_bought + + # Add to trade history the amount bought if greater than 0 + if assets_bought > 0: + self.trade_history.append({'step': self._current_candle, 'type': 'BuyLong', 'amount': assets_bought, 'price': current_price, 'total' : assets_bought * current_price, 'percent_amount': action[1]}) + + + elif action_type == 1: # Sell + # Sell % assets + # Determine the amount of base asset that can be sold + amount_to_sell = self._base_asset * amount + received_quote_asset = amount_to_sell * current_price + # Update the quote asset + self._quote_asset += received_quote_asset + # Update the base asset + self._base_asset -= amount_to_sell + + # substract trading fee from quote asset based on the amount sold + self._quote_asset -= self._trading_fee * received_quote_asset + + # Add to trade history the amount sold if greater than 0 + if amount_to_sell > 0: + self.trade_history.append({'step': self._current_candle, 'type': 'SellLong', 'amount': amount_to_sell, 'price': current_price, 'total' : received_quote_asset, 'percent_amount': action[1]}) + + else: + # Hold + self.trade_history.append({'step': self._current_candle, 'type': 'Hold', 'amount': '0', 'price': current_price, 'total' : 0, 'percent_amount': action[1]}) + + + self.portfolio_history.append({'step': self._current_candle, 'base_asset': self._base_asset, 'quote_asset': self._quote_asset, 'current_price': current_price, 'net_worth' : self._net_worth}) + + # Update the current net worth + self._net_worth = self._base_asset * current_price + self._quote_asset + + + def step(self, action): + """ + Returns the next observation, reward, done and info. + """ + + self._take_action(action) + + # Calculate reward comparing the current net worth with the previous net worth + reward = self._net_worth - self._previous_net_worth + + self._total_reward_accumulated += reward + + # Update the previous net worth to be the current net worth after the reward has been applied + self._previous_net_worth = self._net_worth + + obs = self._get_observation() + # Update the info and add it to history data + info = dict ( + total_reward_accumulated = self._total_reward_accumulated, + net_worth = self._net_worth, + quote_asset = self._quote_asset, + base_asset = self._base_asset, + last_action_type = self.trade_history[-1]['type'] if len(self.trade_history) > 0 else None, + last_action_amount = self.trade_history[-1]['amount'] if len(self.trade_history) > 0 else None, + current_step = self._current_candle, + current_action = action + ) + + self._current_candle += 1 + + # Update observation history + self._obs_env_history.append([self._net_worth, self._base_asset, self._quote_asset]) + + self._done = self._net_worth <= 0 or self._current_candle >= (len( + self.df_normal.loc[:, 'open'].values) - 30)# We assume that the last observation is not the last row of the dataframe, in order to avoid the case where there are no calculated indicators. + + if self._done: + print('I have finished the episode (',self._current_candle,'Candles )') + + return obs, reward, self._done, info + + + def _get_observation(self): + """ + Returns the current observation. + """ + data_frame = self.features[(self._current_candle - self.window_size):self._current_candle] + + obs_env_history = np.array(self._obs_env_history).astype(np.float32) + + #TODO We definetely need to scale the observation history in a better way, this might influence training results + # Doing it ad-hoc might change the scale of the min and max, thus changing the results + obs_env_history = preprocessing.minmax_scale(obs_env_history, (-0.9,0.9)) + + obs = np.hstack((data_frame, obs_env_history[(self._current_candle - self.window_size):self._current_candle])) + + return obs + + + def render(self, mode='human', **kwargs): + """ + Renders a plot with trades made by the agent. + """ + + if mode == 'human': + print(f'Accumulated Reward: {self._total_reward_accumulated} ---- Current Net Worth: {self._net_worth}') + print(f'Current Quote asset: {self._quote_asset} ---- Current Base asset: {self._base_asset}') + print(f'Number of trades: {len(self.trade_history)}') + + if(len(self.trade_history) > 0): + print(f'Last Action: {self.trade_history[-1]["type"]} {self.trade_history[-1]["amount"]} assets ({self.trade_history[-1]["percent_amount"]} %) at price {self.trade_history[-1]["price"]}, total: {self.trade_history[-1]["total"]}') + print(f'--------------------------------------------------------------------------------------') + elif mode == 'live': + pass + # if self.visualization == None: + # self.visualization = LiveTradingGraph(self.df_normal, kwargs.get('title', None)) + + # if self._current_candle > OBSERVATION_WINDOW_SIZE: + # self.visualization.render(self._current_candle, self._net_worth, self.trade_history, window_size=OBSERVATION_WINDOW_SIZE) + + elif mode == 'portfolio': + return self.positions, self.trade_history, self.portfolio_history, self.df_normal + + def close(self): + if self.visualization != None: + self.visualization.close() + self.visualization = None + + + def _process_data(self, df_scaled): + """ + Processes the dataframe into features. + """ + + prices = self.df_scaled.loc[:, 'close'].to_numpy(dtype=np.float32) + + data_frame = df_scaled.iloc[:, 1:] # drop first column which is date TODO: Should be probably fixed outside of this class + # Convert df to numpy array + return prices, data_frame.to_numpy(dtype=np.float32) + + def _initial_obs_data(self): + for i in range(self.window_size - len(self._obs_env_history)): + self._obs_env_history.append([self._net_worth, self._base_asset, self._quote_asset]) + +# Initialize Ray +if ray.is_initialized(): + ray.shutdown() # let's shutdown first any running instances of ray (don't confuse it with the cluster) +os.environ['RAY_record_ref_creation_sites'] = '1' # Needed for debugging when things go wrong +ray.init() + +try: + available_gpu_in_cluster = ray.available_resources()['GPU'] +except KeyError as e: + available_gpu_in_cluster = 0 + +available_cpu_in_cluster = ray.available_resources()['CPU'] if ray.available_resources()['CPU'] else 0 + +# In the first version we assume that we have only one node cluster, so the allocation logic is based on that +# So the resources are maximized for one ray tune trial at a time +def find_optimal_resource_allocation(available_cpu, available_gpu): + """ + Finds the optimal resource allocation for the agent based on the available resources in the cluster + """ + # If we have GPU available, we allocate it all for the training, while creating as much workers as CPU cores we have minus one for the driver which holds the trainer + if available_gpu > 0: + return { + 'num_workers': available_cpu - 1, + 'num_cpus_per_worker': 1, + 'num_envs_per_worker': 1, + 'num_gpus_per_worker': 0, + 'num_cpus_for_driver': 1, + 'num_gpus' : available_gpu + } + # If we don't have GPU available, we allocate enough CPU cores for stepping the env (workers) while having enough for training maintaing a ratio of around 3 workers with 1 CPU to 1 driver CPU + else: + # according to the benchmark, we should allocate more workers, each with 1 cpu, letting the rest for the driver + num_workers = int(math.floor((available_cpu * 75) / 100)) + num_cpu_for_driver = available_cpu - num_workers + return { + 'num_workers': num_workers, + 'num_cpus_per_worker': 1, # this should be enough for stepping an env at once + 'num_envs_per_worker': 1, # it doesn't seem to add any benefits to have more than one env per worker + 'num_gpus_per_worker': 0, # the inference is done pretty fast, so there is no need to use GPU, at least not when we run one trial at once + 'num_cpus_for_driver': num_cpu_for_driver, + 'num_gpus' : 0 + } + +parallel_config = find_optimal_resource_allocation(available_cpu_in_cluster, 0) # Currently we are going to disable GPU ussage due to it's poor performance on a single instance cluster + +training_config = { + "trading_fee": TRADING_FEE, + "df_normal": X_train, + "df_scaled": X_train_scaled, +} + +test_config = { + "trading_fee": TRADING_FEE, + "df_normal": X_test, + "df_scaled": X_test_scaled, +} + +eval_config = { + "trading_fee": TRADING_FEE, + "df_normal": X_valid, + "df_scaled": X_valid_scaled, +} + +if ENV_NAME == 'SimpleTrading': + training_env = SimpleTradingEnv(training_config) + test_env = SimpleTradingEnv(test_config) + eval_env = SimpleTradingEnv(eval_config) + + training_env_key = "SimpleTradingEnv-training-V01" + test_env_key = "SimpleTradingEnv-testing-V01" + eval_env_key = "SimpleTradingEnv-evaluating-V01" + +tune.register_env(training_env_key, lambda _: training_env) +tune.register_env(test_env_key, lambda _: test_env) +tune.register_env(eval_env_key, lambda _: eval_env) + + +# Create the ppo trainer configuration +ppo_trainer_config = { + "env": training_env_key, # Ray will automatically create multiple environments and vectorize them if needed + "horizon": len(X_train_scaled) - 30, + "log_level": "WARN", #or INFO + "framework": "tf", + #"eager_tracing": True, + "ignore_worker_failures": True, + "num_workers": parallel_config.get("num_workers"), # Number of workers is per trial run, so the more we put the less parallelism we have + "num_envs_per_worker": parallel_config.get("num_envs_per_worker"), # This influences also the length of the episode. the environment length will be split by the number of environments per worker + "num_gpus": parallel_config.get("num_gpus"), # Number of GPUs to use in training (0 means CPU only). After a few experiments, it seems that using GPU is not helping + "num_cpus_per_worker": parallel_config.get("num_cpus_per_worker"), # After some testing, seems the fastest way for this kind of enviroment. It's better to run more trials in parallel than to finish a trial with a couple of minutes faster. Because we can end trial earlier if we see that our model eventuall converge + "num_cpus_for_driver": parallel_config.get("num_cpus_for_driver"), # Number of CPUs to use for the driver. This is the number of CPUs used for the training process. + "num_gpus_per_worker": parallel_config.get("num_gpus_per_worker"), + "rollout_fragment_length": ROLLOUT_FRAGMENT_LENGTH, # Size of batches collected from each worker. If num_envs_per_worker is > 1 the rollout value will be multiplied by num_envs_per_worker + "train_batch_size": TRAIN_BATCH_SIZE, # Number of timesteps collected for each SGD round. This defines the size of each SGD epoch. the batch size is composed of fragments defined above + "sgd_minibatch_size": SGD_MINIBATCH_SIZE, + "batch_mode": BATCH_MODE, + "vf_clip_param": 100, # Default is 10, but we increase it to 100 to adapt it to our rewards scale. It helps our value function to converge faster + "lr": LEARNING_RATE, # Hyperparameter grid search defined above + "gamma": GAMMA, # This can have a big impact on the result and needs to be properly tuned + #"observation_filter": "MeanStdFilter", + "model": { + # "fcnet_hiddens": FC_SIZE, # Hyperparameter grid search defined above + # "use_lstm": True, + # "lstm_cell_size": 256, + # "lstm_use_prev_action_reward": True, + # "lstm_use_prev_action": True, + + }, + "evaluation_interval": 5, # Run one evaluation step on every x `Trainer.train()` call. + "evaluation_duration": 1, # How many episodes to run evaluations for each time we evaluate. + "evaluation_config": { + "explore": True, # We usually don't want to explore during evaluation. All actions have to be repeatable. Similar to deterministic = True, but on-policy algorithms can get better results with exploration. + "env": test_env_key, # We need to define a new environment for evaluation with different parameters + }, + "logger_config": { + "logdir": res_dir, + "type": "ray.tune.logger.UnifiedLogger", + } + } + + +# ### Custom reporter to get progress in Superalgos +class CustomReporter(ProgressReporter): + + def __init__( + self, + max_report_frequency: int = 10, # in seconds + location: str = "/tf/notebooks/", + ): + self._max_report_freqency = max_report_frequency + self._last_report_time = 0 + self._location = location + + def should_report(self, trials, done=False): + if time.time() - self._last_report_time > self._max_report_freqency: + self._last_report_time = time.time() + return True + return done + + def report(self, trials, *sys_info): + + trial_status_dict = {} + for trial in trials: + trial_status_dict['status'] = trial.status + trial_status_dict['name'] = trial.trial_id + trial_status_dict['episodeRewardMax'] = int(trial.last_result['episode_reward_max']) if trial.last_result.get("episode_reward_max") else 0 + trial_status_dict['episodeRewardMean'] = int(trial.last_result['episode_reward_mean']) if trial.last_result.get("episode_reward_mean") else 0 + trial_status_dict['episodeRewardMin'] = int(trial.last_result['episode_reward_min']) if trial.last_result.get("episode_reward_min") else 0 + trial_status_dict['timestepsExecuted'] = int(trial.last_result['timesteps_total']) if trial.last_result.get("timesteps_total") else 0 + trial_status_dict['timestepsTotal'] = int(TIMESTEPS_TO_TRAIN) + + + sys.stdout.write(json.dumps(trial_status_dict)) + sys.stdout.write('\n') + + # Write the results to JSON file + with open(self._location + "training_results.json", "w+") as f: + json.dump(trial_status_dict, f) + f.close() + + def set_start_time(self, timestamp: Optional[float] = None): + if timestamp is not None: + self._start_time = time.time() + else: + self._start_time = timestamp + +# Printing a custom text to let Superalgos know that we are in a RL scenario +sys.stdout.write('RL_SCENARIO') +sys.stdout.write('\n') + +# Run ray tune +analysis = tune.run( + run_or_experiment=ALGORITHM, + name=EXPERIMENT_NAME, + metric='episode_reward_mean', + mode='max', + stop={ + # An iteration is equal with one SGD round which in our case is equal to train_batch_size. If after X iterations we still don't have a good result, we stop the trial + "timesteps_total": TIMESTEPS_TO_TRAIN + }, + config=ppo_trainer_config, + num_samples=1, # Have one sample for each hyperparameter combination. You can have more to average out randomness. + keep_checkpoints_num=30, # Keep the last X checkpoints + checkpoint_freq=5, # Checkpoint every X iterations (save the model) + checkpoint_at_end=True, # Whether to checkpoint at the end of the experiment regardless of the checkpoint_freq + verbose=1, + local_dir=res_dir, # Local directory to store checkpoints and results, we are using tmp folder until we move the notebook to a docker instance and we can use the same directory across all instances, no matter the underlying OS + progress_reporter=CustomReporter(max_report_frequency=10,location=location), + fail_fast=True, + resume="AUTO" # Resume training from the last checkpoint if any exists [True, 'LOCAL', 'REMOTE', 'PROMPT', 'ERRORED_ONLY', 'AUTO'] +) + +# Evaluate trained model restoring it from checkpoint +best_trial = analysis.get_best_trial(metric="episode_reward_mean", mode="max", scope="all") +best_checkpoint = analysis.get_best_checkpoint(best_trial, metric="episode_reward_mean") + +print("best_checkpoint path: " + best_checkpoint.local_path) + +agent = ppo.PPOTrainer(config=ppo_trainer_config) +agent.restore(best_checkpoint) + +json_dict = {} +episodes_to_run = 2 + +envs = [training_env, test_env, eval_env] + +positions = [] +trade_history = [] +portfolio_history = [] +df_normal = [] + +for iter, env in enumerate(envs): + net_worths = [] + q_assets = [] + b_assets = [] + net_worths_at_end = [] + q_assets_at_end = [] + b_assets_at_end = [] + last_actions = [] + + for i in range(episodes_to_run): + episode_reward = 0 + done = False + obs = env.reset() # we are using the evaluation environment for evaluation + last_info = None + while not done: + action = agent.compute_single_action(obs, explore=True) # stochastic evaluation + obs, reward, done, info = env.step(action) + net_worths.append(info['net_worth']) # Add all historical net worths to a list to print statistics at the end of the episode + q_assets.append(info['quote_asset']) # Add all historical quote assets to a list to print statistics at the end of the episode + b_assets.append(info['base_asset']) # Add all historical base assets to a list to print statistics at the end of the episode + episode_reward += reward + last_info = info + + net_worths_at_begin = net_worths[0] + net_worths_at_end.append(last_info['net_worth']) # Add all historical net worths to a list to print statistics at the end of the episode + q_assets_at_end.append(last_info['quote_asset']) # Add all historical quote assets to a list to print statistics at the end of the episode + b_assets_at_end.append(last_info['base_asset']) # Add all historical base assets to a list to print statistics at the end of the episode + last_actions.append(last_info['current_action']) + + r1, r2, r3, r4 = env.render(mode='portfolio') + positions.append(r1) + trade_history.append(r2) + portfolio_history.append(r3) + df_normal.append(r4) + + json_dict_env = {} + json_dict_env['meanNetWorth'] = np.mean(net_worths) + json_dict_env['stdNetWorth'] = np.std(net_worths) + json_dict_env['minNetWorth'] = np.min(net_worths) + json_dict_env['maxNetWorth'] = np.max(net_worths) + json_dict_env['stdQuoteAsset'] = np.std(q_assets) + json_dict_env['minQuoteAsset'] = np.min(q_assets) + json_dict_env['maxQuoteAsset'] = np.max(q_assets) + json_dict_env['stdBaseAsset'] = np.std(b_assets) + json_dict_env['minBaseAsset'] = np.min(b_assets) + json_dict_env['maxBaseAsset'] = np.max(b_assets) + json_dict_env['NetWorthAtBegin'] = net_worths_at_begin + json_dict_env['meanNetWorthAtEnd'] = np.mean(net_worths_at_end) + json_dict_env['stdNetWorthAtEnd'] = np.std(net_worths_at_end) + json_dict_env['minNetWorthAtEnd'] = np.min(net_worths_at_end) + json_dict_env['maxNetWorthAtEnd'] = np.max(net_worths_at_end) + json_dict_env['current_action'] = {"type": int(last_actions[-1][0]), "amount":int(last_actions[-1][1])} + + print(f"NetWorthAtBegin / meanNetWorthAtEnd : {json_dict_env['NetWorthAtBegin']} / {json_dict_env['meanNetWorthAtEnd']}") + json_dict[iter] = json_dict_env + + +# Write the results to JSON file to be picked up by Superalgos +with open(location + "evaluation_results.json", "w+") as f: + json.dump(json_dict, f) + f.close() + +pd_positions_0 = pd.DataFrame(positions[0]) +pd_positions_1 = pd.DataFrame(positions[1]) +pd_positions_2 = pd.DataFrame(positions[2]) + +pd_trade_history_0 = pd.DataFrame(trade_history[0]) +pd_trade_history_1 = pd.DataFrame(trade_history[1]) +pd_trade_history_2 = pd.DataFrame(trade_history[2]) + +pd_portfolio_history_0 = pd.DataFrame(portfolio_history[0]) +pd_portfolio_history_1 = pd.DataFrame(portfolio_history[1]) +pd_portfolio_history_2 = pd.DataFrame(portfolio_history[2]) + +pd_join_0 = pd.merge(pd_trade_history_0, pd_portfolio_history_0, how='right', left_on = 'step', right_on = 'step') +pd_join_1 = pd.merge(pd_trade_history_1, pd_portfolio_history_1, how='right', left_on = 'step', right_on = 'step') +pd_join_2 = pd.merge(pd_trade_history_2, pd_portfolio_history_2, how='right', left_on = 'step', right_on = 'step') +pd_join_2[:].tail(20) + +tic = "BTC train" +plt.figure(figsize=[15,9]); +plt.title(tic) +plt.plot(pd_join_0["step"],pd_join_0["net_worth"]/pd_join_0["net_worth"][0],label = "net_worth", color='black'); +plt.plot(pd_join_0["step"],pd_join_0["current_price"]/pd_join_0["current_price"][0],label = "current_price", color='yellow'); +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'BuyLong']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'BuyLong']["price"]/pd_join_0["current_price"][0]*0.9, label='BuyLong', marker='^', color='lightgreen', alpha=1) +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'SellLong']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'SellLong']["price"]/pd_join_0["current_price"][0]*1.1, label='SellLong', marker='v', color='magenta', alpha=1) +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'BuyShort']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'BuyShort']["price"]/pd_join_0["current_price"][0]*1.1, label='BuyShort', marker='*', color='red', alpha=1) +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'SellShort']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'SellShort']["price"]/pd_join_0["current_price"][0]*0.9, label='SellShort', marker='x', color='blue', alpha=1) +plt.xlabel('Steps') +plt.ylabel('Value normed to first step'); +plt.legend() +plt.savefig(res_dir+tic.replace(" ", "_")+".png") +plt.show() + + +tic = "BTC test" +plt.figure(figsize=[15,9]); +plt.title(tic) +plt.plot(pd_join_1["step"],pd_join_1["net_worth"]/pd_join_1["net_worth"][0],label = "net_worth", color='black'); +plt.plot(pd_join_1["step"],pd_join_1["current_price"]/pd_join_1["current_price"][0],label = "current_price", color='yellow'); +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'BuyLong']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'BuyLong']["price"]/pd_join_1["current_price"][0]*0.9, label='BuyLong', marker='^', color='lightgreen', alpha=1) +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'SellLong']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'SellLong']["price"]/pd_join_1["current_price"][0]*1.1, label='SellLong', marker='v', color='magenta', alpha=1) +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'BuyShort']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'BuyShort']["price"]/pd_join_1["current_price"][0]*1.1, label='BuyShort', marker='*', color='red', alpha=1) +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'SellShort']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'SellShort']["price"]/pd_join_1["current_price"][0]*0.9, label='SellShort', marker='x', color='blue', alpha=1) +plt.xlabel('Steps') +plt.ylabel('Value normed to first step'); +plt.legend() +plt.savefig(res_dir+tic.replace(" ", "_")+".png") +plt.show() + +tic = "BTC validate" +plt.figure(figsize=[15,9]); +plt.title(tic) +plt.plot(pd_join_2["step"],pd_join_2["net_worth"]/pd_join_2["net_worth"][0],label = "net_worth", color='black'); +plt.plot(pd_join_2["step"],pd_join_2["current_price"]/pd_join_2["current_price"][0],label = "current_price", color='yellow'); +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'BuyLong']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'BuyLong']["price"]/pd_join_2["current_price"][0]*0.9, label='BuyLong', marker='^', color='lightgreen', alpha=1) +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'SellLong']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'SellLong']["price"]/pd_join_2["current_price"][0]*1.1, label='SellLong', marker='v', color='magenta', alpha=1) +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'BuyShort']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'BuyShort']["price"]/pd_join_2["current_price"][0]*1.1, label='BuyShort', marker='*', color='red', alpha=1) +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'SellShort']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'SellShort']["price"]/pd_join_2["current_price"][0]*0.9, label='SellShort', marker='x', color='blue', alpha=1) +plt.xlabel('Steps') +plt.ylabel('Value normed to first step'); +plt.legend() +plt.savefig(res_dir+tic.replace(" ", "_")+".png") +plt.show() + +# Cleanup +if ray.is_initialized(): + ray.shutdown() + +# Tell Superalgos we finished +sys.stdout.write('RL_SCENARIO_END') +sys.stdout.write('\n') \ No newline at end of file diff --git a/Bitcoin-Factory/ReadMeReinforcementLearning.md b/Bitcoin-Factory/ReadMeReinforcementLearning.md new file mode 100644 index 0000000000..e2728e013e --- /dev/null +++ b/Bitcoin-Factory/ReadMeReinforcementLearning.md @@ -0,0 +1,16 @@ +# Reinforcement Learning +## 💫 Introduction +[Reinforcement Learning](https://en.wikipedia.org/wiki/Reinforcement_learning) is a term used to describe a special machine learning process. The typical framing of a Reinforcement Learning (RL) scenario: An agent takes actions in an environment, which is interpreted into a reward and a representation of the state, which are fed back into the agent. + +![Learning framework](https://upload.wikimedia.org/wikipedia/commons/1/1b/Reinforcement_learning_diagram.svg "RL Framework") + +In our usage case, the environment is a stock trading one and the possible actions are buy,sell or hold. The reward will be our gain or loss. Based on this reward the agent will learn how to trade better. The process of learning is done with a so called [Proximal Policy Optimization (PPO)](https://en.wikipedia.org/wiki/Proximal_Policy_Optimization). + +## 🤝 Support + +Contributions, issues, and feature requests are welcome! + +Give a ⭐️ if you like this project or even better become a part of the Superalgo community! + +[nodeJS](https://raw.githubusercontent.com/get-icon/geticon/master/icons/nodejs-icon.svg "nodeJS") +[tensorflow](https://github.com/get-icon/geticon/blob/master/icons/tensorflow.svg "tensorflow") \ No newline at end of file diff --git a/Bitcoin-Factory/Test-Client/notebooks/Bitcoin_Factory_RL.py b/Bitcoin-Factory/Test-Client/notebooks/Bitcoin_Factory_RL.py index dd0f860e29..330fa6b634 100644 --- a/Bitcoin-Factory/Test-Client/notebooks/Bitcoin_Factory_RL.py +++ b/Bitcoin-Factory/Test-Client/notebooks/Bitcoin_Factory_RL.py @@ -1,17 +1,12 @@ #!/usr/bin/env python # coding: utf-8 -# ## Import needed deps - -# In[15]: - - import random import gym from gym import spaces -from sklearn import preprocessing import pandas as pd import numpy as np +import matplotlib import matplotlib.pyplot as plt import time import ray @@ -19,77 +14,126 @@ import sys import math import json +from typing import Dict, List, Optional, Union from ray import tune from ray.rllib.agents import ppo from ray.tune import CLIReporter +from ray.tune import ProgressReporter +from ray.tune.registry import register_env +from ray.rllib.env.vector_env import VectorEnv #unused from sklearn.model_selection import train_test_split +from sklearn import preprocessing from sklearn.preprocessing import MinMaxScaler from tabulate import tabulate - -# ## Run tensorboard for data visualisation - -# In[16]: - - -# %load_ext tensorboard -# %tensorboard --logdir "/tf/notebooks/ray_results/" --host 0.0.0.0 - - -# ### Set of parameters received from Test Server - -# In[17]: - - -parameters = pd.read_csv( - '/tf/notebooks/parameters.csv', - sep=' ', -) - - -parameters - - -# In[18]: - - -EXPERIMENT_NAME = "Trading_Signal_Predictor_RL_V01" -PERCENTAGE_OF_DATASET_FOR_TRAINING = 80 -TIMESTEPS_TO_TRAIN = parameters['TIMESTEPS_TO_TRAIN'][0] -OBSERVATION_WINDOW_SIZE = parameters['OBSERVATION_WINDOW_SIZE'][0] -INITIAL_QUOTE_ASSET = parameters['INITIAL_QUOTE_ASSET'][0] -INITIAL_BASE_ASSET = parameters['INITIAL_BASE_ASSET'][0] -TRADING_FEE = parameters['TRADING_FEE'][0] -ENV_VERSION = parameters['ENV_VERSION'][0] -ENV_NAME = parameters['ENV_NAME'][0] -EXPLORE_ON_EVAL = parameters['EXPLORE_ON_EVAL'][0] - -# Hyper-parameters, in case we want to really control them from the test server not from ray -ALGORITHM = parameters['ALGORITHM'][0] -ROLLOUT_FRAGMENT_LENGTH = parameters['ROLLOUT_FRAGMENT_LENGTH'][0] -TRAIN_BATCH_SIZE = parameters['TRAIN_BATCH_SIZE'][0] -SGD_MINIBATCH_SIZE = parameters['SGD_MINIBATCH_SIZE'][0] -BATCH_MODE = parameters['BATCH_MODE'][0] -#VF_CLIP_PARAM = parameters['VF_CLIP_PARAM'][0] -FC_SIZE = [parameters['FC_SIZE'][0]] -LEARNING_RATE = parameters['LEARNING_RATE'][0] -GAMMA = parameters['GAMMA'][0] - - -# In[19]: - - -df = pd.read_csv( - '/tf/notebooks/time-series.csv', - header=0, - index_col=None, - sep=' ', - skipinitialspace=True -) - - -# In[20]: - +location: str = "/tf/notebooks/" +instructions_file: str = "instructions.csv" +run_forcast: bool = False +res_dir: str = location + "/ray_results/" + + +if os.path.isfile(location+instructions_file): #Forecaster + run_forecast = True + + # Load the Instructions Dataset + instructions_dataset = pd.read_csv( + '/tf/notebooks/instructions.csv', + header=0, + sep=' ', + skipinitialspace=True + ) + + # what are we going to do in the current run? + ACTION_TO_TAKE = instructions_dataset.values[0][1] + + # name of the model file to load or save. + MODEL_FILE_NAME = instructions_dataset.values[1][1] + + FILENAME_parameters_dataset = instructions_dataset.values[2][1] + FILENAME_timeseries_dataset = instructions_dataset.values[3][1] + + res_dir = location + "/models/" + MODEL_FILE_NAME + "/" + + parameters = pd.read_csv( + '/tf/notebooks/'+FILENAME_parameters_dataset, + header=0, + sep=' ', + skipinitialspace=True + ) + df = pd.read_csv( + location+FILENAME_timeseries_dataset, + header=0, + index_col=None, + sep=' ', + skipinitialspace=True + ) + +else: #Testclient + parameters = pd.read_csv( + location+'parameters.csv', + sep=' ', + skipinitialspace=True, + ) + df = pd.read_csv( + location+'time-series.csv', + header=0, + index_col=None, + sep=' ', + skipinitialspace=True + ) + +if {'TIMESTEPS_TO_TRAIN'}.issubset(parameters.columns): + EXPERIMENT_NAME = "Trading_Signal_Predictor_RL_V01" + PERCENTAGE_OF_DATASET_FOR_TRAINING = 80 + TIMESTEPS_TO_TRAIN = parameters['TIMESTEPS_TO_TRAIN'][0] + OBSERVATION_WINDOW_SIZE = parameters['OBSERVATION_WINDOW_SIZE'][0] + INITIAL_QUOTE_ASSET = parameters['INITIAL_QUOTE_ASSET'][0] + INITIAL_BASE_ASSET = parameters['INITIAL_BASE_ASSET'][0] + TRADING_FEE = parameters['TRADING_FEE'][0] + ENV_VERSION = parameters['ENV_VERSION'][0] + ENV_NAME = parameters['ENV_NAME'][0] + EXPLORE_ON_EVAL = parameters['EXPLORE_ON_EVAL'][0] + + # Hyper-parameters, in case we want to really control them from the test server not from ray + ALGORITHM = parameters['ALGORITHM'][0] + ROLLOUT_FRAGMENT_LENGTH = parameters['ROLLOUT_FRAGMENT_LENGTH'][0] + TRAIN_BATCH_SIZE = parameters['TRAIN_BATCH_SIZE'][0] + SGD_MINIBATCH_SIZE = parameters['SGD_MINIBATCH_SIZE'][0] + BATCH_MODE = parameters['BATCH_MODE'][0] + #VF_CLIP_PARAM = parameters['VF_CLIP_PARAM'][0] + FC_SIZE = [parameters['FC_SIZE'][0]] + LEARNING_RATE = parameters['LEARNING_RATE'][0] + GAMMA = parameters['GAMMA'][0] + +else: + EXPERIMENT_NAME = "Trading_Signal_Predictor_RL_V01" + PERCENTAGE_OF_DATASET_FOR_TRAINING = 80 + TIMESTEPS_TO_TRAIN = int(parameters.values[2][4]) + OBSERVATION_WINDOW_SIZE = int(parameters.values[2][5]) + INITIAL_QUOTE_ASSET = int(parameters.values[2][6]) + INITIAL_BASE_ASSET = int(parameters.values[2][7]) + TRADING_FEE = float(parameters.values[2][8]) + ENV_NAME = str(parameters.values[2][9]) + ENV_VERSION = int(parameters.values[2][10]) + EXPLORE_ON_EVAL = str(parameters.values[2][12]) + + # Hyper-parameters, in case we want to really control them from the test server not from ray + ALGORITHM = str(parameters.values[2][13]) + ROLLOUT_FRAGMENT_LENGTH = int(parameters.values[2][14]) + TRAIN_BATCH_SIZE = int(parameters.values[2][15]) + SGD_MINIBATCH_SIZE = int(parameters.values[2][16]) + BATCH_MODE = str(parameters.values[2][17]) + #VF_CLIP_PARAM = parameters['VF_CLIP_PARAM'][0] + FC_SIZE = int(parameters.values[2][18]) + LEARNING_RATE = float(parameters.values[2][19]) + GAMMA = float(parameters.values[2][20]) + + +print(f'TIMESTEPS_TO_TRAIN: {TIMESTEPS_TO_TRAIN}\n') +print(f'OBSERVATION_WINDOW_SIZE: {OBSERVATION_WINDOW_SIZE}\n') +print(f'INITIAL_QUOTE_ASSET: {INITIAL_QUOTE_ASSET}\n') +print(f'INITIAL_BASE_ASSET: {INITIAL_BASE_ASSET}\n') +print(f'TRADING_FEE: {TRADING_FEE}\n') def prepare_data(df): # renaming column labels as we wish, regardless what test server sends, hopefully he will maintain position @@ -108,37 +152,20 @@ def prepare_data(df): return df - data = prepare_data(df) -data - - -# # Setup which data to use for training and which data to use for evaluation of RL Model - -# In[21]: - +# Setup which data to use for training and which data to use for evaluation of RL Model def split_data(data): - X_train_test, X_valid = train_test_split(data, train_size=0.67, test_size=0.33, shuffle=False) - + X_train_test, X_valid = train_test_split(data, train_size=0.67, test_size=0.33, shuffle=False) X_train, X_test = train_test_split(X_train_test, train_size=0.50, test_size=0.50, shuffle=False) - return X_train, X_test, X_valid - -# In[22]: - - X_train, X_test, X_valid = split_data(data) -# ## Normalize the dataset subsets to make the model converge faster - -# In[23]: - - +# Normalize the dataset subsets to make the model converge faster scaler_type = MinMaxScaler def get_feature_scalers(X, scaler_type=scaler_type): @@ -151,7 +178,7 @@ def get_scaler_transforms(X, scalers): X_scaled = [] for name, scaler in zip(list(X.columns[X.columns != 'date']), scalers): X_scaled.append(scaler.transform(X[name].values.reshape(-1, 1))) - X_scaled = pd.concat([pd.DataFrame(column, columns=[name]) for name, column in zip(list(X.columns[X.columns != 'date']), X_scaled)], axis='columns') + X_scaled = pd.concat([pd.DataFrame(column, columns=[name]) for name, column in zip(list(X.columns[X.columns != 'date']), X_scaled)], axis='columns') return X_scaled def scale_numpy_array(np_arr, scaler_type = scaler_type): @@ -203,21 +230,9 @@ def normalize_data(X_train, X_test, X_valid): train_test_scalers, train_test_valid_scalers, X_train_scaled, X_test_scaled, X_valid_scaled, X_valid_scaled_leaking = normalize_data(X_train, X_test, X_valid) - -# In[24]: - - -X_train_scaled.tail() - - -# # Defining the environment - -# In[25]: - - class SimpleTradingEnv(gym.Env): - metadata = {'render.modes': ['live', 'human', 'none']} + metadata = {'render.modes': ['live', 'human', 'portfolio', 'none']} visualization = None def __init__(self, config=None): @@ -259,7 +274,9 @@ def __init__(self, config=None): # Render and analysis data self._total_reward_accumulated = None + self.portfolio_history = None self.trade_history = None + self.positions = None self._first_rendering = None @@ -272,7 +289,9 @@ def reset(self): self._previous_net_worth = INITIAL_QUOTE_ASSET # at the begining our previous net worth is the initial quote asset self._total_reward_accumulated = 0. self._first_rendering = True + self.portfolio_history = [] self.trade_history = [] + self.positions = [] self._obs_env_history = [] self._initial_obs_data() @@ -303,7 +322,7 @@ def _take_action(self, action): # Add to trade history the amount bought if greater than 0 if assets_bought > 0: - self.trade_history.append({'step': self._current_candle, 'type': 'Buy', 'amount': assets_bought, 'price': current_price, 'total' : assets_bought * current_price, 'percent_amount': action[1]}) + self.trade_history.append({'step': self._current_candle, 'type': 'BuyLong', 'amount': assets_bought, 'price': current_price, 'total' : assets_bought * current_price, 'percent_amount': action[1]}) elif action_type == 1: # Sell @@ -321,13 +340,15 @@ def _take_action(self, action): # Add to trade history the amount sold if greater than 0 if amount_to_sell > 0: - self.trade_history.append({'step': self._current_candle, 'type': 'Sell', 'amount': amount_to_sell, 'price': current_price, 'total' : received_quote_asset, 'percent_amount': action[1]}) + self.trade_history.append({'step': self._current_candle, 'type': 'SellLong', 'amount': amount_to_sell, 'price': current_price, 'total' : received_quote_asset, 'percent_amount': action[1]}) else: # Hold self.trade_history.append({'step': self._current_candle, 'type': 'Hold', 'amount': '0', 'price': current_price, 'total' : 0, 'percent_amount': action[1]}) + self.portfolio_history.append({'step': self._current_candle, 'base_asset': self._base_asset, 'quote_asset': self._quote_asset, 'current_price': current_price, 'net_worth' : self._net_worth}) + # Update the current net worth self._net_worth = self._base_asset * current_price + self._quote_asset @@ -352,9 +373,12 @@ def step(self, action): info = dict ( total_reward_accumulated = self._total_reward_accumulated, net_worth = self._net_worth, + quote_asset = self._quote_asset, + base_asset = self._base_asset, last_action_type = self.trade_history[-1]['type'] if len(self.trade_history) > 0 else None, last_action_amount = self.trade_history[-1]['amount'] if len(self.trade_history) > 0 else None, - current_step = self._current_candle + current_step = self._current_candle, + current_action = action ) self._current_candle += 1 @@ -366,7 +390,7 @@ def step(self, action): self.df_normal.loc[:, 'open'].values) - 30)# We assume that the last observation is not the last row of the dataframe, in order to avoid the case where there are no calculated indicators. if self._done: - print('I have finished the episode') + print('I have finished the episode (',self._current_candle,'Candles )') return obs, reward, self._done, info @@ -408,249 +432,9 @@ def render(self, mode='human', **kwargs): # if self._current_candle > OBSERVATION_WINDOW_SIZE: # self.visualization.render(self._current_candle, self._net_worth, self.trade_history, window_size=OBSERVATION_WINDOW_SIZE) - - def close(self): - if self.visualization != None: - self.visualization.close() - self.visualization = None - - - def _process_data(self, df_scaled): - """ - Processes the dataframe into features. - """ - - prices = self.df_scaled.loc[:, 'close'].to_numpy(dtype=np.float32) - - data_frame = df_scaled.iloc[:, 1:] # drop first column which is date TODO: Should be probably fixed outside of this class - # Convert df to numpy array - return prices, data_frame.to_numpy(dtype=np.float32) - - def _initial_obs_data(self): - for i in range(self.window_size - len(self._obs_env_history)): - self._obs_env_history.append([self._net_worth, self._base_asset, self._quote_asset]) - - -# In[26]: - - -import random -import gym -from gym import spaces -from sklearn import preprocessing -import pandas as pd -import numpy as np -import matplotlib.pyplot as plt - -# infinite number in python -MAX_NET_WORTH = 2147483647 -MAX_NUM_QUOTE_OR_BASE_ASSET = 2147483647 - -INITIAL_QUOTE_ASSET = 0 -INITIAL_BASE_ASSET = 1 -OBSERVATION_WINDOW_SIZE = 24 # Probably we should put it as param ? - -class BTCAccumulationEnv(gym.Env): - - metadata = {'render.modes': ['live', 'human', 'none']} - visualization = None - - def __init__(self, config=None): - - self.df_scaled = config.get("df_scaled").reset_index(drop=True) - self.df_normal = config.get("df_normal").reset_index(drop=True) - self.window_size = OBSERVATION_WINDOW_SIZE - self.prices, self.features = self._process_data(self.df_scaled) - # The shape of the observation is (window_size * features + environment_features) the environment_features are: quote_asset, base_asset, net_worth. The entire observation is flattened in a 1D np array. - # NOT USED ANYMORE, KEPT FOR REFERENCE - # self.obs_shape = ((OBSERVATION_WINDOW_SIZE * self.features.shape[1] + 3),) - - # The shape of the observation is number of candles to look back, and the number of features (candle_features) + 3 (quote_asset, base_asset, net_worth) - self.obs_shape = (OBSERVATION_WINDOW_SIZE, self.features.shape[1] + 3) - - # Action space - #self.action_space = spaces.Box(low=np.array([0, 0]), high=np.array([3.0, 1.0]), dtype=np.float32) - self.action_space = spaces.MultiDiscrete([3, 100]) - # Observation space - self.observation_space = spaces.Box(low=-1, high=1, shape=self.obs_shape, dtype=np.float32) - - # Initialize the episode environment - - self._start_candle = OBSERVATION_WINDOW_SIZE # We assume that the first observation is not the first row of the dataframe, in order to avoid the case where there are no calculated indicators. - self._end_candle = len(self.features) - 1 - self._trading_fee = config.get("trading_fee") - - self._quote_asset = None - self._base_asset = None - self._done = None - self._current_candle = None - self._net_worth = None - self._previous_net_worth = None - self._previous_base_asset = None - self._previous_quote_asset = None - - # Array that will contain observation history needed for appending it to the observation space - # It will contain observations consisting of the net_worth, base_asset and quote_asset as list of floats - # Other features (OHLC + Indicators) will be appended to the current observation in the _get_observation method that takes the data directly from the available dataframe - self._obs_env_history = None - - # Render and analysis data - self._total_reward_accumulated = None - self.trade_history = None - self._first_rendering = None - - - def reset(self): - self._done = False - self._current_candle = self._start_candle - self._quote_asset = INITIAL_QUOTE_ASSET - self._base_asset = INITIAL_BASE_ASSET - self._net_worth = INITIAL_QUOTE_ASSET # at the begining our net worth is the initial quote asset - self._previous_net_worth = INITIAL_QUOTE_ASSET # at the begining our previous net worth is the initial quote asset - self._previous_base_asset = INITIAL_BASE_ASSET - self._previous_quote_asset = INITIAL_QUOTE_ASSET - self._total_reward_accumulated = 0 - self._first_rendering = True - self.trade_history = [] - self._obs_env_history = [] - - self._initial_obs_data() - - return self._get_observation() - - def _take_action(self, action): - self._done = False - current_price = random.uniform( - self.df_normal.loc[self._current_candle, "low"], self.df_normal.loc[self._current_candle, "high"]) - - - action_type = action[0] - amount = action[1] / 100 - - if action_type == 0: # Buy - # Buy % assets - # Determine the maximum amount of quote asset that can be bought - available_amount_to_buy_with = self._quote_asset / current_price - # Buy only the amount that agent chose - assets_bought = available_amount_to_buy_with * amount - # Update the quote asset balance - self._quote_asset -= assets_bought * current_price - # Update the base asset - self._base_asset += assets_bought - # substract trading fee from base asset based on the amount bought - self._base_asset -= self._trading_fee * assets_bought - - # Add to trade history the amount bought if greater than 0 - if assets_bought > 0: - self.trade_history.append({'step': self._current_candle, 'type': 'Buy', 'amount': assets_bought, 'price': current_price, 'total' : assets_bought * current_price, 'percent_amount': action[1]}) - - - elif action_type == 1: # Sell - # Sell % assets - # Determine the amount of base asset that can be sold - amount_to_sell = self._base_asset * amount - received_quote_asset = amount_to_sell * current_price - # Update the quote asset - self._quote_asset += received_quote_asset - # Update the base asset - self._base_asset -= amount_to_sell - - # substract trading fee from quote asset based on the amount sold - self._quote_asset -= self._trading_fee * received_quote_asset - - # Add to trade history the amount sold if greater than 0 - if amount_to_sell > 0: - self.trade_history.append({'step': self._current_candle, 'type': 'Sell', 'amount': amount_to_sell, 'price': current_price, 'total' : received_quote_asset, 'percent_amount': action[1]}) - - else: - # Hold - self.trade_history.append({'step': self._current_candle, 'type': 'Hold', 'amount': '0', 'price': current_price, 'total' : 0, 'percent_amount': action[1]}) - - - # Update the current net worth - self._net_worth = self._base_asset * current_price + self._quote_asset - - - def step(self, action): - """ - Returns the next observation, reward, done and info. - """ - self._take_action(action) - - # Calculate reward comparing the current base asset with the previous base asset - reward = self._base_asset - self._previous_base_asset - - self._total_reward_accumulated += reward - - # Update the previous net worth to be the current net worth after the reward has been applied - self._previous_net_worth = self._net_worth - self._previous_base_asset = self._base_asset - self._previous_quote_asset = self._quote_asset - - obs = self._get_observation() - # Update the info and add it to history data - info = dict ( - total_reward_accumulated = self._total_reward_accumulated, - net_worth = self._net_worth, - last_action_type = self.trade_history[-1]['type'] if len(self.trade_history) > 0 else None, - last_action_amount = self.trade_history[-1]['amount'] if len(self.trade_history) > 0 else None, - quote_asset = self._quote_asset, - base_asset = self._base_asset, - current_step = self._current_candle - ) - - self._current_candle += 1 - - # Update observation history - self._obs_env_history.append([self._net_worth, self._base_asset, self._quote_asset]) - - self._done = self._net_worth <= 0 or self._current_candle >= (len( - self.df_normal.loc[:, 'open'].values) - 30)# We assume that the last observation is not the last row of the dataframe, in order to avoid the case where there are no calculated indicators. - - if self._done: - print('The episode has finished') - - return obs, reward, self._done, info - - - def _get_observation(self): - """ - Returns the current observation. - """ - data_frame = self.features[(self._current_candle - self.window_size):self._current_candle] - - obs_env_history = np.array(self._obs_env_history).astype(np.float32) - - #TODO We definetely need to scale the observation history in a better way, this might influence training results - # Doing it ad-hoc might change the scale of the min and max, thus changing the results - obs_env_history = preprocessing.minmax_scale(obs_env_history, (-0.9,0.9)) - - obs = np.hstack((data_frame, obs_env_history[(self._current_candle - self.window_size):self._current_candle])) - - return obs - - - def render(self, mode='human', **kwargs): - """ - Renders a plot with trades made by the agent. - """ - - if mode == 'human': - print(f'Accumulated Reward: {self._total_reward_accumulated} ---- Current Net Worth: {self._net_worth}') - print(f'Current Quote asset: {self._quote_asset} ---- Current Base asset: {self._base_asset}') - print(f'Number of trades: {len(self.trade_history)}') - - if(len(self.trade_history) > 0): - print(f'Last Action: {self.trade_history[-1]["type"]} {self.trade_history[-1]["amount"]} assets ({self.trade_history[-1]["percent_amount"]} %) at price {self.trade_history[-1]["price"]}, total: {self.trade_history[-1]["total"]}') - print(f'--------------------------------------------------------------------------------------') - elif mode == 'live': - pass - # if self.visualization == None: - # self.visualization = LiveTradingGraph(self.df_normal, kwargs.get('title', None)) - - # if self._current_candle > OBSERVATION_WINDOW_SIZE: - # self.visualization.render(self._current_candle, self._net_worth, self.trade_history, window_size=OBSERVATION_WINDOW_SIZE) + elif mode == 'portfolio': + return self.positions, self.trade_history, self.portfolio_history, self.df_normal def close(self): if self.visualization != None: @@ -673,12 +457,21 @@ def _initial_obs_data(self): for i in range(self.window_size - len(self._obs_env_history)): self._obs_env_history.append([self._net_worth, self._base_asset, self._quote_asset]) +# Initialize Ray +if ray.is_initialized(): + ray.shutdown() # let's shutdown first any running instances of ray (don't confuse it with the cluster) +os.environ['RAY_record_ref_creation_sites'] = '1' # Needed for debugging when things go wrong +ray.init() -# ### Allocate optimal resources method - -# In[27]: +try: + available_gpu_in_cluster = ray.available_resources()['GPU'] +except KeyError as e: + available_gpu_in_cluster = 0 +available_cpu_in_cluster = ray.available_resources()['CPU'] if ray.available_resources()['CPU'] else 0 +# In the first version we assume that we have only one node cluster, so the allocation logic is based on that +# So the resources are maximized for one ray tune trial at a time def find_optimal_resource_allocation(available_cpu, available_gpu): """ Finds the optimal resource allocation for the agent based on the available resources in the cluster @@ -707,70 +500,37 @@ def find_optimal_resource_allocation(available_cpu, available_gpu): 'num_gpus' : 0 } - -# ### Init ray and trainer config - -# In[28]: - - -import os -import time -import ray -import os -from ray import tune -from ray.rllib.env.vector_env import VectorEnv -from ray.tune.registry import register_env - - - -# Initialize Ray -ray.shutdown() # let's shutdown first any running instances of ray (don't confuse it with the cluster) -os.environ['RAY_record_ref_creation_sites'] = '1' # Needed for debugging when things go wrong -ray.init() - -try: - available_gpu_in_cluster = ray.available_resources()['GPU'] -except KeyError as e: - available_gpu_in_cluster = 0 - -available_cpu_in_cluster = ray.available_resources()['CPU'] if ray.available_resources()['CPU'] else 0 - -# In the first version we assume that we have only one node cluster, so the allocation logic is based on that -# So the resources are maximized for one ray tune trial at a time parallel_config = find_optimal_resource_allocation(available_cpu_in_cluster, 0) # Currently we are going to disable GPU ussage due to it's poor performance on a single instance cluster -trading_fee = 0.0075 training_config = { - "trading_fee": trading_fee, + "trading_fee": TRADING_FEE, "df_normal": X_train, "df_scaled": X_train_scaled, } -eval_config = { - "trading_fee": trading_fee, +test_config = { + "trading_fee": TRADING_FEE, "df_normal": X_test, "df_scaled": X_test_scaled, } +eval_config = { + "trading_fee": TRADING_FEE, + "df_normal": X_valid, + "df_scaled": X_valid_scaled, +} + if ENV_NAME == 'SimpleTrading': training_env = SimpleTradingEnv(training_config) + test_env = SimpleTradingEnv(test_config) eval_env = SimpleTradingEnv(eval_config) training_env_key = "SimpleTradingEnv-training-V01" + test_env_key = "SimpleTradingEnv-testing-V01" eval_env_key = "SimpleTradingEnv-evaluating-V01" -elif ENV_NAME == 'BTCAccumulationEnv': - training_env = BTCAccumulationEnv(training_config) - eval_env = BTCAccumulationEnv(eval_config) - - training_env_key = "BTCAccumulationEnv-training-V01" - eval_env_key = "BTCAccumulationEnv-evaluating-V01" - - - - - tune.register_env(training_env_key, lambda _: training_env) +tune.register_env(test_env_key, lambda _: test_env) tune.register_env(eval_env_key, lambda _: eval_env) @@ -778,7 +538,7 @@ def find_optimal_resource_allocation(available_cpu, available_gpu): ppo_trainer_config = { "env": training_env_key, # Ray will automatically create multiple environments and vectorize them if needed "horizon": len(X_train_scaled) - 30, - "log_level": "INFO", + "log_level": "WARN", #or INFO "framework": "tf", #"eager_tracing": True, "ignore_worker_failures": True, @@ -788,13 +548,13 @@ def find_optimal_resource_allocation(available_cpu, available_gpu): "num_cpus_per_worker": parallel_config.get("num_cpus_per_worker"), # After some testing, seems the fastest way for this kind of enviroment. It's better to run more trials in parallel than to finish a trial with a couple of minutes faster. Because we can end trial earlier if we see that our model eventuall converge "num_cpus_for_driver": parallel_config.get("num_cpus_for_driver"), # Number of CPUs to use for the driver. This is the number of CPUs used for the training process. "num_gpus_per_worker": parallel_config.get("num_gpus_per_worker"), - "rollout_fragment_length": 200, # Size of batches collected from each worker. If num_envs_per_worker is > 1 the rollout value will be multiplied by num_envs_per_worker - "train_batch_size": 2048, # Number of timesteps collected for each SGD round. This defines the size of each SGD epoch. the batch size is composed of fragments defined above - "sgd_minibatch_size": 64, - "batch_mode": "complete_episodes", + "rollout_fragment_length": ROLLOUT_FRAGMENT_LENGTH, # Size of batches collected from each worker. If num_envs_per_worker is > 1 the rollout value will be multiplied by num_envs_per_worker + "train_batch_size": TRAIN_BATCH_SIZE, # Number of timesteps collected for each SGD round. This defines the size of each SGD epoch. the batch size is composed of fragments defined above + "sgd_minibatch_size": SGD_MINIBATCH_SIZE, + "batch_mode": BATCH_MODE, "vf_clip_param": 100, # Default is 10, but we increase it to 100 to adapt it to our rewards scale. It helps our value function to converge faster - "lr": 0.00001, # Hyperparameter grid search defined above - "gamma": 0.95, # This can have a big impact on the result and needs to be properly tuned + "lr": LEARNING_RATE, # Hyperparameter grid search defined above + "gamma": GAMMA, # This can have a big impact on the result and needs to be properly tuned #"observation_filter": "MeanStdFilter", "model": { # "fcnet_hiddens": FC_SIZE, # Hyperparameter grid search defined above @@ -804,29 +564,20 @@ def find_optimal_resource_allocation(available_cpu, available_gpu): # "lstm_use_prev_action": True, }, - #"sgd_minibatch_size": MINIBATCH_SIZE, # Hyperparameter grid search defined above "evaluation_interval": 5, # Run one evaluation step on every x `Trainer.train()` call. "evaluation_duration": 1, # How many episodes to run evaluations for each time we evaluate. "evaluation_config": { "explore": True, # We usually don't want to explore during evaluation. All actions have to be repeatable. Similar to deterministic = True, but on-policy algorithms can get better results with exploration. - "env": eval_env_key, # We need to define a new environment for evaluation with different parameters + "env": test_env_key, # We need to define a new environment for evaluation with different parameters }, "logger_config": { - "logdir": "/tmp/ray_logging/", + "logdir": res_dir, "type": "ray.tune.logger.UnifiedLogger", } } # ### Custom reporter to get progress in Superalgos - -# In[36]: - - -from ray.tune import ProgressReporter -from typing import Dict, List, Optional, Union -import json - class CustomReporter(ProgressReporter): def __init__( @@ -871,22 +622,11 @@ def set_start_time(self, timestamp: Optional[float] = None): else: self._start_time = timestamp -custom_reporter = CustomReporter(max_report_frequency=10) - - -# In[ ]: - - -# Before starting printing a custom text to let Superalgos know that we are in a RL scenario +# Printing a custom text to let Superalgos know that we are in a RL scenario sys.stdout.write('RL_SCENARIO') sys.stdout.write('\n') - -# ### Run ray tune - -# In[32]: - - +# Run ray tune analysis = tune.run( run_or_experiment=ALGORITHM, name=EXPERIMENT_NAME, @@ -900,80 +640,162 @@ def set_start_time(self, timestamp: Optional[float] = None): num_samples=1, # Have one sample for each hyperparameter combination. You can have more to average out randomness. keep_checkpoints_num=30, # Keep the last X checkpoints checkpoint_freq=5, # Checkpoint every X iterations (save the model) - local_dir="/tf/notebooks/ray_results/", # Local directory to store checkpoints and results, we are using tmp folder until we move the notebook to a docker instance and we can use the same directory across all instances, no matter the underlying OS - progress_reporter=custom_reporter, - fail_fast="raise", - resume=False # Resume training from the last checkpoint if any exists + checkpoint_at_end=True, # Whether to checkpoint at the end of the experiment regardless of the checkpoint_freq + verbose=1, + local_dir=res_dir, # Local directory to store checkpoints and results, we are using tmp folder until we move the notebook to a docker instance and we can use the same directory across all instances, no matter the underlying OS + progress_reporter=CustomReporter(max_report_frequency=10,location=location), + fail_fast=True, + resume="AUTO" # Resume training from the last checkpoint if any exists [True, 'LOCAL', 'REMOTE', 'PROMPT', 'ERRORED_ONLY', 'AUTO'] ) - -# ### Evaluate trained model restoring it from checkpoint -# -# #### Store the results in a file to be picked up by Superalgos - -# In[33]: - - +# Evaluate trained model restoring it from checkpoint best_trial = analysis.get_best_trial(metric="episode_reward_mean", mode="max", scope="all") best_checkpoint = analysis.get_best_checkpoint(best_trial, metric="episode_reward_mean") +print("best_checkpoint path: " + best_checkpoint.local_path) agent = ppo.PPOTrainer(config=ppo_trainer_config) agent.restore(best_checkpoint) json_dict = {} -net_worths = [] -q_assets = [] -b_assets = [] -net_worths_at_end = [] -q_assets_at_end = [] -b_assets_at_end = [] -episodes_to_run = 1 - -for i in range(episodes_to_run): - episode_reward = 0 - done = False - obs = eval_env.reset() # we are using the evaluation environment for evaluation - last_info = None - while not done: - action = agent.compute_single_action(obs, explore=True) # stochastic evaluation - obs, reward, done, info = eval_env.step(action) - net_worths.append(info['net_worth']) # Add all historical net worths to a list to print statistics at the end of the episode - q_assets.append(info['quote_asset']) # Add all historical quote assets to a list to print statistics at the end of the episode - b_assets.append(info['base_asset']) # Add all historical base assets to a list to print statistics at the end of the episode - episode_reward += reward - last_info = info - - net_worths_at_end.append(last_info['net_worth']) # Add all historical net worths to a list to print statistics at the end of the episode - q_assets_at_end.append(last_info['quote_asset']) # Add all historical quote assets to a list to print statistics at the end of the episode - b_assets_at_end.append(last_info['base_asset']) # Add all historical base assets to a list to print statistics at the end of the episode - -json_dict['meanNetWorth'] = np.mean(net_worths) -json_dict['stdNetWorth'] = np.std(net_worths) -json_dict['minNetWorth'] = np.min(net_worths) -json_dict['maxNetWorth'] = np.max(net_worths) -json_dict['stdQuoteAsset'] = np.std(q_assets) -json_dict['minQuoteAsset'] = np.min(q_assets) -json_dict['maxQuoteAsset'] = np.max(q_assets) -json_dict['stdBaseAsset'] = np.std(b_assets) -json_dict['minBaseAsset'] = np.min(b_assets) -json_dict['maxBaseAsset'] = np.max(b_assets) -json_dict['meanNetWorthAtEnd'] = np.mean(net_worths_at_end) -json_dict['stdNetWorthAtEnd'] = np.std(net_worths_at_end) -json_dict['minNetWorthAtEnd'] = np.min(net_worths_at_end) -json_dict['maxNetWorthAtEnd'] = np.max(net_worths_at_end) - - -# Write the results to JSON file -with open("evaluation_results.json", "w+") as f: +episodes_to_run = 2 + +envs = [training_env, test_env, eval_env] + +positions = [] +trade_history = [] +portfolio_history = [] +df_normal = [] + +for iter, env in enumerate(envs): + net_worths = [] + q_assets = [] + b_assets = [] + net_worths_at_end = [] + q_assets_at_end = [] + b_assets_at_end = [] + last_actions = [] + + for i in range(episodes_to_run): + episode_reward = 0 + done = False + obs = env.reset() # we are using the evaluation environment for evaluation + last_info = None + while not done: + action = agent.compute_single_action(obs, explore=True) # stochastic evaluation + obs, reward, done, info = env.step(action) + net_worths.append(info['net_worth']) # Add all historical net worths to a list to print statistics at the end of the episode + q_assets.append(info['quote_asset']) # Add all historical quote assets to a list to print statistics at the end of the episode + b_assets.append(info['base_asset']) # Add all historical base assets to a list to print statistics at the end of the episode + episode_reward += reward + last_info = info + + net_worths_at_begin = net_worths[0] + net_worths_at_end.append(last_info['net_worth']) # Add all historical net worths to a list to print statistics at the end of the episode + q_assets_at_end.append(last_info['quote_asset']) # Add all historical quote assets to a list to print statistics at the end of the episode + b_assets_at_end.append(last_info['base_asset']) # Add all historical base assets to a list to print statistics at the end of the episode + last_actions.append(last_info['current_action']) + + r1, r2, r3, r4 = env.render(mode='portfolio') + positions.append(r1) + trade_history.append(r2) + portfolio_history.append(r3) + df_normal.append(r4) + + json_dict_env = {} + json_dict_env['meanNetWorth'] = np.mean(net_worths) + json_dict_env['stdNetWorth'] = np.std(net_worths) + json_dict_env['minNetWorth'] = np.min(net_worths) + json_dict_env['maxNetWorth'] = np.max(net_worths) + json_dict_env['stdQuoteAsset'] = np.std(q_assets) + json_dict_env['minQuoteAsset'] = np.min(q_assets) + json_dict_env['maxQuoteAsset'] = np.max(q_assets) + json_dict_env['stdBaseAsset'] = np.std(b_assets) + json_dict_env['minBaseAsset'] = np.min(b_assets) + json_dict_env['maxBaseAsset'] = np.max(b_assets) + json_dict_env['NetWorthAtBegin'] = net_worths_at_begin + json_dict_env['meanNetWorthAtEnd'] = np.mean(net_worths_at_end) + json_dict_env['stdNetWorthAtEnd'] = np.std(net_worths_at_end) + json_dict_env['minNetWorthAtEnd'] = np.min(net_worths_at_end) + json_dict_env['maxNetWorthAtEnd'] = np.max(net_worths_at_end) + json_dict_env['current_action'] = {"type": int(last_actions[-1][0]), "amount":int(last_actions[-1][1])} + + print(f"NetWorthAtBegin / meanNetWorthAtEnd : {json_dict_env['NetWorthAtBegin']} / {json_dict_env['meanNetWorthAtEnd']}") + json_dict[iter] = json_dict_env + + +# Write the results to JSON file to be picked up by Superalgos +with open(location + "evaluation_results.json", "w+") as f: json.dump(json_dict, f) - - -# In[35]: - + f.close() + +pd_positions_0 = pd.DataFrame(positions[0]) +pd_positions_1 = pd.DataFrame(positions[1]) +pd_positions_2 = pd.DataFrame(positions[2]) + +pd_trade_history_0 = pd.DataFrame(trade_history[0]) +pd_trade_history_1 = pd.DataFrame(trade_history[1]) +pd_trade_history_2 = pd.DataFrame(trade_history[2]) + +pd_portfolio_history_0 = pd.DataFrame(portfolio_history[0]) +pd_portfolio_history_1 = pd.DataFrame(portfolio_history[1]) +pd_portfolio_history_2 = pd.DataFrame(portfolio_history[2]) + +pd_join_0 = pd.merge(pd_trade_history_0, pd_portfolio_history_0, how='right', left_on = 'step', right_on = 'step') +pd_join_1 = pd.merge(pd_trade_history_1, pd_portfolio_history_1, how='right', left_on = 'step', right_on = 'step') +pd_join_2 = pd.merge(pd_trade_history_2, pd_portfolio_history_2, how='right', left_on = 'step', right_on = 'step') +pd_join_2[:].tail(20) + +tic = "BTC train" +plt.figure(figsize=[15,9]); +plt.title(tic) +plt.plot(pd_join_0["step"],pd_join_0["net_worth"]/pd_join_0["net_worth"][0],label = "net_worth", color='black'); +plt.plot(pd_join_0["step"],pd_join_0["current_price"]/pd_join_0["current_price"][0],label = "current_price", color='yellow'); +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'BuyLong']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'BuyLong']["price"]/pd_join_0["current_price"][0]*0.9, label='BuyLong', marker='^', color='lightgreen', alpha=1) +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'SellLong']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'SellLong']["price"]/pd_join_0["current_price"][0]*1.1, label='SellLong', marker='v', color='magenta', alpha=1) +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'BuyShort']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'BuyShort']["price"]/pd_join_0["current_price"][0]*1.1, label='BuyShort', marker='*', color='red', alpha=1) +plt.scatter(pd_trade_history_0[pd_trade_history_0['type'] == 'SellShort']["step"], pd_trade_history_0[pd_trade_history_0['type'] == 'SellShort']["price"]/pd_join_0["current_price"][0]*0.9, label='SellShort', marker='x', color='blue', alpha=1) +plt.xlabel('Steps') +plt.ylabel('Value normed to first step'); +plt.legend() +plt.savefig(res_dir+tic.replace(" ", "_")+".png") +plt.show() + + +tic = "BTC test" +plt.figure(figsize=[15,9]); +plt.title(tic) +plt.plot(pd_join_1["step"],pd_join_1["net_worth"]/pd_join_1["net_worth"][0],label = "net_worth", color='black'); +plt.plot(pd_join_1["step"],pd_join_1["current_price"]/pd_join_1["current_price"][0],label = "current_price", color='yellow'); +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'BuyLong']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'BuyLong']["price"]/pd_join_1["current_price"][0]*0.9, label='BuyLong', marker='^', color='lightgreen', alpha=1) +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'SellLong']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'SellLong']["price"]/pd_join_1["current_price"][0]*1.1, label='SellLong', marker='v', color='magenta', alpha=1) +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'BuyShort']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'BuyShort']["price"]/pd_join_1["current_price"][0]*1.1, label='BuyShort', marker='*', color='red', alpha=1) +plt.scatter(pd_trade_history_1[pd_trade_history_1['type'] == 'SellShort']["step"], pd_trade_history_1[pd_trade_history_1['type'] == 'SellShort']["price"]/pd_join_1["current_price"][0]*0.9, label='SellShort', marker='x', color='blue', alpha=1) +plt.xlabel('Steps') +plt.ylabel('Value normed to first step'); +plt.legend() +plt.savefig(res_dir+tic.replace(" ", "_")+".png") +plt.show() + +tic = "BTC validate" +plt.figure(figsize=[15,9]); +plt.title(tic) +plt.plot(pd_join_2["step"],pd_join_2["net_worth"]/pd_join_2["net_worth"][0],label = "net_worth", color='black'); +plt.plot(pd_join_2["step"],pd_join_2["current_price"]/pd_join_2["current_price"][0],label = "current_price", color='yellow'); +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'BuyLong']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'BuyLong']["price"]/pd_join_2["current_price"][0]*0.9, label='BuyLong', marker='^', color='lightgreen', alpha=1) +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'SellLong']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'SellLong']["price"]/pd_join_2["current_price"][0]*1.1, label='SellLong', marker='v', color='magenta', alpha=1) +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'BuyShort']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'BuyShort']["price"]/pd_join_2["current_price"][0]*1.1, label='BuyShort', marker='*', color='red', alpha=1) +plt.scatter(pd_trade_history_2[pd_trade_history_2['type'] == 'SellShort']["step"], pd_trade_history_2[pd_trade_history_2['type'] == 'SellShort']["price"]/pd_join_2["current_price"][0]*0.9, label='SellShort', marker='x', color='blue', alpha=1) +plt.xlabel('Steps') +plt.ylabel('Value normed to first step'); +plt.legend() +plt.savefig(res_dir+tic.replace(" ", "_")+".png") +plt.show() # Cleanup -os.remove('/tf/notebooks/training_results.json') -os.remove('/tf/notebooks/evaluation_results.json') -ray.shutdown() +if ray.is_initialized(): + ray.shutdown() +# Tell Superalgos we finished +sys.stdout.write('RL_SCENARIO_END') +sys.stdout.write('\n') \ No newline at end of file diff --git a/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js b/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js index a3106e51c5..3cc625a992 100644 --- a/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js +++ b/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js @@ -175,8 +175,6 @@ .catch(onError) async function onSuccess(thisForecastCase) { await onSuccessgetNextForecastCase(thisForecastCase) - forecasting = false - callBackFunction(TS.projects.foundations.globals.standardResponses.DEFAULT_OK_RESPONSE) } async function onError(err) { forecasting = false @@ -249,6 +247,9 @@ userProfile: response.data.serverData.userProfile, instance: response.data.serverData.instance } + } + if ((bestPredictions[i].testServer.userProfile == undefined) || (bestPredictions[i].testServer.userProfile === '')) { + bestPredictions[i].testServer.userProfile == response.data.serverData.userProfile } } console.log((new Date()).toISOString(), '[INFO] Size of local forecast array did change by ', checkSetForecastCaseResultsResponse(bestPredictions)) @@ -391,7 +392,7 @@ for (let i = 0; i < thisObject.forecastCasesArray.length; i++) { if (thisObject.forecastCasesArray[i].id == nextForecastCase.id) { console.log((new Date()).toISOString(), '[ERROR] Test Server ' + nextForecastCase.testServer.instance + ' did send me forecast case ' + nextForecastCase.id + ', which is allready in local database') - reject('DUPLICATE FORECAST CASE') + // reject('DUPLICATE FORECAST CASE') } } resolve(nextForecastCase) @@ -410,6 +411,9 @@ async function promiseWork(resolve, reject) { + //debug + console.log("DEBUG requested testserver: " + JSON.stringify(forecastCase.testServer)) + let message = { type: 'Get This Forecast Case', testServer: forecastCase.testServer, @@ -561,8 +565,10 @@ /* Set default script name. */ - if (nextForecastCase.pythonScriptName === undefined) { nextForecastCase.pythonScriptName = "Bitcoin_Factory_LSTM_Forecasting.py" } - + if (nextForecastCase.pythonScriptName === undefined) { + console.log("pythonScriptName undefined ... set default name") + nextForecastCase.pythonScriptName = "Bitcoin_Factory_LSTM_Forecasting.py" + } console.log('') if (buildnewModel) { console.log('------------------------------------------------------- Forecasting Case # ' + nextForecastCase.id + ' ------------------------------------------------------------') @@ -587,10 +593,6 @@ return new Promise(executeThePythonScript) async function executeThePythonScript(resolve, reject) { - /* - Set default script name. - */ - if (nextForecastCase.pythonScriptName === undefined) { nextForecastCase.pythonScriptName = "Bitcoin_Factory_LSTM_Forecasting.py" } let processExecutionResult let startingTimestamp = (new Date()).valueOf() @@ -601,27 +603,44 @@ dockerPID = dockerProc.pid dockerProc.stdout.on('data', (data) => { data = data.toString() - /* - Removing Carriedge Return from string. - */ - try { - let percentage = '' - let heartbeatText = '' - let statusText = 'Forecast Case ' + nextForecastCase.id + ' from ' + nextForecastCase.testServer.instance - if (data.substring(0, 5) === 'Epoch') { - let regEx = new RegExp('Epoch (\\d+)/(\\d+)', 'gim') - let match = regEx.exec(data) - heartbeatText = match[0] - - percentage = Math.round(match[1] / match[2] * 100) - TS.projects.foundations.functionLibraries.processFunctions.processHeartBeat(processIndex, heartbeatText, percentage, statusText) - } - } catch (err) { - console.log('Error pricessing heartbeat: ' + err) - } + if (data.includes('RL_SCENARIO_START') || data.includes('episodeRewardMean')) { + try { + let fileContent = SA.nodeModules.fs.readFileSync(global.env.PATH_TO_BITCOIN_FACTORY + "/Forecast-Client/notebooks/training_results.json") + + if (fileContent !== undefined) { + let percentage = 0 + let statusText = 'Forecast Case: ' + nextForecastCase.id + ' from ' + nextForecastCase.testServer.instance - for (let i = 0; i < 1000; i++) { - data = data.replace(/\n/, "") + data = JSON.parse(fileContent) + + percentage = Math.round(data.timestepsExecuted / data.timestepsTotal * 100) + let heartbeatText = 'Episode reward mean / max / min: ' + data.episodeRewardMean + ' | ' + data.episodeRewardMax + ' | ' + data.episodeRewardMin + + TS.projects.foundations.functionLibraries.processFunctions.processHeartBeat(processIndex, heartbeatText, percentage, statusText) + } + } catch (err) { } + } else { + /* + Removing Carriedge Return from string. + */ + try { + let percentage = '' + let heartbeatText = '' + let statusText = 'Forecast Case ' + nextForecastCase.id + ' from ' + nextForecastCase.testServer.instance + if (data.substring(0, 5) === 'Epoch') { + let regEx = new RegExp('Epoch (\\d+)/(\\d+)', 'gim') + let match = regEx.exec(data) + heartbeatText = match[0] + + percentage = Math.round(match[1] / match[2] * 100) + TS.projects.foundations.functionLibraries.processFunctions.processHeartBeat(processIndex, heartbeatText, percentage, statusText) + } + } catch (err) { + console.log('Error pricessing heartbeat: ' + err) + } + for (let i = 0; i < 1000; i++) { + data = data.replace(/\n/, "") + } } dataReceived = dataReceived + data.toString() @@ -644,7 +663,7 @@ console.log((new Date()).toISOString(), '[ERROR] Forecaster: Docker Python Script exited with code ' + code); console.log((new Date()).toISOString(), '[ERROR] Unexpected error trying to execute a Python script inside the Docker container. ') console.log((new Date()).toISOString(), '[ERROR] Check at a console if you can run this command: ') - console.log((new Date()).toISOString(), '[ERROR] docker exec -it Bitcoin-Factory-ML-Forecasting python /tf/notebooks/Bitcoin_Factory_LSTM_Forecasting.py') + console.log((new Date()).toISOString(), '[ERROR] docker exec -it Bitcoin-Factory-ML-Forecasting python -u /tf/notebooks/' + nextForecastCase.pythonScriptName) console.log((new Date()).toISOString(), '[ERROR] Once you can sucessfully run it at the console you might want to try to run this App again. ') reject('Unexpected Error.') } @@ -656,34 +675,59 @@ } function onFinished(dataReceived) { - try { - - let index = dataReceived.indexOf('{') - dataReceived = dataReceived.substring(index) - //just for debug: console.log(dataReceived) - processExecutionResult = JSON.parse(fixJSON(dataReceived)) - - console.log('Prediction RMSE Error: ' + processExecutionResult.errorRMSE) - console.log('Predictions [candle.max, candle.min, candle.close]: ' + processExecutionResult.predictions) - - let endingTimestamp = (new Date()).valueOf() - processExecutionResult.enlapsedTime = (endingTimestamp - startingTimestamp) / 1000 - console.log('Enlapsed Time (HH:MM:SS): ' + (new Date(processExecutionResult.enlapsedTime * 1000).toISOString().substr(14, 5)) + ' ') - - processExecutionResult.testServer = nextForecastCase.testServer - processExecutionResult.id = nextForecastCase.id - processExecutionResult.caseIndex = nextForecastCase.caseIndex + if (dataReceived.includes('RL_SCENARIO_END')) { //RL + let fileContent = SA.nodeModules.fs.readFileSync(global.env.PATH_TO_BITCOIN_FACTORY + "/Forecast-Client/notebooks/evaluation_results.json") + if (fileContent !== undefined) { + try { + processExecutionResult = JSON.parse(fileContent) + console.log(processExecutionResult) + let endingTimestamp = (new Date()).valueOf() + processExecutionResult.enlapsedTime = (endingTimestamp - startingTimestamp) / 1000 + processExecutionResult.pythonScriptName = nextForecastCase.pythonScriptName + processExecutionResult.testServer = nextForecastCase.testServer + processExecutionResult.id = nextForecastCase.id + processExecutionResult.caseIndex = nextForecastCase.caseIndex + console.log((new Date()).toISOString(), '[INFO] {Forecastclient} Enlapsed Time: ' + timeUnits(processExecutionResult.enlapsedTime * 1000) + ' ') + console.log((new Date()).toISOString(), '[INFO] {Forecastclient} Mean Networth at End of Train: ' + processExecutionResult["0"].meanNetWorthAtEnd) + console.log((new Date()).toISOString(), '[INFO] {Forecastclient} Mean Networth at End of Test: ' + processExecutionResult["1"].meanNetWorthAtEnd) + console.log((new Date()).toISOString(), '[INFO] {Forecastclient} Mean Networth at End of Validation: ' + processExecutionResult["2"].meanNetWorthAtEnd) + console.log((new Date()).toISOString(), '[INFO] {Forecastclient} Next Action: ' + processExecutionResult["2"].current_action.type + ' / ' + processExecutionResult["2"].current_action.amount) + + } catch (err) { + console.log('Error parsing the information generated at the Docker Container executing the Python script. err.stack = ' + err.stack) + console.log('The data that can not be parsed is = ' + fileContent) + } + } else { + console.log('Can not read result file: ' + global.env.PATH_TO_BITCOIN_FACTORY + "/Forecast-Client/notebooks/evaluation_results.json") + } + } else { //LSTM + try { + + let index = dataReceived.indexOf('{') + dataReceived = dataReceived.substring(index) + //just for debug: console.log(dataReceived) + processExecutionResult = JSON.parse(fixJSON(dataReceived)) + + console.log('Prediction RMSE Error: ' + processExecutionResult.errorRMSE) + console.log('Predictions [candle.max, candle.min, candle.close]: ' + processExecutionResult.predictions) + + let endingTimestamp = (new Date()).valueOf() + processExecutionResult.enlapsedTime = (endingTimestamp - startingTimestamp) / 1000 + console.log('Enlapsed Time (HH:MM:SS): ' + (new Date(processExecutionResult.enlapsedTime * 1000).toISOString().substr(14, 5)) + ' ') + + processExecutionResult.testServer = nextForecastCase.testServer + processExecutionResult.id = nextForecastCase.id + processExecutionResult.caseIndex = nextForecastCase.caseIndex - } catch (err) { + } catch (err) { - if (processExecutionResult !== undefined && processExecutionResult.predictions !== undefined) { - console.log('processExecutionResult.predictions:' + processExecutionResult.predictions) - } - - console.log(err.stack) - console.error(err) + if (processExecutionResult !== undefined && processExecutionResult.predictions !== undefined) { + console.log('processExecutionResult.predictions:' + processExecutionResult.predictions) + } + console.log(err.stack) + console.error(err) + } } - resolve(processExecutionResult) } } @@ -751,10 +795,10 @@ caseIndex: 0 } console.log() - console.log((new Date()).toISOString(), 'Current Forecast table') + console.log((new Date()).toISOString(), '[INFO] {Forecastclient} Current Forecast table') } else { console.log() - console.log((new Date()).toISOString(), 'A new Forecast for the Case Id ' + forecastCase.id + ' was produced / attemped.') + console.log((new Date()).toISOString(), '[INFO] {Forecastclient} A new Forecast for the Case Id ' + forecastCase.id + ' was produced / attemped.') } let logQueue = [] for (let i = Math.max(0, forecastCase.caseIndex - 5); i < Math.min(thisObject.forecastCasesArray.length, forecastCase.caseIndex + 5); i++) { @@ -988,4 +1032,35 @@ } return counter } + + /** + * Converts milliseconds into greater time units as possible + * @param {int} ms - Amount of time measured in milliseconds + * @return {?Object} Reallocated time units. NULL on failure. + */ + function timeUnits( ms ) { + if ( !Number.isInteger(ms) ) { + return null + } + /** + * Takes as many whole units from the time pool (ms) as possible + * @param {int} msUnit - Size of a single unit in milliseconds + * @return {int} Number of units taken from the time pool + */ + const allocate = msUnit => { + const units = Math.trunc(ms / msUnit) + ms -= units * msUnit + return units + } + // Property order is important here. + // These arguments are the respective units in ms. + return ""+ + // weeks: allocate(604800000), // Uncomment for weeks + // days: allocate(86400000), + allocate(3600000) + "h:" + + allocate(60000)+"m:" + + allocate(1000)+"s:" + //ms: ms // remainder + + } } diff --git a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Client/TestClient.js b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Client/TestClient.js index 058af03b85..808d0cf0a7 100644 --- a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Client/TestClient.js +++ b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Client/TestClient.js @@ -226,6 +226,7 @@ Set default script name. */ if (nextTestCase.pythonScriptName === undefined) { nextTestCase.pythonScriptName = "Bitcoin_Factory_LSTM.py" } + if (BOT_CONFIG.dockerContainerName === undefined) { BOT_CONFIG.dockerContainerName = "Bitcoin-Factory-ML" } /* Remove from Parameters the properties that are in OFF */ @@ -259,7 +260,7 @@ async function promiseWork(resolve, reject) { const { spawn } = require('child_process'); - const ls = spawn('docker', ['exec', 'Bitcoin-Factory-ML', 'python', '-u', '/tf/notebooks/' + nextTestCase.pythonScriptName]); + const ls = spawn('docker', ['exec', BOT_CONFIG.dockerContainerName, 'python', '-u', '/tf/notebooks/' + nextTestCase.pythonScriptName]); let dataReceived = '' ls.stdout.on('data', (data) => { data = data.toString() @@ -280,7 +281,7 @@ data = JSON.parse(fileContent) percentage = Math.round(data.timestepsExecuted / data.timestepsTotal * 100) - let heartbeatText = 'Episode reward mean: ' + data.episodeRewardMean + ' | Episode reward max: ' + data.episodeRewardMax + ' | Episode reward min: ' + data.episodeRewardMin + let heartbeatText = 'Episode reward mean / max / min: ' + data.episodeRewardMean + ' | ' + data.episodeRewardMax + ' | ' + data.episodeRewardMin TS.projects.foundations.functionLibraries.processFunctions.processHeartBeat(processIndex, heartbeatText, percentage, statusText) @@ -325,7 +326,7 @@ } else { console.log((new Date()).toISOString(), '[ERROR] Unexpected error trying to execute a Python script inside the Docker container. ') console.log((new Date()).toISOString(), '[ERROR] Check at a console if you can run this command: ') - console.log((new Date()).toISOString(), '[ERROR] docker exec -it Bitcoin-Factory-ML python /tf/notebooks/' + nextTestCase.pythonScriptName) + console.log((new Date()).toISOString(), '[ERROR] docker exec ' + BOT_CONFIG.dockerContainerName + ' python -u /tf/notebooks/' + nextTestCase.pythonScriptName) console.log((new Date()).toISOString(), '[ERROR] Once you can sucessfully run it at the console you might want to try to run this App again. ') reject('Unexpected Error.') } @@ -339,7 +340,29 @@ function onFinished(dataReceived) { try { if (dataReceived.includes('RL_SCENARIO_END')) { - //TODO: read from the evaluation_results.json file + let fileContent = SA.nodeModules.fs.readFileSync(global.env.PATH_TO_BITCOIN_FACTORY + "/Test-Client/notebooks/evaluation_results.json") + if (fileContent !== undefined) { + try { + processExecutionResult = JSON.parse(fileContent) + console.log(processExecutionResult) +/* example of fileContent: + {"meanNetWorth": 721.2464292834837, "stdNetWorth": 271.8523338823371, "minNetWorth": 248.60280285744497, "maxNetWorth": 1264.2342365877673, "stdQuoteAsset": 193.18343367092214, "minQuoteAsset": 4.0065377572671893e-10, "maxQuoteAsset": 1161.3969522280302, "stdBaseAsset": 0.005149471273320009, "minBaseAsset": 0.0, "maxBaseAsset": 0.0284320291802237, "meanNetWorthAtEnd": 260.82332674553476, "stdNetWorthAtEnd": 0.0, "minNetWorthAtEnd": 260.82332674553476, "maxNetWorthAtEnd": 260.82332674553476} +*/ + let endingTimestamp = (new Date()).valueOf() + processExecutionResult.enlapsedTime = (endingTimestamp - startingTimestamp) / 1000 + processExecutionResult.pythonScriptName = nextTestCase.pythonScriptName + console.log((new Date()).toISOString(), '[INFO] {Testclient} Enlapsed Time: ' + timeUnits(processExecutionResult.enlapsedTime * 1000) + ' ') + console.log((new Date()).toISOString(), '[INFO] {Testclient} Mean Networth at End of Train: ' + processExecutionResult["0"].meanNetWorthAtEnd) + console.log((new Date()).toISOString(), '[INFO] {Testclient} Mean Networth at End of Test: ' + processExecutionResult["1"].meanNetWorthAtEnd) + console.log((new Date()).toISOString(), '[INFO] {Testclient} Mean Networth at End of Validation: ' + processExecutionResult["2"].meanNetWorthAtEnd) + console.log((new Date()).toISOString(), '[INFO] {Testclient} Next Action: ' + processExecutionResult["2"].current_action.type + ' / ' + processExecutionResult["2"].current_action.amount) + } catch (err) { + console.log('Error parsing the information generated at the Docker Container executing the Python script. err.stack = ' + err.stack) + console.log('The data that can not be parsed is = ' + fileContent) + } + } else { + console.log('Can not read result file: ' + global.env.PATH_TO_BITCOIN_FACTORY + "/Test-Client/notebooks/evaluation_results.json") + } } else { try { let cleanedData = filterOutput(dataReceived) @@ -422,4 +445,36 @@ } return cleanText } + + /** + * Converts milliseconds into greater time units as possible + * @param {int} ms - Amount of time measured in milliseconds + * @return {?Object} Reallocated time units. NULL on failure. + */ + function timeUnits( ms ) { + if ( !Number.isInteger(ms) ) { + return null + } + /** + * Takes as many whole units from the time pool (ms) as possible + * @param {int} msUnit - Size of a single unit in milliseconds + * @return {int} Number of units taken from the time pool + */ + const allocate = msUnit => { + const units = Math.trunc(ms / msUnit) + ms -= units * msUnit + return units + } + // Property order is important here. + // These arguments are the respective units in ms. + return ""+ + // weeks: allocate(604800000), // Uncomment for weeks + // days: allocate(86400000), + allocate(3600000) + "h:" + + allocate(60000)+"m:" + + allocate(1000)+"s:" + //ms: ms // remainder + + } + } diff --git a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastCasesManager.js b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastCasesManager.js index daabcd757c..2f984b627e 100644 --- a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastCasesManager.js +++ b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastCasesManager.js @@ -64,32 +64,68 @@ exports.newForecastCasesManager = function newForecastCasesManager(processIndex, for (let i = 0; i < thisObject.forecastCasesArray.length; i++) { let forecastCase = thisObject.forecastCasesArray[i] if (forecastCase.mainAsset === testCase.mainAsset && forecastCase.mainTimeFrame === testCase.mainTimeFrame) { - if (Number(testCase.percentageErrorRMSE) < Number(forecastCase.percentageErrorRMSE) && Number(testCase.percentageErrorRMSE) >= 0) { - thisObject.forecastCasesArray.splice(i, 1) - thisObject.forecastCasesMap.delete(testCase.id) - addForcastCase(testCase) - return + //LSTM + if (forecastCase.percentageErrorRMSE !== undefined) { + if (Number(testCase.percentageErrorRMSE) < Number(forecastCase.percentageErrorRMSE) && Number(testCase.percentageErrorRMSE) >= 0) { + thisObject.forecastCasesArray.splice(i, 1) + thisObject.forecastCasesMap.delete(testCase.id) + addForcastCase(testCase) + // return + } else { + // continue + } + //RL + } else if (forecastCase.ratio !== undefined) { + if (Number(testCase.ratio.validate) > Number(forecastCase.ratio.validate) ) { + thisObject.forecastCasesArray.splice(i, 1) + thisObject.forecastCasesMap.delete(testCase.id) + addForcastCase(testCase) + // return + } else { + // continue + } } else { - return + // continue } + } else { + addForcastCase(testCase) + // return } } - addForcastCase(testCase) + if (thisObject.forecastCasesArray.length == 0) addForcastCase(testCase) saveForecastCasesFile() + console.log("Testserver: Current Forecast table:") + console.table(thisObject.forecastCasesArray) + function addForcastCase(testCase) { - if (testCase.forcastedCandle === undefined) { testCase.forcastedCandle = {} } + let testServer + let parameters + let predictions + let forcastedCandle + try { + testServer = JSON.parse(JSON.stringify(testCase.testServer)) + } catch (err) {} + try { + parameters = JSON.parse(JSON.stringify(testCase.parameters)) + } catch (err) {} + try { + predictions = JSON.parse(JSON.stringify(testCase.predictions)) + } catch (err) {} + try { + forcastedCandle = JSON.parse(JSON.stringify(testCase.forcastedCandle)) + } catch (err) {} let forecastCase = { id: testCase.id, caseIndex: thisObject.forecastCasesArray.length, - testServer: JSON.parse(JSON.stringify(testCase.testServer)), + testServer: testServer, mainAsset: testCase.mainAsset, mainTimeFrame: testCase.mainTimeFrame, percentageErrorRMSE: testCase.percentageErrorRMSE, - parameters: JSON.parse(JSON.stringify(testCase.parameters)), + parameters: parameters, parametersHash: testCase.parametersHash, - predictions: JSON.parse(JSON.stringify(testCase.predictions)), - forcastedCandle: JSON.parse(JSON.stringify(testCase.forcastedCandle)), + predictions: predictions, + forcastedCandle: forcastedCandle, timeSeriesFileName: testCase.timeSeriesFileName, timestamp: testCase.timestamp, when: testCase.when, @@ -150,6 +186,7 @@ exports.newForecastCasesManager = function newForecastCasesManager(processIndex, caseIndex: forecastCase.caseIndex, totalCases: thisObject.forecastCasesArray.length, parameters: forecastCase.parameters, + pythonScriptName: forecastCase.pythonScriptName, testServer: { userProfile: ((forecastCase.testServer != undefined) && (forecastCase.testServer.userProfile != undefined) ? forecastCase.testServer.userProfile : ''), instance: ((forecastCase.testServer != undefined) && (forecastCase.testServer.instance != undefined) ? forecastCase.testServer.instance : TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.config.serverInstanceName) @@ -172,6 +209,7 @@ exports.newForecastCasesManager = function newForecastCasesManager(processIndex, id: forecastCase.id, caseIndex: forecastCase.caseIndex, parameters: forecastCase.parameters, + pythonScriptName: forecastCase.pythonScriptName, testServer: { userProfile: ((forecastCase.testServer != undefined) && (forecastCase.testServer.userProfile != undefined) ? forecastCase.testServer.userProfile : ''), instance: ((forecastCase.testServer != undefined) && (forecastCase.testServer.instance != undefined) ? forecastCase.testServer.instance : TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.config.serverInstanceName) @@ -193,16 +231,32 @@ exports.newForecastCasesManager = function newForecastCasesManager(processIndex, } if (forecastCase != undefined) { forecastCase.status = 'Forecasted' - forecastCase.predictions = forecastResult.predictions - forecastCase.errorRMSE = forecastResult.errorRMSE - forecastCase.percentageErrorRMSE = calculatePercentageErrorRMSE(forecastResult) forecastCase.enlapsedSeconds = forecastResult.enlapsedTime.toFixed(0) forecastCase.enlapsedMinutes = (forecastResult.enlapsedTime / 60).toFixed(2) forecastCase.enlapsedHours = (forecastResult.enlapsedTime / 3600).toFixed(2) forecastCase.forecastedBy = forecastedBy forecastCase.testServer = forecastResult.testServer + forecastCase.pythonScriptName = forecastResult.pythonScriptName forecastCase.timestamp = (new Date()).valueOf() - + //LSTM + if (forecastResult.errorRMSE != undefined) { + forecastCase.predictions = forecastResult.predictions + forecastCase.errorRMSE = forecastResult.errorRMSE + forecastCase.percentageErrorRMSE = calculatePercentageErrorRMSE(forecastResult) + //RL + } else if (forecastResult["0"] != undefined) { + forecastCase.predictions = forecastResult["2"].current_action + forecastCase.ratio = { + train: forecastResult["0"].meanNetWorthAtEnd / forecastResult["0"].NetWorthAtBegin, + test: forecastResult["1"].meanNetWorthAtEnd / forecastResult["1"].NetWorthAtBegin, + validate: forecastResult["2"].meanNetWorthAtEnd / forecastResult["2"].NetWorthAtBegin + } + forecastCase.std = { + train: forecastResult["0"].stdNetWorthAtEnd , + test: forecastResult["1"].stdNetWorthAtEnd , + validate: forecastResult["2"].stdNetWorthAtEnd + } + } let logQueue = [] for (let i = Math.max(0, forecastResult.caseIndex - 5); i < Math.min(thisObject.forecastCasesArray.length, forecastResult.caseIndex + 5); i++) { let forecastCase = thisObject.forecastCasesArray[i] diff --git a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastClientsManager.js b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastClientsManager.js index 80a1060842..f0414407bb 100644 --- a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastClientsManager.js +++ b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/ForecastClientsManager.js @@ -78,6 +78,7 @@ exports.newForecastClientsManager = function newForecastClientsManager(processIn console.log((new Date()).toISOString(), 'Forecast Case Id ' + nextForecastCase.id + ' delivered to', currentClientInstance) nextForecastCase.files.parameters = nextForecastCase.files.parameters.toString() nextForecastCase.files.timeSeries = nextForecastCase.files.timeSeries.toString() + if (nextForecastCase.pythonScriptName == undefined) nextForecastCase.pythonScriptName = TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.config.pythonScriptName return nextForecastCase } else { console.log((new Date()).toISOString(), 'No more Forecast Cases to Build. Could not deliver one to ' + currentClientInstance) diff --git a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestCasesManager.js b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestCasesManager.js index f8583405a8..baed910325 100644 --- a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestCasesManager.js +++ b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestCasesManager.js @@ -14,7 +14,8 @@ exports.newTestCasesManager = function newTestCasesManager(processIndex, network const REPORT_NAME = networkCodeName + '-' + (new Date()).toISOString().substring(0, 16).replace("T", "-").replace(":", "-").replace(":", "-") + '-00' const MUST_BE_ON_PARAMS = [ 'CANDLES_CANDLES-VOLUMES_CANDLES_CANDLE_MAX', 'CANDLES_CANDLES-VOLUMES_CANDLES_CANDLE_MIN', - 'CANDLES_CANDLES-VOLUMES_CANDLES_CANDLE_CLOSE', 'CANDLES_CANDLES-VOLUMES_CANDLES_CANDLE_OPEN' + 'CANDLES_CANDLES-VOLUMES_CANDLES_CANDLE_CLOSE', 'CANDLES_CANDLES-VOLUMES_CANDLES_CANDLE_OPEN', + 'CANDLES_CANDLES-VOLUMES_VOLUMES_VOLUME_BUY' ] let parametersRanges = TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.config.parametersRanges @@ -41,6 +42,12 @@ exports.newTestCasesManager = function newTestCasesManager(processIndex, network for (let i = 0; i < thisObject.testCasesArray.length; i++) { let testCase = thisObject.testCasesArray[i] thisObject.testCasesMap.set(testCase.parametersHash, testCase) + if (TS.projects.foundations.globals.taskConstants.TEST_SERVER.forecastCasesManager.forecastCasesArray == undefined) { + TS.projects.foundations.globals.taskConstants.TEST_SERVER.forecastCasesManager.initialize() + } + if (testCase.status === "Tested") { + TS.projects.foundations.globals.taskConstants.TEST_SERVER.forecastCasesManager.addToforecastCases(testCase) + } } } generateTestCases() @@ -371,19 +378,36 @@ exports.newTestCasesManager = function newTestCasesManager(processIndex, network return } testCase.status = 'Tested' - testCase.predictions = testResult.predictions - testCase.errorRMSE = testResult.errorRMSE - testCase.percentageErrorRMSE = calculatePercentageErrorRMSE(testResult) testCase.enlapsedSeconds = testResult.enlapsedTime.toFixed(0) testCase.enlapsedMinutes = (testResult.enlapsedTime / 60).toFixed(2) testCase.enlapsedHours = (testResult.enlapsedTime / 3600).toFixed(2) testCase.testedByInstance = currentClientInstance + testCase.pythonScriptName = testResult.pythonScriptName testCase.testedByProfile = userProfile testCase.timestamp = (new Date()).valueOf() testCase.testServer = { userProfile: ((testResult.testServer != undefined) && (testResult.testServer.userProfile != undefined) ? testResult.testServer.userProfile : ''), instance: TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.config.serverInstanceName } + //LSTM + if (testResult.errorRMSE != undefined) { + testCase.predictions = testResult.predictions + testCase.errorRMSE = testResult.errorRMSE + testCase.percentageErrorRMSE = calculatePercentageErrorRMSE(testResult) + //RL + } else if (testResult["0"] != undefined) { + testCase.predictions = testResult["2"].current_action + testCase.ratio = { + train: testResult["0"].meanNetWorthAtEnd / testResult["0"].NetWorthAtBegin, + test: testResult["1"].meanNetWorthAtEnd / testResult["1"].NetWorthAtBegin, + validate: testResult["2"].meanNetWorthAtEnd / testResult["2"].NetWorthAtBegin + } + testCase.std = { + train: testResult["0"].stdNetWorthAtEnd , + test: testResult["1"].stdNetWorthAtEnd , + validate: testResult["2"].stdNetWorthAtEnd + } + } let logQueue = [] for (let i = Math.max(0, testResult.id - 5); i < Math.min(thisObject.testCasesArray.length, testResult.id + 5); i++) { diff --git a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestServer.js b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestServer.js index 83c4b8f562..7afcc6a863 100644 --- a/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestServer.js +++ b/Projects/Bitcoin-Factory/TS/Bot-Modules/Test-Server/TestServer.js @@ -7,7 +7,8 @@ dataBridge: undefined, testCasesManager: undefined, testClientsManager: undefined, - forecastsManager: undefined, + forecastCasesManager: undefined, + forecastClientsManager: undefined, initialize: initialize, finalize: finalize, start: start @@ -33,7 +34,9 @@ thisObject.dataBridge.initialize() await thisObject.testCasesManager.initialize() await thisObject.testClientsManager.initialize() - thisObject.forecastCasesManager.initialize() + if (thisObject.forecastCasesManager.forecastCasesArray == undefined) { + thisObject.forecastCasesManager.initialize() + } await thisObject.forecastClientsManager.initialize() console.log((new Date()).toISOString(), 'Running Test Server v.' + TEST_SERVER_VERSION) callBackFunction(TS.projects.foundations.globals.standardResponses.DEFAULT_OK_RESPONSE) From 943c8f2193443ef35fb62276edbb0f55023eef28 Mon Sep 17 00:00:00 2001 From: p-pl Date: Fri, 16 Sep 2022 08:43:59 +0000 Subject: [PATCH 2/3] Initial Reinforcementlearning version for ML --- .../ReadMeReinforcementLearning.md | 122 +++++++++++++++++- Bitcoin-Factory/docs/BTC_test.png | Bin 0 -> 78369 bytes Bitcoin-Factory/docs/BTC_train.png | Bin 0 -> 96339 bytes Bitcoin-Factory/docs/BTC_validate.png | Bin 0 -> 105177 bytes 4 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 Bitcoin-Factory/docs/BTC_test.png create mode 100644 Bitcoin-Factory/docs/BTC_train.png create mode 100644 Bitcoin-Factory/docs/BTC_validate.png diff --git a/Bitcoin-Factory/ReadMeReinforcementLearning.md b/Bitcoin-Factory/ReadMeReinforcementLearning.md index e2728e013e..b8f431be08 100644 --- a/Bitcoin-Factory/ReadMeReinforcementLearning.md +++ b/Bitcoin-Factory/ReadMeReinforcementLearning.md @@ -1,16 +1,126 @@ # Reinforcement Learning -## 💫 Introduction +## 💫 1. Introduction [Reinforcement Learning](https://en.wikipedia.org/wiki/Reinforcement_learning) is a term used to describe a special machine learning process. The typical framing of a Reinforcement Learning (RL) scenario: An agent takes actions in an environment, which is interpreted into a reward and a representation of the state, which are fed back into the agent. ![Learning framework](https://upload.wikimedia.org/wikipedia/commons/1/1b/Reinforcement_learning_diagram.svg "RL Framework") In our usage case, the environment is a stock trading one and the possible actions are buy,sell or hold. The reward will be our gain or loss. Based on this reward the agent will learn how to trade better. The process of learning is done with a so called [Proximal Policy Optimization (PPO)](https://en.wikipedia.org/wiki/Proximal_Policy_Optimization). -## 🤝 Support +At the end the agent will provide us an action for the current candle. The possible actions at the moment are: +* 0 -> buy long +* 1 -> sell +* 2 -> hold -Contributions, issues, and feature requests are welcome! +For buy and sell signals an additionaly percentage is provided. + +## 📒 2. Configuration +The basic config has to be done as pointed out in [Bitcoin Factory ReadMe](./README.md). Hereafter the differences for RL are shown. +### 2.1 Testserver config +To run a Testserver for RL und need to change the configuration of the testserver node in SA. First you need to define the python script, which should be used for the docker sessions on the clients. +Second you need to define the range of parameters to be tested: For example the learning rate and so on. +```js +{ + ... + "pythonScriptName": "Bitcoin_Factory_RL.py", + ... + "parametersRanges": { + "LIST_OF_ASSETS": [ + [ + "BTC" + ] + ], + "LIST_OF_TIMEFRAMES": [ + [ + "01-hs" + ], + [ + "02-hs" + ] + ], + "NUMBER_OF_LAG_TIMESTEPS": [ + 10 + ], + "PERCENTAGE_OF_DATASET_FOR_TRAINING": [ + 80 + ], + "NUMBER_OF_EPOCHS": [ + 750 + ], + "NUMBER_OF_LSTM_NEURONS": [ + 50 + ], + "TIMESTEPS_TO_TRAIN": [ + 1e7 + ], + "OBSERVATION_WINDOW_SIZE": [ + 24, + 48 + ], + "INITIAL_QUOTE_ASSET": [ + 1000 + ], + "INITIAL_BASE_ASSET": [ + 0 + ], + "TRADING_FEE": [ + 0.01 + ], + "ENV_NAME": [ + "SimpleTrading" + ], + "ENV_VERSION": [ + 1 + ], + "REWARD_FUNCTION": [ + "unused" + ], + "EXPLORE_ON_EVAL": [ + "unused" + ], + "ALGORITHM": [ + "PPO" + ], + "ROLLOUT_FRAGMENT_LENGTH": [ + 200 + ], + "TRAIN_BATCH_SIZE": [ + 2048 + ], + "SGD_MINIBATCH_SIZE": [ + 64 + ], + "BATCH_MODE": [ + "complete_episodes" + ], + "FC_SIZE": [ + 256 + ], + "LEARNING_RATE": [ + 0.00001 + ], + "GAMMA": [ + 0.95 + ] + } +} +``` +### 2.2 Testclient config +No special config is needed. +But run only one client per machine (The python script takes care of parallel execution on its own). + +## 💡 3. Results +> __Note__ +> The processing of one test case on the client takes roughly 2h-6h on a recent System. + +The provided Timeseries values are devided in 3 parts (Train, Test, Validate). The first one (train) is used to train the network. The second one (test) is used by the PPO-agent to evaluate the current net during the learning process. The third part is never seen by the agent, it is used to validate if the trained model is able to trade profitable on unseen data. -Give a ⭐️ if you like this project or even better become a part of the Superalgo community! +The python script produces 3 charts to visualize the results. The follwing 3 examples are preliminary - made by a not good trained agent. +![Example Train Results](docs/BTC_train.png) "BTC train") +![Example Test Results](docs/BTC_test.png) "BTC test") +![Example Validate Results](docs/BTC_validate.png) "BTC validate") + +## 🤝 4. Support + +Contributions, issues, and feature requests are welcome! -[nodeJS](https://raw.githubusercontent.com/get-icon/geticon/master/icons/nodejs-icon.svg "nodeJS") -[tensorflow](https://github.com/get-icon/geticon/blob/master/icons/tensorflow.svg "tensorflow") \ No newline at end of file +Give a ⭐️ if you like this project or even better become a part of the Superalgos community! \ No newline at end of file diff --git a/Bitcoin-Factory/docs/BTC_test.png b/Bitcoin-Factory/docs/BTC_test.png new file mode 100644 index 0000000000000000000000000000000000000000..dd324bf83b90d91e233b8131a33dacb6d91533ea GIT binary patch literal 78369 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 literal 0 HcmV?d00001 diff --git a/Bitcoin-Factory/docs/BTC_train.png b/Bitcoin-Factory/docs/BTC_train.png new file mode 100644 index 0000000000000000000000000000000000000000..96afbfab6f5744f7541988e9ee1528e49be01d51 GIT binary patch literal 96339 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

*ROF2_FaujF0eb!MeDtG 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 literal 0 HcmV?d00001 diff --git a/Bitcoin-Factory/docs/BTC_validate.png b/Bitcoin-Factory/docs/BTC_validate.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1acd5f1259ccce7ec7eb8b871b12e2997bccc0 GIT binary patch literal 105177 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 Date: Fri, 16 Sep 2022 08:50:19 +0000 Subject: [PATCH 3/3] Initial Reinforcementlearning version for ML --- .../TS/Bot-Modules/Forecast-Client/ForecastClient.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js b/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js index 3cc625a992..a0433af2b4 100644 --- a/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js +++ b/Projects/Bitcoin-Factory/TS/Bot-Modules/Forecast-Client/ForecastClient.js @@ -249,7 +249,7 @@ } } if ((bestPredictions[i].testServer.userProfile == undefined) || (bestPredictions[i].testServer.userProfile === '')) { - bestPredictions[i].testServer.userProfile == response.data.serverData.userProfile + bestPredictions[i].testServer.userProfile = response.data.serverData.userProfile } } console.log((new Date()).toISOString(), '[INFO] Size of local forecast array did change by ', checkSetForecastCaseResultsResponse(bestPredictions))