コード例 #1
0
 def calcMA(self, dates, price):
     #ma = pd.DataFrame(columns=['timestamp','price','data_sma5','data_sma10','data_sma15','data_sma20','data_sma60'])
     data_sma5 = np.array(MA(price, 5))
     data_sma10 = np.array(MA(price, 10))
     data_sma15 = np.array(MA(price, 15))
     data_sma20 = np.array(MA(price, 20))
     data_sma60 = np.array(MA(price, 60))
     """
     isExist = 0
     for data,date in zip(price,dates):
         timestamp_ = self.training_window['timestamp'].values
         if(all(ele in self.training_window.columns.values for ele in ma.columns.values)):
             isExist = 1
         if math.isnan(data) or (date.date() in timestamp_ and all(ele in self.training_window.columns.values for ele in ma.columns.values) and not any(np.isnan(ele) for ele in self.training_window.loc[self.training_window['timestamp'] == date.date()].values[0][1:])):
             index = index + 1
             continue
         ma = ma.append({'timestamp':date.date(), 'price':price[index], 'data_sma5':data_sma5[index], 'data_sma10':data_sma10[index], 'data_sma15':data_sma15[index], 'data_sma20':data_sma20[index],
                    'data_sma60':data_sma60[index]},ignore_index=True)
         index = index + 1
     """
     ma, isExist = self.createDateFrame(
         dates,
         np.column_stack(
             (data_sma5, data_sma10, data_sma15, data_sma20, data_sma60)), [
                 'timestamp', 'data_sma5', 'data_sma10', 'data_sma15',
                 'data_sma20', 'data_sma60'
             ])
     #print(ma)
     return ma, isExist
コード例 #2
0
ファイル: ma_strategy_demo.py プロジェクト: shigubuhua/agares
    def compute_trading_points(self, stocks, szTimeAxis, n_ahead):
        assert len(
            stocks
        ) == 1, "This strategy allows only a daily candlestick data of one stock."
        code = next(iter(stocks))
        cst = stocks[code].cst  # get candlestick data
        DataTimeAxis = cst['1Day'].index

        # Moving average
        maf = MA(cst['1Day']['close'].values, self.nfast)
        mas = MA(cst['1Day']['close'].values, self.nslow)

        # skip extra data
        TimeAxis = DataTimeAxis[n_ahead:]
        df_ma = pd.DataFrame(
            {
                'ma_fast': maf[n_ahead:],
                'ma_slow': mas[n_ahead:]
            },
            index=TimeAxis)

        #df_ma.plot()
        #plt.show()
        start_flag = 0
        hold_flag = 0
        for ticker in TimeAxis:
            # skip null value at the beginning
            if np.isnan(df_ma.at[ticker, 'ma_fast']) or np.isnan(
                    df_ma.at[ticker, 'ma_slow']):
                continue
            # skip the days of 'ma_fast'>='ma_slow' at the beginning
            # those should be the days waiting fo selling, not buying, thus not suitable for a start
            if (start_flag == 0) and (df_ma.at[ticker, 'ma_fast'] <=
                                      df_ma.at[ticker, 'ma_slow']):
                continue
            else:
                start_flag = 1
            # start trading
            if (start_flag == 1):
                price = cst['1Day'].at[ticker, 'close']
                if (hold_flag == 0) and (df_ma.at[ticker, 'ma_fast'] >
                                         df_ma.at[ticker, 'ma_slow']):
                    # quantity is the number of shares (unit: boardlot) you buy this time
                    quantity, _, _ = buy(code, price, str(ticker), ratio=1)
                    hold_flag = 1
                if (hold_flag == 1) and (df_ma.at[ticker, 'ma_fast'] <
                                         df_ma.at[ticker, 'ma_slow']):
                    # sell all the shares bought last time
                    sell(code, price, str(ticker), quantity)
                    hold_flag = 0
コード例 #3
0
def getMA(price):
    date = 1
    ma = []
    data_sma5 = np.array(MA(price, 5))
    data_sma10 = np.array(MA(price, 10))
    data_sma15 = np.array(MA(price, 15))
    data_sma20 = np.array(MA(price, 20))
    data_sma60 = np.array(MA(price, 60))

    for data in price:
        if (math.isnan(data)):
            continue
        ma.append([date, data_sma5[date - 1], data_sma10[date - 1], data_sma15[date - 1], data_sma20[date - 1],
                   data_sma60[date - 1]])
        date = date + 1
    return ma
コード例 #4
0
def moving_average(data, tp=14):
    """
    :param data: ndarray
        data for MA
    :param tp: int
        time period for MA
    """
    return MA(data, timeperiod=tp)
コード例 #5
0
def handle_data(context, data):
    long_period = 40
    short_period = 20
    context.count += 1
    if context.count < long_period:
        return
    price_history = data.history(context.asset, 'price', long_period, '1d')
    short_MA = MA(price_history.values, 20)
    long_MA = MA(price_history.values, 40)
    if short_MA[-1] < long_MA[-1] and not context.invest:
        order(context.asset, 10)
        context.invest = True
    if short_MA[-1] > long_MA[-1] and context.invest:
        order(context.asset, -10)
        context.invest = False
    record(price=data.current(context.asset, 'price'),
           promedioMovilCorto=short_MA,
           promedioMovilLargo=long_MA)
    lt
コード例 #6
0
def addlineplot(input_df):
    '''划线,以均线为例子'''
    source = create_data_source(input_df)
    MAs = [5, 10, 15, 20]
    line_color = ['white', 'yellow', 'red', 'green']
    for ma_th, ma in enumerate(MAs):
        legend = 'MA' + str(ma)
        p.line(x=input_df['date'],
               y=MA(input_df['close'].as_matrix(), ma, matype=1),
               legend=legend,
               line_color=line_color[ma_th],
               source=create_data_source(input_df))
コード例 #7
0
    def handle_single_asset_data(self, context, asset, data):
        short_ema_value, long_ema_value = self.current_parameter_

        trailing_window = data.history(asset, 'price', long_ema_value * 3,
                                       '1d')

        if trailing_window.isnull().values.any():
            return

        short_ema = EMA(trailing_window.values, timeperiod=short_ema_value)
        long_ema = EMA(trailing_window.values, timeperiod=long_ema_value)

        vv = data.history(asset, ['high', 'low'], 5, '1d')

        vv = (vv['high'] - vv['low']).mean()

        vvv = data.history(asset, ['high', 'low'], 3, '1d')

        vvv = (vvv['high'] - vvv['low']).mean() * .5

        _long = (short_ema[-1] > long_ema[-1]) and (short_ema[-2] >=
                                                    long_ema[-2])
        _short = (short_ema[-1] < long_ema[-1]) and (short_ema[-2] <=
                                                     long_ema[-2])

        pv = data.current(asset, "price")

        if context.price_highest[asset] < pv:
            context.price_highest[asset] = pv - vvv

        trailing_stop = MA(trailing_window.values,
                           timeperiod=3)[-1] < context.price_highest[asset]
        _short = _short or (context.portfolio_highest[asset] >
                            pv) or trailing_stop

        pct_per_stock = 1.0 / len(context.assets)
        cash = context.portfolio.cash * pct_per_stock

        if _long and cash > pv and context.stock_shares[asset] == 0:
            number_of_shares = int(cash / pv)
            order(asset, number_of_shares)
            context.portfolio_highest[asset] = pv - vv
            context.stock_shares[asset] = number_of_shares
            logging.debug('{} buy {} shares at {}'.format(
                asset, number_of_shares, pv))
        elif _short and context.stock_shares[asset] > 0:
            order_target_percent(asset, 0)
            number_of_shares = context.stock_shares[asset]
            context.portfolio_highest[asset] = 0.0
            context.price_highest[asset] = 0.0
            context.stock_shares[asset] = 0
            logging.debug('{} sell {} shares at {}'.format(
                asset, number_of_shares, pv))
コード例 #8
0
    def _calc_indicator(self, OHLCV_input):
        """
        Calculates the EMA technical indicator using a wrapper for the TA-lib

        Args:
            :param OHLCV_input:  the dataframe with the Open, High, Low, Close and Volume values
            :type OHLCV_input: pandas DataFrame

        Returns:
            DataFrame with the indicators values.
        """
        try:
            close = OHLCV_input['close'].values[:, 0]
        except IndexError:
            close = OHLCV_input['close'].values

        output = DataFrame(MA(close, self.__timeperiod, self.__matype))
        output.columns = ['MA%d' % self.__timeperiod]

        return output
コード例 #9
0
def ma(candles: np.ndarray, period: int = 30, matype: int = 0,  source_type: str = "close", sequential: bool = False) -> Union[
    float, np.ndarray]:
    """
    MA - (nearly) All Moving Averages of Jesse

    :param candles: np.ndarray
    :param period: int - default: 30
    :param source_type: str - default: "close"
    :param sequential: bool - default: False

    :return: float | np.ndarray
    """

    # Accept normal array too.
    if len(candles.shape) == 1:
        source = candles
    else:
        candles = slice_candles(candles, sequential)
        source = get_candle_source(candles, source_type=source_type)

    if matype <= 8:
        from talib import MA
        res = MA(source, timeperiod=period, matype=matype)
    elif matype == 9:
        from . import fwma
        res = fwma(source, period, source_type=source_type, sequential=True)
    elif matype == 10:
        from . import hma
        res = hma(source, period, source_type=source_type,  sequential=True)
    elif matype == 11:
        from talib import LINEARREG
        res = LINEARREG(source, period)
    elif matype == 12:
        from . import wilders
        res = wilders(source, period, source_type=source_type,  sequential=True)
    elif matype == 13:
        from . import sinwma
        res = sinwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 14:
        from . import supersmoother
        res = supersmoother(source, period, source_type=source_type,  sequential=True)
    elif matype == 15:
        from . import supersmoother_3_pole
        res = supersmoother_3_pole(source, period, source_type=source_type,  sequential=True)
    elif matype == 16:
        from . import gauss
        res = gauss(source, period, source_type=source_type,  sequential=True)
    elif matype == 17:
        from . import high_pass
        res = high_pass(source, period, source_type=source_type,  sequential=True)
    elif matype == 18:
        from . import high_pass_2_pole
        res = high_pass_2_pole(source, period, source_type=source_type,  sequential=True)
    elif matype == 19:
        from talib import HT_TRENDLINE
        res = HT_TRENDLINE(source)
    elif matype == 20:
        from . import jma
        res = jma(source, period, source_type=source_type,  sequential=True)
    elif matype == 21:
        from . import reflex
        res = reflex(source, period, source_type=source_type,  sequential=True)
    elif matype == 22:
        from . import trendflex
        res = trendflex(source, period, source_type=source_type,  sequential=True)
    elif matype == 23:
        from . import smma
        res = smma(source, period, source_type=source_type,  sequential=True)
    elif matype == 24:
        if len(candles.shape) == 1:
          raise ValueError("vwma only works with normal candles.")
        from . import vwma
        res = vwma(candles, period, source_type=source_type,  sequential=True)
    elif matype == 25:
        from . import pwma
        res = pwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 26:
        from . import swma
        res = swma(source, period, source_type=source_type,  sequential=True)
    elif matype == 27:
        from . import alma
        res = alma(source, period, source_type=source_type,  sequential=True)
    elif matype == 28:
        from . import hwma
        res = hwma(source, source_type=source_type,  sequential=True)
    elif matype == 29:
        from . import vwap
        if len(candles.shape) == 1:
          raise ValueError("vwap only works with normal candles.")
        res = vwap(source, source_type=source_type,  sequential=True)
    elif matype == 30:
        from . import nma
        res = nma(source, period, source_type=source_type,  sequential=True)
    elif matype == 31:
        from . import edcf
        res = edcf(source, period, source_type=source_type,  sequential=True)
    elif matype == 32:
        from . import mwdx
        res = mwdx(source, source_type=source_type,  sequential=True)
    elif matype == 33:
        from . import maaq
        res = maaq(source, period, source_type=source_type,  sequential=True)
    elif matype == 34:
        from . import srwma
        res = srwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 35:
        from . import sqwma
        res = sqwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 36:
        from . import vpwma
        res = vpwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 37:
        from . import cwma
        res = cwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 38:
        from . import jsa
        res = jsa(source, period, source_type=source_type,  sequential=True)
    elif matype == 39:
        from . import epma
        res = epma(source, period, source_type=source_type,  sequential=True)

    return res if sequential else res[-1]
コード例 #10
0
ファイル: utils.py プロジェクト: yigitbaser/jesse
def signal_line(series: np.ndarray,
                period: int = 10,
                matype: int = 0) -> np.ndarray:
    return MA(series, timeperiod=period, matype=matype)
コード例 #11
0
# ----------------------Graph plotting-----------------------------------
df_plot['Date'] = df_plot['Date'].astype('datetime64[ns]')
df_plot['Date'] = df_plot['Date'].map(mdates.date2num)

# Candlestick chart with 2 moving average line(10days and 30days)
charts_plot, (ax, ax2, ax3) = plt.subplots(nrows=3,
                                           ncols=1,
                                           figsize=(40, 30),
                                           gridspec_kw={
                                               'height_ratios': [3, 0.5, 1],
                                               'hspace': 0
                                           })
candlestick_ohlc(ax, df_plot.values, width=1, colorup='g', colordown='r')

ma_10_plot = MA(df_plot['Close'].values, timeperiod=10, matype=0)
ma_30_plot = MA(df_plot['Close'].values, timeperiod=30, matype=0)
ax.xaxis_date()

ax.plot(df_plot['Date'], ma_10_plot, label='MA-10')
ax.plot(df_plot['Date'], ma_30_plot, label='MA-30')
ax.legend()

# KD line chart
k_plot, d_plot = STOCH(df_plot['High'].values,
                       df_plot['Low'].values,
                       df_plot['Close'].values,
                       fastk_period=5,
                       slowk_period=3,
                       slowk_matype=0,
                       slowd_period=3,
コード例 #12
0
 def generate_data(self, cst_d, n_ahead):
     """ 
     Generate train data from cst data.
     
     Returns:
         train_data(pd.dataframe), with index of pd.TimeStamp type
         
         the feature columns of train_data are:
         ['close', 'PriceChangeRatio', 'dif', 'dea', 'macd', 'ma5', 'ma10', 'ma20', 'ma5-ma10', \
         'ma5-ma20', 'ma10-ma20', 'vol', 'VolChangeRatio']
         and labels/turnouts of train_data are:
         ['after1d', 'after2d', 'after3d', 'after4d', 'after5d', 'after5dChange2%?', \
         'after3dChangeRatio', 'after5dChangeRatio']
     """
     # get time axis of the cst data
     DataTimeAxis = cst_d.index
     # PriceChangeRatio feature
     price_change_ratio = self.ChangeRatio(cst_d['close'].values)
     # MACD feature
     dif, dea, macd = self.MACD(cst_d['close'].values)
     # Moving average features
     ma5 = MA(cst_d['close'].values, 5)
     ma10 = MA(cst_d['close'].values, 10)
     ma20 = MA(cst_d['close'].values, 20)
     ma5_ma10 = ma5 - ma10
     ma5_ma20 = ma5 - ma20
     ma10_ma20 = ma10 - ma20
     # VolChangeRatio feature
     vol_change_ratio = self.ChangeRatio(cst_d['volume'].values)
     # VolChangeRatioAverage: vol vs that of the average of pass 5 days
     vol_change_ratio_aver = self.ChangeRatioAverage(
         cst_d['volume'].values, 5)
     # skip extra data and create feature dataframe
     TimeAxis = DataTimeAxis[n_ahead:]
     cst_v = cst_d['close'].values[n_ahead:]
     df_features = pd.DataFrame({'close': cst_v}, index=TimeAxis)
     df_features = df_features.join(pd.DataFrame({'dif': dif[n_ahead:], 'dea': dea[n_ahead:], \
                                     'macd': macd[n_ahead:]}, index = TimeAxis))
     df_features = df_features.join(pd.DataFrame({'ma5': ma5[n_ahead:], 'ma10': ma10[n_ahead:], \
         'ma20': ma20[n_ahead:], 'ma5-ma10': ma5_ma10[n_ahead:],'ma5-ma20': ma5_ma20[n_ahead:],\
          'ma10-ma20': ma10_ma20[n_ahead:]}, index = TimeAxis))
     df_features['PriceChangeRatio'] = price_change_ratio[n_ahead:]
     df_features['VolChangeRatio'] = vol_change_ratio[n_ahead:]
     df_features['VolChangeRatioAverage'] = vol_change_ratio_aver[n_ahead:]
     df_features['vol'] = cst_d['volume'].values[n_ahead:]
     # to store tickers of the train data
     tmp_tickers = []
     # to store features of the train data
     turnout = ['after1d', 'after2d', 'after3d', 'after4d', 'after5d', 'after5dChange2%?', \
                 'after3dChangeRatio', 'after5dChangeRatio']
     tmp_turnout = {column: [] for column in turnout}
     # flags. 'dc' is short for 'dead cross'; 'gc' is short for 'golden cross'
     wait_dc, wait_gc = False, False
     # start selecting useful data
     for i, ticker in enumerate(TimeAxis):
         # skip null value at the beginning
         if np.isnan(df_features.at[ticker, 'dif']) or np.isnan(
                 df_features.at[ticker, 'dea']):
             continue
         # if golden cross or dead cross
         if ((wait_dc is True) and \
                             (df_features.at[ticker, 'dif'] < df_features.at[ticker, 'dea']))\
             or ((wait_gc is True) and \
                             (df_features.at[ticker, 'dif'] > df_features.at[ticker, 'dea'])):
             # record useful data
             tmp_tickers.append(ticker)
             for day, column in enumerate(turnout[:5], start=1):
                 tmp_turnout[column].append(cst_v[i + day])
             after3dChangeRatio = (cst_v[i + 3] - cst_v[i]) / cst_v[i]
             tmp_turnout['after3dChangeRatio'].append(after3dChangeRatio)
             after5dChangeRatio = (cst_v[i + 5] - cst_v[i]) / cst_v[i]
             tmp_turnout['after5dChangeRatio'].append(after5dChangeRatio)
             if after5dChangeRatio >= 0.02:
                 tmp_turnout['after5dChange2%?'].append('rise2%')
             elif after5dChangeRatio <= -0.02:
                 tmp_turnout['after5dChange2%?'].append('fall2%')
             else:
                 tmp_turnout['after5dChange2%?'].append('within2%')
         # change state
         if df_features.at[ticker, 'dif'] > df_features.at[ticker, 'dea']:
             wait_dc, wait_gc = True, False
         if df_features.at[ticker, 'dif'] < df_features.at[ticker, 'dea']:
             wait_dc, wait_gc = False, True
     # create train data
     train_data = df_features.loc[tmp_tickers, :]
     train_data = train_data.join(
         pd.DataFrame(tmp_turnout, index=tmp_tickers))
     return train_data
コード例 #13
0
def ma(candles: np.ndarray, period: int = 30, matype: int = 0,  source_type: str = "close", sequential: bool = False) -> Union[
    float, np.ndarray]:
    """
    MA - (nearly) All Moving Averages of Jesse

    :param candles: np.ndarray
    :param period: int - default: 30
    :param source_type: str - default: "close"
    :param sequential: bool - default=False

    :return: float | np.ndarray
    """

    # Accept normal array too.
    if len(candles.shape) == 1:
        source = candles
    else:
        candles = slice_candles(candles, sequential)
        source = get_candle_source(candles, source_type=source_type)

    if matype <= 8:
        from talib import MA
        res = MA(source, timeperiod=period, matype=matype)
    elif matype == 9:
        from . import fwma
        res = fwma(source, period, source_type=source_type, sequential=True)
    elif matype == 10:
        from . import hma
        res = hma(source, period, source_type=source_type,  sequential=True)
    elif matype == 11:
        from talib import LINEARREG
        res = LINEARREG(source, period)
    elif matype == 12:
        from . import wilders
        res = wilders(source, period, source_type=source_type,  sequential=True)
    elif matype == 13:
        from . import sinwma
        res = sinwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 14:
        from . import supersmoother
        res = supersmoother(source, period, source_type=source_type,  sequential=True)
    elif matype == 15:
        from . import supersmoother_3_pole
        res = supersmoother_3_pole(source, period, source_type=source_type,  sequential=True)
    elif matype == 16:
        from . import gauss
        res = gauss(source, period, source_type=source_type,  sequential=True)
    elif matype == 17:
        from . import high_pass
        res = high_pass(source, period, source_type=source_type,  sequential=True)
    elif matype == 18:
        from . import high_pass_2_pole
        res = high_pass_2_pole(source, period, source_type=source_type,  sequential=True)
    elif matype == 19:
        from talib import HT_TRENDLINE
        res = HT_TRENDLINE(source, period)
    elif matype == 20:
        from . import jma
        res = jma(source, period, source_type=source_type,  sequential=True)
    elif matype == 21:
        from . import reflex
        res = reflex(source, period, source_type=source_type,  sequential=True)
    elif matype == 22:
        from . import trendflex
        res = trendflex(source, period, source_type=source_type,  sequential=True)
    elif matype == 23:
        from . import smma
        res = smma(source, period, source_type=source_type,  sequential=True)
    elif matype == 24:
        from . import vwma
        res = vwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 25:
        from . import pwma
        res = pwma(source, period, source_type=source_type,  sequential=True)
    elif matype == 25:
        from . import swma
        res = swma(source, period, source_type=source_type,  sequential=True)

    return res if sequential else res[-1]
コード例 #14
0
ファイル: utils.py プロジェクト: w1r2p1/jesse
def signal_line(series: np.array, period=10, matype=0):
    return MA(series, timeperiod=period, matype=matype)
コード例 #15
0
def m_average(a_list, window):
    from talib import MA
    ma_array = np.asarray(a_list)
    return MA(ma_array, window)
コード例 #16
0
    def fetch(self,
              symbol: str,
              interval: Interval = Interval.DAY,
              window: Window = Window.YEAR,
              indicators: Indicators = [],
              verbose=False) -> pd.DataFrame:
        """
        Fetch symbol stock OHLCV from Yahoo Finance API

        Args:
            symbol (str): Symbol to fetch
            interval (Interval, optional): Interval (hour, day, week, ...) of data. Defaults to Interval.DAY.
            window (Window, optional): Length (day, week, month, year) of interval. Defaults to Window.YEAR.
            indicators (Indicators, optional): Array of indicators to include in the result. Defaults to empty array.

        Returns:
            pd.DataFrame: OHLCV pandas DataFrame with interval on window length and indicators if specified
        """
        try:
            if verbose:
                print(
                    f"Fetching OHLCV {symbol} stock data on {interval.name} interval and {window.name} window"
                )

            # Generic url to fetch
            url = f"https://query1.finance.yahoo.com/v8/finance/chart/{symbol}?region=FR&lang=fr-FR&includePrePost=false&interval={interval.value}&range={window.value}&corsDomain=fr.finance.yahoo.com&.tsrc=finance"

            req = requests.get(url)

            # Testing request status code
            if req.status_code == 200:

                # Extracting data as json
                data = req.json()

                # Creating new DataFrame
                df = pd.DataFrame()

                # Extract date from object
                if interval in [
                        Interval.MINUTE, Interval.TWO_MINUTE,
                        Interval.FIVE_MINUTE, Interval.FIFTEEN_MINUTE,
                        Interval.THIRTY_MINUTE, Interval.HOUR
                ]:
                    dateFromUnix = [
                        datetime.utcfromtimestamp(dt).strftime(
                            "%Y-%m-%d %H:%M:%S")
                        for dt in data["chart"]["result"][0]["timestamp"]
                    ]
                else:
                    dateFromUnix = [
                        datetime.utcfromtimestamp(dt).strftime("%Y-%m-%d")
                        for dt in data["chart"]["result"][0]["timestamp"]
                    ]

                # Date & OHLCV to DataFrame
                df["date"] = pd.to_datetime(dateFromUnix)
                df["open"] = data["chart"]["result"][0]["indicators"]["quote"][
                    0]["open"]
                df["high"] = data["chart"]["result"][0]["indicators"]["quote"][
                    0]["high"]
                df["low"] = data["chart"]["result"][0]["indicators"]["quote"][
                    0]["low"]
                df["close"] = data["chart"]["result"][0]["indicators"][
                    "quote"][0]["close"]
                df["volume"] = data["chart"]["result"][0]["indicators"][
                    "quote"][0]["volume"]

                # Drop NaN on close col
                df.dropna(subset=["close"], inplace=True)

                # Divide volume column by a 1 000
                df["volume"] = df["volume"].div(1000)

                # Set date column as index
                df.set_index("date", inplace=True)

                for indicator in indicators:
                    # ADX
                    if indicator == Indicators.ADX:
                        df[indicator.value] = ADX(df["high"], df["low"],
                                                  df["close"])
                    # BBANDS
                    elif indicator == Indicators.BBANDS:
                        df[Indicators.BBANDS.value[0]], df[
                            Indicators.BBANDS.value[1]], df[
                                Indicators.BBANDS.value[2]] = BBANDS(
                                    df["close"])
                        df["p_band"] = 100 - \
                            (df["l_band"] / df["u_band"] * 100)
                        df["p_band_ma_5"] = MA(df["p_band"], timeperiod=5)
                    # EMA
                    elif indicator == Indicators.EMA:
                        for ema in Indicators.EMA.value:
                            df[ema] = EMA(df["close"],
                                          timeperiod=int(ema.split("_")[1]))
                    # MA
                    elif indicator == Indicators.MA:
                        for ma in Indicators.MA.value:
                            df[ma] = MA(df["close"],
                                        timeperiod=int(ma.split("_")[1]))

                    # OBV
                    elif indicator == Indicators.OBV:
                        df[indicator.value] = OBV(df["close"], df["volume"])
                        df[indicator.value] = df[indicator.value].div(1000)
                    # PSAR
                    elif indicator == Indicators.PSAR:
                        df[indicator.value] = SAR(df["high"], df["low"])
                    # PERCENT CHANGE
                    elif indicator == Indicators.P_CHANGE:
                        for p_change in Indicators.P_CHANGE.value:
                            df[p_change] = df["close"].pct_change(
                                int(p_change.split(" ")[1])) * 100
                    # RSI
                    elif indicator == Indicators.RSI:
                        df[indicator.value] = RSI(df["close"])

                return df.round(decimals=2)

        except Exception as e:
            print(e)