예제 #1
0
def add_bbands(df, period=5, stddev=2):
    l = len(df.close.values)
    (bbands_lower, bbands_middle, bbands_upper) = ti.bbands(
        (df.close.values),
        period, stddev,)
    df[f'bbands_upper_{period}{stddev}'] = pad_left(bbands_upper, l)
    df[f'bbands_lower_{period}{stddev}'] = pad_left(bbands_lower, l)
    df[f'bbands_middle_{period}{stddev}'] = pad_left(bbands_middle, l)
예제 #2
0
 def _Bull(self, data, timeframe=None, symbol=None):
     timeframe = '1h'
     ohlcv_close = self.ohlcv[:, 3].copy(order='C')
     __bbands = ti.bbands(ohlcv_close, period=20, stddev=2)
     self.BBands = {
         'low': __bbands[0][-1],
         'middle': __bbands[1][-1],
         'high': __bbands[2][-1]
     }
예제 #3
0
def test_TA_basics():
    rsi_result = tulipy.rsi(DATA, period=9)
    assert all(74 < v < 86 for v in rsi_result)
    assert len(rsi_result) == 6
    sma_result = tulipy.sma(DATA, period=9)
    assert all(74 < v < 86 for v in sma_result)
    assert len(sma_result) == 7
    bands = tulipy.bbands(DATA, period=9, stddev=2)
    assert all(80 < v < 89 for band in bands for v in band)
    assert len(bands) == 3
예제 #4
0
def get_mean_open_close(number=120, kline_size='1m'):
    prices = []

    # A utiliser que pour testnet !!
    # link = str(settings.BASE_URL) + "trade?symbol=XBTUSD&count="\
    #        + str(number * binsizes[kline_size]) + "&columns=price&reverse=true"

    link_ohlc = "https://www.bitmex.com/api/v1/trade/bucketed?binSize=1m&partial=true&symbol=XBTUSD&count=20&reverse=true"
    f = requests.get(link_ohlc)
    ohlc = pd.DataFrame(f.json())
    ohlc = ohlc[['open', 'high', 'low', 'close']]
    # datta = TA.bb


    link = str(settings.BASE_URL) + "trade?symbol=.BXBT&count="\
           + str(number * binsizes[kline_size]) + "&columns=price&reverse=true"
    f = requests.get(link)
    for x in f.json():
        prices.append(float(x['price']))
    prices = get_prices_binsize(prices, binsizes[kline_size])
    prices.reverse()

    # Library Tulipy
    DATA = np.array(prices)
    bbands = ti.bbands(DATA, period=5, stddev=2)

    res = TA.BBANDS(
        get_all_bitmex('XBTUSD',
                       kline_size,
                       False,
                       nb=(number * 2 * binsizes[kline_size])))
    temp_df = pd.DataFrame()
    temp_df['BB_LOWER'] = bbands[0][-1:]
    temp_df['BB_MIDDLE'] = bbands[1][-1:]
    temp_df['BB_UPPER'] = bbands[2][-1:]
    #
    #   AFFICHAGE COURBES
    #

    low = list(bbands[0])
    middle = list(bbands[1])
    high = list(bbands[2])

    low = list(res.BB_LOWER[-number:])
    middle = list(res.BB_MIDDLE[-number:])
    high = list(res.BB_UPPER[-number:])

    # plt.plot(high, color='orange')
    # plt.plot(middle, color='g')
    # plt.plot(low, color='yellow')
    # plt.plot(prices, color='red')
    # plt.show()

    # return temp_df
    return res[-number:], bbands
예제 #5
0
 def calculate(self, candles):        
     candles_len = len(candles)
     if candles_len < self.period:
         return float(0)
     
     val_array = np.array([float(x['ohlc'].close) for x in candles[-self.period:]])
     
     #calculate 
     (upperband, middleband, lowerband) = ti.bbands (val_array, period=self.period, stddev=self.stddev)
     
     return (upperband[-1], middleband[-1], lowerband[-1])
예제 #6
0
    async def evaluate(self, cryptocurrency, symbol, time_frame, candle_data,
                       candle):
        self.eval_note = commons_constants.START_PENDING_EVAL_NOTE
        if len(candle_data) >= self.period_length:
            # compute bollinger bands
            lower_band, middle_band, upper_band = tulipy.bbands(
                candle_data, self.period_length, 2)

            # if close to lower band => low value => bad,
            # therefore if close to middle, value is keeping up => good
            # finally if up the middle one or even close to the upper band => very good

            current_value = candle_data[-1]
            current_up = upper_band[-1]
            current_middle = middle_band[-1]
            current_low = lower_band[-1]
            delta_up = current_up - current_middle
            delta_low = current_middle - current_low

            # its exactly on all bands
            if current_up == current_low:
                self.eval_note = commons_constants.START_PENDING_EVAL_NOTE

            # exactly on the middle
            elif current_value == current_middle:
                self.eval_note = 0

            # up the upper band
            elif current_value > current_up:
                self.eval_note = 1

            # down the lower band
            elif current_value < current_low:
                self.eval_note = -1

            # regular values case: use parabolic factor all the time
            else:

                # up the middle band
                if current_middle < current_value:
                    self.eval_note = math.pow(
                        (current_value - current_middle) / delta_up, 2)

                # down the middle band
                elif current_middle > current_value:
                    self.eval_note = -1 * math.pow(
                        (current_middle - current_value) / delta_low, 2)
        await self.evaluation_completed(
            cryptocurrency,
            symbol,
            time_frame,
            eval_time=evaluators_util.get_eval_time(full_candle=candle,
                                                    time_frame=time_frame))
    def analyse_recent_trend_changes(data, delta_function):
        # compute bollinger bands
        lower_band, middle_band, upper_band = tulipy.bbands(data, 20, 2)
        # if close to lower band => low value => bad,
        # therefore if close to middle, value is keeping up => good
        # finally if up the middle one or even close to the upper band => very good

        current_value = data[-1]
        current_up = upper_band[-1]
        current_middle = middle_band[-1]
        current_low = lower_band[-1]
        delta_up = current_up - current_middle
        delta_low = current_middle - current_low

        # its exactly on all bands
        if current_up == current_low:
            return commons_constants.START_PENDING_EVAL_NOTE

        # exactly on the middle
        elif current_value == current_middle:
            return 0

        # up the upper band
        elif current_value > current_up:
            return -1

        # down the lower band
        elif current_value < current_low:
            return 1

        # delta given: use parabolic factor after delta, linear before
        delta = delta_function(numpy.mean([delta_up, delta_low]))

        micro_change = ((current_value / current_middle) - 1) / 2

        # approximately on middle band
        if current_middle + delta >= current_value >= current_middle - delta:
            return micro_change

        # up the middle area
        elif current_middle + delta < current_value:
            return -1 * max(micro_change,
                            (current_value - current_middle) / delta_up)

        # down the middle area
        elif current_middle - delta > current_value:
            return max(micro_change,
                       (current_middle - current_value) / delta_low)

        # should not happen
        return 0
    def eval_impl(self):
        self.eval_note = START_PENDING_EVAL_NOTE
        period_length = 20
        if len(self.data[PriceIndexes.IND_PRICE_CLOSE.value]) >= period_length:
            # compute bollinger bands
            lower_band, middle_band, upper_band = tulipy.bbands(
                self.data[PriceIndexes.IND_PRICE_CLOSE.value], period_length,
                2)

            # if close to lower band => low value => bad,
            # therefore if close to middle, value is keeping up => good
            # finally if up the middle one or even close to the upper band => very good

            current_value = self.data[PriceIndexes.IND_PRICE_CLOSE.value][-1]
            current_up = upper_band[-1]
            current_middle = middle_band[-1]
            current_low = lower_band[-1]
            delta_up = current_up - current_middle
            delta_low = current_middle - current_low

            # its exactly on all bands
            if current_up == current_low:
                self.eval_note = START_PENDING_EVAL_NOTE

            # exactly on the middle
            elif current_value == current_middle:
                self.eval_note = 0

            # up the upper band
            elif current_value > current_up:
                self.eval_note = 1

            # down the lower band
            elif current_value < current_low:
                self.eval_note = -1

            # regular values case: use parabolic factor all the time
            else:

                # up the middle band
                if current_middle < current_value:
                    self.eval_note = math.pow(
                        (current_value - current_middle) / delta_up, 2)

                # down the middle band
                elif current_middle > current_value:
                    self.eval_note = -1 * math.pow(
                        (current_middle - current_value) / delta_low, 2)
예제 #9
0
    def inds(self):

        Indicators = {}

        for i in range(len(self.time)):
            #i/o?
            ''' 2 = High, 3 = Low, 4 = Close, 5 = Volume
            collects the needed market data into one list to push to the indicators'''
            close = self.time[i][4].values.copy(order='C')
            high = self.time[i][2].values.copy(order='C')
            low = self.time[i][3].values.copy(order='C')
            volume = self.time[i][5].values.copy(order='C')
            # !!!This needs to be changed. Each volume of the base time must be indexed up to the slice
            __time = self.time[i][6]

            # these are the indicators currently being used, and recored
            Indicators[i] = {
                'stochrsi': ti.stochrsi(close, 5),
                'rsi': ti.rsi(close, 5),
                # indicators that need to be doublechecked
                'mfi': ti.mfi(high, low, close, volume, 5),
                'sar': ti.psar(high, low, .2, 2),
                'cci': ti.cci(high, low, close, 5),
                'ema': ti.ema(close, 5)
            }
            # this one is good
            Indicators[i]['stoch_k'], Indicators[i]['stoch_d'] = ti.stoch(
                high, low, close, 5, 3, 3)

            # check on this, to see if it functions properly
            Indicators[i]['bbands_lower'], Indicators[i]['bbands_middle'],
            Indicators[i]['bbands_upper'] = ti.bbands(close, 5, 2)

            Indicators[i]['macd'], Indicators[i]['macd_signal'],
            Indicators[i]['macd_histogram'] = ti.macd(close, 12, 26, 9)

            Indicators[i]['time'] = __time
            Indicators[i]['close'] = close
            ''' below changes the length of each array to match the longest one, for a pandas df
             np.nan for the tail of the shorter ones'''
            Indicators[i] = to_pd(Indicator=Indicators[i]).dropna(how='all')
        return Indicators
예제 #10
0
    def analyze(self, historical_data, period_count=20):
        """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)

        bb_columns = {
            'upperband': [numpy.nan] * dataframe.index.shape[0],
            'middleband': [numpy.nan] * dataframe.index.shape[0],
            'lowerband': [numpy.nan] * dataframe.index.shape[0]
        }

        bb_values = pandas.DataFrame(
            bb_columns,
            index=dataframe.index
        )

        bb_df_size = bb_values.shape[0]
        close_data = numpy.array(dataframe['close'])

        if close_data.size > period_count:
            bb_data = tulipy.bbands(close_data, period_count, 2)

            for index in range(period_count, bb_df_size):
                data_index = index - period_count
                bb_values['lowerband'][index] = bb_data[0][data_index]
                bb_values['middleband'][index] = bb_data[1][data_index]
                bb_values['upperband'][index] = bb_data[2][data_index]

        bb_values.dropna(how='all', inplace=True)

        return bb_values
예제 #11
0
    def strategy():

        import smtplib, ssl  # E-Mail
        from website import config
        from website.helpers import helpers
        from website.models import Param_stock_strategy_bollinger, Stock_strategy, Strategy, Stock, Market
        from website.extensions import db, alpaca_api
        from sqlalchemy import asc
        import tulipy
        import pandas as pd
        import time
        t0 = time.time()

        DEBUG = False

        ## TODO:
        # - Database for opening-times Market and times to apply the strategy.
        # - Backtesting strategy with UI

        current_date = '2021-06-24'  # Check on specific day (DEBUG)
        # current_date = helpers.get_date_today()                                                             # Check today (Script)
        if DEBUG == True: print(f"Current date: {current_date}")

        context = ssl.create_default_context()  # Email
        messages = []  # Placeholder messages

        # [cursor, connection] = helpers.init_database()                                                      # Init Database

        strategy_id = db.session.query(Strategy).with_entities(
            Strategy.id, ).filter(
                Strategy.name == 'bollinger_bands').first()[0]

        # Get Stocks which get handled with bollinger band strategy

        stocks = db.session.query(Stock).join(
            Market, Market.id == Stock.market_id
            #         join market on market.id = stock.market_id
        ).join(
            Stock_strategy, Stock_strategy.stock_id == Stock.id
            #         join stock_strategy on stock_strategy.stock_id = stock.id
        ).join(
            Param_stock_strategy_bollinger,
            Param_stock_strategy_bollinger.parameter_id ==
            Stock_strategy.parameter_id
            #         join param_stock_strategy_breakdown on param_stock_strategy_breakdown.id = stock_strategy.parameter_id
        ).with_entities(
            #         select stock.symbol, stock.name, market.market_open_local, market.market_close_local,
            #             market.timezone, param_stock_strategy_breakdown.observe_from,
            #             param_stock_strategy_breakdown.observe_until,
            #             param_stock_strategy_breakdown.trade_price
            Stock.symbol,
            Stock.name,
            Market.market_open_local,
            Market.market_close_local,
            Market.timezone,
            Param_stock_strategy_bollinger.period,
            Param_stock_strategy_bollinger.stddev,
            Param_stock_strategy_bollinger.trade_price).filter(
                Stock_strategy.strategy_id == strategy_id
                #         where stock_strategy.strategy_id = ?
            ).order_by(asc(Stock.symbol)).all()

        # symbols = [stock.symbol for stock in stocks]                                                     # extract symbols from stocks                   (stock)

        # for stock in stocks:
        # if DEBUG == True: print(stock.name)

        # for symbol in symbols:
        # if DEBUG == True: print(symbol)

        # orders = alpaca_api.list_orders()                                                                            # get list of all orders
        orders = alpaca_api.list_orders(
            status='all', after=current_date
        )  # get list of all orders from today (we only want to trade once a day)
        existing_order_symbols = [
            order.symbol for order in orders if order.status !=
            'canceled'  # if any order not been placed, trade it        (List)
        ]

        for stock in stocks:
            start = helpers.get_timestamp(
                current_date, stock.market_open_local, stock.timezone
            ).isoformat()  # start-date and time market-opening
            end_time = helpers.get_timestamp(current_date,
                                             stock.market_close_local,
                                             stock.timezone)
            end = end_time.isoformat()  # end-date and time market-closing

            if DEBUG == True:
                print("Ready_steady")  # end-date and time market-closing
            if not pd.Timestamp.today().strftime("%H:%M") < end_time.strftime(
                    "%H:%M"):  # if market is open
                if DEBUG == True:
                    print("go bollinger")  # end-date and time market-closing

                time_bars = alpaca_api.get_barset(
                    stock.symbol, 'minute', start=start, end=end
                ).df  # get stock-specific minute bars for the day online
                # minute_bars = alpaca_api.polygon.historic_agg_v2(stock['symbol'], 1, 'minute', _from='2020-10-28', to='2020-10-29').df

                if DEBUG == True: print(time_bars)
                if DEBUG == True: print(start)
                # if DEBUG == True: print(helpers.get_timestamp2(f"{time_bars[stock.symbol].index[0]}", stock.timezone).isoformat())

                market_open_mask = [
                    (helpers.get_timestamp2(
                        f"{index}", stock.timezone).isoformat() >= start) &
                    (helpers.get_timestamp2(f"{index}",
                                            stock.timezone).isoformat() < end)
                    for index in time_bars[stock.symbol].index
                ]

                market_open_bars = time_bars[
                    stock.symbol].loc[market_open_mask]

                if len(market_open_bars) >= 20:
                    closes = market_open_bars.close.values

                    lower, middle, upper = tulipy.bbands(
                        closes, stock.period, stock.stddev)
                    current_candle = market_open_bars.iloc[-1]
                    previous_candle = market_open_bars.iloc[-2]

                    if current_candle.close > lower[
                            -1] and previous_candle.close < lower[-2]:
                        print(
                            f"{stock.symbol} closed below the lower bollingerband"
                        )

                        if stock.symbol not in existing_order_symbols:
                            limit_price = current_candle.close

                            candle_range = previous_candle.high - previous_candle.low
                            message = f"placing order for {stock.symbol} at {limit_price}"
                            if DEBUG == True: print(message)
                            f = open("logfiles/bollinger_bands.txt", "a")
                            f.write(message + "\r")
                            f.close()
                            messages.append(message)

                            try:
                                alpaca_api.submit_order(
                                    symbol=stock.symbol,
                                    side='buy',
                                    type='limit',
                                    qty=helpers.calculate_quantity(
                                        stock.trade_price, limit_price),
                                    time_in_force='day',
                                    order_class='bracket',
                                    limit_price=limit_price,
                                    take_profit=dict(limit_price=limit_price +
                                                     candle_range * 3, ),
                                    stop_loss=dict(
                                        stop_price=previous_candle.low, ))
                            except Exception as e:
                                print(f"could not submit order {e}")
                        else:
                            print(
                                f"Already an order for {stock.symbol}, skipping"
                            )

            # print(messages)

            if len(messages) > 0:
                with smtplib.SMTP_SSL(config.EMAIL_HOST,
                                      config.EMAIL_PORT,
                                      context=context) as server:
                    server.login(config.EMAIL_ADDRESS, config.EMAIL_PASSWORD)

                    email_message = f"Subject: Trade Notification for {current_date}\n\n"
                    email_message += "\n\n".join(messages)

                    server.sendmail(config.EMAIL_ADDRESS,
                                    '*****@*****.**', email_message)

        t1 = time.time() - t0
        print("Time elapsed bollinger: ",
              t1)  # CPU seconds elapsed (floating point)
예제 #12
0
for symbol in symbols:

    # REPLACE with tda-stream
    # minute_bars = api.polygon.historic_agg_v2(symbol, 1, 'minute', _from=current_date, to=current_date).df

    # REPLACEMENT
    minute_bars = get_latest_tda_minute_bars(symbol, conn)

    market_open_mask = (minute_bars.chart_time >= start_minute_bar) & (
        minute_bars.chart_time < end_minute_bar)
    market_open_bars = minute_bars.loc[market_open_mask]

    if len(market_open_bars) >= 20:
        closes = market_open_bars.close.values

        lower, middle, upper = tulipy.bbands(closes, 20, 2)

        current_candle = market_open_bars.iloc[-1]
        previous_candle = market_open_bars.iloc[-2]

        # entry signal
        if current_candle.close > lower[-1] and previous_candle.close < lower[
                -2]:

            if symbol not in existing_order_symbols:

                limit_price = current_candle.close
                candle_range = current_candle.high - current_candle.low

                qty = calculate_quantity(limit_price)
                print(f"placing order for {symbol} at {limit_price}")
예제 #13
0
 def bbands(self):
     try:
         return bbands(self.data, self.period, self.stddev)
     except Exception:
         logging.exception('')
def get_BollingerBands(close, signal, stddev):
    bbands = np.zeros([3, len(close)])
    bbands[:,(signal-1):] = np.array(ti.bbands(close, signal,stddev))
    return bbands
예제 #15
0
    def compute(self, data_dict):

        close = data_dict.get('close')

        return ti.bbands(close, self.per, self.std)[1]