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 Momemnt stock_market_data : StockMarketData for evaluation Returns: A OrderList instance, may be empty never None """ y_a = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A) y_b = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B) p_a = self.stock_a_predictor.doPredict( stock_market_data[CompanyEnum.COMPANY_A]) p_b = self.stock_b_predictor.doPredict( stock_market_data[CompanyEnum.COMPANY_B]) r_a = (p_a - y_a) / y_a * 100 r_b = (p_b - y_b) / y_b * 100 result = OrderList() if (r_a < 0 and portfolio.get_amount(CompanyEnum.COMPANY_A) > 0): result.sell(CompanyEnum.COMPANY_A, portfolio.get_amount(CompanyEnum.COMPANY_A)) if (r_b < 0 and portfolio.get_amount(CompanyEnum.COMPANY_B) > 0): result.sell(CompanyEnum.COMPANY_B, portfolio.get_amount(CompanyEnum.COMPANY_B)) if (r_a <= 0 and r_b <= 0): return result company = CompanyEnum.COMPANY_A if (r_b > r_a): company = CompanyEnum.COMPANY_B buy_amount = math.floor( portfolio.cash / stock_market_data.get_most_recent_price(company)) if (portfolio.cash > 0 and buy_amount > 0): result.buy(company, buy_amount) print("Portfolio: " + str( portfolio.total_value( stock_market_data.get_most_recent_trade_day(), stock_market_data))) # TODO: implement trading logic return result
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 """ current_price_a = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A) current_price_b = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B) predicted_price_a = self.stock_a_predictor.doPredict(stock_market_data[CompanyEnum.COMPANY_A]) predicted_price_b = self.stock_b_predictor.doPredict(stock_market_data[CompanyEnum.COMPANY_B]) portfolio_value = portfolio.total_value( stock_market_data.get_most_recent_trade_day(), stock_market_data) state = State(portfolio_value, current_price_a, predicted_price_a, current_price_b, predicted_price_b) if self.last_state and self.train_while_trading: self.train_model(state, self.last_state) action = self.decide_action(state, self.last_state) orders = self.create_orders(action, portfolio, stock_market_data) self.last_state = state # log_orders(orders) return orders
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 s_a_current = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A) s_b_current = stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B) pct_a = round((s_a_current * portfolio.get_amount(CompanyEnum.COMPANY_A))/portfolio.total_value(stock_market_data.get_most_recent_trade_day(), stock_market_data), 2) pct_b = round((s_b_current * portfolio.get_amount(CompanyEnum.COMPANY_B))/portfolio.total_value(stock_market_data.get_most_recent_trade_day(), stock_market_data), 2) pct_cash = 1 - pct_a - pct_b; s_a_next = self.stock_a_predictor.doPredict(stock_market_data[CompanyEnum.COMPANY_A]); s_b_next = self.stock_b_predictor.doPredict(stock_market_data[CompanyEnum.COMPANY_B]); pct_a_diff = round((s_a_next - s_a_current) / s_a_current, 2); pct_b_diff = round((s_b_next - s_b_current) / s_b_current, 2); portfolio_value = portfolio.total_value(stock_market_data.get_most_recent_trade_day(), stock_market_data); portfolio_diff = round((self.portfolio_value_prev - portfolio_value) / self.portfolio_value_prev, 2); #r = -1; #if (portfolio_diff < 0): # r = 1; #elif (portfolio_diff == 0): # r = 0; if (portfolio_diff < 0): self.y_prev[0][self.idx_prev] = 1; elif (portfolio_diff >= 0): self.y_prev[0][self.idx_prev] = -1; # TODO: Store experience and train the neural network only if doTrade was called before at least once if (self.loop_value > 0): self.model.fit(np.array([[self.pct_a_prev, self.pct_b_prev, self.pct_cash_prev, self.diff_a_prev, self.diff_b_prev]]), self.y_prev, epochs=1, batch_size=1) # TODO: Create actions for current state and decrease epsilon for fewer random actions res = self.model.predict(np.array([[pct_a, pct_b, pct_cash, pct_a_diff, pct_b_diff]])) # [0, 0, 1, 0] idx = np.argmax(res); ret = OrderList() if (idx == 0): ret.buy(CompanyEnum.COMPANY_A, math.floor(portfolio.cash / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_A))) elif (idx == 1): ret.buy(CompanyEnum.COMPANY_B, math.floor(portfolio.cash / stock_market_data.get_most_recent_price(CompanyEnum.COMPANY_B))) elif (idx == 2): ret.sell(CompanyEnum.COMPANY_A, portfolio.get_amount(CompanyEnum.COMPANY_A)) else: ret.sell(CompanyEnum.COMPANY_B, portfolio.get_amount(CompanyEnum.COMPANY_B)) # TODO: Save created state, actions and portfolio value for the next call of doTrade self.portfolio_value_prev = portfolio_value; self.pct_a_prev = pct_a; self.pct_b_prev = pct_b; self.pct_cash_prev = pct_cash; self.diff_a_prev = pct_a_diff; self.diff_b_prev = pct_a_diff; self.idx_prev = idx; self.y_prev = res; self.loop_value = self.loop_value + 1; return ret
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