def test_eq__wrong_instance(self): portfolio = Portfolio(10.0, [SharesOfCompany(CompanyEnum.COMPANY_A, 200)]) assert portfolio != "a string"
def doTrade(self, portfolio: Portfolio, current_portfolio_value: float, stock_market_data: StockMarketData) -> OrderList: """ Generate action to be taken on the "stock market" Args: portfolio : current Portfolio of this trader current_portfolio_value : value of Portfolio at given moment stock_market_data : StockMarketData for evaluation Returns: A OrderList instance, may be empty never None """ # TODO: Store experience and train the neural network only if doTrade was called before at least once # TODO: Create actions for current state and decrease epsilon for fewer random actions # TODO: Save created state, actions and portfolio value for the next call of doTrade deltaA = self.stock_a_predictor.doPredict( stock_market_data[CompanyEnum.COMPANY_A]) / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A) deltaB = self.stock_b_predictor.doPredict( stock_market_data[CompanyEnum.COMPANY_B]) / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B) INPUT = numpy.asarray([[ (deltaA - 1.0) / 0.04, (deltaB - 1.0) / 0.04, ]]) qualities = self.model.predict(INPUT)[0] qmax = max(qualities[0], qualities[1], qualities[2]) currentValue = portfolio.total_value(stock_market_data.get_most_recent_trade_day(), stock_market_data) if self.lastValue and self.train_while_trading: lastReward = min(1, max(-1, (currentValue / self.lastValue - 1) / 0.04)) shouldBeQ = lastReward + GAMMA * qmax self.lastOutput[self.lastAmax] = shouldBeQ xtrain = [self.lastInput[0]] ytrain = [self.lastOutput] for m in self.memory: xtrain.append(m[0][0]) qs = self.model.predict(m[0])[0] qs[m[1]] = m[2] + GAMMA * qs[m[1]] ytrain.append(qs) self.model.fit(numpy.asarray(xtrain), numpy.asarray(ytrain)) self.memory.append([self.lastInput, self.lastAmax, lastReward]) if len(self.memory) > MEMOMRY_SIZE: self.memory.pop(0) self.lastValue = currentValue self.lastInput = INPUT self.lastOutput = qualities result = OrderList() actions = ["BUY_A__SELL_B", "BUY_A", "BUY_B__SELL_A", "BUY_B", "SELL_ALL"] nextAction = None if random.random() < self.epsilon and self.train_while_trading: nextAction = actions[random.randint(0, self.action_size - 1)] else: i = 0 if qualities[0] > qualities[1] else 1 i = 2 if qualities[2] > qualities[i] else i i = 3 if qualities[3] > qualities[i] else i i = 4 if qualities[4] > qualities[i] else i nextAction = actions[i] self.epsilon = max(self.epsilon_decay * self.epsilon, self.epsilon_min) if nextAction == "BUY_A__SELL_B": result.sell(CompanyEnum.COMPANY_B, portfolio.get_amount(CompanyEnum.COMPANY_B)) count = math.floor(portfolio.cash / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A)) result.buy(CompanyEnum.COMPANY_A, count) self.lastAmax = 0 elif nextAction == "BUY_A": count = math.floor(portfolio.cash / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A)) result.buy(CompanyEnum.COMPANY_A, count) self.lastAmax = 1 elif nextAction == "BUY_B__SELL_A": result.sell(CompanyEnum.COMPANY_A, portfolio.get_amount(CompanyEnum.COMPANY_A)) count = math.floor(portfolio.cash / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B)) result.buy(CompanyEnum.COMPANY_B, count) self.lastAmax = 2 elif nextAction == "BUY_B": count = math.floor(portfolio.cash / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B)) result.buy(CompanyEnum.COMPANY_B, count) self.lastAmax = 3 elif nextAction == "SELL_ALL": result.sell(CompanyEnum.COMPANY_A, portfolio.get_amount(CompanyEnum.COMPANY_A)) result.sell(CompanyEnum.COMPANY_B, portfolio.get_amount(CompanyEnum.COMPANY_B)) self.lastAmax = 4 return result
""" save_keras_sequential(self.model, self.RELATIVE_DATA_DIRECTORY, self.network_filename) # This method retrains the trader from scratch using training data from PERIOD_1 and test data from PERIOD_2 EPISODES = 7 if __name__ == "__main__": # Read the training data training_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1]) test_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1, PERIOD_2]) start_training_day, final_training_day = dt.date(2009, 1, 2), dt.date(2011, 12, 29) start_test_day, final_test_day = dt.date(2012, 1, 3), dt.date(2015, 12, 30) # Define initial portfolio name = 'DQL trader portfolio' portfolio = Portfolio(10000.0, [], name) # Initialize trader: use perfect predictors, don't use an already trained model, but learn while trading trader = TeamGreenDqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False, True, MODEL_FILENAME_DQLTRADER_PERFECT_PREDICTOR) # trader = DqlTrader(StockANnPerfectBinaryPredictor(), StockBNnPerfectBinaryPredictor(), False, True, MODEL_FILENAME_DQLTRADER_PERFECT_NN_BINARY_PREDICTOR) # trader = TeamGreenDqlTrader(StockANnBinaryPredictor(), StockBNnBinaryPredictor(), False, True, MODEL_FILENAME_DQLTRADER_NN_BINARY_PREDICTOR) # Start evaluation and train correspondingly; don't display the results in a plot but display final portfolio value evaluator = PortfolioEvaluator([trader], False) final_values_training, final_values_test = [], [] for i in range(EPISODES): logger.info(f"DQL Trader: Starting training episode {i}") all_portfolios_over_time = evaluator.inspect_over_time(training_data, [portfolio], date_offset=start_training_day) portfolio_over_time = all_portfolios_over_time[name]
def doTrade(self, portfolio: Portfolio, current_portfolio_value: float, stock_market_data: StockMarketData) -> OrderList: """ Generate action to be taken on the "stock market" Args: portfolio : current Portfolio of this trader current_portfolio_value : value of Portfolio at given moment stock_market_data : StockMarketData for evaluation Returns: A OrderList instance, may be empty never None """ # TODO: Build and store current state object ## cash %, portfolio a value %, portfolio b %, pred a, pred b account_value = portfolio.cash + current_portfolio_value a_value = portfolio.get_amount(CompanyEnum.COMPANY_A) * stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A) b_value = portfolio.get_amount(CompanyEnum.COMPANY_B) * stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B) a_value_percent = a_value / account_value b_value_percent = b_value / account_value cash_percent = portfolio.cash / account_value pred_a_value = self.stock_a_predictor.doPredict(stock_market_data[CompanyEnum.COMPANY_A]) pred_b_value = self.stock_b_predictor.doPredict(stock_market_data[CompanyEnum.COMPANY_B]) stock_a_value = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A) stock_b_value = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B) increase_a = (pred_a_value - stock_a_value) / stock_a_value increase_b = (pred_b_value - stock_b_value) / stock_b_value current_status = [[cash_percent, a_value_percent, b_value_percent, increase_a, increase_b]] np_current_status = np.array(current_status) # TODO: Store experience and train the neural network only if doTrade was called before at least once ## calc rewards = was cash + portfolio - (old cash + old portfolio), map auf 1 0 -1, now simple: if self.stored_action >= 0: if current_portfolio_value > self.stored_portfolio_value: reward = 1.0 elif current_portfolio_value < self.stored_portfolio_value: reward = -1.0 else: reward = 0 reward_array = [0, 0, 0] reward_array[self.stored_action] = reward np_reward_array = np.array([reward_array]) ## train again # print(np_reward_array) if self.train_while_trading: self.model.fit(self.np_previous_status, np_reward_array, epochs=1, batch_size=1, verbose=0) # TODO: Create actions for current state and decrease epsilon for fewer random actions action = -1 random_value = uniform(0.0, 1.0) if random_value > self.epsilon: action = randint(0, 2) else: pred = self.model.predict(np_current_status) prediction = pred[0] if len(prediction) != 3: print("komische prediction") action = 2 max = prediction[action] for i in range(3): if prediction[i] > max: action = i self.count[action] = self.count[action] + 1 # print("actions") # print(self.count) self.epsilon = self.epsilon * self.epsilon_decay if self.epsilon < self.epsilon_min: self.epsilon = self.epsilon_min order_list = OrderList() if action < 0 or action > 2: print("komische action") print(action) else: stock_a = portfolio.get_amount(CompanyEnum.COMPANY_A) stock_b = portfolio.get_amount(CompanyEnum.COMPANY_B) if action == 0: # sell a if stock_a > 0: order_list.sell(CompanyEnum.COMPANY_A, stock_a) # buy b count_b = portfolio.cash / stock_b_value if count_b > 0: order_list.buy(CompanyEnum.COMPANY_B, int(count_b)) if action == 1: # sell b if stock_b > 0: order_list.sell(CompanyEnum.COMPANY_B, stock_b) # boy a count_a = portfolio.cash / stock_a_value if count_a > 0: order_list.buy(CompanyEnum.COMPANY_A, int(count_a)) # TODO: Save created state, actions and portfolio value for the next call of self.stored_action = action self.stored_portfolio_value = current_portfolio_value self.np_previous_status = np_current_status ## save current state as laststate, current portfolio and cash return order_list
def testCreateActionList(self): trader = DqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False) self.assertIsNotNone(trader) portfolio = Portfolio(10000, []) stock_market_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_3]) self.assertIsNotNone(stock_market_data) # Check doing nothing # commented because that STOCKACTION is not used anymore # action_a, action_b = 0.0, 0.0 # order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data) # self.assertIsNotNone(order_list) # self.assertTrue(order_list.is_empty()) # Check buying halve stock # commented because that STOCKACTION is not used anymore # action_a, action_b = 0.5, 0.5 # order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data) # self.assertIsNotNone(order_list) # self.assertEqual(order_list.get(0).action, OrderType.BUY) # self.assertEqual(order_list.get(0).shares.company_enum, CompanyEnum.COMPANY_A) # self.assertEqual(order_list.get(0).shares.amount, 49) # self.assertEqual(order_list.get(1).action, OrderType.BUY) # self.assertEqual(order_list.get(1).shares.company_enum, CompanyEnum.COMPANY_B) # self.assertEqual(order_list.get(1).shares.amount, 33) # Check buying full stock action_a, action_b = 1.0, 1.0 order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data) self.assertIsNotNone(order_list) order_1 = order_list[0] order_2 = order_list[1] self.assertEqual(order_1.action, OrderType.BUY) self.assertEqual(order_1.shares.company_enum, CompanyEnum.COMPANY_A) self.assertEqual(order_1.shares.amount, 98) self.assertEqual(order_2.action, OrderType.BUY) self.assertEqual(order_2.shares.company_enum, CompanyEnum.COMPANY_B) self.assertEqual(order_2.shares.amount, 66) # Check selling stock without enough owned shares action_a, action_b = -1.0, -1.0 order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data) self.assertIsNotNone(order_list) self.assertTrue(order_list.is_empty()) # Check selling halve stock with enough owned shares # commented because that STOCKACTION is not used anymore # portfolio = Portfolio(10000, [SharesOfCompany(CompanyEnum.COMPANY_A, 2), SharesOfCompany(CompanyEnum.COMPANY_B, 2)]) # action_a, action_b = -0.5, -0.5 # order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data) # self.assertIsNotNone(order_list) # self.assertEqual(order_list.get(0).action, OrderType.SELL) # self.assertEqual(order_list.get(0).shares.company_enum, CompanyEnum.COMPANY_A) # self.assertEqual(order_list.get(0).shares.amount, 2) # self.assertEqual(order_list.get(1).action, OrderType.SELL) # self.assertEqual(order_list.get(1).shares.company_enum, CompanyEnum.COMPANY_B) # self.assertEqual(order_list.get(1).shares.amount, 1) # Check selling full stock with enough owned shares portfolio = Portfolio(10000, [SharesOfCompany(CompanyEnum.COMPANY_A, 2), SharesOfCompany(CompanyEnum.COMPANY_B, 2)]) action_a, action_b = -1.0, -1.0 order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data) self.assertIsNotNone(order_list) order_1 = order_list[0] order_2 = order_list[1] self.assertEqual(order_1.action, OrderType.SELL) self.assertEqual(order_1.shares.company_enum, CompanyEnum.COMPANY_A) self.assertEqual(order_1.shares.amount, 2) self.assertEqual(order_2.action, OrderType.SELL) self.assertEqual(order_2.shares.company_enum, CompanyEnum.COMPANY_B) self.assertEqual(order_2.shares.amount, 2)
if __name__ == '__main__': portfolio = 'Norway' portfolio_obj = Portfolio('Norway') powerplant_df = get_powerplants_by_portfolio(portfolio) # powerplant_df.to_csv("ppd.csv") """ 1 Convert PCUC file and save it to KEAN """ # plant_tech_master_file = r"C:\Users\cliu\Kindle Energy Dropbox\Chang Liu\LBO\data\Norway\pcuc\Norway plant char assumption_input v11.xlsx" # pc_date_start = date(2020, 1, 1) # pc_date_end = date(2027,12,31) # pc_scenario = 'Norway Converted' # pc_version = 'v1' # # run_convert_uc(plant_tech_master_file, pc_date_start, pc_date_end, pc_scenario, pc_version) # run_convert_uc('Norway', pc_date_start, pc_date_end, pc_scenario, pc_version, plant_tech_master_file=plant_tech_master_file, push_to_powerplant=False, push_to_technology=True, push_to_plant_characteristics=False) #