Ejemplo n.º 1
0
    def populate_indicators(self, dataframe: DataFrame,
                            metadata: dict) -> DataFrame:

        # Set Up Bollinger Bands
        upper_bb1, mid_bb1, lower_bb1 = ta.BBANDS(dataframe['close'],
                                                  timeperiod=40)
        upper_bb2, mid_bb2, lower_bb2 = ta.BBANDS(
            qtpylib.typical_price(dataframe), timeperiod=20)

        # only putting some bands into dataframe as the others are not used elsewhere in the strategy
        dataframe['lower-bb1'] = lower_bb1
        dataframe['lower-bb2'] = lower_bb2
        dataframe['mid-bb2'] = mid_bb2

        dataframe['bb1-delta'] = (mid_bb1 - dataframe['lower-bb1']).abs()
        dataframe['closedelta'] = (dataframe['close'] -
                                   dataframe['close'].shift()).abs()
        dataframe['tail'] = (dataframe['close'] - dataframe['low']).abs()

        dataframe['ema_slow'] = ta.EMA(dataframe['close'], timeperiod=48)
        dataframe['volume_mean_slow'] = dataframe['volume'].rolling(
            window=24).mean()

        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)

        # # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy)
        rsi = 0.1 * (dataframe['rsi'] - 50)
        dataframe['fisher-rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1)

        dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
        dataframe['adx'] = ta.ADX(dataframe)

        return dataframe
Ejemplo n.º 2
0
    def populate_indicators(self, dataframe: DataFrame,
                            metadata: dict) -> DataFrame:

        # Set Up Bollinger Bands
        upper_bb1, mid_bb1, lower_bb1 = ta.BBANDS(dataframe['close'],
                                                  timeperiod=36)
        upper_bb2, mid_bb2, lower_bb2 = ta.BBANDS(
            qtpylib.typical_price(dataframe), timeperiod=12)

        # Only putting some bands into dataframe as the others are not used elsewhere in the strategy
        dataframe['lower-bb1'] = lower_bb1
        dataframe['lower-bb2'] = lower_bb2
        dataframe['mid-bb2'] = mid_bb2

        dataframe['bb1-delta'] = (mid_bb1 - dataframe['lower-bb1']).abs()
        dataframe['closedelta'] = (dataframe['close'] -
                                   dataframe['close'].shift()).abs()
        dataframe['tail'] = (dataframe['close'] - dataframe['low']).abs()

        # Additional indicators
        dataframe['ema_fast'] = ta.EMA(dataframe['close'], timeperiod=6)
        dataframe['ema_slow'] = ta.EMA(dataframe['close'], timeperiod=48)
        dataframe['volume_mean_slow'] = dataframe['volume'].rolling(
            window=24).mean()

        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)

        # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy)
        rsi = 0.1 * (dataframe['rsi'] - 50)
        dataframe['fisher-rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1)

        # Informative Pair Indicators
        coin, stake = metadata['pair'].split('/')
        fiat = self.fiat
        stake_fiat = f"{stake}/{self.fiat}"
        coin_fiat = f"{coin}/{self.fiat}"

        coin_fiat_inf = self.dp.get_pair_dataframe(pair=f"{coin}/{fiat}",
                                                   timeframe=self.timeframe)
        dataframe['coin-fiat-adx'] = ta.ADX(coin_fiat_inf, timeperiod=21)
        coin_aroon = ta.AROON(coin_fiat_inf, timeperiod=25)
        dataframe['coin-fiat-aroon-down'] = coin_aroon['aroondown']
        dataframe['coin-fiat-aroon-up'] = coin_aroon['aroonup']

        stake_fiat_inf = self.dp.get_pair_dataframe(pair=f"{stake}/{fiat}",
                                                    timeframe=self.timeframe)
        dataframe['stake-fiat-adx'] = ta.ADX(stake_fiat_inf, timeperiod=21)
        stake_aroon = ta.AROON(stake_fiat_inf, timeperiod=25)
        dataframe['stake-fiat-aroon-down'] = stake_aroon['aroondown']
        dataframe['stake-fiat-aroon-up'] = stake_aroon['aroonup']

        # These indicators are used to persist a buy signal in live trading only
        # They dramatically slow backtesting down
        if self.config['runmode'].value in ('live', 'dry_run'):
            dataframe['sar'] = ta.SAR(dataframe)

        return dataframe
Ejemplo n.º 3
0
def populate_indicators(dataframe: DataFrame) -> DataFrame:
    """
    Adds several different TA indicators to the given DataFrame
    """
    dataframe['sar'] = ta.SAR(dataframe)
    dataframe['adx'] = ta.ADX(dataframe)
    stoch = ta.STOCHF(dataframe)
    dataframe['fastd'] = stoch['fastd']
    dataframe['fastk'] = stoch['fastk']
    dataframe['blower'] = ta.BBANDS(dataframe, nbdevup=2,
                                    nbdevdn=2)['lowerband']
    dataframe['sma'] = ta.SMA(dataframe, timeperiod=40)
    dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
    dataframe['mfi'] = ta.MFI(dataframe)
    dataframe['cci'] = ta.CCI(dataframe)
    dataframe['rsi'] = ta.RSI(dataframe)
    dataframe['mom'] = ta.MOM(dataframe)
    dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5)
    dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10)
    dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
    dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)
    dataframe['ao'] = awesome_oscillator(dataframe)
    macd = ta.MACD(dataframe)
    dataframe['macd'] = macd['macd']
    dataframe['macdsignal'] = macd['macdsignal']
    dataframe['macdhist'] = macd['macdhist']
    return dataframe
Ejemplo n.º 4
0
def technical(profile):
    """
    Updates profile with SMA, BB, and RSI calculations

    In: profile with basic ohlc price data
    Out: profile updated with studies merged with profile's price history
    """
    prices = {
        'open': np.array([record['o'] for record in profile.history]),
        'high': np.array([record['h'] for record in profile.history]),
        'low': np.array([record['l'] for record in profile.history]),
        'close': np.array([record['c'] for record in profile.history]),
        'volume': np.array([record['vol'] for record in profile.history])
    }
    # print(prices['open'])
    # print(prices)

    sma = ta.SMA(prices, timeperiod=200)
    profile.add_study("sma", [round(float(point), 2) for point in sma])

    bb_upper, bb_middle, bb_lower = ta.BBANDS(prices, 100, 2, 2)
    profile.add_study("bb_upper",
                      [round(float(point), 2) for point in bb_upper])
    profile.add_study("bb_middle",
                      [round(float(point), 2) for point in bb_middle])
    profile.add_study("bb_lower",
                      [round(float(point), 2) for point in bb_lower])

    rsi = ta.RSI(prices, timeperiod=14)
    profile.add_study("rsi", [round(float(point), 2) for point in rsi])
Ejemplo n.º 5
0
    def __init__(self, equityDataFrame, tickerCode):
        """
        Create the Bollinger Band-specific logic. Everything else lives in the Indicator Base Class.

        :param equityDataFrame: A Pandas DataFrame from the Equity Class.
        :param tickerCode: Ticker Code (String).
        """

        tableName = "Indicator_BB20"
        tickerCode = tickerCode

        insertQuery = "insert or replace into %s (Date, upperband, middleband, lowerband, Code, upperbandroc, middlebandroc, lowerbandroc) values (?,?,?,?,?,?,?,?)" % (
            tableName)

        equityDataFrame = equityDataFrame

        # Stick the Indicator Values into the new DataFrame
        indicatorDataFrame = abstract.BBANDS(equityDataFrame,
                                             20,
                                             2,
                                             2,
                                             price='Close')
        indicatorDataFrame['Code'] = tickerCode
        indicatorDataFrame['upperbandroc'] = abstract.ROC(indicatorDataFrame,
                                                          timeperiod=5,
                                                          price='upperband')
        indicatorDataFrame['middlebandroc'] = abstract.ROC(indicatorDataFrame,
                                                           timeperiod=5,
                                                           price='middleband')
        indicatorDataFrame['lowerbandroc'] = abstract.ROC(indicatorDataFrame,
                                                          timeperiod=5,
                                                          price='lowerband')

        Indicator.__init__(self, tableName, tickerCode, insertQuery,
                           equityDataFrame, indicatorDataFrame)
Ejemplo n.º 6
0
    def analyze_bollinger_bands(self, historial_data, all_data=False):
        """Performs a bollinger band analysis on the historical data

        Args:
            historial_data (list): A matrix of historical OHCLV data.
            all_data (bool, optional): Defaults to False. If True, we return the BB's associated with each
                data point in our historical dataset. Otherwise just return the last one.

        Returns:
            dict: A dictionary containing a tuple of indicator values and booleans for buy / sell
                indication.
        """

        dataframe = self.__convert_to_dataframe(historial_data)
        bollinger_data = abstract.BBANDS(dataframe)

        bb_result_data = []
        for bb_row in bollinger_data.iterrows():
            data_point_result = {
                'values': (
                    bb_row[1]['upperband'],
                    bb_row[1]['middleband'],
                    bb_row[1]['lowerband']
                ),
                'is_hot': False,
                'is_cold': False
            }

            bb_result_data.append(data_point_result)

        if all_data:
            return bb_result_data
        else:
            return bb_result_data[-1]
Ejemplo n.º 7
0
    def BBANDS(
        self
    ):  #BOLL timeperiod = 5 , nbdevup = 2, nbdevdn = 2, matype = 0(simple moving average)
        bbands = abstract.BBANDS(self.company_stock, timeperiod=5)

        self.company_stock['BOLL_U'] = bbands['upperband']
        self.company_stock['BOLL_M'] = bbands['middleband']
        self.company_stock['BOLL_D'] = bbands['lowerband']
Ejemplo n.º 8
0
def test_talib_bollingerbands_near_zero_values():
    inputs = pd.DataFrame([
        {'close': 0.00000010},
        {'close': 0.00000011},
        {'close': 0.00000012},
        {'close': 0.00000013},
        {'close': 0.00000014}
    ])
    bollinger = ta.BBANDS(inputs, matype=0, timeperiod=2)
    assert bollinger['upperband'][3] != bollinger['middleband'][3]
Ejemplo n.º 9
0
    def cal_bb(self, period=20):
        upperband, middleband, lowerband = ta.BBANDS(self.close,
                                                     timeperiod=period,
                                                     nbdevup=2.0,
                                                     nbdevdn=2.0,
                                                     matype=0)

        self.analysis_data['upperband'] = upperband
        self.analysis_data['middleband'] = middleband
        self.analysis_data['lowerband'] = lowerband
Ejemplo n.º 10
0
def BBANDS(ohlcv, kw):
    """ :return Bollinger Bands (upperband, middleband, lowerband) """
    params = {'timeperiod': 5, 'nbdevup': 2, 'nbdevdn': 2, 'matype': 0}
    timeperiod, nbdevup, nbdevdn, matype = _get_params(kw, params, ['timeperiod', 'nbdevup', 'nbdevdn', 'matype'])
    result = talib.BBANDS(ohlcv, timeperiod, nbdevup, nbdevdn, matype)
    return {
        'upperband': result[0],
        'middleband': result[1],
        'lowerband': result[2]
    }
Ejemplo n.º 11
0
def TA_BBANDS(prices: np.ndarray,
              timeperiod: int = 5,
              nbdevup: int = 2.,
              nbdevdn: int = 2.,
              matype: int = 0):

    up, middle, low = ta.BBANDS(prices, timeperiod, nbdevup, nbdevdn, matype)
    ch = (up - low) / middle
    b = (prices - low) / (up - low)
    return up, middle, low, ch, b
Ejemplo n.º 12
0
    def add_indicators(self, df: pd.DataFrame = None) -> pd.DataFrame:
        """Add indicators."""

        cols = ['high', 'low', 'open', 'close', 'volume']
        HLOCV = {key: df[key].values for key in df if key in cols}

        try:
            df['volume'] = df['volumeto']
        except:
            pass

        # Moving Averages
        df['sma'] = abstract_ta.SMA(df, timeperiod=25)
        df['ema20'] = abstract_ta.EMA(df, timeperiod=20)
        df['ema50'] = abstract_ta.EMA(df, timeperiod=50)
        df['ema100'] = abstract_ta.EMA(df, timeperiod=100)
        df['ema200'] = abstract_ta.EMA(df, timeperiod=200)
        df['ema300'] = abstract_ta.EMA(df, timeperiod=300)

        # Bollinger Bands
        u, m, l = abstract_ta.BBANDS(HLOCV,
                                     timeperiod=24,
                                     nbdevup=2.5,
                                     nbdevdn=2.5,
                                     matype=MA_Type.T3)
        df['upper'] = u
        df['middle'] = m
        df['lower'] = l

        # Stochastic
        # uses high, low, close (default)
        slowk, slowd = abstract_ta.STOCH(HLOCV, 5, 3, 0, 3,
                                         0)  # uses high, low, close by default
        df['slowk'] = slowk
        df['slowd'] = slowd
        df['slow_stoch'] = (slowk + slowd) / 2
        df['slow_stoch_sma14'] = df.slow_stoch.rolling(window=14).mean()
        df['slow_stoch_sma26'] = df.slow_stoch.rolling(window=26).mean()

        # Relative Strength Index
        rsi = abstract_ta.RSI(df, timeperiod=14)
        df['rsi'] = rsi

        # Money Flow Index
        mfi = abstract_ta.MFI(df, timeperiod=14)
        df['mfi'] = mfi

        # Medivh Relative Flow Index
        mrfi_df = MRFI(df)
        df['mrfi'] = mrfi_df['mrfi'].astype(float)
        df['smrfi'] = mrfi_df['smrfi'].astype(float)
        df['mrfi_basis'] = mrfi_df['mrfi_basis'].astype(float)
        df['mrfi_inverse'] = mrfi_df['mrfi_inverse'].astype(float)

        return df
def BBANDS_pic(stockNumber, msg):
    stock_name = get_stockName(stockNumber)
    df_x = general_df(stockNumber)
    jj=df_x.reset_index(drop=False)
    abstract.BBANDS(df_x).plot(figsize=(16,8))
    plt.xlabel("date",  FontProperties=chinese_font)
    plt.ylabel("價格",  FontProperties=chinese_font)
    plt.grid(True,axis='y')
    plt.title(stock_name+"BBANDS" ,FontProperties=chinese_font)
    plt.savefig(msg + ".png")
    plt.close()
    return Imgur.showImgurBBAND(msg)
Ejemplo n.º 14
0
def TA_processing(dataframe):
    bias(dataframe, days=[3, 6, 10, 25])
    moving_average(dataframe, days=[5, 10, 20])
    dataframe['ROC'] = abstract.ROC(dataframe, timeperiod=10)
    dataframe['MACD'] = abstract.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)['macd']
    dataframe['MACD_signal'] = abstract.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)['macdsignal']
    dataframe['UBBANDS'] = abstract.BBANDS(dataframe, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)['upperband']
    dataframe['MBBANDS'] = abstract.BBANDS(dataframe, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)['middleband']
    dataframe['LBBANDS'] = abstract.BBANDS(dataframe, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)['lowerband']
    dataframe['%K'] = abstract.STOCH(dataframe, fastk_period=9)['slowk']/100
    dataframe['%D'] = abstract.STOCH(dataframe, fastk_period=9)['slowd']/100
    dataframe['W%R'] = abstract.WILLR(dataframe, timeperiod=14)/100
    dataframe['RSI9'] = abstract.RSI(dataframe, timeperiod = 9)/100
    dataframe['RSI14'] = abstract.RSI(dataframe, timeperiod = 14)/100
    dataframe['CCI'] = abstract.CCI(dataframe, timeperiod=14)/100
    counter_daily_potential(dataframe)
    dataframe['MOM'] = abstract.MOM(dataframe, timeperiod=10)
    dataframe['DX'] = abstract.DX(dataframe, timeperiod=14)/100
    psy_line(dataframe)
    volumn_ratio(dataframe, d=26)
    on_balance_volume(dataframe)
Ejemplo n.º 15
0
    def populate_indicators(self, dataframe: DataFrame,
                            metadata: dict) -> DataFrame:

        # Heikin Ashi Candles
        heikinashi = qtpylib.heikinashi(dataframe)
        dataframe['ha_open'] = heikinashi['open']
        dataframe['ha_close'] = heikinashi['close']
        dataframe['ha_high'] = heikinashi['high']
        dataframe['ha_low'] = heikinashi['low']

        # Set Up Bollinger Bands
        upper_bb1, mid_bb1, lower_bb1 = ta.BBANDS(dataframe['ha_close'],
                                                  timeperiod=40)
        upper_bb2, mid_bb2, lower_bb2 = ta.BBANDS(
            qtpylib.typical_price(heikinashi), timeperiod=20)

        # only putting some bands into dataframe as the others are not used elsewhere in the strategy
        dataframe['lower-bb1'] = lower_bb1
        dataframe['lower-bb2'] = lower_bb2
        dataframe['mid-bb2'] = mid_bb2

        dataframe['bb1-delta'] = (mid_bb1 - dataframe['lower-bb1']).abs()
        dataframe['closedelta'] = (dataframe['ha_close'] -
                                   dataframe['ha_close'].shift()).abs()
        dataframe['tail'] = (dataframe['ha_close'] - dataframe['ha_low']).abs()

        dataframe['ema_slow'] = ta.EMA(dataframe['ha_close'], timeperiod=48)
        dataframe['volume_mean_slow'] = dataframe['volume'].rolling(
            window=24).mean()

        dataframe['rsi'] = ta.RSI(heikinashi, timeperiod=14)

        dataframe['tema'] = ta.TEMA(heikinashi, timeperiod=9)
        dataframe['adx'] = ta.ADX(heikinashi)
        dataframe['rmi'] = RMI(heikinashi)

        dataframe['sar'] = ta.SAR(heikinashi)

        return dataframe
Ejemplo n.º 16
0
def get_indicators(stockData, period):
    stocks_indicators = {}

    #data = pd.DataFrame(SMA(stockData, timeperiod=5))
    #data.columns = ['sma_5']
    #data['sma_10'] = pd.DataFrame(SMA(stockData, timeperiod=10))

    #features['diff_sma'] = data['sma_10'] - data['sma_5']

    features = pd.DataFrame()
    bands = ta.BBANDS(stockData, timeperiod=8, nbdevup=2, nbdevdn=2)

    features['BB'] = (stockData['close'] - bands['middleband']) / (
        (bands['upperband'] - bands['lowerband']) / 2)
    features['close'] = stockData['close']
    #features = pd.concat([features,STOCHF(stockData,
    #                                 fastk_period=14,
    #                                   fastd_period=3)],
    #                      axis=1)
    #features['MA50day']= pd.DataFrame(SMA(stockData, timeperiod=50))
    features['NATR'] = ta.NATR(stockData, timeperiod=14)
    #features['adx'] =ADX(stockData,timeperiod=14) Not Good
    #features['macd'] = pd.DataFrame(MACD(stockData, fastperiod=12, slowperiod=26)['macd'])
    features['rsi'] = pd.DataFrame(ta.RSI(stockData, timeperiod=14))
    features['profit'] = ta.ROC(stockData, timeperiod=period)
    features['profit'] = features['profit'].shift(-period)
    features['pct_change'] = ta.ROC(stockData, timeperiod=period)
    features['pct_change'] = features['pct_change'].shift(-period)
    features['pct_change'] = features['pct_change'].apply(
        lambda x: 1 if x > 0 else -1 if x <= 0 else np.nan)
    features = features.dropna()

    #=============Not currenctly using these features below =====================
    #features[['diff_sma', 'sma_10']].sub(features['sma_5'], axis=0)
    #features['mom_10'] = pd.DataFrame(MOM(stockData, 10))

    #data['wma_10'] = pd.DataFrame(WMA(stockData, 10))
    #data['wma_5'] = pd.DataFrame(WMA(stockData,5))
    #features['diff_wma'] = data['wma_10'] - data['wma_5']

    #features = pd.concat([features,STOCHF(stockData,
    #                                fastk_period=14,
    #                                 fastd_period=3)],
    #                   axis=1)
    #features['willr'] = pd.DataFrame(WILLR(stockData, timeperiod=14))
    #features['cci'] = pd.DataFrame(CCI(stockData, timeperiod=14))
    #features['adosc'] = pd.DataFrame(ADOSC(stockData, fastperiod=3, slowperiod=10))

    return features
Ejemplo n.º 17
0
    def populate_indicators(self, dataframe: DataFrame,
                            metadata: dict) -> DataFrame:

        # Set Up Bollinger Bands
        upper_bb1, mid_bb1, lower_bb1 = ta.BBANDS(dataframe['close'],
                                                  timeperiod=40)
        upper_bb2, mid_bb2, lower_bb2 = ta.BBANDS(
            qtpylib.typical_price(dataframe), timeperiod=20)

        # only putting some bands into dataframe as the others are not used elsewhere in the strategy
        dataframe['lower-bb1'] = lower_bb1
        dataframe['lower-bb2'] = lower_bb2
        dataframe['mid-bb2'] = mid_bb2

        dataframe['bb1-delta'] = (mid_bb1 - dataframe['lower-bb1']).abs()
        dataframe['closedelta'] = (dataframe['close'] -
                                   dataframe['close'].shift()).abs()
        dataframe['tail'] = (dataframe['close'] - dataframe['low']).abs()

        dataframe['ema_fast'] = ta.EMA(dataframe['close'], timeperiod=6)
        dataframe['ema_slow'] = ta.EMA(dataframe['close'], timeperiod=48)
        dataframe['volume_mean_slow'] = dataframe['volume'].rolling(
            window=24).mean()

        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=9)

        # # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy)
        rsi = 0.1 * (dataframe['rsi'] - 50)
        dataframe['fisher-rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1)

        # These indicators are used to persist a buy signal in live trading only
        # They dramatically slow backtesting down
        if self.config['runmode'].value in ('live', 'dry_run'):
            dataframe['sar'] = ta.SAR(dataframe)

        return dataframe
Ejemplo n.º 18
0
def populate_indicators(dataframe: DataFrame) -> DataFrame:
    """
    Adds several different TA indicators to the given DataFrame
    """
    dataframe['sar'] = ta.SAR(dataframe)
    dataframe['adx'] = ta.ADX(dataframe)
    stoch = ta.STOCHF(dataframe)
    dataframe['fastd'] = stoch['fastd']
    dataframe['fastk'] = stoch['fastk']
    dataframe['blower'] = ta.BBANDS(dataframe, nbdevup=2, nbdevdn=2)['lowerband']
    dataframe['sma'] = ta.SMA(dataframe, timeperiod=40)
    dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
    dataframe['mfi'] = ta.MFI(dataframe)
    dataframe['cci'] = ta.CCI(dataframe)
    return dataframe
Ejemplo n.º 19
0
 def bbands(self):
     bbands = tb.BBANDS(self.dataframe,
                        timeperiod=100,
                        nbdevup=2.0,
                        nbdevdn=2.0,
                        matype=0)
     if (self.dataframe['open'][len(self.dataframe) - 1] <
             bbands['lowerband'][len(bbands) - 1] <
             self.dataframe['close'][len(self.dataframe) - 1]):
         return "buy"
     elif (self.dataframe['open'][len(self.dataframe) - 1] >
           bbands['upperband'][len(bbands) - 1] >
           self.dataframe['close'][len(self.dataframe) - 1]):
         return "sell"
     else:
         return "neutral"
Ejemplo n.º 20
0
    def analyze(self, historical_data, period_count=21):
        """Performs a bollinger band analysis on the historical data

        Args:
            historical_data (list): A matrix of historical OHCLV data.
            period_count (int, optional): Defaults to 21. The number of data points to consider for
                our bollinger bands.

        Returns:
            pandas.DataFrame: A dataframe containing the indicators and hot/cold values.
        """

        dataframe = self.convert_to_dataframe(historical_data)
        bollinger_data = abstract.BBANDS(dataframe, period_count)
        bollinger_data.dropna(how='all', inplace=True)

        return bollinger_data
Ejemplo n.º 21
0
    def BB(self, window_size):
        from talib import abstract

        input_arrays = {
            'open': self.data['Open'].values,
            'high': self.data['High'].values,
            'low': self.data['Low'].values,
            'close': self.data['Close'].values,
            'volume': self.data['Volume'].values
        }

        return abstract.BBANDS(input_arrays,
                               timeperiod=window_size *
                               self.no_of_intervals_per_day,
                               nbdevup=2,
                               nbdevdn=2,
                               matype=0)
Ejemplo n.º 22
0
    def test_ta_lib_abstract_api(self):
        """Test the abstract API of TA-Lib"""

        with IQFeedHistoryProvider() as provider:
            df = provider.request_data(BarsFilter(ticker="AAPL",
                                                  interval_len=300,
                                                  interval_type='s',
                                                  max_bars=1000),
                                       sync_timestamps=False)
            close = df['close']

            output = abstract.SMA(df)
            self.assertTrue(isinstance(output, pd.Series))
            self.assertFalse(output.empty)
            self.assertTrue(pd.isna(output[0]))
            self.assertFalse(pd.isna(output[-1]))
            self.assertEqual(close.shape, output.shape)
            self.assertEqual(close.dtype, output.dtype)
            assert_index_equal(close.index, output.index)

            bbands = abstract.BBANDS(df, matype=talib.MA_Type.T3)
            self.assertTrue(isinstance(bbands, pd.DataFrame))
            assert_index_equal(close.index, bbands.index)

            for _, bband in bbands.iteritems():
                self.assertTrue(isinstance(bband, pd.Series))
                self.assertFalse(bband.empty)
                self.assertEqual(close.shape, bband.shape)
                self.assertEqual(close.dtype, bband.dtype)
                self.assertTrue(pd.isna(bband[0]))
                self.assertFalse(pd.isna(bband[-1]))

            stoch = abstract.STOCH(df, 5, 3, 0, 3, 0)
            self.assertTrue(isinstance(stoch, pd.DataFrame))
            assert_index_equal(close.index, stoch.index)

            for _, s in stoch.iteritems():
                self.assertTrue(isinstance(s, pd.Series))
                self.assertFalse(s.empty)
                self.assertEqual(close.shape, s.shape)
                self.assertEqual(close.dtype, s.dtype)
                self.assertTrue(pd.isna(s[0]))
                self.assertFalse(pd.isna(s[-1]))
Ejemplo n.º 23
0
    def __init__(self, feed: pd.DataFrame):
        super().__init__(feed)

        if self.has_enough_feed():
            rsi = abstract.RSI(self.feed, period=self.period)
            maxrsi = abstract.MAX(rsi, period=self.period)
            minrsi = abstract.MIN(rsi, period=self.period)
            srsi = (rsi - minrsi) / (maxrsi - minrsi)

            self.feed["srsi"] = srsi

            bb = abstract.BBANDS(self.feed,
                                 matype=MA_Type.T3,
                                 period=self.period)
            self.feed["bbh"] = bb["upperband"]
            prev_close = self.feed["close"].shift(1)
            prev_bbh = self.feed["bbh"].shift(1)
            self.feed["bbh_cross_up"] = (self.feed["close"] > self.feed["bbh"]
                                         ) & (prev_close <= prev_bbh)
Ejemplo n.º 24
0
    def _process(self, v, param):
        data = {
            "open" : v["open"].astype(float),
            "high" : v["high"].astype(float),
            "low" : v["low"].astype(float),
            "close" : v["close"].astype(float),
            "volume" : v["jdiff_vol"].astype(float)
        }

        # 이동평균선
        if "SMA" in param:
            for p in param["SMA"]:
                v["SMA" + str(p)] = Series(abstract.SMA(data, p), index=v.index)

        # Bollinger Bands
        if "BBANDS" in param:
            temp = abstract.BBANDS(data, param["BBANDS"][0], param["BBANDS"][1], param["BBANDS"][1])
            v["BBANDS-UPPER"] = temp[0]
            v["BBANDS-MIDDLE"] = temp[1]
            v["BBANDS-LOWER"] = temp[2]

        # Slow stochastic
        if "STOCH" in param:
            temp = abstract.STOCH(data, param["STOCH"][0], param["STOCH"][1], param["STOCH"][2])
            v["STOCH-K"] = temp[0]
            v["STOCH-D"] = temp[1]

        # ATR (Average True Range)
        if "ATR" in param:
            v["ATR"] = Series(abstract.ATR(data, param["ATR"]), index=v.index)

        # MACD (Moving Average Convergence/Divergence)
        if "MACD" in param:
            temp = abstract.MACD(data, param["MACD"][0], param["MACD"][1], param["MACD"][2])
            v["MACD-OUT"] = temp[0]
            v["MACD-SIGNAL"] = temp[1]
            v["MACD-HIST"] = temp[2]

        # RSI (Relative Strength Index)
        if "RSI" in param:
            v["RSI"] = Series(abstract.RSI(data, param["RSI"]), index=v.index)
Ejemplo n.º 25
0
    def get_overlap_studies(self):
        # https://mrjbq7.github.io/ta-lib/func_groups/overlap_studies.html
        if self.verbose:
            print self.ticker, 'get_overlap_studies'

        _a = ['open', 'high', 'low', 'close', 'volume']
        inputs = {_a[i]: self.data[_a[i]].values for i in range(len(_a))}

        # simple moving average
        self.data['os_sma_20'] = abstract.SMA(inputs, timeperiod=20)
        self.data['os_sma_50'] = abstract.SMA(inputs, timeperiod=50)
        self.data['os_sma_200'] = abstract.SMA(inputs, timeperiod=200)

        # bollinger bands
        self.data['os_bbu_20'], self.data['os_bbm_20'], self.data[
            'os_bbl_20'] = abstract.BBANDS(inputs,
                                           timeperiod=20,
                                           nbdevup=2,
                                           nbdevdn=2,
                                           matype=0)

        # double exponential moving average
        self.data['os_dema_20'] = abstract.DEMA(inputs, timeperiod=20)

        # exponential moving average
        self.data['os_ema_20'] = abstract.EMA(inputs, timeperiod=20)

        # midpoint over period
        self.data['os_mp_14'] = abstract.MIDPOINT(inputs, timeperiod=14)

        # parabolic SAR
        self.data['os_sar'] = abstract.SAR(inputs, acceleration=0, maximum=0)

        # triple exponential moving average
        self.data['os_tema_5'] = abstract.TEMA(inputs, timeperiod=5)

        # triangular moving average
        self.data['os_trima_30'] = abstract.TRIMA(inputs, timeperiod=30)

        # weighted moving average
        self.data['os_wma_30'] = abstract.WMA(inputs, timeperiod=30)
Ejemplo n.º 26
0
 def BBANDS(self):
     BBANDS = tb.BBANDS(self.dataframe,
                        timeperiod=100,
                        nbdevup=2,
                        nbdevdn=2,
                        matype=0)
     # print("lowerband", BBANDS['lowerband'][len(BBANDS)-1])
     # print("upperband", BBANDS['upperband'][len(BBANDS)-1])
     # print("open", self.dataframe['open'][len(self.dataframe)-1])
     # print("close", self.dataframe['close'][len(self.dataframe)-1])
     if (self.dataframe['open'][len(self.dataframe) - 1] <
             BBANDS['lowerband'][len(BBANDS) - 1]
             and BBANDS['lowerband'][len(BBANDS) - 1] <
             self.dataframe['close'][len(self.dataframe) - 1]):
         return "buy"
     elif (self.dataframe['open'][len(self.dataframe) - 1] >
           BBANDS['upperband'][len(BBANDS) - 1]
           and BBANDS['upperband'][len(BBANDS) - 1] >
           self.dataframe['close'][len(self.dataframe) - 1]):
         return "sell"
     else:
         return "neutral"
Ejemplo n.º 27
0
    def analyze_bollinger_bands(self, historial_data):
        """Performs a bollinger band analysis on the historical data

        Args:
            historial_data (list): A matrix of historical OHCLV data.

        Returns:
            dict: A dictionary containing a tuple of indicator values and booleans for buy / sell
                indication.
        """

        dataframe = self.__convert_to_dataframe(historial_data)
        upper_band, middle_band, lower_band = abstract.BBANDS(
            dataframe).iloc[-1]

        bb_data = {
            'values': (upper_band, middle_band, lower_band),
            'is_hot': False,
            'is_cold': False
        }

        return bb_data
    def populate_indicators(self, dataframe: DataFrame) -> DataFrame:
        """
        Adds several different TA indicators to the given DataFrame

        Performance Note: For the best performance be frugal on the number of indicators
        you are using. Let uncomment only the indicator you are using in your strategies
        or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
        """

        # Momentum Indicator
        # ------------------------------------

        # ADX
        dataframe['adx'] = ta.ADX(dataframe)

        # Awesome oscillator
        dataframe['ao'] = qtpylib.awesome_oscillator(dataframe)
        """
        # Commodity Channel Index: values Oversold:<-100, Overbought:>100
        dataframe['cci'] = ta.CCI(dataframe)
        """
        # MACD
        macd = ta.MACD(dataframe)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']

        # MFI
        dataframe['mfi'] = ta.MFI(dataframe)

        # Minus Directional Indicator / Movement
        dataframe['minus_dm'] = ta.MINUS_DM(dataframe)
        dataframe['minus_di'] = ta.MINUS_DI(dataframe)

        # Plus Directional Indicator / Movement
        dataframe['plus_dm'] = ta.PLUS_DM(dataframe)
        dataframe['plus_di'] = ta.PLUS_DI(dataframe)
        dataframe['minus_di'] = ta.MINUS_DI(dataframe)
        """
        # ROC
        dataframe['roc'] = ta.ROC(dataframe)
        """
        # RSI
        dataframe['rsi'] = ta.RSI(dataframe)

        # Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy)
        dataframe['fisher_rsi'] = fishers_inverse(dataframe['rsi'])

        # Inverse Fisher transform on RSI normalized, value [0.0, 100.0] (https://goo.gl/2JGGoy)
        dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1)

        # Stoch
        stoch = ta.STOCH(dataframe)
        dataframe['slowd'] = stoch['slowd']
        dataframe['slowk'] = stoch['slowk']

        # Stoch fast
        stoch_fast = ta.STOCHF(dataframe)
        dataframe['fastd'] = stoch_fast['fastd']
        dataframe['fastk'] = stoch_fast['fastk']
        """
        # Stoch RSI
        stoch_rsi = ta.STOCHRSI(dataframe)
        dataframe['fastd_rsi'] = stoch_rsi['fastd']
        dataframe['fastk_rsi'] = stoch_rsi['fastk']
        """

        # Overlap Studies
        # ------------------------------------

        # Previous Bollinger bands
        # Because ta.BBANDS implementation is broken with small numbers, it actually
        # returns middle band for all the three bands. Switch to qtpylib.bollinger_bands
        # and use middle band instead.
        dataframe['blower'] = ta.BBANDS(dataframe, nbdevup=2,
                                        nbdevdn=2)['lowerband']

        # Bollinger bands
        bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe),
                                            window=20,
                                            stds=2)
        dataframe['bb_lowerband'] = bollinger['lower']
        dataframe['bb_middleband'] = bollinger['mid']
        dataframe['bb_upperband'] = bollinger['upper']

        # EMA - Exponential Moving Average
        dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3)
        dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5)
        dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10)
        dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
        dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)

        # SAR Parabol
        dataframe['sar'] = ta.SAR(dataframe)

        # SMA - Simple Moving Average
        dataframe['sma'] = ta.SMA(dataframe, timeperiod=40)

        # TEMA - Triple Exponential Moving Average
        dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)

        # Cycle Indicator
        # ------------------------------------
        # Hilbert Transform Indicator - SineWave
        hilbert = ta.HT_SINE(dataframe)
        dataframe['htsine'] = hilbert['sine']
        dataframe['htleadsine'] = hilbert['leadsine']

        # Pattern Recognition - Bullish candlestick patterns
        # ------------------------------------
        """
        # Hammer: values [0, 100]
        dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe)
        # Inverted Hammer: values [0, 100]
        dataframe['CDLINVERTEDHAMMER'] = ta.CDLINVERTEDHAMMER(dataframe)
        # Dragonfly Doji: values [0, 100]
        dataframe['CDLDRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe)
        # Piercing Line: values [0, 100]
        dataframe['CDLPIERCING'] = ta.CDLPIERCING(dataframe) # values [0, 100]
        # Morningstar: values [0, 100]
        dataframe['CDLMORNINGSTAR'] = ta.CDLMORNINGSTAR(dataframe) # values [0, 100]
        # Three White Soldiers: values [0, 100]
        dataframe['CDL3WHITESOLDIERS'] = ta.CDL3WHITESOLDIERS(dataframe) # values [0, 100]
        """

        # Pattern Recognition - Bearish candlestick patterns
        # ------------------------------------
        """
        # Hanging Man: values [0, 100]
        dataframe['CDLHANGINGMAN'] = ta.CDLHANGINGMAN(dataframe)
        # Shooting Star: values [0, 100]
        dataframe['CDLSHOOTINGSTAR'] = ta.CDLSHOOTINGSTAR(dataframe)
        # Gravestone Doji: values [0, 100]
        dataframe['CDLGRAVESTONEDOJI'] = ta.CDLGRAVESTONEDOJI(dataframe)
        # Dark Cloud Cover: values [0, 100]
        dataframe['CDLDARKCLOUDCOVER'] = ta.CDLDARKCLOUDCOVER(dataframe)
        # Evening Doji Star: values [0, 100]
        dataframe['CDLEVENINGDOJISTAR'] = ta.CDLEVENINGDOJISTAR(dataframe)
        # Evening Star: values [0, 100]
        dataframe['CDLEVENINGSTAR'] = ta.CDLEVENINGSTAR(dataframe)
        """

        # Pattern Recognition - Bullish/Bearish candlestick patterns
        # ------------------------------------
        """
        # Three Line Strike: values [0, -100, 100]
        dataframe['CDL3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe)
        # Spinning Top: values [0, -100, 100]
        dataframe['CDLSPINNINGTOP'] = ta.CDLSPINNINGTOP(dataframe) # values [0, -100, 100]
        # Engulfing: values [0, -100, 100]
        dataframe['CDLENGULFING'] = ta.CDLENGULFING(dataframe) # values [0, -100, 100]
        # Harami: values [0, -100, 100]
        dataframe['CDLHARAMI'] = ta.CDLHARAMI(dataframe) # values [0, -100, 100]
        # Three Outside Up/Down: values [0, -100, 100]
        dataframe['CDL3OUTSIDE'] = ta.CDL3OUTSIDE(dataframe) # values [0, -100, 100]
        # Three Inside Up/Down: values [0, -100, 100]
        dataframe['CDL3INSIDE'] = ta.CDL3INSIDE(dataframe) # values [0, -100, 100]
        """

        # Chart type
        # ------------------------------------
        # Heikinashi stategy
        heikinashi = qtpylib.heikinashi(dataframe)
        dataframe['ha_open'] = heikinashi['open']
        dataframe['ha_close'] = heikinashi['close']
        dataframe['ha_high'] = heikinashi['high']
        dataframe['ha_low'] = heikinashi['low']

        return dataframe
Ejemplo n.º 29
0
def populate_indicators(dataframe: DataFrame) -> DataFrame:
    """
    Adds several different TA indicators to the given DataFrame
    """
    dataframe['sar'] = ta.SAR(dataframe)
    dataframe['adx'] = ta.ADX(dataframe)
    stoch = ta.STOCHF(dataframe)
    dataframe['fastd'] = stoch['fastd']
    dataframe['fastk'] = stoch['fastk']
    dataframe['blower'] = ta.BBANDS(dataframe, nbdevup=2,
                                    nbdevdn=2)['lowerband']
    dataframe['sma'] = ta.SMA(dataframe, timeperiod=40)
    dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
    dataframe['mfi'] = ta.MFI(dataframe)
    dataframe['cci'] = ta.CCI(dataframe)
    dataframe['rsi'] = ta.RSI(dataframe)
    dataframe['mom'] = ta.MOM(dataframe)
    dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5)
    dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10)
    dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
    dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)
    dataframe['ao'] = awesome_oscillator(dataframe)
    macd = ta.MACD(dataframe)
    dataframe['macd'] = macd['macd']
    dataframe['macdsignal'] = macd['macdsignal']
    dataframe['macdhist'] = macd['macdhist']

    # add volatility indicators
    dataframe['natr'] = ta.NATR(dataframe)

    # add volume indicators
    dataframe['obv'] = ta.OBV(dataframe)

    # add more momentum indicators
    dataframe['rocp'] = ta.ROCP(dataframe)

    # add some pattern recognition
    dataframe['CDL2CROWS'] = ta.CDL2CROWS(dataframe)
    dataframe['CDL3BLACKCROWS'] = ta.CDL3BLACKCROWS(dataframe)
    dataframe['CDL3INSIDE'] = ta.CDL3INSIDE(dataframe)
    dataframe['CDL3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe)
    dataframe['CDL3OUTSIDE'] = ta.CDL3OUTSIDE(dataframe)
    dataframe['CDL3STARSINSOUTH'] = ta.CDL3STARSINSOUTH(dataframe)
    dataframe['CDL3WHITESOLDIERS'] = ta.CDL3WHITESOLDIERS(dataframe)
    dataframe['CDLADVANCEBLOCK'] = ta.CDLADVANCEBLOCK(dataframe)
    dataframe['CDLBELTHOLD'] = ta.CDLBELTHOLD(dataframe)
    dataframe['CDLBREAKAWAY'] = ta.CDLBREAKAWAY(dataframe)
    dataframe['CDLDOJI'] = ta.CDLDOJI(dataframe)
    dataframe['CDLDOJISTAR'] = ta.CDLDOJISTAR(dataframe)
    dataframe['CDLDRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe)
    dataframe['CDLENGULFING'] = ta.CDLENGULFING(dataframe)
    dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe)
    dataframe['CDLBREAKAWAY'] = ta.CDLBREAKAWAY(dataframe)
    dataframe['CDLBREAKAWAY'] = ta.CDLBREAKAWAY(dataframe)

    # enter categorical time
    hour = datetime.strptime(str(dataframe['date'][len(dataframe) - 1]),
                             "%Y-%m-%d %H:%M:%S").hour
    for h in range(24):
        dataframe['hour_{0:02}'.format(h)] = int(h == hour)

    return dataframe
Ejemplo n.º 30
0
def Do_back_test(inner_start_date, inner_end_date, outer_start_date,
                 outer_end_date, stock_selected, answer_y, method_selected,
                 table_feature, inLimitValue, outLimitValue, stopLossPoint,
                 lockInGainValue):
    #try:

    file_path = 'static/data/stock_' + str(stock_selected) + '.csv'
    data = pd.read_csv(file_path, index_col='date')[[
        'open', 'high', 'low', 'close', 'volume'
    ]].dropna()
    data.index = pd.to_datetime(data.index, format='%Y%m%d')
    factorList = []
    table_feature = asList(table_feature)[0]
    stopLossPoint = 0 if stopLossPoint == '' else stopLossPoint
    lockInGainValue = 0 if lockInGainValue == '' else lockInGainValue

    for i in range(len(table_feature)):
        if table_feature[i]['index'] == 'ma':
            data[table_feature[i]['index'] +
                 str(table_feature[i]['day'])] = np.array(
                     abstract.SMA(data, int(table_feature[i]['day'])))
            factorList.append(table_feature[i]['index'] +
                              str(table_feature[i]['day']))
        elif table_feature[i]['index'] == 'rsi':
            data[table_feature[i]['index'] +
                 str(table_feature[i]['day'])] = np.array(
                     abstract.RSI(data, int(table_feature[i]['day'])))
            factorList.append(table_feature[i]['index'] +
                              str(table_feature[i]['day']))
        elif table_feature[i]['index'] == 'kd':
            data[table_feature[i]['index'] +
                 "_K"], data[table_feature[i]['index'] + "_D"] = np.array(
                     abstract.STOCH(data))
            factorList.append(table_feature[i]['index'] + "_K")
            factorList.append(table_feature[i]['index'] + "_D")
        elif table_feature[i]['index'] == 'bband':
            data[table_feature[i]['index'] + str(table_feature[i]['day']) +
                 "_Upper"], data[table_feature[i]['index'] +
                                 str(table_feature[i]['day']) +
                                 "_Middle"], data[table_feature[i]['index'] +
                                                  str(table_feature[i]['day'])
                                                  + "_Lower"] = np.array(
                                                      abstract.BBANDS(data))
            factorList.append(table_feature[i]['index'] +
                              str(table_feature[i]['day']) + "_Upper")
            factorList.append(table_feature[i]['index'] +
                              str(table_feature[i]['day']) + "_Middle")
            factorList.append(table_feature[i]['index'] +
                              str(table_feature[i]['day']) + "_Lower")
        else:
            factorList.append(table_feature[i]['index'])
            #data['rsi'] = np.array(abstract.RSI(data, int(table_params1[i])))
        #factorList.append(table_feature[i]['index'] + str(table_feature[i]['day']))

    train_data = data[(data.index >= inner_start_date)
                      & (data.index < inner_end_date)].copy()
    train_data['train_y'] = Get_train_y(train_data, answer_y)

    train_data = train_data.dropna()

    test_data = data[(data.index >= outer_start_date)
                     & (data.index < outer_end_date)].copy()
    test_data = test_data.dropna()
    test_data['sig'] = Get_ML_sig(train_data[factorList + ['train_y']],
                                  test_data[factorList], method_selected)

    test_data['bh_sig'] = 1
    netValueData = BuildTradeTable(test_data,
                                   'sig',
                                   stopProfit=int(lockInGainValue) * 1000,
                                   stopLoss=int(stopLossPoint) * 1000).replace(
                                       [np.inf, -np.inf], np.nan)
    detailData = Detail(netValueData).replace([np.inf, -np.inf], np.nan)
    evaluateData = Evaluate(netValueData, "custom", method_selected)
    bh_netValueData = BuildTradeTable(test_data, 'bh_sig')
    bh_evaluateData = Evaluate(bh_netValueData, 'custom', '買進持有')
    evaluateData = evaluateData.append(bh_evaluateData).replace(
        [np.inf, -np.inf], np.nan)
    netValueData = netValueData.rename(columns={"netValue": "ml_netValue"})
    bh_netValueData = bh_netValueData.rename(
        columns={"netValue": "bh_netValue"})
    ohlc_data = test_data[['open', 'high', 'low', 'close']].copy()
    ohlc_data['date'] = ohlc_data.index
    ohlc_data = ohlc_data.reset_index(drop=True)
    return netValueData.fillna(''), detailData.fillna(''), evaluateData.fillna(
        ''), bh_netValueData.fillna(''), ohlc_data.fillna('')