Exemplo n.º 1
0
 def get_features(self, prices):
     """
     Compute the technical features of a position and feed that
     into the Q-Learning process
     
     TODO: Try different parameters to see if you can improve
           the portfolio
           
     Try out different window sizes (right now set to 10 trading days)
     
     prices: Adjusted close prices of the given symbol
     
     df_features: A pandas dataframe of the technical indicators
     """
     
     rolling_mean = prices.rolling(window=self.window_size).mean()
     rolling_std = prices.rolling(window=self.window_size).std()
     
     momentum      = get_momentum(prices, self.window_size)
     sma_indicator = get_sma_indicator(prices, rolling_mean)
     
     bollinger_val = compute_bollinger_value(prices, rolling_mean, rolling_std)
     
     df_features   = pd.concat([momentum, sma_indicator], axis=1)
     df_features   = pd.concat([df_features, bollinger_val], axis=1)
     df_features.columns = ["ind{}".format(i) 
                             for i in range(len(df_features.columns))]
     
     # Perhaps you can come up with a different feature?
     # Try it!
     
     df_features.dropna(inplace=True)
     return df_features
Exemplo n.º 2
0
    def get_features(self, prices):
        """Compute technical indicators and use them as features to be fed
        into a Q-learner.

        Parameters:
        prices: Adjusted close prices of the given symbol

        Returns:
        df_features: A pandas dataframe of the technical indicators
        """
        window = 10
        # Compute rolling mean
        rolling_mean = prices.rolling(window=window).mean()
        # Compute_rolling_std
        rolling_std = prices.rolling(window=window).std()
        # Compute momentum
        momentum = get_momentum(prices, window)
        # Compute SMA indicator
        sma_indicator = get_sma_indicator(prices, rolling_mean)
        # Compute Bollinger value
        bollinger_val = compute_bollinger_value(prices, rolling_mean, rolling_std)
        # Create a dataframe with three features
        df_features = pd.concat([momentum, sma_indicator], axis=1)
        df_features = pd.concat([df_features, bollinger_val], axis=1)
        df_features.columns = ["ind{}".format(i)
                                for i in range(len(df_features.columns))]
        df_features.dropna(inplace=True)
        return df_features
Exemplo n.º 3
0
    def trading_strategy(self, sym_price):
        """Create a dataframe of order signals that maximizes portfolio's return.
        This function has been optimized for the symbol and training period in 
        the main function

        Parameters:
        sym_price: The price series of a stock symbol of interest

        Returns:
        df_order_signals: A series that contains 1 for buy, 0 for hold and -1 for sell
        """

        # Get momentum indicator and generate signals
        momentum = get_momentum(sym_price, 40)
        mom_signal = -1 * (momentum < -0.07) + 1 * (momentum > 0.14)

        # Get RSI indicator and generate signals
        rsi_indicator = get_RSI(sym_price)
        rsi_signal = 1 * (rsi_indicator < 50) + -1 * (rsi_indicator > 50)

        # Get SMA indicator and generate signals
        sma_indicator = get_sma_indicator(sym_price,
                                          sym_price.rolling(window=30).mean())
        sma_signal = 1 * (sma_indicator < 0.0) + -1 * (sma_indicator > 0.0)

        # Combine individual signals
        signal = 1 * ((sma_signal == 1) & (rsi_signal == 1) & (mom_signal == 1)) \
            + -1 * ((sma_signal == -1) & (rsi_signal == -1) & (mom_signal == -1))

        # Create an order series with 0 as default values
        self.df_order_signals = signal * 0

        # Keep track of net signals which are constrained to -1, 0, and 1
        net_signals = 0
        for date in self.df_order_signals.index:
            net_signals = self.df_order_signals.loc[:date].sum()

            # If net_signals is not long and signal is to buy
            if (net_signals < 1) and (signal.loc[date] == 1):
                self.df_order_signals.loc[date] = 1

            # If net_signals is not short and signal is to sell
            elif (net_signals > -1) and (signal.loc[date] == -1):
                self.df_order_signals.loc[date] = -1

        # On the last day, close any open positions
        if self.df_order_signals.sum() == -1:
            self.df_order_signals[-1] = 1
        elif self.df_order_signals.sum() == 1:
            self.df_order_signals[-1] = -1

        return self.df_order_signals
Exemplo n.º 4
0
    def get_features1(self, prices, symbol, print=False):
        '''
        Compute technical indicators and use them as features to be fed
        into a Q-learner.
        :param: prices: Adj Close prices dataframe
        :param: Whether adding data for printing to dataframe or not
        :return: Normalize Features dataframe
        '''

        # Fill NAN values if any
        prices.fillna(method="ffill", inplace=True)
        prices.fillna(method="bfill", inplace=True)
        prices.fillna(1.0, inplace=True)

        # Price
        adj_close = prices[symbol]

        # Compute Momentum
        mom = get_momentum(adj_close, window=10)

        # Compute RSI
        rsi = get_RSI(adj_close)

        # Compute rolling mean
        rm = get_rolling_mean(adj_close, window=10)

        # Compute rolling standard deviation
        rstd = get_rolling_std(adj_close, window=10)

        # Compute upper and lower bands
        upper_band, lower_band = get_bollinger_bands(rm, rstd)



        # Compute SMA
        sma = get_sma_indicator(adj_close, rm)

        df = prices.copy()
        df['Momentum'] = mom
        df['Adj. Close/SMA'] = adj_close/sma
        df['middle_band'] = rm

        # Delete 'Adj Close' column
        del df[symbol]

        if set(['cash']).issubset(df.columns):
            del df['cash']

        # Normalize dataframe
        df_norm = normalize_data(df)

        # Add Adj Close, Bollinrt Bands and RSY if printing
        if print:
            df_norm['Adj Close'] = prices[symbol]
            df_norm['upper_band'] = upper_band
            df_norm['lower_band'] = lower_band
            df_norm['middle_band'] = rm
            df_norm['RSI'] = rsi



        # Drop NaN
        df_norm.dropna(inplace=True)

        return df_norm