def __init__(self, config, device="cpu"): """ :param config: config dictionary :param device: the device used to train the network """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.best_metric = 0 # np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__coin_number = self.input_config["coin_number"] self.__batch_size = self.train_config["batch_size"] self._matrix = DataMatrices.create_from_config(config) self.stock_code = self._matrix.stock_code self.test_set = self._matrix.get_test_set() # if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() self.upperbound_validation = 1 self.upperbound_test = 1 # tf.set_random_seed(self.config["random_seed"]) self.device = device if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, device) else: self._agent = NNAgent(config, device)
def __init__(self, config, main_config, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None, index=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self._matrix = DataMatrices.create_from_config(config) self._coin_number = self._matrix.coin_number() config['input']['coin_number'] = self._coin_number self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data self._asset_list = self._matrix.coin_list self._time_index = self._matrix.global_weights.index self._test_portion = self.input_config["test_portion"] self.test_set = self._matrix.get_test_set() if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device if agent: self._agent = agent else: if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, restore_dir, device) else: self._agent = NNAgent(config, restore_dir, device)
def __init__(self, config, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__coin_number = self.input_config["coin_number"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data #creates Datamatrices from net_config.json self._matrix = DataMatrices.create_from_config(config) #:test set :-windowsize+1 self.test_set = self._matrix.get_test_set() #fast train: true without pre-training if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() self.training_set = self._matrix.get_training_set() self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device #needed for backtetst if agent: self._agent = agent else: #first run else is used to initialize NNAgent if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, restore_dir, device) else: self._agent = NNAgent(config, restore_dir, device)
def train_net(self, log_file_dir="./tensorboard", index="0"): """ :param log_file_dir: logging of the training process :param index: sub-folder name under train_package :return: the result named tuple """ self.__print_upperbound() if log_file_dir: if self.device == "cpu": with tf.device("/cpu:0"): self.__init_tensor_board(log_file_dir) #初始化summary else: self.__init_tensor_board(log_file_dir) starttime = time.time() total_data_time = 0 total_training_time = 0 for i in range(self.train_config["steps"]): #训练步数 step_start = time.time() x, y, last_w, setw = self.next_batch( ) #获取batch x:(109, 3, 11, 31) y:(109, 3, 11) last_w: (109,11) setw:function if 'noise' in self.train_config: if self.train_config['noise']: noise = np.random.normal(0, 0.002, size=y.shape) y = y + noise finish_data = time.time() total_data_time += (finish_data - step_start) #训练智能体 self._agent.train(x, y, last_w=last_w, setw=setw) total_training_time += time.time() - finish_data if i % 50 == 0 and log_file_dir: logging.info("average time for data accessing is %s" % (total_data_time / 50)) logging.info("average time for training is %s" % (total_training_time / 50)) total_training_time = 0 total_data_time = 0 #每隔固定的步数对测试集进行评估 self.log_between_steps(i) if self.save_path: self._agent.recycle() # best_agent = NNAgent(self.config, self.stockList, self.featureList, restore_dir=self.save_path) self._agent = best_agent pv, log_mean = self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean) #最后在评估一下 #logging.warning('the portfolio value train No.%s is %s log_mean is %s,' # ' the training time is %d seconds' % (index, pv, log_mean, time.time() - starttime)) return self.__log_result_csv(index, time.time() - starttime, self.save_path)
def __init__(self, config, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__coin_number = self.input_config["coin_number"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data self._matrix = DataMatrices.create_from_config(config) self.test_set = self._matrix.get_test_set() if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device if agent: self._agent = agent else: if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, restore_dir, device) else: self._agent = NNAgent(config, restore_dir, device)
def train_net(self, log_file_dir="./tensorboard", index="0"): """ :param log_file_dir: logging of the training process :param index: sub-folder name under train_package :return: the result named tuple """ self.__print_upperbound() if log_file_dir: if self.device == "cpu": with tf.device("/cpu:0"): self.__init_tensor_board(log_file_dir) else: self.__init_tensor_board(log_file_dir) starttime = time.time() total_data_time = 0 total_training_time = 0 for i in range(self.train_config["steps"]): step_start = time.time() x, y, last_w, setw = self.next_batch() finish_data = time.time() total_data_time += (finish_data - step_start) self._agent.train(x, y, last_w=last_w, setw=setw) total_training_time += time.time() - finish_data if i % 1000 == 0 and log_file_dir: logging.info("average time for data accessing is %s" % (total_data_time / 1000)) logging.info("average time for training is %s" % (total_training_time / 1000)) total_training_time = 0 total_data_time = 0 self.log_between_steps(i) # Train step by 1000 if self.save_path: self._agent.recycle() best_agent = NNAgent(self.config, restore_dir=self.save_path) self._agent = best_agent pv, log_mean = self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean) logging.warning('the portfolio value train No.%s is %s log_mean is %s,' ' the training time is %d seconds' % (index, pv, log_mean, time.time() - starttime)) return self.__log_result_csv( index, time.time() - starttime) # save results in train_summary.csv
class TraderTrainer: def __init__(self, config, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__coin_number = self.input_config["coin_number"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data self._matrix = DataMatrices.create_from_config(config) # obtain global_data self.test_set = self._matrix.get_test_set() # obtain test_data if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() # obtain training_data self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device if agent: self._agent = agent else: if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, restore_dir, device) else: self._agent = NNAgent(config, restore_dir, device) def _evaluate(self, set_name, *tensors): if set_name == "test": feed = self.test_set elif set_name == "training": feed = self.training_set else: raise ValueError() result = self._agent.evaluate_tensors(feed["X"],feed["y"],last_w=feed["last_w"], setw=feed["setw"], tensors=tensors) return result @staticmethod def calculate_upperbound(y): array = np.maximum.reduce(y[:, 0, :], 1) #print("array",array) total = 1.0 for i in array: total = total * i return total def log_between_steps(self, step): # log the information per step fast_train = self.train_config["fast_train"] tflearn.is_training(False, self._agent.session) summary, v_pv, v_log_mean, v_loss, log_mean_free, weights= \ self._evaluate("test", self.summary, self._agent.portfolio_value, self._agent.log_mean, self._agent.loss, self._agent.log_mean_free, self._agent.portfolio_weights) self.test_writer.add_summary(summary, step) if not fast_train: summary, loss_value = self._evaluate("training", self.summary, self._agent.loss) self.train_writer.add_summary(summary, step) # fast_train is ued to control the output of tensorboard. # print 'ouput is %s' % out logging.info('='*30) logging.info('step %d' % step) logging.info('-'*30) if not fast_train: logging.info('training loss is %s\n' % loss_value) logging.info('the portfolio value on test set is %s\nlog_mean is %s\n' 'loss_value is %3f\nlog mean without commission fee is %3f\n' % \ (v_pv, v_log_mean, v_loss, log_mean_free)) logging.info('='*30+"\n") if not self.__snap_shot: self._agent.save_model(self.save_path) elif v_pv > self.best_metric: self.best_metric = v_pv logging.info("get better model at %s steps," " whose test portfolio value is %s" % (step, v_pv)) if self.save_path: self._agent.save_model(self.save_path) self.check_abnormal(v_pv, weights) def check_abnormal(self, portfolio_value, weigths): if portfolio_value == 1.0: logging.info("average portfolio weights {}".format(weigths.mean(axis=0))) def next_batch(self): batch = self._matrix.next_batch() # sampling batch based on experience batch_input = batch["X"] batch_y = batch["y"] batch_last_w = batch["last_w"] batch_w = batch["setw"] return batch_input, batch_y, batch_last_w, batch_w def __init_tensor_board(self, log_file_dir): tf.summary.scalar('benefit', self._agent.portfolio_value) tf.summary.scalar('log_mean', self._agent.log_mean) tf.summary.scalar('loss', self._agent.loss) tf.summary.scalar("log_mean_free", self._agent.log_mean_free) for layer_key in self._agent.layers_dict: tf.summary.histogram(layer_key, self._agent.layers_dict[layer_key]) for var in tf.trainable_variables(): tf.summary.histogram(var.name, var) #grads = tf.gradients(self._agent.loss, tf.trainable_variables()) #for grad in grads: # tf.summary.histogram(grad.name + '/gradient', grad) self.summary = tf.summary.merge_all() location = log_file_dir self.network_writer = tf.summary.FileWriter(location + '/network', self._agent.session.graph) self.test_writer = tf.summary.FileWriter(location + '/test') self.train_writer = tf.summary.FileWriter(location + '/train') def __print_upperbound(self): upperbound_test = self.calculate_upperbound(self.test_set["y"]) logging.info("upper bound in test is %s" % upperbound_test) def train_net(self, log_file_dir="./tensorboard", index="0"): """ :param log_file_dir: logging of the training process :param index: sub-folder name under train_package :return: the result named tuple """ self.__print_upperbound() if log_file_dir: if self.device == "cpu": with tf.device("/cpu:0"): self.__init_tensor_board(log_file_dir) else: self.__init_tensor_board(log_file_dir) starttime = time.time() total_data_time = 0 total_training_time = 0 for i in range(self.train_config["steps"]): step_start = time.time() x, y, last_w, setw = self.next_batch() finish_data = time.time() total_data_time += (finish_data - step_start) self._agent.train(x, y, last_w=last_w, setw=setw) total_training_time += time.time() - finish_data if i % 1000 == 0 and log_file_dir: logging.info("average time for data accessing is %s"%(total_data_time/1000)) logging.info("average time for training is %s"%(total_training_time/1000)) total_training_time = 0 total_data_time = 0 self.log_between_steps(i) # log the information every 1000 rounds if self.save_path: self._agent.recycle() best_agent = NNAgent(self.config, restore_dir=self.save_path) self._agent = best_agent pv, log_mean = self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean) # execute test once logging.warning('the portfolio value train No.%s is %s log_mean is %s,' ' the training time is %d seconds' % (index, pv, log_mean, time.time() - starttime)) return self.__log_result_csv(index, time.time() - starttime) def __log_result_csv(self, index, time): # execute backtest, and save the result in train_summary.csv from pgportfolio.trade import backtest dataframe = None csv_dir = './train_package/train_summary.csv' tflearn.is_training(False, self._agent.session) v_pv, v_log_mean, benefit_array, v_log_mean_free, v_turn_over =\ self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean, self._agent.pv_vector, self._agent.log_mean_free, self._agent.turn_over) backtest = backtest.BackTest(self.config.copy(), net_dir=None, agent=self._agent) backtest.start_trading() result = Result(test_pv=[v_pv], test_log_mean=[v_log_mean], test_log_mean_free=[v_log_mean_free], test_history=[''.join(str(e)+', ' for e in benefit_array)], test_turn_over = [v_turn_over], config=[json.dumps(self.config)], net_dir=[index], backtest_test_pv=[backtest.test_pv], backtest_test_history=[''.join(str(e)+', ' for e in backtest.test_pc_vector)], backtest_test_log_mean=[np.mean(np.log(backtest.test_pc_vector))], backtest_turn_over = [backtest.turn_over], training_time=int(time)) new_data_frame = pd.DataFrame(result._asdict()).set_index("net_dir") if os.path.isfile(csv_dir): dataframe = pd.read_csv(csv_dir).set_index("net_dir") dataframe = dataframe.append(new_data_frame) else: dataframe = new_data_frame if int(index) > 0: dataframe.to_csv(csv_dir) return result
def __init__(self, config, stockList, featureList, start_date, end_date, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data self.stockList = stockList self.featureList = featureList self.start_date = start_date self.end_date = end_date self.fake_data = fake_data self._matrix = DataMatrices.create_from_config(config, stockList, featureList, start_date, end_date) #数据 self.test_set = self._matrix.get_test_set( ) #测试集 dict:{'X', 'y', 'last_w', 'setw'} # X: (260, 4, 3, 31), y: (260, 4, 3), last_w: (260, 3) # X: (test_length, feature_num, stock_num, time_windows) if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() #训练集 self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device if agent: self._agent = agent else: if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, stockList, featureList, restore_dir, device) else: self._agent = NNAgent(config, stockList, featureList, restore_dir, device)
class TraderTrainer: def __init__(self, config, stockList, featureList, start_date, end_date, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data self.stockList = stockList self.featureList = featureList self.start_date = start_date self.end_date = end_date self.fake_data = fake_data self._matrix = DataMatrices.create_from_config(config, stockList, featureList, start_date, end_date) #数据 self.test_set = self._matrix.get_test_set( ) #测试集 dict:{'X', 'y', 'last_w', 'setw'} # X: (260, 4, 3, 31), y: (260, 4, 3), last_w: (260, 3) # X: (test_length, feature_num, stock_num, time_windows) if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() #训练集 self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device if agent: self._agent = agent else: if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, stockList, featureList, restore_dir, device) else: self._agent = NNAgent(config, stockList, featureList, restore_dir, device) def _evaluate(self, set_name, *tensors): if set_name == "test": feed = self.test_set elif set_name == "training": feed = self.training_set else: raise ValueError() result = self._agent.evaluate_tensors(feed["X"], feed["y"], last_w=feed["last_w"], setw=feed["setw"], tensors=tensors) # len: 6, result[5]: (260,4) # 计算的是tensors的值,有几个tensor就相应的有几个输出 return result @staticmethod def calculate_upperbound(y): array = np.maximum.reduce(y[:, 0, :], 1) #第1维的最大值 total = 1.0 for i in array: total = total * i return total def log_between_steps(self, step): fast_train = self.train_config["fast_train"] tflearn.is_training(False, self._agent.session) summary, v_pv, v_log_mean, v_loss, log_mean_free, weights= \ self._evaluate("test", self.summary, self._agent.portfolio_value, self._agent.log_mean, self._agent.loss, self._agent.log_mean_free, self._agent.portfolio_weights) self.test_writer.add_summary(summary, step) if not fast_train: summary, loss_value = self._evaluate("training", self.summary, self._agent.loss) self.train_writer.add_summary(summary, step) # print 'ouput is %s' % out logging.info('=' * 30) logging.info('step %d' % step) logging.info('-' * 30) if not fast_train: logging.info('training loss is %s\n' % loss_value) logging.info('the portfolio value on test set is %s\nlog_mean is %s\n' 'loss_value is %3f\nlog mean without commission fee is %3f\n' % \ (v_pv, v_log_mean, v_loss, log_mean_free)) logging.info('=' * 30 + "\n") if not self.__snap_shot: self._agent.save_model(self.save_path) elif v_pv > self.best_metric: self.best_metric = v_pv logging.info("get better model at %s steps," " whose test portfolio value is %s" % (step, v_pv)) if self.save_path: self._agent.save_model(self.save_path) self.check_abnormal(v_pv, weights) def check_abnormal(self, portfolio_value, weigths): if portfolio_value == 1.0: logging.info("average portfolio weights {}".format( weigths.mean(axis=0))) def next_batch(self): batch = self._matrix.next_batch() batch_input = batch["X"] batch_y = batch["y"] batch_last_w = batch["last_w"] batch_w = batch["setw"] return batch_input, batch_y, batch_last_w, batch_w def __init_tensor_board(self, log_file_dir): tf.summary.scalar('benefit', self._agent.portfolio_value) tf.summary.scalar('log_mean', self._agent.log_mean) tf.summary.scalar('loss', self._agent.loss) tf.summary.scalar("log_mean_free", self._agent.log_mean_free) for layer_key in self._agent.layers_dict: tf.summary.histogram(layer_key, self._agent.layers_dict[layer_key]) for var in tf.trainable_variables(): tf.summary.histogram(var.name, var) grads = tf.gradients(self._agent.loss, tf.trainable_variables()) for grad in grads: tf.summary.histogram(grad.name + '/gradient', grad) self.summary = tf.summary.merge_all() location = log_file_dir self.network_writer = tf.summary.FileWriter(location + '/network', self._agent.session.graph) self.test_writer = tf.summary.FileWriter(location + '/test') #保存的是训练结果 self.train_writer = tf.summary.FileWriter(location + '/train') def __print_upperbound(self): upperbound_test = self.calculate_upperbound(self.test_set["y"]) #都乘起来 logging.info("upper bound in test is %s" % upperbound_test) def train_net(self, log_file_dir="./tensorboard", index="0"): """ :param log_file_dir: logging of the training process :param index: sub-folder name under train_package :return: the result named tuple """ self.__print_upperbound() if log_file_dir: if self.device == "cpu": with tf.device("/cpu:0"): self.__init_tensor_board(log_file_dir) #初始化summary else: self.__init_tensor_board(log_file_dir) starttime = time.time() total_data_time = 0 total_training_time = 0 for i in range(self.train_config["steps"]): #训练步数 step_start = time.time() x, y, last_w, setw = self.next_batch( ) #获取batch x:(109, 3, 11, 31) y:(109, 3, 11) last_w: (109,11) setw:function if 'noise' in self.train_config: if self.train_config['noise']: noise = np.random.normal(0, 0.002, size=y.shape) y = y + noise finish_data = time.time() total_data_time += (finish_data - step_start) #训练智能体 self._agent.train(x, y, last_w=last_w, setw=setw) total_training_time += time.time() - finish_data if i % 50 == 0 and log_file_dir: logging.info("average time for data accessing is %s" % (total_data_time / 50)) logging.info("average time for training is %s" % (total_training_time / 50)) total_training_time = 0 total_data_time = 0 #每隔固定的步数对测试集进行评估 self.log_between_steps(i) if self.save_path: self._agent.recycle() # best_agent = NNAgent(self.config, self.stockList, self.featureList, restore_dir=self.save_path) self._agent = best_agent pv, log_mean = self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean) #最后在评估一下 #logging.warning('the portfolio value train No.%s is %s log_mean is %s,' # ' the training time is %d seconds' % (index, pv, log_mean, time.time() - starttime)) return self.__log_result_csv(index, time.time() - starttime, self.save_path) def __log_result_csv(self, index, time, path): from pgportfolio.trade import backtest dataframe = None csv_dir = './train_package/train_summary.csv' tflearn.is_training(False, self._agent.session) v_pv, v_log_mean, benefit_array, v_log_mean_free = self._evaluate("test", self._agent.portfolio_value,\ self._agent.log_mean, self._agent.pv_vector,\ self._agent.log_mean_free) backtest = backtest.BackTest(self.config.copy(), self.stockList, self.featureList, self.start_date, self.end_date, self.fake_data, net_dir=None, result_path=path, agent=self._agent) # 回测 backtest.start_trading() result = Result( test_pv=[v_pv], test_log_mean=[v_log_mean], test_log_mean_free=[v_log_mean_free], test_history=[''.join(str(e) + ', ' for e in benefit_array)], config=[json.dumps(self.config)], net_dir=[index], backtest_test_pv=[backtest.test_pv], backtest_test_history=[ ''.join(str(e) + ', ' for e in backtest.test_pc_vector) ], backtest_test_log_mean=[np.mean(np.log(backtest.test_pc_vector))], training_time=int(time)) new_data_frame = pd.DataFrame(result._asdict()).set_index("net_dir") if os.path.isfile(csv_dir): dataframe = pd.read_csv(csv_dir).set_index("net_dir") dataframe = dataframe.append(new_data_frame) else: dataframe = new_data_frame if int(index) > 0: dataframe.to_csv(csv_dir) return result
class TraderTrainer: def __init__(self, config, device="cpu"): """ :param config: config dictionary :param device: the device used to train the network """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.best_metric = 0 # np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__coin_number = self.input_config["coin_number"] self.__batch_size = self.train_config["batch_size"] self._matrix = DataMatrices.create_from_config(config) self.stock_code = self._matrix.stock_code self.test_set = self._matrix.get_test_set() # if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() self.upperbound_validation = 1 self.upperbound_test = 1 # tf.set_random_seed(self.config["random_seed"]) self.device = device if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, device) else: self._agent = NNAgent(config, device) def _evaluate(self, set_name, *tensors): if set_name == "test": feed = self.test_set elif set_name == "training": feed = self.training_set else: raise ValueError() result,output = self._agent.evaluate_tensors(feed["X"],feed["y"],last_w=feed["last_w"], setw=feed["setw"], tensors=tensors, stock_index=feed["stock_index"], # market_capticalization=feed["market_capticalization"], # all_market_capticalization=feed["all_market_capticalization"] ) if set_name == "test": res = [] for i in range(self.__coin_number): rowtemp = [] rowtemp.append(self.stock_code[i]) for j in range(60): if j < self.__window_size - 1: rowtemp.append(0.0) elif j == self.__window_size - 1: rowtemp.append(1.0/self.__coin_number) else: rowtemp.append(output[j - self.__window_size][i]) res.append(rowtemp) print(res) outwb = Workbook() wo = outwb.active sheet = outwb.create_sheet('decision', 0) sheet.cell(1, 1).value = '' for col in range(60): sheet.cell(1, col + 2).value = col + 1 for row in range(self.__coin_number): for col in range(61): sheet.cell(row + 2, col + 1).value = res[row][col] outwb.save('F:\portfolio_rx\portfolio_rx\\N225\\vol_pg_result.xlsx') return result @staticmethod def calculate_upperbound(y): array = np.maximum.reduce(y[:, 0, :], 1) total = 1.0 for i in array: total = total * i return total def log_between_steps(self, step): tflearn.is_training(False, self._agent.session) # v_pv, v_log_mean, v_loss, log_mean_free, weights, tracking_error, excess_return, sharpe_ratio, information_ratio, tracking_ratio= \ v_pv, v_log_mean, v_loss, log_mean_free, weights, tracking_error, excess_return, sharpe_ratio, information_ratio =\ self._evaluate("training", self._agent.portfolio_value, self._agent.log_mean, self._agent.loss, self._agent.log_mean_free, self._agent.portfolio_weights, self._agent.tracking_error, self._agent.excess_return, self._agent.sharp_ratio, self._agent.information_ratio, # self._agent.tracking_ratio ) loss_value = self._evaluate("training",self._agent.loss) print('='*30) print('step %d' % step) print('-'*30) print('the portfolio value on training set is %s\nlog_mean is %s\n' 'loss_value is %3f\nlog mean without commission fee is %3f\ntracking error is %3f\n' 'excess_return is %3f\nsharpe_ratio is %3f\ninformation_ratio is %3f\n'% \ (v_pv, v_log_mean, v_loss, log_mean_free, tracking_error, excess_return, sharpe_ratio, information_ratio)) # print('tracking_ratio is '+str(tracking_ratio)) print('='*30+"\n") def next_batch(self): batch = self._matrix.next_batch() batch_input = batch["X"] batch_y = batch["y"] batch_last_w = batch["last_w"] batch_w = batch["setw"] batch_stock_index = batch["stock_index"] # batch_market_capticalization = batch["market_capticalization"] # batch_all_market_capticalization = batch["all_market_capticalization"] # return batch_input, batch_y, batch_last_w, batch_w, batch_stock_index, batch_market_capticalization,batch_all_market_capticalization return batch_input, batch_y, batch_last_w, batch_w, batch_stock_index def __print_upperbound(self): upperbound_test = self.calculate_upperbound(self.test_set["y"]) logging.info("upper bound in test is %s" % upperbound_test) def train_net(self): self.__print_upperbound() for i in range(self.train_config["steps"]): # x, y, last_w, setw, stock_index, market_capticalization, all_market_capticalization = self.next_batch() x, y, last_w, setw, stock_index = self.next_batch() # self._agent.train(x, y, last_w=last_w, setw=setw, stock_index=stock_index, market_capticalization=market_capticalization, all_market_capticalization=all_market_capticalization) self._agent.train(x, y, last_w=last_w, setw=setw, stock_index=stock_index) if i % 1000 == 0: self.log_between_steps(i) sr, te,er,ir = self._evaluate("test", self._agent.sharp_ratio, self._agent.tracking_error,self._agent.excess_return,self._agent.information_ratio) print('test set:sharp ratio is %lf, TE is %lf, ER is %lf, IR is %lf'% ( sr, te,er,ir))
def predict_portfolio(algo, investment, chosen_coins, date, old_omega): # Set config if algo.isdigit(): config = load_config(algo) else: base_dir = os.path.abspath(os.path.dirname(__file__)) file_path = os.path.join(os.path.dirname(base_dir), 'PGPortfolio/pgportfolio/net_config.json') with open(file_path) as file: config = json.load(file) input_config = config["input"] feature_number = input_config["feature_number"] period = input_config["global_period"] volume = input_config["volume_average_days"] features = get_type_list(feature_number) # Set start and end times for retrieving data date = date - 300 * (date % period < 300) end = int( date - (date % period) ) # converts into closest round time, minus 5 min if too close from it if algo.isdigit(): # Use absolute path, to change to your configuration base_dir = os.path.abspath(os.path.dirname(__file__)) net_dir = os.path.join( os.path.dirname(base_dir), 'PGPortfolio/train_package/' + algo + '/netfile') #train_package_path = "/home/michael/cryptofolio/Django/projet/PGPortfolio/train_package/" #net_dir = train_package_path + algo + "/netfile" start = end - volume * period # setting start to 30 periods before end start = int(start - (start % period)) elif algo in ['bcrp', 'best']: start = end - 90 * volume * period # setting start to 2700 periods before end (special algos) start = int(start - (start % period)) else: start = end - volume * period # setting start to 30 periods before end start = int(start - (start % period)) # Create history matrix coin_list = create_coinlist( ) # a pandas dataframe with coins (index), pair, volume, price (in BTC) history = create_history(coin_list, chosen_coins, start, end, period, features) # history matrix # Generate new omega if algo.isdigit(): os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): myAgent = NNAgent(config=config, restore_dir=net_dir, device="cpu") omega = myAgent.decide_by_history(history, old_omega) elif algo in valid_algorithms: package = importlib.import_module("pgportfolio.tdagent.algorithms." + algo) myAgent = getattr(package, algo.upper())() y = (history[0, :, 1:] / history[0, :, :-1]) y = np.concatenate((np.ones((1, y.shape[1])), y), axis=0) omega = myAgent.decide_by_history(y.T, old_omega) else: print("Invalid algorithm") omega = None # Current BTC per Currency price (transformed into Currency per BTC) v = 1.0 / history[0, :, -1] v = np.concatenate((np.zeros(1), v), axis=0) # Round omega to percentage round_omega = np.around(omega, decimals=1) # Compute omega in term of currencies, not percentage portfolio = investment * round_omega * v return portfolio, round_omega
class TraderTrainer: def __init__(self, config, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__coin_number = self.input_config["coin_number"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data #creates Datamatrices from net_config.json self._matrix = DataMatrices.create_from_config(config) #:test set :-windowsize+1 self.test_set = self._matrix.get_test_set() #fast train: true without pre-training if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() self.training_set = self._matrix.get_training_set() self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device #needed for backtetst if agent: self._agent = agent else: #first run else is used to initialize NNAgent if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, restore_dir, device) else: self._agent = NNAgent(config, restore_dir, device) #returns results on the test or training set def _evaluate(self, set_name, *tensors): if set_name == "test": feed = self.test_set elif set_name == "training": feed = self.training_set else: raise ValueError() #evaluate Network on the whole set, where the whole last_w is feeded in one go result = self._agent.evaluate_tensors(feed["X"], feed["y"], last_w=feed["last_w"], setw=feed["setw"], tensors=tensors) return result @staticmethod def calculate_upperbound(y): array = np.maximum.reduce(y[:, 0, :], 1) total = 1.0 for i in array: total = total * i return total #evaluates every 1000 steps on test set and on the training set if not fast train def log_between_steps(self, step): fast_train = self.train_config["fast_train"] tflearn.is_training(False, self._agent.session) summary, v_pv, v_log_mean, v_loss, log_mean_free, weights= \ self._evaluate("test", self.summary, self._agent.portfolio_value, self._agent.log_mean, self._agent.loss, self._agent.log_mean_free, self._agent.portfolio_weights) self.test_writer.add_summary(summary, step) #if not fast_train: evaluate on the training set as well if not fast_train: summary, loss_value = self._evaluate("training", self.summary, self._agent.loss) self.train_writer.add_summary(summary, step) # print 'ouput is %s' % out logging.info('=' * 30) logging.info('step %d' % step) logging.info('-' * 30) if not fast_train: logging.info('training loss is %s\n' % loss_value) logging.info('the portfolio value on test set is %s\nlog_mean is %s\n' 'loss_value is %3f\nlog mean without commission fee is %3f\n' % \ (v_pv, v_log_mean, v_loss, log_mean_free)) logging.info('=' * 30 + "\n") #snap_shot: fals: saves model if not self.__snap_shot: self._agent.save_model(self.save_path) #saves best portfolio return and saves model parameter if we have a new best portfolio return elif v_pv > self.best_metric: self.best_metric = v_pv logging.info("get better model at %s steps," " whose test portfolio value is %s" % (step, v_pv)) if self.save_path: self._agent.save_model(self.save_path) self.check_abnormal(v_pv, weights) def check_abnormal(self, portfolio_value, weigths): if portfolio_value == 1.0: logging.info("average portfolio weights {}".format( weigths.mean(axis=0))) #returns next batch def next_batch(self): #opens DataMatrices for the next batch batch = self._matrix.next_batch() batch_input = batch["X"] batch_y = batch["y"] batch_last_w = batch["last_w"] batch_w = batch["setw"] return batch_input, batch_y, batch_last_w, batch_w def __init_tensor_board(self, log_file_dir): tf.summary.scalar('benefit', self._agent.portfolio_value) tf.summary.scalar('log_mean', self._agent.log_mean) tf.summary.scalar('loss', self._agent.loss) tf.summary.scalar("log_mean_free", self._agent.log_mean_free) self.summary = tf.summary.merge_all() location = log_file_dir self.network_writer = tf.summary.FileWriter(location + '/network', self._agent.session.graph) self.test_writer = tf.summary.FileWriter(location + '/test') self.train_writer = tf.summary.FileWriter(location + '/train') def __print_upperbound(self): upperbound_test = self.calculate_upperbound(self.test_set["y"]) logging.info("upper bound in test is %s" % upperbound_test) #method opened by training during training def train_net(self, log_file_dir="./tensorboard", index="0"): """ :param log_file_dir: logging of the training process :param index: sub-folder name under train_package :return: the result named tuple """ self.__print_upperbound() if log_file_dir: if self.device == "cpu": with tf.device("/cpu:0"): self.__init_tensor_board(log_file_dir) else: self.__init_tensor_board(log_file_dir) #activate to use GARCH(1,1) garchmodel = Garch(self.config) print(self.config["input"]["global_period"]) for i in range(0, 40000): batch = garchmodel.simulate() x = batch["X"] y = batch["y"] last_w = batch["last_w"] setw = batch["setw"] self._agent.train(x, y, last_w=last_w, setw=setw) if i % 1000 == 0: print(i) #tflearn.is_training(False, self._agent.session) result = self._evaluate("training") print(result) #tflearn.is_training(True, self.__net.session) starttime = time.time() """ total_data_time = 0 total_training_time = 0 for i in range(self.train_config["steps"]): step_start = time.time() x, y, last_w, setw = self.next_batch() finish_data = time.time() total_data_time += (finish_data - step_start) #trains network for the batch and sets w self._agent.train(x, y, last_w=last_w, setw=setw) total_training_time += time.time() - finish_data if i % 1000 == 0 and log_file_dir: logging.info("average time for data accessing is %s"%(total_data_time/1000)) logging.info("average time for training is %s"%(total_training_time/1000)) total_training_time = 0 total_data_time = 0 self.log_between_steps(i) #after training, set agent if self.save_path: self._agent.recycle() best_agent = NNAgent(self.config, restore_dir=self.save_path) self._agent = best_agent #evaluate agent on the test set pv, log_mean = self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean) logging.warning('the portfolio value train No.%s is %s log_mean is %s,' ' the training time is %d seconds' % (index, pv, log_mean, time.time() - starttime)) """ #start backtesting during training on the test set return self.__log_result_csv(index, time.time() - starttime) def __log_result_csv(self, index, time): from pgportfolio.trade import backtest dataframe = None csv_dir = './train_package/train_summary.csv' json_dir = "./train_package/" + str( int(index)) + "/weight_history" + str(int(index)) + ".json" tflearn.is_training(False, self._agent.session) #evaluate on the test set v_pv, v_log_mean, benefit_array, v_log_mean_free =\ self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean, self._agent.pv_vector, self._agent.log_mean_free) #initialize backtest backtest = backtest.BackTest(self.config.copy(), net_dir=None, agent=self._agent) #method of trader, initialized by BackTest backtest.start_trading() #collects the result in a dic result = Result( test_pv=[v_pv], test_log_mean=[v_log_mean], test_log_mean_free=[v_log_mean_free], test_history=[''.join(str(e) + ', ' for e in benefit_array)], config=[json.dumps(self.config)], net_dir=[index], backtest_test_pv=[backtest.test_pv], backtest_test_history=[ ''.join(str(e) + ', ' for e in backtest.test_pc_vector) ], backtest_test_log_mean=[np.mean(np.log(backtest.test_pc_vector))], training_time=int(time)) new_data_frame = pd.DataFrame(result._asdict()).set_index("net_dir") historyweights = [] for weight in backtest.test_updated_omega: historyweights.append(weight.tolist()) backtesthistory = {"portfolioweights": historyweights} if os.path.isfile(csv_dir): dataframe = pd.read_csv(csv_dir).set_index("net_dir") dataframe = dataframe.append(new_data_frame) else: dataframe = new_data_frame if int(index) > 0: #writes everything in train_package/train_summary.csv and creates it dataframe.to_csv(csv_dir) #writes everything in train_package/int(index)/weight_history int(index).json with open(json_dir, 'w') as outfile: json.dump(backtesthistory, outfile) return result
class TraderTrainer: def __init__(self, config, fake_data=False, restore_dir=None, save_path=None, device="cpu", agent=None): """ :param config: config dictionary :param fake_data: if True will use data generated randomly :param restore_dir: path to the model trained before :param save_path: path to save the model :param device: the device used to train the network :param agent: the nnagent object. If this is provides, the trainer will not create a new agent by itself. Therefore the restore_dir will not affect anything. """ self.config = config self.train_config = config["training"] self.input_config = config["input"] self.save_path = save_path self.best_metric = 0 np.random.seed(config["random_seed"]) self.__window_size = self.input_config["window_size"] self.__coin_number = self.input_config["coin_number"] self.__batch_size = self.train_config["batch_size"] self.__snap_shot = self.train_config["snap_shot"] config["input"]["fake_data"] = fake_data self._matrix = DataMatrices.create_from_config(config) self.test_set = self._matrix.get_test_set() if not config["training"]["fast_train"]: self.training_set = self._matrix.get_training_set() self.upperbound_validation = 1 self.upperbound_test = 1 tf.set_random_seed(self.config["random_seed"]) self.device = device if agent: self._agent = agent else: if device == "cpu": os.environ["CUDA_VISIBLE_DEVICES"] = "" with tf.device("/cpu:0"): self._agent = NNAgent(config, restore_dir, device) else: self._agent = NNAgent(config, restore_dir, device) def _evaluate(self, set_name, *tensors): if set_name == "test": feed = self.test_set elif set_name == "training": feed = self.training_set else: raise ValueError() result = self._agent.evaluate_tensors(feed["X"],feed["y"],last_w=feed["last_w"], setw=feed["setw"], tensors=tensors) return result @staticmethod def calculate_upperbound(y): array = np.maximum.reduce(y[:, 0, :], 1) total = 1.0 for i in array: total = total * i return total def log_between_steps(self, step): fast_train = self.train_config["fast_train"] tflearn.is_training(False, self._agent.session) summary, v_pv, v_log_mean, v_loss, log_mean_free, weights= \ self._evaluate("test", self.summary, self._agent.portfolio_value, self._agent.log_mean, self._agent.loss, self._agent.log_mean_free, self._agent.portfolio_weights) self.test_writer.add_summary(summary, step) if not fast_train: summary, loss_value = self._evaluate("training", self.summary, self._agent.loss) self.train_writer.add_summary(summary, step) # print 'ouput is %s' % out logging.info('='*30) logging.info('step %d' % step) logging.info('-'*30) if not fast_train: logging.info('training loss is %s\n' % loss_value) logging.info('the portfolio value on test set is %s\nlog_mean is %s\n' 'loss_value is %3f\nlog mean without commission fee is %3f\n' % \ (v_pv, v_log_mean, v_loss, log_mean_free)) logging.info('='*30+"\n") if not self.__snap_shot: self._agent.save_model(self.save_path) elif v_pv > self.best_metric: self.best_metric = v_pv logging.info("get better model at %s steps," " whose test portfolio value is %s" % (step, v_pv)) if self.save_path: self._agent.save_model(self.save_path) self.check_abnormal(v_pv, weights) def check_abnormal(self, portfolio_value, weigths): if portfolio_value == 1.0: logging.info("average portfolio weights {}".format(weigths.mean(axis=0))) def next_batch(self): batch = self._matrix.next_batch() batch_input = batch["X"] batch_y = batch["y"] batch_last_w = batch["last_w"] batch_w = batch["setw"] return batch_input, batch_y, batch_last_w, batch_w def __init_tensor_board(self, log_file_dir): tf.summary.scalar('benefit', self._agent.portfolio_value) tf.summary.scalar('log_mean', self._agent.log_mean) tf.summary.scalar('loss', self._agent.loss) tf.summary.scalar("log_mean_free", self._agent.log_mean_free) self.summary = tf.summary.merge_all() location = log_file_dir self.network_writer = tf.summary.FileWriter(location + '/network', self._agent.session.graph) self.test_writer = tf.summary.FileWriter(location + '/test') self.train_writer = tf.summary.FileWriter(location + '/train') def __print_upperbound(self): upperbound_test = self.calculate_upperbound(self.test_set["y"]) logging.info("upper bound in test is %s" % upperbound_test) def train_net(self, log_file_dir="./tensorboard", index="0"): """ :param log_file_dir: logging of the training process :param index: sub-folder name under train_package :return: the result named tuple """ self.__print_upperbound() if log_file_dir: if self.device == "cpu": with tf.device("/cpu:0"): self.__init_tensor_board(log_file_dir) else: self.__init_tensor_board(log_file_dir) starttime = time.time() total_data_time = 0 total_training_time = 0 for i in range(self.train_config["steps"]): step_start = time.time() x, y, last_w, setw = self.next_batch() finish_data = time.time() total_data_time += (finish_data - step_start) self._agent.train(x, y, last_w=last_w, setw=setw) total_training_time += time.time() - finish_data if i % 1000 == 0 and log_file_dir: logging.info("average time for data accessing is %s"%(total_data_time/1000)) logging.info("average time for training is %s"%(total_training_time/1000)) total_training_time = 0 total_data_time = 0 self.log_between_steps(i) if self.save_path: self._agent.recycle() best_agent = NNAgent(self.config, restore_dir=self.save_path) self._agent = best_agent pv, log_mean = self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean) logging.warning('the portfolio value train No.%s is %s log_mean is %s,' ' the training time is %d seconds' % (index, pv, log_mean, time.time() - starttime)) return self.__log_result_csv(index, time.time() - starttime) def __log_result_csv(self, index, time): from pgportfolio.trade import backtest dataframe = None csv_dir = './train_package/train_summary.csv' tflearn.is_training(False, self._agent.session) v_pv, v_log_mean, benefit_array, v_log_mean_free =\ self._evaluate("test", self._agent.portfolio_value, self._agent.log_mean, self._agent.pv_vector, self._agent.log_mean_free) backtest = backtest.BackTest(self.config.copy(), net_dir=None, agent=self._agent) backtest.start_trading() result = Result(test_pv=[v_pv], test_log_mean=[v_log_mean], test_log_mean_free=[v_log_mean_free], test_history=[''.join(str(e)+', ' for e in benefit_array)], config=[json.dumps(self.config)], net_dir=[index], backtest_test_pv=[backtest.test_pv], backtest_test_history=[''.join(str(e)+', ' for e in backtest.test_pc_vector)], backtest_test_log_mean=[np.mean(np.log(backtest.test_pc_vector))], training_time=int(time)) new_data_frame = pd.DataFrame(result._asdict()).set_index("net_dir") if os.path.isfile(csv_dir): dataframe = pd.read_csv(csv_dir).set_index("net_dir") dataframe = dataframe.append(new_data_frame) else: dataframe = new_data_frame if int(index) > 0: dataframe.to_csv(csv_dir) return result