def test_policy(symbol='AAPL', sd=dt.datetime(2010, 1, 1), ed=dt.datetime(2012, 12, 31),
                st=100000, shares_contraint=1000, look_back_period=14):
    df_trades = create_trades_df(start_date=sd, end_date=ed)
    df_trades.set_index('Date', inplace=True)
    df_trades['Symbol'] = symbol
    df_trades['Order'] = 'NOTHING'
    df_prices_sym = get_data([symbol], pd.date_range(sd, ed), False)
    df_prices_idx = get_data(['SPY'], pd.date_range(sd, ed), False, dropNonTradingSPY=False)
    df_price_filter_sym = df_prices_sym.dropna(subset=[symbol])
    df_price_filter_idx = df_prices_idx.dropna(subset=['SPY'])
    iterator = more_itertools.peekable(df_price_filter_sym.iloc[look_back_period:].iterrows())
    ltd_shares = 0.0
    prev_sym_price_over_sma = indicator.get_price_over_sma(df_price_filter_sym.iloc[:look_back_period])
    for index, row in iterator:
        # get current price to determine when we should close the position.
        df_prices_historical_sym = df_price_filter_sym.loc[:index][-look_back_period:] # Todo: Can we do this in one shot?
        df_prices_historical_idx = df_price_filter_idx.loc[:index][-look_back_period:]

        sym_price_over_sma = indicator.get_price_over_sma(df_prices_historical_sym)
        sym_bollinger_band_percent = indicator.get_bollinger_band_percent(df_prices_historical_sym)
        sym_rsi = indicator.get_rsi(df_prices_historical_sym, look_back_period)
        idx_price_over_sma = indicator.get_price_over_sma(df_prices_historical_idx)
        idx_bollinger_band_percent = indicator.get_bollinger_band_percent(df_prices_historical_idx)
        idx_rsi = indicator.get_rsi(df_prices_historical_idx, look_back_period)
        signal = get_signal(sym_price_over_sma, sym_bollinger_band_percent, sym_rsi, idx_price_over_sma,
                           idx_bollinger_band_percent, idx_rsi, prev_sym_price_over_sma)
        print(signal)
        process_signal(df_trades, index, signal, ltd_shares, shares_contraint)
        ltd_shares = update_life_to_date_shares(ltd_shares, df_trades, index, shares_contraint)
        prev_sym_price_over_sma = sym_price_over_sma
    return df_trades.reset_index()
예제 #2
0
    def get_signal(self, price, ohlc, window=20, ga_train=False):
        symbol = price.dtypes.index[0]
        # Find Candlestick patterns and generate signals
        patterns_signal = pd.DataFrame(0, index=price.index, columns=[symbol])
        found_patterns = cdsd.pattern_signals(ohlc, ['Abandoned Baby', 'Morning Star', 'Evening Star', 'Harami Cross'])
        for pattern in found_patterns:
            patterns_signal.loc[pattern[0]] = pattern[1]

        # Find trendlines and iterlines points and generate signals
        trends, points_signal = ind.get_trendlines(price, charts=False)

        #Get SMA and generate signals
        sma = ind.get_price_sma(price, window=30)
        sma_signal = 1 * (sma < 0.0) + -1 * (sma > 0.0)

        #Get RSI and generate signals
        rsi = ind.get_rsi(price, window=14)
        rsi_signal = 1 * (rsi < 30.0) + -1 * (rsi > 70.0)

        #Get MACD and generate signals
        macd, macdsign, macddiff = ind.get_macd(price, fast_window=12, slow_window=26)
        macd_signal = 1 * (macd>macdsign) + -1 * (macd<macdsign)

        #Get Bollinger Bands and generate signals
        bb_values = ind.get_bollinger_band_values(price, window=30)
        bb_signal = 1 * (bb_values < -1)  + -1 * (bb_values > 1)
        
        pdb.set_trace()
예제 #3
0
 def get_df_with_indicators_single_currency(self, currency_dir):
     logger.log_info(
         "Calculating technical indicators for data from {}.".format(
             currency_dir))
     df_result = self.get_tf_resampled_single_currency_raw_data_with_base(
         currency_dir)
     for period in config.MA_PERIODS:
         df_result = indicators.get_ma(df_result, "close", period)
     for period in config.RSI_PERIODS:
         df_result = indicators.get_rsi(df_result, "close", period)
     return df_result
예제 #4
0
    def buildIndicators(self, df_prices, symbol="IBM"):
        """
        Build (panda Series) indicators from the prices dataframe
        @params df_prices: the prices dataframe
        @params symbol: the asset's symbol
        5,10,20,30
        """
        # rolling bollinger band
        self.bband = idc.get_bbands(pd.DataFrame(df_prices,
                                                 index=df_prices.index,
                                                 columns=[symbol]),
                                    self.window_size,
                                    symbol=symbol).dropna()
        # fixing treshold for consistencies before normalization
        self.bband[self.bband < -1] = -1
        self.bband[self.bband > 1] = 1
        self.discretize_bband = self.normalizeIndicators(self.bband)

        # rolling momentum abs
        self.momentum = idc.get_momentum(pd.DataFrame(df_prices,
                                                      index=df_prices.index,
                                                      columns=[symbol]),
                                         self.window_size,
                                         symbol=symbol).dropna()
        self.momentum[self.momentum < -0.3] = -0.3
        self.momentum[self.momentum > 0.3] = 0.3
        self.discretize_momentum = self.normalizeIndicators(self.momentum)

        # rolling standard deviation
        self.rstd = pd.Series(pd.rolling_std(df_prices, window=2),
                              name='rstd').dropna()
        self.rstd[self.rstd < 0.5] = 0.5
        self.rstd[self.rstd > 4] = 4
        self.discretize_rstd = self.normalizeIndicators(self.rstd)

        # rolling rsi
        self.rsi = idc.get_rsi(df_prices, self.window_size).dropna()
        self.rsi[self.rsi < 40] = 40
        self.rsi[self.rsi > 70] = 70
        self.discretize_rsi = self.normalizeIndicators(self.rsi)

        self.discretize_holding = {0: 0, -1000: 1, 1000: 2}
        self.n_states = int(3 * 10**4)
예제 #5
0
    def trade_strategy(self, price, ohlc, ga_train=False):
        """
        Create a dataframe of order signals that maximizes portfolio return
        Signals:
            buy  = 1
            hold = 0
            sell  = -1
        """
        symbol = price.dtypes.index[0]
        
        # Find Candlestick patterns and generate signals
        patterns_signal = pd.DataFrame(0, index=price.index, columns=[symbol])
        found_patterns = cdsd.pattern_signals(ohlc, ['Abandoned Baby', 'Morning Star', 'Evening Star', 'Harami Cross'])
        for pattern in found_patterns:
            patterns_signal.loc[pattern[0]] = pattern[1]

        # Find trendlines and iterlines points and generate signals
        trends, points_signal = ind.get_trendlines(price, charts=False)

        #Get SMA and generate signals
        sma = ind.get_price_sma(price, window=30)
        sma_signal = 1 * (sma < 0.0) + -1 * (sma > 0.0)

        #Get RSI and generate signals
        rsi = ind.get_rsi(price, window=14)
        rsi_signal = 1 * (rsi < 30.0) + -1 * (rsi > 70.0)

        #Get MACD and generate signals
        macd, macdsign, macddiff = ind.get_macd(price, fast_window=12, slow_window=26)
        macd_signal = 1 * (macd>macdsign) + -1 * (macd<macdsign)

        #Get Bollinger Bands and generate signals
        bb_values = ind.get_bollinger_band_values(price, window=30)
        bb_signal = 1 * (bb_values < -1)  + -1 * (bb_values > 1)
            
        #pdb.set_trace()
        
        #Combine signals
        if type(ga_train)==bool:
            signal = 1 * ( ((patterns_signal==1)*0.2 + (macd_signal==1)*0.2 + (sma_signal==1)*0.2 + (rsi_signal==1)*0.2 + (bb_signal==1)*0.2) + (points_signal==1)*0.4 >= 0.8) + -1 * ( ((patterns_signal==-1)*0.2 + (macd_signal==-1)*0.2 + (sma_signal==-1)*0.2 + (rsi_signal==-1)*0.2 + (bb_signal==-1)*0.2) + (points_signal==-1)*0.4 >= 0.8)
        else:
            signal = 1 * ( ((patterns_signal==1)*ga_train[0] + (macd_signal==1)*ga_train[1] + (sma_signal==1)*ga_train[2] + (rsi_signal==1)*ga_train[3] + (bb_signal==1)*ga_train[4]) + (points_signal==1)*ga_train[5] >= ga_train[6]) + -1 * ( ((patterns_signal==-1)*ga_train[0] + (macd_signal==-1)*ga_train[1] + (sma_signal==-1)*ga_train[2] + (rsi_signal==-1)*ga_train[3] + (bb_signal==-1)*ga_train[4]) + (points_signal==-1)*ga_train[5] >= ga_train[6])
            
        # 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).values[0] and (signal.loc[date]==1).values[0]:
                self.df_order_signals.loc[date]=1
                
            # If net_signals is not short and signal is to sell
            elif (net_signals > -1).values[0] and (signal.loc[date]==-1).values[0]:
                self.df_order_signals.loc[date]=-1
        
        if trends != None:
            trades = self.df_order_signals[self.df_order_signals[symbol]!=0]
            for i in range(len(trades)):
                date = trades.index[i]
                signal = trades.ix[i][0]
                #closest_trend, slope = ind.get_closest_trendline([date, price.loc[date][0]], trends, max_sep=0.3)
                closest_trend, slope = ind.get_closest_trendline([date, price.loc[date][0]], trends)
                if closest_trend != None:
                    if closest_trend == "Resistance":
                        #pdb.set_trace()
                        if signal==1 and slope>0:
                            self.df_order_signals.loc[date] = 0
                    elif closest_trend == "Support":
                        if signal==-1 and slope<0:
                            self.df_order_signals.loc[date] = 0

        #pdb.set_trace()
        
        
        # On the last day, close any open positions
        if self.df_order_signals.values.sum() == -1:
            # Found short position
            self.df_order_signals.ix[-1] = 1
        if self.df_order_signals.values.sum() == 1:
            # Found held position
            self.df_order_signals.ix[-1]=-1
            
        # Alternative close positions
        open_pos = self.df_order_signals.values.sum()
        if open_pos != 0:
            self.df_order_signals.ix[-1] = -1 * open_pos
        
        #pdb.set_trace()
            
        return self.df_order_signals
예제 #6
0
def testPolicyMixed(n_days_bb=20,
                    n_days_mtum=20,
                    n_days_std=20,
                    n_days_rsi=20,
                    tresh_bb=1,
                    tresh_mmtum=0.2,
                    tresh_std_low=1,
                    tresh_std_high=1,
                    symbol="JPM",
                    sd=dt.datetime(2008, 1, 1),
                    ed=dt.datetime(2009, 12, 31),
                    sv=100000):
    df_prices_all = get_data([symbol], pd.date_range(sd, ed))
    df_prices = df_prices_all[symbol]
    df_trades = pd.DataFrame(data=np.zeros(len(df_prices)),
                             index=df_prices.index,
                             columns=['trades'])

    #rstd = idc.get_rolling_stdev(pd.DataFrame(df_prices, index = df_prices.index, columns = [symbol]),  n_days_std)
    rstd = pd.rolling_std(df_prices, window=n_days_std)
    bband = idc.get_bbands(
        pd.DataFrame(df_prices, index=df_prices.index, columns=[symbol]),
        n_days_bb)
    momentum = idc.get_momentum(
        pd.DataFrame(df_prices, index=df_prices.index, columns=[symbol]),
        n_days_mtum)
    abs_momentum = momentum.abs()
    rsi = idc.get_rsi(df_prices, n_days_rsi)
    # use rsi to generat sell & buy signal:
    # > 70 : overbought : should sell
    # < 30 : oversold : should buy
    #use volatility as a filter:
    # if std to low, time to buy, std will increase soon, # maybe make a cross over on the rmean of std ?
    # if std to high, means the growth was strong but will back to the mean
    # use momentum to confirm sell & buy signal:
    # confirmed if small enough momentum
    # (changes in prices is slowing - time to take action)
    for t in range(1, len(df_prices) - 1):
        df_net_holdings = df_trades.cumsum(axis=0)
        net_holdings = df_net_holdings.values[t]
        if (net_holdings > 1000) | (net_holdings < -1000):
            print("ERROR")

        # buy signal
        if ((bband[t - 1] <= -tresh_bb) &
            (bband[t] > -tresh_bb)) | (rsi.iloc[t] < 30):
            if (abs_momentum[t] <= tresh_mmtum):
                if rstd[t] <= tresh_std_low:
                    if (net_holdings == 0):
                        df_trades.iloc[t] = 1000
                    elif (net_holdings == -1000):
                        df_trades.iloc[t] = 2000
        # sell signal
        if ((bband[t - 1] >= tresh_bb) &
            (bband[t] < tresh_bb)) | (rsi.iloc[t] > 70):
            if (abs_momentum[t] <= tresh_mmtum):
                if rstd[t] >= tresh_std_high:  # could be remove since thresh = 0
                    if (net_holdings == 0):
                        df_trades.iloc[t] = -1000
                    elif (net_holdings == 1000):
                        df_trades.iloc[t] = -2000
    return df_trades, rstd