def create_bollinger_bands(prices):
    bollUPPER, bollMIDDLE, bollLOWER = BBANDS(prices,
                                              timeperiod=20,
                                              nbdevup=2.,
                                              nbdevdn=2.,
                                              matype=0)

    upper_bolling_percent = np.reshape(bollUPPER / prices, (len(prices), 1))
    lower_bolling_percent = np.reshape(bollLOWER / prices, (len(prices), 1))

    bollinger_bands = np.hstack((upper_bolling_percent, lower_bolling_percent))

    for time_period in range(10, 31):
        for up in range(18, 23):
            for down in range(18, 23):
                upper, middle, lower = BBANDS(prices,
                                              timeperiod=time_period,
                                              nbdevup=float(up) / 10,
                                              nbdevdn=float(down) / 10,
                                              matype=0)

                bollinger_bands = np.hstack(
                    (bollinger_bands,
                     np.reshape(upper / prices, (len(prices), 1)),
                     np.reshape(lower / prices, (len(prices), 1))))

    return bollinger_bands
def minwidth_BBANDS(p, ma_ts, sigma, mid_width):
    """
    Custom technical indicator: 
        Bollinger bands, with a user-defined minimum width.
    """
    from talib import BBANDS
    import numpy as np

    # Obtain indicators
    (t_b, m_o, b_b) = BBANDS(p.values,
                             timeperiod=ma_ts,
                             nbdevup=sigma,
                             nbdevdn=sigma)

    # Impose a minimum width on the bollinger bands - can't use nan values as clips
    t_m = np.isfinite(
        t_b * m_o)  # top band mask: neither top band nor moving av can be nan
    b_m = np.isfinite(
        b_b * m_o)  # bot band mask: neither bot band nor moving av can be nan

    # Clip bands
    t_b[t_m] = np.clip(t_b[t_m], m_o[t_m] + mid_width, np.inf)
    b_b[b_m] = np.clip(b_b[b_m], -np.inf, m_o[b_m] - mid_width)

    return t_b, m_o, b_b
    def analyze(self,
                historical_data,
                signal=['close'],
                hot_thresh=None,
                cold_thresh=None,
                period_count=20,
                std_dev=2):
        """Check when close price cross the Upper/Lower bands.

        Args:
            historical_data (list): A matrix of historical OHCLV data.
            period_count (int, optional): Defaults to 20. The number of data points to consider for the BB bands indicator.
            signal (list, optional): Defaults to close. Unused in this indicator
            std_dev (int, optional): number of std dev to use. Common values are 2 or 1

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

        dataframe = self.convert_to_dataframe(historical_data)

        #Required to avoid getting same values for low, middle, up
        dataframe['close_10k'] = dataframe['close'] * 10000

        up_band, mid_band, low_band = BBANDS(dataframe['close_10k'],
                                             timeperiod=period_count,
                                             nbdevup=std_dev,
                                             nbdevdn=std_dev,
                                             matype=0)

        bollinger = pandas.concat([dataframe, up_band, mid_band, low_band],
                                  axis=1)
        bollinger.rename(columns={
            0: 'up_band',
            1: 'mid_band',
            2: 'low_band'
        },
                         inplace=True)

        old_up, old_low = bollinger.iloc[-2]['up_band'], bollinger.iloc[-2][
            'low_band']
        cur_up, cur_low = bollinger.iloc[-1]['up_band'], bollinger.iloc[-1][
            'low_band']

        old_close = bollinger.iloc[-2]['close_10k']
        cur_close = bollinger.iloc[-1]['close_10k']

        bollinger['is_hot'] = False
        bollinger['is_cold'] = False

        bollinger['is_hot'].iloc[
            -1] = old_low < old_close and cur_low > cur_close
        bollinger['is_cold'].iloc[
            -1] = old_up > old_close and cur_up < cur_close

        bollinger['up_band'] = bollinger['up_band'] / 10000
        bollinger['mid_band'] = bollinger['mid_band'] / 10000
        bollinger['low_band'] = bollinger['low_band'] / 10000

        return bollinger
Exemple #4
0
def WADDAH_ATTAR_EXPLOSION(close, high, low, sensitive = 150, fast_period=20, slow_period = 40, channel_period = 20, channel_mult = 2, dead_zone=30):
    
    from talib import MACD 
    from talib import BBANDS 
    from talib import ATR 
    from talib import WMA 
    macd, macdsignal, macdhist = MACD(close, fastperiod=fast_period, slowperiod=slow_period, signalperiod=9)
    upperband, middleband, lowerband = BBANDS(close, timeperiod=channel_period, nbdevup=channel_mult, nbdevdn=channel_mult, matype=0)

    ind_trend1 = np.full(len(close), np.nan)
    ind_itrend1 = np.full(len(close), np.nan)
    ind_explo1 = np.full(len(close), np.nan)
    tr = WMA(ATR(high, low, close, 20),3)
    ind_dead = tr*dead_zone / 10
    for i in range(0,len(close)):
        if(i<2):
            continue
        trend1 = (macd[i] - macd[i-1]) * sensitive;
        trend2 = (macd[i-1] - macd[i-2]) * sensitive;
        explo1 = (upperband[i] - lowerband[i])
        #explo2 = (upperband[i-1] - lowerband[i-1])
        
        if(trend1>=0):
            ind_trend1[i]=trend1
            ind_itrend1[i]=0
        if(trend1<0):
            ind_trend1[i]=0
            ind_itrend1[i]=(trend1*-1)
        ind_explo1[i] = explo1
        #print(str(i)+"\t "+str(close[i])+"\t "+str(close[i])+"\t "+str(ind_trend1[i])+"\t"+str(ind_itrend1[i]))
    return ind_trend1, ind_itrend1, ind_explo1, ind_dead
Exemple #5
0
    def refit(self, ohlcv, params=None, ba=None, **kwargs):
        """
        refit the strategy using given parameters and return signals

        :param ohlcv: a DataFrame object with OHLCV columns ordered by date, ascending
        :param params: optimal parameters
        :ba: bid ask spread
        :return: signal
        """

        required_params = ['trailing_window', 'ema_s', 'ema_l', 'bb']
        if not all(param in params for param in required_params):
            raise KeyError("incorrect parameters")
        lookback = params['trailing_window']
        close = ohlcv['close']
        ema_s = EMA(close[-lookback:], timeperiod=params['ema_s'])
        ema_l = EMA(close[-lookback:], timeperiod=params['ema_l'])
        bb = BBANDS(close[-lookback:], timeperiod=params['bb'])
        if ba in None:
            buy_signal = (ema_s > ema_l) and (close[-1] >
                                              (bb[1])) and (close[-1] > ema_s)
        else:
            bid = ba['bid']
            ask = ba['ask']
            mid = (bid[-1] + ask[-1]) / 2
            buy_signal = (ema_s > ema_l) and (mid > (bb[1])) and (mid > ema_s)

        return {'buy': buy_signal, 'sell': None}
Exemple #6
0
def bbp(price):
    up, mid, low = BBANDS(close,
                          timeperiod=200,
                          nbdevup=2,
                          nbdevdn=2,
                          matype=0)
    bbp = (price['AdjClose'] - low) / (up - low)
    return bbp
Exemple #7
0
def add_technicals(price, close):
    price["RSI"] = RSI(close, timeperiod=14)
    price["BBP"] = bbp(price)
    price["BB_up"], price["BB_mid"], price["BB_low"] = BBANDS(close,
                                                              timeperiod=20,
                                                              nbdevup=2,
                                                              nbdevdn=2,
                                                              matype=0)
    return price
Exemple #8
0
 def process_data(self, data):
     r = None
     try:
         r = BBANDS(np.array(data['close']), timeperiod=self.period, nbdevup=self.nbdevup, nbdevdn=self.nbdevdn, matype=self.matype)
     except Exception as e:
         print("Exception in BollingerBands", e)
         logger.exception(e)
         r = {self.k: [0,0]}
     self.setd(0 if np.isnan(r[self.k][-1]) else r[self.k][-1])
     return self
Exemple #9
0
def bbp():
    up, mid, low = BBANDS(close,
                          timeperiod=20,
                          nbdevup=2.5,
                          nbdevdn=2.5,
                          matype=8)
    #   up, mid, low = BBANDS(close, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
    #   bbp = (price['Close'] - low) / (up - low)
    bbp = (close - low) / (up - low)
    return bbp, up, mid, low
Exemple #10
0
    async def calc_pullback(self) -> None:
        for i, row in self.portfolio.iterrows():
            # print(row.symbol, len(self.data_bars[row.symbol]))

            bband = BBANDS(
                self.data_bars[row.symbol].close,
                timeperiod=7,
                nbdevdn=1,
                nbdevup=1,
                matype=MA_Type.EMA,
            )

            lower_band = bband[2]
            upper_band = bband[0]

            volatility = upper_band[-1] - lower_band[-1]

            position = 0
            profit = 0.0
            count = 0
            for i in range(-self.pullback_days, -1, 1):
                if (not position and self.data_bars[row.symbol].close[i - 1] <
                        lower_band[i - 1]
                        and self.data_bars[row.symbol].close[i] >
                        self.data_bars[row.symbol].close[i - 1] and
                        self.data_bars[row.symbol].close[i] > lower_band[i]):
                    position = (self.portfolio_size //
                                self.data_bars[row.symbol].open[i])
                    profit -= position * self.data_bars[row.symbol].open[i]
                    count += 1
                elif (position and
                      self.data_bars[row.symbol].open[i] > upper_band[i - 1]):
                    profit += position * self.data_bars[row.symbol].open[i]
                    position = 0

            self.portfolio.loc[self.portfolio.symbol == row.symbol,
                               "count"] = count
            self.portfolio.loc[self.portfolio.symbol == row.symbol,
                               "profit"] = profit
            self.portfolio.loc[self.portfolio.symbol == row.symbol,
                               "volatility"] = volatility
            qty = int(count * self.risk_factor / volatility)
            self.portfolio.loc[self.portfolio.symbol == row.symbol,
                               "qty"] = qty
            self.portfolio.loc[self.portfolio.symbol == row.symbol,
                               "est"] = (qty *
                                         self.data_bars[row.symbol].close[-1])
            self.portfolio.loc[
                self.portfolio.symbol == row.symbol, "opt"] = bool(
                    self.data_bars[row.symbol].close[-1] < lower_band[-1])
        self.portfolio = self.portfolio.loc[(self.portfolio.profit > 0)
                                            & (self.portfolio.opt == True)
                                            & (self.portfolio.volatility > 2.0)
                                            & (self.portfolio.score > 35.0)]
Exemple #11
0
    def init(self):
        super().init()

        up_band, mid, down_band = BBANDS(self.data.Close,
                                         timeperiod=self.ma_len,
                                         nbdevup=self.band_width,
                                         nbdevdn=self.band_width,
                                         matype=0)

        self.up_band = self.I(lambda x: up_band, 'up_band')
        self.mid = self.I(lambda x: mid, 'mid')
        self.down_band = self.I(lambda x: down_band, 'down_band')
 def get_bbands_score(self, product_df):
     upper_df, middle_df, lower_df = BBANDS(product_df.close, 20, 2, 2)
     close = product_df.close.iloc[-1]
     upper = upper_df.iloc[-1]
     middle = middle_df.iloc[-1]
     lower = lower_df.iloc[-1]
     #print(f"Upper: {upper}, Middle: {middle}, Lower: {lower}")
     if close < lower:
         return 1
     elif close > upper:
         return -1
     else:
         return 0
Exemple #13
0
    def analyze(self,
                historical_data,
                signal=['bbp'],
                hot_thresh=0,
                cold_thresh=0.8,
                period_count=20,
                std_dev=2):
        """Check when close price cross the Upper/Lower bands.

        Args:
            historical_data (list): A matrix of historical OHCLV data.
            period_count (int, optional): Defaults to 20. The number of data points to consider for the BB bands indicator.
            signal (list, optional): Defaults bbp value.
            hot_thresh (float, optional): Defaults to 0. The threshold at which this might be
                good to purchase.
            cold_thresh (float, optional): Defaults to 0.8. The threshold at which this might be
                good to sell.            
            std_dev (int, optional): number of std dev to use. Common values are 2 or 1

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

        dataframe = self.convert_to_dataframe(historical_data)

        mfi = abstract.MFI(dataframe, period_count=14)

        # Required to avoid getting same values for low, middle, up
        dataframe['close_10k'] = dataframe['close'] * 10000

        up_band, mid_band, low_band = BBANDS(dataframe['close_10k'],
                                             timeperiod=period_count,
                                             nbdevup=std_dev,
                                             nbdevdn=std_dev,
                                             matype=0)

        bbp = (dataframe['close_10k'] - low_band) / (up_band - low_band)

        bollinger = pandas.concat([dataframe, bbp, mfi], axis=1)
        bollinger.rename(columns={0: 'bbp', 1: 'mfi'}, inplace=True)

        bollinger['is_hot'] = False
        bollinger['is_cold'] = False

        bollinger['is_hot'].iloc[
            -1] = bollinger['bbp'].iloc[-2] <= hot_thresh and bollinger[
                'bbp'].iloc[-2] < bollinger['bbp'].iloc[-1]
        bollinger['is_cold'].iloc[
            -1] = bollinger['bbp'].iloc[-1] >= cold_thresh

        return bollinger
Exemple #14
0
def get_indicators(df, indicators=[]):
    if "bbands" in indicators:
        df["upperband"], df["middleband"], df["lowerband"] = BBANDS(
            df["close"], timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
    if "macd" in indicators:
        df["macd"], df["macdsignal"], df["macdhist"] = MACD(df["close"],
                                                            fastperiod=12,
                                                            slowperiod=26,
                                                            signalperiod=9)
    if "price_logreturn" in indicators:
        df["price_logreturn"] = log_return(df["close"].to_numpy())
    if "volume_logreturn" in indicators:
        df["volume_logreturn"] = log_return(df["volume"].to_numpy())

    return df
Exemple #15
0
def bbww(price):
    multiplier = 1000000
    # Bollinger Band Width = (Upper Band - Lower Band) / Simple Moving Average for the same period.
    up, mid, low = BBANDS(price['Close'].values * multiplier,
                          timeperiod=5,
                          nbdevup=2,
                          nbdevdn=2,
                          matype=talib.MA_Type.T3)

    # up, mid, low = up * 10000000, mid * 10000000, low * 10000000

    sma = SMA(price['Close'].values, timeperiod=14) * multiplier

    bbw = (up - low) / (sma)

    return bbw
Exemple #16
0
def get_technical_analysis(stock_data: pd.DataFrame,
                           stock_name: str) -> pd.DataFrame:
    data = stock_data.query(f'stock_name=="{stock_name}"')
    close_prices = data['Adj Close'].values
    up, mid, low = BBANDS(close_prices,
                          timeperiod=20,
                          nbdevup=2,
                          nbdevdn=2,
                          matype=0)
    rsi = RSI(close_prices, timeperiod=14)
    bbp = (data['Adj Close'] - low) / (up - low)
    data['lower_bound'] = low
    data['upper_bound'] = up
    data['RSI'] = rsi
    data['BBP'] = bbp
    return data
Exemple #17
0
    async def handle_sell_side(
        self,
        symbols_position: Dict[str, float],
        data_loader: DataLoader,
        now: datetime,
        trade_fee_precentage: float,
    ) -> Dict[str, Dict]:
        actions = {}

        for symbol, position in symbols_position.items():
            if position == 0:
                continue

            current_price = data_loader[symbol].close[now]
            resampled_close = self.calc_close(symbol, data_loader, now)
            bband = BBANDS(
                resampled_close,
                timeperiod=7,
                nbdevdn=1,
                nbdevup=1,
                matype=MA_Type.EMA,
            )

            yesterday_upper_band = bband[0][-2]

            print(
                f"\ncurrent_price > yesterday_upper_band : {current_price > yesterday_upper_band}({current_price} < {yesterday_upper_band})"
            )

            if current_price > yesterday_upper_band:
                sell_indicators[symbol] = {
                    "upper_band": bband[0][-2:].tolist(),
                    "lower_band": bband[2][-2:].tolist(),
                }

                tlog(
                    f"[{self.name}][{now}] Submitting sell for {position} shares of {symbol} at market"
                )
                tlog(f"indicators:{sell_indicators[symbol]}")
                actions[symbol] = {
                    "side": "sell",
                    "qty": str(position),
                    "type": "limit",
                    "limit_price": str(current_price),
                }

        return actions
Exemple #18
0
def bbp(price):
    # bolinger bands %
    multiplier = 1000000

    up, mid, low = BBANDS(price['Close'].values * multiplier,
                          timeperiod=5,
                          nbdevup=2,
                          nbdevdn=2,
                          matype=talib.MA_Type.T3)
    # multiply to avoid very small numbers leading to inf

    # up, mid, low = up * mutiplier, mid * mutiplier, low * mutiplier

    bbp = (((price['Close'] * multiplier) - low) / (up - low))

    if isNaN(bbp.values[-1]):
        print("ok")
    return bbp
Exemple #19
0
            def handle_data(context, data):
                required_params = ['trailing_window', 'ema_s', 'ema_l', 'bb']
                if not all(param in context.params
                           for param in required_params):
                    raise KeyError("incorrect parameter list")
                trailing_window = data.history(
                    context.asset, 'close', context.params['trailing_window'],
                    '1d')
                if trailing_window.isnull().values.any():
                    return
                ema_s = EMA(trailing_window.values,
                            timeperiod=context.params['ema_s'])
                ema_l = EMA(trailing_window.values,
                            timeperiod=context.params['ema_l'])
                bb = BBANDS(trailing_window.values,
                            timeperiod=context.params['bb'])

                buy = False
                sell = False
                buy_signal = (ema_s[-1] > ema_l[-1]) and (
                    trailing_window.values[-1] >
                    (bb[1][-1])) and (trailing_window.values[-1] > ema_s[-1])

                if buy_signal and not context.invested:
                    order(context.asset, 100)
                    context.invested = True
                    buy = True

                elif not buy_signal and context.invested:
                    order(context.asset, -100)
                    context.invested = False
                    sell = True

                record(BTC=data.current(context.asset, "price"),
                       ema_s=ema_s[-1],
                       ema_l=ema_l[-1],
                       bb=bb[1][-1],
                       buy=buy,
                       sell=sell)
Exemple #20
0
def create_bollinger_bands(historical_data):
    prices = historical_data['Adj Close'].as_matrix()

    bollinger_bands = dict()

    for time_period in range(10, 31):
        for up in range(18, 23):
            for down in range(18, 23):
                upper, middle, lower = BBANDS(prices,
                                              timeperiod=time_period,
                                              nbdevup=float(up) / 10,
                                              nbdevdn=float(down) / 10,
                                              matype=0)

                bollinger_bands['bbands_upper_{}_{}_{}'.format(
                    time_period, up, down)] = upper / prices
                bollinger_bands['bbands_lower_{}_{}_{}'.format(
                    time_period, up, down)] = lower / prices

    macds_dataframe = pd.DataFrame(bollinger_bands)

    return historical_data.join(macds_dataframe)
Exemple #21
0
    def _calc_indicator(self, OHLCV_input):
        """
        Calculates the Bollinger bands 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 scaled features with size (n_observations, n_features).
        """
        try:
            close = OHLCV_input['close'].values[:, 0]
        except IndexError:
            close = OHLCV_input['close'].values
        upperband, middleband, lowerband = BBANDS(close, self.__timeperiod, self.__nbdevup, self.__nbdevdn,
                                                  self.__matype)
        upperband = DataFrame(upperband)
        middleband = DataFrame(middleband)
        lowerband = DataFrame(lowerband)

        return concat([upperband, middleband, lowerband], axis=1, ignore_index=True)
def main():
    file_content = file_io_service.load_historical_data('PETR4.SA')
    file_content = file_content.dropna()

    close = file_content['Adj Close'].values
    date = np.array(
        list(
            map(lambda x: date_helper.parse_date_to_datetime(x),
                file_content['Date'])))

    rsi = RSI(close, timeperiod=14)
    macd, macdsignal, macdhist = MACD(close,
                                      fastperiod=12,
                                      slowperiod=26,
                                      signalperiod=9)
    up, mid, low = BBANDS(close, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)

    fig, (ax0, ax1, ax2) = plt.subplots(3, 1, sharex=True, figsize=(12, 8))
    ax0.plot(date, close, label='Close')
    ax0.set_xlabel('Date')
    ax0.set_ylabel('Close')
    ax0.grid()

    ax1.plot(date, rsi, label='Close', linewidth=.5)
    ax1.set_xlabel('Date')
    ax1.set_ylabel('Close')
    ax1.grid()

    ax2.plot(date, up, label='BB_up', color='BLUE', linewidth=.5)
    ax2.plot(date, close, label='AdjClose', color='BLACK', linewidth=.5)
    ax2.plot(date, low, label='BB_low', color='RED', linewidth=.5)
    ax2.fill_between(date, y1=low, y2=up, color='#adccff', alpha='0.3')
    ax2.set_xlabel('Date')
    ax2.set_ylabel('Bollinger Bands')
    ax2.grid()

    fig.tight_layout()
    plt.show()
Exemple #23
0
def compute_bb(close):
    high, mid, low = BBANDS(close, timeperiod=20)
    return pd.DataFrame({'bb_high': high, 'bb_low': low}, index=close.index)
Exemple #24
0
    def bbands200(self, df, pattern, patterntype):
        df = df.dropna()

        #1. Calculate ATR for potential trade
        atr = atrcalc.ATRcalc(df)

        ##b. get BBands
        bband = df.head(21)
        bband = bband.iloc[1:]
        bband = bband.iloc[::-1]
        bbandInput = bband['close'].values
        upperband, middleband, lowerband = BBANDS(bbandInput,
                                                  timeperiod=20,
                                                  nbdevup=2,
                                                  nbdevdn=2,
                                                  matype=0)

        ##c. 200EMA
        emaInput = df.head(200)
        emaInput = emaInput.iloc[::-1]
        EMAclose = emaInput['close'].values
        ema = EMA(EMAclose, timeperiod=200)

        ##d. current price action
        priceaction = df.head(1)
        pricehigh = priceaction['high'].values[0]
        pricelow = priceaction['low'].values[0]
        priceclose = priceaction['close'].values[0]

        if pricehigh > upperband[-1]: breakBand = -1
        elif pricelow < lowerband[-1]: breakBand = 1
        else: breakBand = 0

        if pricelow > ema[-1]: marketEMA = 1
        elif pricehigh < ema[-1]: marketEMA = -1
        else: marketEMA = 0

        ##OUTPUT
        if marketEMA == 1 and pattern > 0 and patterntype == -1 and breakBand == 1:
            position = 1
        elif marketEMA == -1 and pattern < 0 and patterntype == -1 and breakBand == -1:
            position = -1
        else:
            position = 0
        amount = 50
        if position == 1:
            stoploss = priceclose - 1.05 * atr
            takeprofit = priceclose + 1.45 * atr
            # amount = priceclose / (priceclose - stoploss)
            if (stoploss - priceclose) * amount < 0.1:
                position = 0
                amount = 0
                stoploss = 0
                takeprofit = 0

        elif position == -1:
            stoploss = priceclose + 1.05 * atr
            takeprofit = priceclose - 1.45 * atr
            # amount = priceclose / (stoploss - priceclose)
            if (stoploss - priceclose) * amount < 0.1:
                position = 0
                amount = 0
                stoploss = 0
                takeprofit = 0

        else:
            stoploss = 0
            takeprofit = 0
            amount = 0

        if position * pattern > 0:
            confidence = abs(pattern)
        elif position * pattern < 0:
            confidence = abs(1 / pattern)
        elif position == 0:
            confidence = 0
        else:
            confidence = 1

        # ##FOR TEST
        # position = 1
        return [position, amount, priceclose, stoploss, takeprofit, confidence]
def bbp(data):
    price = data.dropna()
    close = price['Close'].values
    up, mid, low = BBANDS(close, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
    bbp = (price['Close'] - low) / (up - low)
    return bbp
Exemple #26
0
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as web
import matplotlib.pyplot as plt
from talib import RSI, BBANDS
import datetime as dt
import numpy as np
start = '2015-04-22'
end = '2017-04-22'
symbol = 'MCD'
max_holding = 100
price = web.DataReader(name=symbol, data_source='quandl', start=start, end=end)
print(price.head())
price = price.iloc[::-1]
print(price.head())
price = price.dropna()
close = price['AdjClose'].values
up, mid, low = BBANDS(close, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
rsi = RSI(close, timeperiod=14)
print("RSI (first 10 elements)\n", rsi[14:24])
Exemple #27
0
def bbands(close,
           length=None,
           std=None,
           mamode=None,
           ddof=0,
           offset=None,
           **kwargs):
    """Indicator: Bollinger Bands (BBANDS)"""
    # Validate arguments
    length = int(length) if length and length > 0 else 5
    std = float(std) if std and std > 0 else 2.0
    mamode = mamode if isinstance(mamode, str) else "sma"
    ddof = int(ddof) if ddof >= 0 and ddof < length else 1
    close = verify_series(close, length)
    offset = get_offset(offset)

    if close is None: return

    # Calculate Result
    if Imports["talib"]:
        from talib import BBANDS
        upper, mid, lower = BBANDS(close, length)
    else:
        standard_deviation = stdev(close=close, length=length, ddof=ddof)
        deviations = std * standard_deviation
        # deviations = std * standard_deviation.loc[standard_deviation.first_valid_index():,]

        mid = ma(mamode, close, length=length, **kwargs)
        lower = mid - deviations
        upper = mid + deviations

    ulr = non_zero_range(upper, lower)
    bandwidth = 100 * ulr / mid
    percent = non_zero_range(close, lower) / ulr

    # Offset
    if offset != 0:
        lower = lower.shift(offset)
        mid = mid.shift(offset)
        upper = upper.shift(offset)
        bandwidth = bandwidth.shift(offset)
        percent = bandwidth.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        lower.fillna(kwargs["fillna"], inplace=True)
        mid.fillna(kwargs["fillna"], inplace=True)
        upper.fillna(kwargs["fillna"], inplace=True)
        bandwidth.fillna(kwargs["fillna"], inplace=True)
        percent.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        lower.fillna(method=kwargs["fill_method"], inplace=True)
        mid.fillna(method=kwargs["fill_method"], inplace=True)
        upper.fillna(method=kwargs["fill_method"], inplace=True)
        bandwidth.fillna(method=kwargs["fill_method"], inplace=True)
        percent.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    lower.name = f"BBL_{length}_{std}"
    mid.name = f"BBM_{length}_{std}"
    upper.name = f"BBU_{length}_{std}"
    bandwidth.name = f"BBB_{length}_{std}"
    percent.name = f"BBP_{length}_{std}"
    upper.category = lower.category = "volatility"
    mid.category = bandwidth.category = upper.category

    # Prepare DataFrame to return
    data = {
        lower.name: lower,
        mid.name: mid,
        upper.name: upper,
        bandwidth.name: bandwidth,
        percent.name: percent
    }
    bbandsdf = DataFrame(data)
    bbandsdf.name = f"BBANDS_{length}_{std}"
    bbandsdf.category = mid.category

    return bbandsdf
def runModel(factors, paras):

    import pandas as pd
    from talib import MACD, SMA, LINEARREG_SLOPE, RSI, BBANDS, KAMA
    import numpy as np

    import matplotlib.pyplot as plt
    from keras.models import Sequential
    from keras.layers import Dense, Activation, LSTM
    from keras.optimizers import SGD, RMSprop, Adagrad, Adam, Adamax, Nadam
    from keras.callbacks import EarlyStopping

    close = data['adjclose']
    date = list(data['date'])
    ret = close.diff() / close.shift(1)
    #2: rise, 1:stay, 0:drop
    ret_dir = 1 * (ret > ret.quantile(0.66)) + 1 * (ret > ret.quantile(0.33))
    #ret_dir=ret>ret.quantile(0.6)
    MA_diff1 = SMA(close, timeperiod=5) - close
    MA_diff2 = SMA(close, timeperiod=5) - SMA(close, timeperiod=15)
    macd, macdsignal, macdhist = MACD(close,
                                      fastperiod=12,
                                      slowperiod=26,
                                      signalperiod=9)
    SLOPE5 = LINEARREG_SLOPE(close, timeperiod=5)
    SLOPE15 = LINEARREG_SLOPE(close, timeperiod=15)
    SLOPE_diff = LINEARREG_SLOPE(close, timeperiod=5) - LINEARREG_SLOPE(
        close, timeperiod=10)
    SKEW = ret.rolling(window=10, center=False).skew()
    RSI20 = RSI(close, timeperiod=20)
    RSI_SIG = 1 * (RSI20 < 40) - (RSI20 > 60)
    upper, middle, lower = BBANDS(close, timeperiod=15)
    BOLL_SIG = 1 * (close < lower) - (close > upper)
    MACD_RATIO = macd / SMA(macd, timeperiod=5)
    Kalman = KAMA(close, timeperiod=5)
    STD = close.rolling(window=10, center=False).std()
    KALMAN_SIG = 1 * (close < Kalman - 0.1 * STD) - (close >
                                                     Kalman + 0.1 * STD)

    train_ratio = paras[0]
    trans_fee = paras[1]
    stop_loss = paras[2]
    take_profit = paras[3]

    originalDataSet = pd.DataFrame({
        'dir': ret_dir.shift(-1),
        0: MA_diff1,
        1: MA_diff2,
        2: macd,
        3: SLOPE5,
        4: SLOPE15,
        5: SLOPE_diff,
        6: SKEW,
        7: RSI20,
        8: RSI_SIG,
        9: BOLL_SIG,
        10: KALMAN_SIG,
        11: MACD_RATIO
    })
    originalDataSet = originalDataSet.dropna(axis=0)
    del_num = []
    for i in range(len(factors)):
        if factors[i] == 0:
            del_num.append(i)
    originalDataSet = originalDataSet.drop(labels=del_num, axis=1)

    def normalize(train, flag=0):
        if flag == 0:
            train_norm = train.apply(lambda x: (x - np.mean(x)) /
                                     (np.max(x) - np.min(x)))
        else:
            y = train.iloc[:, 0]
            train_norm = train.apply(lambda x: (x - np.mean(x)) /
                                     (np.max(x) - np.min(x)))
            train_norm.iloc[:, 0] = y
        return train_norm

    win_size = 5

    def windows(da, window_size):
        start = 0
        while start < len(da):
            yield start, start + window_size
            start += 1

    #        start += (window_size // 2)

    def extract_segments(da, window_size=30):
        segments = np.empty((0, (window_size) * (da.shape[1] - 1)))
        labels = np.empty((0))
        for (start, end) in windows(da, window_size):
            if end >= len(originalDataSet):
                break
            if (len(da.iloc[start:end]) == (window_size)):
                signal = np.array(da.iloc[start:end, 1:]).reshape(1, -1)[0]
                segments = np.vstack([segments, signal])
                labels = np.append(labels, da.iloc[end, 0])

        return segments, labels

    segments, labels = extract_segments(originalDataSet, win_size)

    num_train = int(train_ratio * labels.shape[0])
    num_test = labels.shape[0] - num_train

    dummy_labels = np.asarray(pd.get_dummies(labels), dtype=np.int8)
    reshaped_segments = segments.reshape(
        [labels.shape[0], win_size, originalDataSet.shape[1] - 1])
    train_x = reshaped_segments[:num_train]
    train_y = dummy_labels[:num_train]
    test_x = reshaped_segments[num_train:]
    test_y = dummy_labels[num_train:]

    batch_size = 32
    model = Sequential()
    model.add(
        LSTM(units=50,
             return_sequences=True,
             input_shape=[train_x.shape[1], train_x.shape[2]],
             dropout=0.2))
    model.add(Activation('relu'))
    model.add(
        LSTM(units=50,
             return_sequences=True,
             input_shape=[train_x.shape[1], train_x.shape[2]],
             dropout=0.2))
    model.add(Activation('relu'))
    model.add(LSTM(units=24, dropout=0.2, recurrent_dropout=0.2))
    model.add(Activation('relu'))
    model.add(Dense(3, activation='softmax'))

    sgd = SGD(lr=0.002, decay=1e-6, momentum=0.9, nesterov=True)
    rmsprop = RMSprop(lr=0.0002, rho=0.9, epsilon=1e-06)
    adagrad = Adagrad(lr=0.001, epsilon=1e-06)
    adam = Adam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
    adamax = Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
    nadam = Nadam(lr=0.0005,
                  beta_1=0.9,
                  beta_2=0.999,
                  epsilon=1e-08,
                  schedule_decay=0.004)

    model.compile(loss='categorical_crossentropy',
                  optimizer=sgd,
                  metrics=['accuracy'])

    model.fit(train_x,
              train_y,
              epochs=50,
              batch_size=batch_size,
              validation_data=(test_x, test_y),
              verbose=2,
              shuffle=False,
              callbacks=[EarlyStopping(patience=40)])

    initial_captial = 10000000
    pred_y = model.predict(test_x)

    norm_y = np.diff(np.log(pred_y), axis=0)
    norm_y = np.array(norm_y, dtype=float)

    price = list(close[len(close) - 1 - len(pred_y):len(close) - 1])

    signal = [0 for i in range(len(pred_y))]
    buySell = [0 for i in range(len(pred_y))]
    buySell_size = [0 for i in range(len(pred_y))]
    position = [0 for i in range(len(pred_y))]
    Notional = [0 for i in range(len(pred_y))]
    CumNotional = [0 for i in range(len(pred_y))]
    PnL = [0 for i in range(len(pred_y))]
    cost = 1
    station = 0
    for i in range(1, len(pred_y)):
        temp = list(norm_y[i - 1])
        signal[i] = temp.index(max(temp)) - 1
        if i == 0:
            buySell[i] = signal[i]
            buySell_size[i] = (initial_captial +
                               PnL[-1]) // price[i] * buySell[i]
            position[i] = buySell_size[i]
            Notional[i] = -buySell_size[i] * price[i]
            CumNotional[i] = Notional[i]
            PnL[i] = CumNotional[i] + position[i] * price[i]
        else:
            station = np.sign(position[i - 1])
            if signal[i] != station:

                if station == 1:
                    if signal[i] == 0:
                        buySell_size[i] = -position[i - 1]
                    if signal[i] == -1:
                        buySell_size[i] = -position[i - 1] - (
                            initial_captial + PnL[-1]) // price[i]
                elif station == 0:
                    if signal[i] == 1:
                        buySell_size[i] = (initial_captial +
                                           PnL[-1]) // price[i]
                    if signal[i] == -1:
                        buySell_size[i] = -(initial_captial +
                                            PnL[-1]) // price[i]
                else:
                    if signal[i] == 0:
                        buySell_size[i] = -position[i - 1]
                    if signal[i] == 1:
                        buySell_size[i] = -position[i - 1] + (
                            initial_captial + PnL[-1]) // price[i]

            #stop loss and take profit
            if i != 0 and buySell_size[i] == 0 and position[i - 1] != 0:

                if position[i - 1] > 0:
                    if price[i] / cost > 1 + take_profit or price[
                            i] / cost < 1 - stop_loss:
                        buySell_size[i] = -position[i - 1]
                else:
                    if price[i] / cost < 1 - take_profit or price[
                            i] / cost > 1 + stop_loss:
                        buySell_size[i] = -position[i - 1]
            position[i] = position[i - 1] + buySell_size[i]
            Notional[i] = -buySell_size[i] * price[i]
            CumNotional[i] = CumNotional[i - 1] + Notional[i]
            PnL[i] = CumNotional[i] + position[i] * price[i]

            if buySell_size[i] != 0 and position[i] != 0:
                cost = price[i]

    oneMinPnL = np.diff(PnL)
    oneMinPnL[0] = 0
    from math import sqrt
    Sharpe = oneMinPnL.mean() / oneMinPnL.std() * sqrt(252)

    pnl = list(PnL)
    price = [round(x, 2) for x in price]
    pnl = [round(x, 2) for x in pnl]
    date = date[len(close) - 1 - len(pred_y):len(close) - 1]
    srp = round(Sharpe, 2)
    totalrtn = round(PnL[-1] / initial_captial, 2)

    return date, pnl, price, srp, totalrtn
Exemple #29
0
def PlotStockChart(shareCode, showChart=False):

    RSI_T = 10
    MACD_FAST = 10
    MACD_SLOW = 21
    MACD_SIGNAL = 5
    BBAND_PERIOD = 21

    data = pd.read_json('D:\\Personal\\share\\data\\' + shareCode + '.txt')
    data['t'] = pd.to_datetime(data['t'], unit='s')
    data['date'] = data['t'].dt.date
    data.set_index(['date'], inplace=True, drop=False)

    df = data

    # First instance
    trace1 = {
        'x': df.index,
        'open': df.o,
        'close': df.c,
        'high': df.h,
        'low': df.l,
        'type': 'candlestick',
        'name': shareCode,
        'showlegend': False
    }

    rsi = RSI(df.c, timeperiod=10)
    macd, macdSignal, macdHist = MACD(df.c, MACD_FAST, MACD_SLOW, MACD_SIGNAL)
    upper, middle, lower = BBANDS(df.c,
                                  timeperiod=BBAND_PERIOD,
                                  nbdevup=2,
                                  nbdevdn=2)

    # Second instance - avg_30
    trace2 = {
        'x': df.index,
        'y': rsi,
        'type': 'scatter',
        'mode': 'lines',
        'line': {
            'width': 1,
            'color': 'blue'
        },
        'name': 'RSI'
    }

    rsiLower = {
        'x': df.index,
        'y': 30 * (rsi / rsi),
        'type': 'scatter',
        'line': {
            'width': 1,
            'color': 'red'
        },
        'name': 'RSI Lower'
    }

    rsiUpper = {
        'x': df.index,
        'y': 70 * (rsi / rsi),
        'type': 'scatter',
        'line': {
            'width': 1,
            'color': 'red'
        },
        'name': 'RSI Upper'
    }

    # MACD
    trace4 = {
        'x': df.index,
        'y': macd,
        'type': 'scatter',
        'mode': 'lines',
        'line': {
            'width': 1,
            'color': 'blue'
        },
        'name': 'macd'
    }

    trace5 = {'x': df.index, 'y': macdHist, 'type': 'bar', 'name': 'macdHist'}

    trace6 = {
        'x': df.index,
        'y': macdSignal,
        'type': 'scatter',
        'mode': 'lines',
        'line': {
            'width': 1,
            'color': 'red'
        },
        'name': 'macdSignal'
    }

    bbUpper = {
        'x': df.index,
        'y': upper,
        'type': 'scatter',
        'mode': 'lines',
        'line': {
            'width': 1,
            'color': 'blue'
        },
        'name': 'BB Upper'
    }

    bbLower = {
        'x': df.index,
        'y': lower,
        'type': 'scatter',
        'mode': 'lines',
        'line': {
            'width': 1,
            'color': 'blue'
        },
        'name': 'BB Lower'
    }

    bbMiddle = {
        'x': df.index,
        'y': middle,
        'type': 'scatter',
        'mode': 'lines',
        'line': {
            'width': 1,
            'color': 'orange'
        },
        'name': 'BB Middle'
    }
    # Aggregate all instances and define 'data' variable

    xaxisType = {'type': "category", 'categoryorder': 'category ascending'}
    layout = dict(title=shareCode,
                  xaxis=xaxisType,
                  xaxis3=xaxisType,
                  xaxis4=xaxisType)

    fig = make_subplots(rows=4,
                        cols=1,
                        shared_xaxes=True,
                        vertical_spacing=0.02)

    fig.append_trace(trace1, row=1, col=1)
    fig.append_trace(bbLower, row=1, col=1)
    fig.append_trace(bbMiddle, row=1, col=1)
    fig.append_trace(bbUpper, row=1, col=1)

    fig.append_trace(trace2, row=4, col=1)
    fig.append_trace(rsiLower, row=4, col=1)
    fig.append_trace(rsiUpper, row=4, col=1)

    fig.append_trace(trace4, row=3, col=1)
    fig.append_trace(trace5, row=3, col=1)
    fig.append_trace(trace6, row=3, col=1)

    fig.update_layout(layout)

    def zoom(layout, xrange):
        in_view = df.loc[fig.layout.xaxis.range[0]:fig.layout.xaxis.range[1]]
        fig.layout.yaxis.range = [
            in_view.High.min() - 10,
            in_view.High.max() + 10
        ]

    #fig.layout.on_change(zoom, 'xaxis.range')

    fig.layout.on_change(
        lambda obj, xrange, yrange: print("%s-%s" % (xrange, yrange)),
        ('xaxis', 'range'), ('yaxis', 'range'))

    if showChart:
        fig.show()
    else:
        fig.write_html('D:\\Personal\\share\\results\\charts\\' + shareCode +
                       '.html',
                       include_plotlyjs='cdn')
    return


#PlotStockChart('JKH.N0000', True)
Exemple #30
0
    def calculate_signals(self):
        for symbol in self.symbol_list:
            print('Searching for {1} signals ...'.format(symbol))

            last_price = self.data_handler.current_price(symbol)[0]

            h1_highs = self.data_handler.get_latest_bars_values(
                symbol, 'high', timeframe='H1', N=self.bars_window)

            h1_lows = self.data_handler.get_latest_bars_values(
                symbol, 'low', timeframe='H1', N=self.bars_window)

            h1_closes = self.data_handler.get_latest_bars_values(
                symbol, 'close', timeframe='H1', N=self.bars_window)

            h1_hlc3 = (h1_highs + h1_lows + h1_closes) / 3

            h1_ema_50 = EMA(h1_hlc3, timeperiod=50)
            h1_ema_100 = EMA(h1_hlc3, timeperiod=100)
            h1_ema_200 = EMA(h1_hlc3, timeperiod=200)

            m15_highs = self.data_handler.get_latest_bars_values(
                symbol, 'high', timeframe='m15', N=self.bars_window)

            m15_lows = self.data_handler.get_latest_bars_values(
                symbol, 'low', timeframe='m15', N=self.bars_window)

            m15_closes = self.data_handler.get_latest_bars_values(
                symbol, 'close', timeframe='m15', N=self.bars_window)

            m15_hlc3 = (m15_highs + m15_lows + m15_closes) / 3

            m15_ema_50 = EMA(m15_hlc3, timeperiod=50)
            m15_ema_100 = EMA(m15_hlc3, timeperiod=100)
            m15_ema_200 = EMA(m15_hlc3, timeperiod=200)

            m15_price_bb_up, m15_price_bb_mid, m15_price_bb_low = BBANDS(
                m15_hlc3, timeperiod=20, nbdevup=2, nbdevdn=2)

            m15_price_bb_low_dist = (m15_price_bb_mid + m15_price_bb_low) / 2
            m15_price_bb_up_dist = (m15_price_bb_up + m15_price_bb_mid) / 2

            m15_rsi = RSI(m15_closes, timeperiod=14)
            m15_rsi_bb_up, m15_rsi_bb_mid, m15_rsi_bb_low = BBANDS(
                m15_rsi, timeperiod=20, nbdevup=2, nbdevdn=2)

            m15_stochrsi = STOCHRSI(pd.Series(m15_closes), timeperiod=14)

            m15_atr = ATR(m15_highs, m15_lows, m15_closes, timeperiod=14)

            datetime = self.data_handler.get_latest_bar_datetime(symbol)[0]

            direction = None
            status = None
            position = 'Not yet'

            print(datetime)

            if last_price > h1_ema_50[-1] and last_price > h1_ema_100[
                    -1] and last_price > h1_ema_200[-1]:
                print('Uprend detected')

                if last_price > m15_ema_50[-1] and last_price > m15_ema_100[
                        -1] and last_price > m15_ema_200[-1]:
                    print('Uprend confirmed')
                    direction = 'LONG'

                    if m15_rsi[-1] < m15_rsi_bb_low[-1]:
                        print('Reversal Detected')
                        status = 'Reversal detected'

                        if last_price < m15_price_bb_low_dist[-1]:
                            print('Reversal confirmed')
                            status = 'Reversal confirmed'

                            if m15_stochrsi[-1] < 25:
                                print('Go LONG')
                                position = 'Go ahead'

            elif last_price < h1_ema_50[-1] and last_price < h1_ema_100[
                    -1] and last_price < h1_ema_200[-1]:
                print('Downrend detected')

                if last_price < m15_ema_50[-1] and last_price < m15_ema_100[
                        -1] and last_price < m15_ema_200[-1]:
                    print('Downrend confirmed')
                    direction = 'SHORT'

                    if m15_rsi[-1] > m15_rsi_bb_up[-1]:
                        print('Reversal Detected')
                        status = 'Reversal detected'

                        if last_price > m15_price_bb_up_dist[-1]:
                            print('Reversal confirmed')
                            status = 'Reversal confirmed'

                            if m15_stochrsi[-1] > 75:
                                print('Go SHORT')
                                position = 'Go ahead'

            else:
                pass

            print(symbol, direction, status, position, datetime)

            if status is not None:
                self.telegram.send_text({
                    'symbol':
                    symbol,
                    'direction':
                    direction,
                    'status':
                    status,
                    'position':
                    position,
                    'atr':
                    np.around(m15_atr[-1], decimals=5),
                    'datetime':
                    datetime
                })