Exemplo n.º 1
0
    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