Beispiel #1
0
def data_to_indicators(data, o, h, l, c, v, window) -> pd.DataFrame:
    """
    Given a DataFrame of stock prices, return the data along with the corresponding indicators

    :param data: Data in C-OHLV format
    :param window: default value of window for indicators (only for indicators that support this)
    :param o: name of column containing 'OPEN' values
    :param h: name of column containing 'HIGH' values
    :param l: name of column containing 'LOW' values
    :param c: name of column containing 'CLOSE' values
    :param v: name of column containing 'VOLUME' values
    :return: DataFrame with all indicators
    """
    df = data.reset_index(drop=True)

    # Momentum
    # TODO PMO
    df['macd_' + str(window)] = macd(df[c], n_fast=int(window / 2), n_slow=window)
    df['rsi_' + str(window)] = rsi(df[c], n=window)
    df['wr_' + str(window)] = wr(df[h], df[l], df[c], lbp=window)
    df['mfi_' + str(window)] = money_flow_index(df[h], df[l], df[c], df[v], n=window)
    df['stochk_' + str(window)] = stoch(df[h], df[l], df[c], n=window)
    df['stochd_' + str(window)] = stoch_signal(df[h], df[l], df[c], n=window, d_n=3)

    # ROC
    df['roc_' + str(window)] = [(df[c][i] - df[c][i - window]) / df[c][i - window] if i >= window else np.nan
                                for i in range(0, df[c].size)]

    # Smoothing
    df['sma_' + str(window)] = simple_moving_average.simple_moving_average(df[c], period=window)
    df['wma_' + str(window)] = weighted_moving_average.weighted_moving_average(df[c], period=window)
    df['ema_' + str(window)] = exponential_moving_average.exponential_moving_average(np.array(df[c]), period=window)
    df['hma_' + str(window)] = hull_moving_average.hull_moving_average(np.array(df[c]), period=window)
    # df['cma_' + str(window)] = [df[c][i - int(window / 2): i + int(window / 2)].mean()
    #                             if (i >= int(window / 2) and (i + int(window / 2)) < df[c].size) else np.nan
    #                             for i in range(0, df[c].size)]

    # Overbought/Oversold Signals
    df['cci_' + str(window)] = cci(df[h], df[l], df[c], n=window, c=0.015)

    # Volume
    df['adl'] = acc_dist_index(df[h], df[l], df[c], df[v])
    df['cmf_' + str(window)] = chaikin_money_flow(df[h], df[l], df[c], df[v], n=window)
    df['obv'] = on_balance_volume(df[c], df[v])
    df['emv_' + str(window)] = ease_of_movement(df[h], df[l], df[c], df[v], n=window)

    # Volatility
    df['atr_' + str(window)] = average_true_range(df[h], df[l], df[c], n=window)
    df['mass_ind_' + str(window)] = mass_index(df[h], df[l], n=window / 2, n2=window)

    # Trends
    # How will model know b/w Ichmoku A and B?
    df['ichimoku_a'] = ichimoku_a(df[h], df[l], n1=9, n2=26)
    df['ichimoku_b'] = ichimoku_b(df[h], df[l], n2=26, n3=52)

    series_aroon_up = aroon_up(df[c], n=window)
    series_aroon_down = aroon_down(df[c], n=window)
    df['aroon_ind_' + str(window)] = series_aroon_up - series_aroon_down

    df['adx_' + str(window)] = adx(df[h], df[l], df[c], n=window)

    return df
Beispiel #2
0
 def test_hma_period_10(self):
     period = 10
     hma = hull_moving_average.hull_moving_average(self.data, period)
     np.testing.assert_array_equal(hma, self.hma_period_10_expected)
Beispiel #3
0
 def test_hull_moving_average_invalid_period(self):
     period = 128
     with self.assertRaises(Exception) as cm:
         hull_moving_average.hull_moving_average(self.data, period)
     expected = "Error: data_len < period"
     self.assertEqual(str(cm.exception), expected)
Beispiel #4
0
    def analyze(signal):
        """
        Analyze data
        """
        def calc_rsi(prices, n=14):
            deltas = np.diff(prices)
            seed = deltas[:n + 1]
            up = seed[seed >= 0].sum() / n
            down = -seed[seed < 0].sum() / n
            rs = up / down
            rsi = np.zeros_like(prices)
            rsi[:n] = 100. - 100. / (1. + rs)
            for i in range(n, len(prices)):
                delta = deltas[i - 1]  # cause the diff is 1 shorter
                if delta > 0:
                    upval = delta
                    downval = 0.
                else:
                    upval = 0.
                    downval = -delta
                up = (up * (n - 1) + upval) / n
                down = (down * (n - 1) + downval) / n
                rs = up / down
                rsi[i] = 100. - 100. / (1. + rs)
            return rsi

        def get_last_peak(data):
            np_data = np.array(data)
            peaks = (np_data >= np.roll(np_data, 1)) & (np_data > np.roll(
                np_data, -1))
            peaks = list(peaks[1:len(peaks) - 1])
            idx = len(peaks) - peaks[::-1].index(True)
            return DictMap({'index': idx, 'value': data[idx]})

        def get_last_trough(data):
            np_data = np.array(data)
            troughs = (np_data <= np.roll(np_data, 1)) & (np_data < np.roll(
                np_data, -1))
            troughs = list(troughs[1:len(troughs) - 1])
            idx = len(troughs) - troughs[::-1].index(True)
            return DictMap({'index': idx, 'value': data[idx]})

        data = list(signal)
        ema = exponential_moving_average(data[-EMA_PERIOD:], EMA_PERIOD)[-1]
        if Trader.selling_analyzed_data:
            hull_data = hull_moving_average(data[-(HULL_PERIOD + 30):],
                                            HULL_PERIOD)
        else:
            hull_data = hull_moving_average(data, HULL_PERIOD)

        # @TODO: clean up the code
        sell_now = False
        if not Trader.selling_analyzed_data:  # first time
            hd = [x for x in hull_data if x >= 0]
            last_peak = get_last_peak(hd)
            last_trough = get_last_trough(hd)
            if last_peak.index > last_trough.index:
                Trader.selling_analyzed_data.last_is_trough = False
            else:
                Trader.selling_analyzed_data.last_is_trough = True
            Trader.selling_analyzed_data.peak = last_peak.value
            Trader.selling_analyzed_data.trough = last_trough.value
            Trader.selling_analyzed_data.previous_peak = None
            Trader.selling_analyzed_data.previous_trough = None
            Trader.selling_analyzed_data.last = hull_data[-1]
        else:
            last = hull_data[-1]
            height = Trader.selling_analyzed_data.peak - Trader.selling_analyzed_data.trough
            if Trader.selling_analyzed_data.last_is_trough:
                retrace_height = last - Trader.selling_analyzed_data.trough
            else:
                retrace_height = Trader.selling_analyzed_data.peak - last

            retrace_perc = retrace_height / height * 100.0
            if Trader.selling_analyzed_data.last_is_trough:
                if retrace_perc < 0:
                    Trader.selling_analyzed_data.last_is_trough = False
                    if Trader.selling_analyzed_data.previous_trough:
                        Trader.selling_analyzed_data.trough = Trader.selling_analyzed_data.previous_trough
                if last < Trader.selling_analyzed_data.last:
                    if retrace_perc > IGNORE_SMALL_PEAK_PERCENTAGE:
                        Trader.selling_analyzed_data.last_is_trough = False
                        Trader.selling_analyzed_data.previous_peak = Trader.selling_analyzed_data.peak
                        Trader.selling_analyzed_data.peak = Trader.selling_analyzed_data.last
            else:
                if retrace_perc < 0:
                    Trader.selling_analyzed_data.last_is_trough = True
                    if Trader.selling_analyzed_data.previous_peak:
                        Trader.selling_analyzed_data.peak = Trader.selling_analyzed_data.previous_peak
                if last > Trader.selling_analyzed_data.last:  # got a new reversal
                    if retrace_perc > IGNORE_SMALL_PEAK_PERCENTAGE:
                        Trader.selling_analyzed_data.last_is_trough = True
                        Trader.selling_analyzed_data.previous_trough = Trader.selling_analyzed_data.trough
                        Trader.selling_analyzed_data.trough = Trader.selling_analyzed_data.last
                if retrace_perc >= SELL_MAX_RETRACEMENT_PERCENTAGE:
                    sell_now = True
            Trader.selling_analyzed_data.last = last
        Trader.logger.debug("selling analyze data: %s" %
                            str(Trader.selling_analyzed_data))

        rsi = calc_rsi(data[-(RSI_PERIOD + 1):], RSI_PERIOD)[-1]
        ma_spread = 100 * (ema / hull_data[-1] - 1)
        Trader.logger.debug("ema - rsi - ma_spread: %s - %s - %s" %
                            (str(ema), str(rsi), str(ma_spread)))
        buy_now = False

        if rsi < RSI_OVERSOLD_PERCENTAGE and ma_spread > MIN_MA_SPREAD and hull_data[
                -1] <= hull_data[-2]:
            Trader.buy_now_tracking = True
        else:
            if Trader.buy_now_tracking and hull_data[-1] > hull_data[
                    -2] and Trader.selling_analyzed_data.last_is_trough:
                height = Trader.selling_analyzed_data.peak - Trader.selling_analyzed_data.trough
                retrace_height = last - Trader.selling_analyzed_data.trough
                retrace_perc = retrace_height / height * 100.0
                if retrace_perc >= BUY_MAX_RETRACEMENT_PERCENTAGE:
                    buy_now = True
                    Trader.buy_now_tracking = False

        return DictMap({
            'buy_now': buy_now,
            'sell_now': sell_now,
            'ema': ema,
            'hull': hull_data[-1],
            'close': data[-1]
        })