Beispiel #1
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)
     # Get RSI indicator
     rsi_indicator = get_RSI(prices, window)
     # 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, rsi_indicator], axis=1)
     df_features.columns = [
         "ind{}".format(i) for i in range(len(df_features.columns))
     ]
     df_features.dropna(inplace=True)
     return df_features
    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
Beispiel #3
0
    def addEvidence(self, symbol="AAPL", sd=dt.datetime(2008,1,1), ed=dt.datetime(2009,12,31), sv=100000):

        syms = [symbol]
        dates = pd.date_range(sd, ed)
        total_prices = ut.get_data(syms, dates)
        prices = total_prices[syms]
        psr = get_Price_SMA_Ratio(symbols=syms,dates=dates,lookback=14)
        rsi = get_RSI(symbols=syms,dates=dates,lookback=14)
        mfi = get_MFI(symbols=syms,dates=dates,lookback=14)
        spsr = psr.ix[:,symbol]
        srsi = rsi.ix[:,symbol]
        smfi = mfi.ix[:,symbol]
        dpsr=self.Discretization(spsr,steps=5)
        drsi=self.Discretization(srsi,steps=5)
        dmfi=self.Discretization(smfi,steps=5)

        prices = prices.ix[:,symbol]
        dr = prices.copy()
        dr[0] = np.nan
        dr[1:] = (prices[1:] / prices[:-1].values) - 1

        States = dpsr * 100 + drsi + dmfi
        States = States.ix[:,'discretized_value']
        self.learner = ql.QLearner(num_states=1000, num_actions=3)
        oldprofit = 0
        for iteration in range(100):
            current_holding = 0
            total_profit = 0
            rewards = 0
            for i in range(dr.shape[0] - 1):
                if (i > 0):
                    total_profit += prices[i - 1] * current_holding * dr[i]
                state = States[i]
                if i == 0:
                    action = self.learner.querysetstate(state)
                else:
                    action = self.learner.query(state, rewards)
                holding, rewards = self.trade_actions(current_holding, action, dr[i + 1])
                current_holding = holding
            total_profit += prices[-2] * current_holding * dr[-1]
            if total_profit == oldprofit:
                break
            oldprofit = total_profit
Beispiel #4
0
    def testPolicy(self,symbol,sd,ed,sv):
        symbols = []
        symbols.append(symbol)
        dates = pd.date_range(sd, ed)
        price = get_data(symbols, dates)
        orders = []
        holdings = {sym: 0 for sym in symbols}
        lookback = 14
        psr = get_Price_SMA_Ratio(symbols,dates,lookback=14)
        rsi = get_RSI(symbols,dates,lookback=14)
        mfi = get_MFI(symbols,dates)
        
        for day in range(price.shape[0]):
            for sym in symbols:
                if (psr.ix[day, sym] < 1.05) and (rsi.ix[day, sym] < 15) and (mfi.ix[day, sym] < 10):
                    if holdings[sym] < 1000:
                        holdings[sym] = holdings[sym] + 1000
                        orders.append([price.index[day].date(), sym, 'BUY', 1000])
                    else:
                        orders.append([price.index[day].date(), sym, 'NOTHING', 0])
                elif (psr.ix[day, sym] > 0.95) and (rsi.ix[day, sym] > 55) and (mfi.ix[day, sym] > 40):
                    if holdings[sym] > -1000:
                        holdings[sym] = holdings[sym] - 1000
                        orders.append([price.index[day].date(), sym, 'SELL', 1000])
                    else:
                        orders.append([price.index[day].date(), sym, 'NOTHING', 0])
                elif (psr.ix[day, sym] < 1) and (psr.ix[day-1,sym] > 1) and (holdings[sym] < 0):
                    holdings[sym] = holdings[sym] + 1000
                    orders.append([price.index[day].date(), sym, 'BUY', 1000])
                elif (psr.ix[day, sym] > 1) and (psr.ix[day-1,sym] < 1) and (holdings[sym] > 0):
                    holdings[sym] = holdings[sym] - 1000
                    orders.append([price.index[day].date(), sym, 'SELL', 1000])
                else:
                    orders.append([price.index[day].date(), sym, 'NOTHING', 0])

        df_trades = pd.DataFrame(orders, columns=["Date", "Symbol", "Order", "Shares"])
        df_trades.set_index('Date', inplace=True)
        return df_trades
Beispiel #5
0
    def testPolicy(self, symbol="AAPL", sd=dt.datetime(2010,1,1), ed=dt.datetime(2011,12,31), sv=100000):

        dates = pd.date_range(sd, ed)
        total_prices = ut.get_data([symbol], dates)
        syms = [symbol]
        prices = total_prices[syms]
        psr = get_Price_SMA_Ratio(symbols=syms, dates=dates, lookback=14)
        rsi = get_RSI(symbols=syms, dates=dates, lookback=14)
        mfi = get_MFI(symbols=syms, dates=dates, lookback=14)
        spsr = psr.ix[:, symbol]
        srsi = rsi.ix[:, symbol]
        smfi = mfi.ix[:, symbol]
        dpsr = self.Discretization(spsr, steps=5)
        drsi = self.Discretization(srsi, steps=5)
        dmfi = self.Discretization(smfi, steps=5)
        States = dpsr * 100 + drsi + dmfi
        States = States.ix[:, 'discretized_value']
        prices = prices.ix[:, symbol]
        dr = prices.copy()
        trades = prices.copy()
        trades[:] = 0
        dr[0] = 0
        dr[1:] = (prices[1:] / prices[:-1].values) - 1
        current_holding = 0
        total_profit = 0
        for i in range(len(dr)- 1):
            if (i > 0):
                total_profit += prices[i - 1] * current_holding * dr[i]
            state = States[i]
            action = self.learner.querysetstate(state)
            holding, rewards = self.trade_actions(current_holding, action, dr[i + 1])
            trades[i] = (holding - current_holding)
            current_holding = holding
        total_profit += prices[-2] * current_holding * dr[-1]
        trades = pd.DataFrame(trades, columns=[symbol])
        return trades
Beispiel #6
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
Beispiel #7
0
def showvalues():
    # Specify the start and end dates for this period.
    start_d = dt.date(2008, 1, 1)
    #end_d = dt.datetime(2018, 10, 30)
    yesterday = dt.date.today() - dt.timedelta(1)

    # Get portfolio values from Yahoo
    symbol = request.form['symbol']
    portf_value = fetchOnlineData(start_d, yesterday, symbol)

    # ****Stock prices chart****
    plot_prices = plot_stock_prices(portf_value.index,
                                    portf_value['Adj Close'], symbol)

    # ****Momentum chart****
    # Normalize the prices Dataframe
    normed = pd.DataFrame()
    normed['Adj Close'] = portf_value['Adj Close'].values / portf_value[
        'Adj Close'].iloc[0]

    # Compute momentum
    sym_mom = get_momentum(normed['Adj Close'], window=10)

    # Create momentum chart
    plot_mom = plot_momentum(portf_value.index, normed['Adj Close'], sym_mom,
                             "Momentum Indicator", (12, 8))

    # ****Bollinger Bands****
    # Compute rolling mean
    rm_JPM = get_rolling_mean(portf_value['Adj Close'], window=10)

    # Compute rolling standard deviation
    rstd_JPM = get_rolling_std(portf_value['Adj Close'], window=10)

    # Compute upper and lower bands
    upper_band, lower_band = get_bollinger_bands(rm_JPM, rstd_JPM)

    # Plot raw symbol values, rolling mean and Bollinger Bands
    dates = pd.date_range(start_d, yesterday)
    plot_boll = plot_bollinger(dates,
                               portf_value.index,
                               portf_value['Adj Close'],
                               symbol,
                               upper_band,
                               lower_band,
                               rm_JPM,
                               num_std=1,
                               title="Bollinger Indicator",
                               fig_size=(12, 6))

    # ****Simple moving average (SMA)****
    # Compute SMA
    sma_JPM, q = get_sma(normed['Adj Close'], window=10)

    # Plot symbol values, SMA and SMA quality
    plot_sma = plot_sma_indicator(dates, portf_value.index,
                                  normed['Adj Close'], symbol, sma_JPM, q,
                                  "Simple Moving Average (SMA)")

    # ****Relative Strength Index (RSI)****
    # Compute RSI
    rsi_value = get_RSI(portf_value['Adj Close'])

    # Plot RSI
    plot_rsi = plot_rsi_indicator(dates,
                                  portf_value.index,
                                  portf_value['Adj Close'],
                                  symbol,
                                  rsi_value,
                                  window=14,
                                  title="RSI Indicator",
                                  fig_size=(12, 6))

    # Session variables
    session['start_val'] = request.form['start_val']
    session['symbol'] = request.form['symbol']
    session['start_d'] = start_d.strftime('%Y/%m/%d')
    session['num_shares'] = request.form['num_shares']
    session['commission'] = request.form['commission']
    session['impact'] = request.form['impact']

    return render_template(
        # name of template
        "stockpriceschart.html",

        # now we pass in our variables into the template
        start_val=request.form['start_val'],
        symbol=request.form['symbol'],
        commission=request.form['commission'],
        impact=request.form['impact'],
        num_shares=request.form['num_shares'],
        start_date=start_d,
        end_date=yesterday,
        tables=[portf_value.to_html(classes=symbol)],
        titles=['na', 'Stock Prices '],
        div_placeholder_stock_prices=Markup(plot_prices),
        div_placeholder_momentum=Markup(plot_mom),
        div_placeholder_bollinger=Markup(plot_boll),
        div_placeholder_sma=Markup(plot_sma),
        div_placeholder_rsi=Markup(plot_rsi))