Ejemplo n.º 1
0
 def test_tsi2(self):
     target = 'TSI'
     result = tsi(**self._params)
     pd.testing.assert_series_equal(self._df[target].tail(),
                                    result.tail(),
                                    check_names=False,
                                    check_less_precise=True)
Ejemplo n.º 2
0
    def get_ml_feature(self, symbol, prices=None, cutoff=None):
        if prices:
            price = prices.get(symbol, 1E10)
            vix = prices['^VIX']
        else:
            price = self.closes[symbol][cutoff]
            vix = self.closes['^VIX'][cutoff]

        if cutoff:
            close = self.closes[symbol][cutoff - DAYS_IN_A_YEAR:cutoff]
            high = np.array(
                self.hists[symbol].get('High')[cutoff - DAYS_IN_A_YEAR:cutoff])
            low = np.array(
                self.hists[symbol].get('Low')[cutoff - DAYS_IN_A_YEAR:cutoff])
        else:
            close = self.closes[symbol][-DAYS_IN_A_YEAR:]
            high = np.array(self.hists[symbol].get('High')[-DAYS_IN_A_YEAR:])
            low = np.array(self.hists[symbol].get('Low')[-DAYS_IN_A_YEAR:])
        # Basic stats
        day_range_change = price / np.max(close[-DATE_RANGE:]) - 1
        today_change = price / close[-1] - 1
        yesterday_change = close[-1] / close[-2] - 1
        day_before_yesterday_change = close[-2] / close[-3] - 1
        twenty_day_change = price / close[-20] - 1
        year_high_change = price / np.max(close) - 1
        year_low_change = price / np.min(close) - 1
        all_changes = [
            close[t + 1] / close[t] - 1 for t in range(len(close) - 1)
            if close[t + 1] > 0 and close[t] > 0
        ]
        # Technical indicators
        close = np.append(close, price)
        high = np.append(high, price)
        low = np.append(low, price)
        pd_close = pd.Series(close)
        pd_high = pd.Series(high)
        pd_low = pd.Series(low)
        rsi = momentum.rsi(pd_close).values[-1]
        macd_rate = trend.macd_diff(pd_close).values[-1] / price
        wr = momentum.wr(pd_high, pd_low, pd_close).values[-1]
        tsi = momentum.tsi(pd_close).values[-1]
        feature = {
            'Today_Change': today_change,
            'Yesterday_Change': yesterday_change,
            'Day_Before_Yesterday_Change': day_before_yesterday_change,
            'Twenty_Day_Change': twenty_day_change,
            'Day_Range_Change': day_range_change,
            'Year_High_Change': year_high_change,
            'Year_Low_Change': year_low_change,
            'Change_Average': np.mean(all_changes),
            'Change_Variance': np.var(all_changes),
            'RSI': rsi,
            'MACD_Rate': macd_rate,
            'WR': wr,
            'TSI': tsi,
            'VIX': vix
        }
        return feature
def Feature_Extraction_Momentum(df):
    df = SOK(df)
    df = SOD(df)
    df = SOJ(df)
    df = MACD(df)
    df = MACD_Signal(df)
    df = MACD_Hist(df)
    df['RSI'] = tas.RSI(df['close'].values)
    df['ROC'] = tas.ROC(df['close'].values)
    df['WillR'] = tas.WILLR(df['high'].values, df['low'].values,
                            df['close'].values)
    df['CCI'] = tas.CCI(df['high'].values, df['low'].values,
                        df['close'].values)
    df['TSI'] = tsi(df['close'], window_slow=25, window_fast=13)
    df['ADX'] = tas.ADX(df['high'].values, df['low'].values,
                        df['close'].values)
    df['MFI'] = tas.MFI(df['high'], df['low'], df['close'], df['volume'])
    df['MOM'] = tas.MOM(df['close'])
    df['TRIX'] = tas.TRIX(df['close'])
    df['ULTOSC'] = tas.ULTOSC(df['high'], df['low'], df['close'])

    df = df.fillna(0)
    return df
Ejemplo n.º 4
0
def engineer_data_over_single_interval(df: pd.DataFrame,
                                       indicators: list,
                                       ticker: str = "",
                                       rsi_n: int = 14,
                                       cmo_n: int = 7,
                                       macd_fast: int = 12,
                                       macd_slow: int = 26,
                                       macd_sign: int = 9,
                                       roc_n: int = 12,
                                       cci_n: int = 20,
                                       dpo_n: int = 20,
                                       cmf_n: int = 20,
                                       adx_n: int = 14,
                                       mass_index_low: int = 9,
                                       mass_index_high: int = 25,
                                       trix_n: int = 15,
                                       stochastic_oscillator_n: int = 14,
                                       stochastic_oscillator_sma_n: int = 3,
                                       ultimate_oscillator_short_n: int = 7,
                                       ultimate_oscillator_medium_n: int = 14,
                                       ultimate_oscillator_long_n: int = 28,
                                       ao_short_n: int = 5,
                                       ao_long_n: int = 34,
                                       kama_n: int = 10,
                                       tsi_high_n: int = 25,
                                       tsi_low_n: int = 13,
                                       eom_n: int = 14,
                                       force_index_n: int = 13,
                                       ichimoku_low_n: int = 9,
                                       ichimoku_medium_n: int = 26):
    from ta.momentum import rsi, wr, roc, ao, stoch, uo, kama, tsi
    from ta.trend import macd, macd_signal, cci, dpo, adx, mass_index, trix, ichimoku_a
    from ta.volume import chaikin_money_flow, acc_dist_index, ease_of_movement, force_index

    # Momentum Indicators
    if Indicators.RELATIVE_STOCK_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.RELATIVE_STOCK_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.RELATIVE_STOCK_INDEX.value] = rsi(close=df['close'],
                                                        n=rsi_n)

    if Indicators.WILLIAMS_PERCENT_RANGE in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.WILLIAMS_PERCENT_RANGE.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.WILLIAMS_PERCENT_RANGE.value] = wr(
            df['high'], df['low'], df['close'])

    if Indicators.CHANDE_MOMENTUM_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.CHANDE_MOMENTUM_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.CHANDE_MOMENTUM_OSCILLATOR.
           value] = chande_momentum_oscillator(close_data=df['close'],
                                               period=cmo_n)

    if Indicators.RATE_OF_CHANGE in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.RATE_OF_CHANGE.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.RATE_OF_CHANGE.value] = roc(close=df['close'], n=roc_n)

    if Indicators.STOCHASTIC_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.STOCHASTIC_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.STOCHASTIC_OSCILLATOR.value] = stoch(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            n=stochastic_oscillator_n,
            d_n=stochastic_oscillator_sma_n)

    if Indicators.ULTIMATE_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.ULTIMATE_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.ULTIMATE_OSCILLATOR.value] = uo(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            s=ultimate_oscillator_short_n,
            m=ultimate_oscillator_medium_n,
            len=ultimate_oscillator_long_n)

    if Indicators.AWESOME_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.AWESOME_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.AWESOME_OSCILLATOR.value] = ao(high=df['high'],
                                                     low=df['low'],
                                                     s=ao_short_n,
                                                     len=ao_long_n)

    if Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE.value] = kama(
            close=df['close'], n=kama_n)

    if Indicators.TRUE_STRENGTH_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.TRUE_STRENGTH_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.TRUE_STRENGTH_INDEX.value] = tsi(close=df['close'],
                                                       r=tsi_high_n,
                                                       s=tsi_low_n)

    # Trend Indicator
    if Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE in indicators:
        Logger.console_log(
            message="Calculating " +
            Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE.value +
            " for stock " + ticker,
            status=Logger.LogStatus.EMPHASIS)
        df[Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE.value] = macd(close=df['close'],
                                                                          n_slow=macd_slow,
                                                                          n_fast=macd_fast) - \
                                                                     macd_signal(close=df['close'],
                                                                                 n_slow=macd_slow,
                                                                                 n_fast=macd_fast,
                                                                                 n_sign=macd_sign)

    if Indicators.COMMODITY_CHANNEL_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.COMMODITY_CHANNEL_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.COMMODITY_CHANNEL_INDEX.value] = cci(high=df['high'],
                                                           low=df['low'],
                                                           close=df['close'],
                                                           n=cci_n)

    if Indicators.DETRENDED_PRICE_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.DETRENDED_PRICE_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.DETRENDED_PRICE_OSCILLATOR.value] = dpo(
            close=df['close'], n=dpo_n)

    if Indicators.AVERAGE_DIRECTIONAL_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.AVERAGE_DIRECTIONAL_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.AVERAGE_DIRECTIONAL_INDEX.value] = adx(high=df['high'],
                                                             low=df['low'],
                                                             close=df['close'],
                                                             n=adx_n)

    if Indicators.MASS_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.MASS_INDEX.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.MASS_INDEX.value] = mass_index(high=df['high'],
                                                     low=df['low'],
                                                     n=mass_index_low,
                                                     n2=mass_index_high)

    if Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE in indicators:
        Logger.console_log(
            message="Calculating " +
            Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE.value +
            " for stock " + ticker,
            status=Logger.LogStatus.EMPHASIS)
        df[Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE.
           value] = trix(close=df['close'], n=trix_n)

    if Indicators.ICHIMOKU_A in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.ICHIMOKU_A.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.ICHIMOKU_A.value] = ichimoku_a(high=df['high'],
                                                     low=df['low'],
                                                     n1=ichimoku_low_n,
                                                     n2=ichimoku_medium_n)

    # Volume Indicator
    if Indicators.CHAIKIN_MONEY_FLOW in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.CHAIKIN_MONEY_FLOW.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.CHAIKIN_MONEY_FLOW.value] = chaikin_money_flow(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            volume=df['volume'],
            n=cmf_n)

    if Indicators.ACCUMULATION_DISTRIBUTION_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.ACCUMULATION_DISTRIBUTION_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.ACCUMULATION_DISTRIBUTION_INDEX.value] = acc_dist_index(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            volume=df['volume'])

    if Indicators.EASE_OF_MOVEMENT in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.EASE_OF_MOVEMENT.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.EASE_OF_MOVEMENT.value] = ease_of_movement(
            high=df['high'], low=df['low'], volume=df['volume'], n=eom_n)

    if Indicators.FORCE_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.FORCE_INDEX.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.FORCE_INDEX.value] = force_index(close=df['close'],
                                                       volume=df['volume'],
                                                       n=force_index_n)
Ejemplo n.º 5
0
    def get_ml_feature(self, symbol, prices=None, cutoff=None):
        feature = {}
        if prices:
            price = prices.get(symbol, 1E10)
            vix = prices['^VIX']
        else:
            price = self.closes[symbol][cutoff]
            vix = self.closes['^VIX'][cutoff]

        if cutoff:
            close = self.closes[symbol][cutoff - DAYS_IN_A_YEAR:cutoff]
            volume = self.volumes[symbol][cutoff - DAYS_IN_A_YEAR:cutoff]
        else:
            close = self.closes[symbol][-DAYS_IN_A_YEAR:]
            volume = self.volumes[symbol][-DAYS_IN_A_YEAR:]
        close = np.append(close, price)

        # Log returns
        feature['Day_1_Return'] = np.log(close[-1] / close[-2])
        feature['Day_2_Return'] = np.log(close[-2] / close[-3])
        feature['Day_3_Return'] = np.log(close[-3] / close[-4])
        feature['Weekly_Return'] = np.log(price / close[-DAYS_IN_A_WEEK])
        feature['Monthly_Return'] = np.log(price / close[-DAYS_IN_A_MONTH])
        feature['Quarterly_Return'] = np.log(price / close[-DAYS_IN_A_QUARTER])
        feature['From_Weekly_High'] = np.log(price /
                                             np.max(close[-DAYS_IN_A_WEEK:]))
        feature['From_Weekly_Low'] = np.log(price /
                                            np.min(close[-DAYS_IN_A_WEEK:]))

        # Technical indicators
        pd_close = pd.Series(close)
        feature['RSI'] = momentum.rsi(pd_close).values[-1]
        feature['MACD_Rate'] = trend.macd_diff(pd_close).values[-1] / price
        feature['TSI'] = momentum.tsi(pd_close).values[-1]

        # Markets
        feature['VIX'] = vix

        # Other numerical factors
        # Fit five data points to a second order polynomial
        feature['Acceleration'] = (2 * close[-5] - 1 * close[-4] -
                                   2 * close[-3] - 1 * close[-2] +
                                   2 * close[-1]) / 14
        feature['Momentum'] = (-2 * close[-5] - 1 * close[-4] + 1 * close[-2] +
                               2 * close[-1]) / 10
        quarterly_returns = [
            np.log(close[i] / close[i - 1])
            for i in range(-DAYS_IN_A_QUARTER, -1)
        ]
        monthly_returns = quarterly_returns[-DAYS_IN_A_MONTH:]
        weekly_returns = quarterly_returns[-DAYS_IN_A_WEEK:]
        feature['Monthly_Skewness'] = stats.skew(monthly_returns)
        feature['Monthly_Volatility'] = np.std(monthly_returns)
        feature['Weekly_Skewness'] = stats.skew(weekly_returns)
        feature['Weekly_Volatility'] = np.std(weekly_returns)
        feature['Z_Score'] = (
            feature['Day_1_Return'] -
            np.mean(quarterly_returns)) / np.std(quarterly_returns)
        feature['Monthly_Avg_Dollar_Volume'] = np.average(
            np.multiply(close[-DAYS_IN_A_MONTH - 1:-1],
                        volume[-DAYS_IN_A_MONTH:])) / 1E6

        return feature