Beispiel #1
0
def vwma(candles: np.ndarray,
         period: int = 20,
         source_type: str = "close",
         sequential: bool = False) -> Union[float, np.ndarray]:
    """
    VWMA - Volume Weighted Moving Average

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

    :return: float | np.ndarray
    """
    if len(candles.shape) == 1:
        source = candles
    else:
        candles = slice_candles(candles, sequential)
        source = get_candle_source(candles, source_type=source_type)

    res = ti.vwma(np.ascontiguousarray(source),
                  np.ascontiguousarray(candles[:, 5]),
                  period=period)

    return same_length(candles, res) if sequential else res[-1]
Beispiel #2
0
Datei: vwma.py Projekt: wcy/jesse
def vwma(candles: np.ndarray,
         period: int = 20,
         source_type: str = "close",
         sequential: bool = False) -> Union[float, np.ndarray]:
    """
    VWMA - Volume Weighted Moving Average

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

    :return: float | np.ndarray
    """
    warmup_candles_num = get_config('env.data.warmup_candles_num', 240)
    if not sequential and len(candles) > warmup_candles_num:
        candles = candles[-warmup_candles_num:]

    source = get_candle_source(candles, source_type=source_type)
    res = ti.vwma(np.ascontiguousarray(source),
                  np.ascontiguousarray(candles[:, 5]),
                  period=period)

    return np.concatenate(
        (np.full((candles.shape[0] - res.shape[0]), np.nan),
         res), axis=0) if sequential else res[-1]
Beispiel #3
0
def performance_indicators(df, period):
    # generate the performance indicators
    data = df.astype('float64')
    rsi = ti.rsi(data['day_close'].values, period)
    rsi = np.insert(rsi, 0, [np.nan for i in range(period)])

    wma = ti.wma(data['day_close'].values, period=period)
    wma = np.insert(wma, 0, [np.nan for i in range(period - 1)])

    vwma = ti.vwma(close=data['day_close'].values,
                   volume=data['day_volume'].values,
                   period=period)
    vwma = np.insert(vwma, 0, [np.nan for i in range(period - 1)])

    willr = ti.willr(high=data['day_high'].values,
                     low=data['day_low'].values,
                     close=data['day_close'].values,
                     period=period)
    willr = np.insert(willr, 0, [np.nan for i in range(period - 1)])

    stddev = ti.stddev(data['day_close'].values, period=period)
    stddev = np.insert(stddev, 0, [np.nan for i in range(period - 1)])

    # set the performance indicator data
    df[f'{period}days_rsi'] = rsi
    df[f'{period}days_wma'] = wma
    df[f'{period}days_vwma'] = vwma
    df[f'{period}days_willr'] = willr
    df[f'{period}days_stddev'] = stddev
    return df
Beispiel #4
0
def calculate_vwma(df, period):
    """ Calculates the Volume Weighted Moving Average for the period given"""

    # Tail the data-frame to the needed data
    data = df.tail(period)[['day_close', 'day_volume']].astype('float64')
    return ti.vwma(close=data['day_close'].values,
                   volume=data['day_volume'].values,
                   period=float(period))[0]
Beispiel #5
0
    def greed(self):
        tr = ta.trange(candles=self.candles, sequential=True)
        core = tr[np.logical_not(np.isnan(tr))]
        vwma_tr = ti.vwma(np.ascontiguousarray(core),
                          np.ascontiguousarray(self.candles[:, 5]),
                          period=200)
        mult = 2

        return (same_length(self.candles[:, 5], vwma_tr) / self.candles[:, 2] *
                100 * mult)[-1]
Beispiel #6
0
    async def evaluate(self, cryptocurrency, symbol, time_frame, candle,
                       candle_data, volume_data):
        if self.fast_ma_type == "vwma":
            ma1 = tulipy.vwma(candle_data, volume_data, self.fast_length)[-1]
        elif self.fast_ma_type == "lsma":
            ma1 = tulipy.linreg(candle_data, self.fast_length)[-1]
        else:
            ma1 = getattr(tulipy, self.fast_ma_type)(candle_data,
                                                     self.fast_length)[-1]

        if self.slow_ma_type == "vwma":
            ma2 = tulipy.vwma(candle_data, volume_data, self.slow_length)[-1]
        elif self.slow_ma_type == "lsma":
            ma2 = tulipy.linreg(candle_data, self.slow_length)[-1]
        else:
            ma2 = getattr(tulipy, self.slow_ma_type)(candle_data,
                                                     self.slow_length)[-1]

        if ma1 > ma2:
            self.eval_note = -1
        elif ma1 < ma2:
            self.eval_note = 1
Beispiel #7
0
def vwma(candles: np.ndarray,
         period=20,
         sequential=False) -> Union[float, np.ndarray]:
    """
    VWMA - Volume Weighted Moving Average

    :param candles: np.ndarray
    :param period: int - default: 20
    :param sequential: bool - default=False

    :return: float | np.ndarray
    """
    if not sequential and len(candles) > 240:
        candles = candles[-240:]

    res = ti.vwma(np.ascontiguousarray(candles[:, 2]),
                  np.ascontiguousarray(candles[:, 5]),
                  period=period)

    return np.concatenate((np.full(
        (period - 1), np.nan), res), axis=0) if sequential else res[-1]
Beispiel #8
0
def bot():

    # globalize variables that are changed by the bot
    global amount_crypto
    global current_position
    global current_entry_price
    global old_position
    global old_entry_price_adjusted
    global next_position
    global n_trades
    global cumulated_profit

    # initiate start time to track how long one full bot iteration takes
    start = time.time()

    # fetch the required data from the exchange to compute the indicator from
    df = use_function[exchange.lower()][0](symbol=symbol,
                                           timeframe=timeframe,
                                           length=length,
                                           include_current_candle=True,
                                           file_format='',
                                           api_cooldown_seconds=0)

    ###   INDICATOR   ##########################################################################################
    if moving_average_type == 'simple_ma':
        short_ma = pd.rolling_mean(df['Close'], window=short_period)
        long_ma = pd.rolling_mean(df['Close'], window=long_period)
    if moving_average_type == 'double_exponential_ma':
        short_ma = pd.Series(ti.dema(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.dema(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'triple_exponential_ma':
        short_ma = pd.Series(ti.tema(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.tema(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'exponential_ma':
        short_ma = pd.Series(ti.ema(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.ema(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'hull_ma':
        short_ma = pd.Series(ti.hma(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.hma(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'kaufman_adaptive_ma':
        short_ma = pd.Series(ti.kama(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.kama(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'triangular_ma':
        short_ma = pd.Series(ti.trima(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.trima(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'volume_weighted_ma':
        short_ma = pd.Series(ti.vwma(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.vwma(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'zero_lag_exponential_ma':
        short_ma = pd.Series(ti.zlema(df['Close'].as_matrix(), short_period))
        long_ma = pd.Series(ti.zlema(df['Close'].as_matrix(), long_period))
    if moving_average_type == 'arnaud_legoux_ma':
        # prepare the data to be used for the actual indicator computation
        # (when this step is not done the ALMA function returns the ALMA value
        # from the last full candle, effectively omitting the most current value)
        alma_data = df['Close'].shift(-1)
        alma_data.iloc[-1] = 0

        def ALMA(data, period=100, offset=0.85, sigma=6):
            '''
            ALMA - Arnaud Legoux Moving Average,
            http://www.financial-hacker.com/trend-delusion-or-reality/
            https://github.com/darwinsys/Trading_Strategies/blob/master/ML/Features.py
            '''
            m = np.floor(float(offset) * (period - 1))
            s = period / float(sigma)
            alma = np.zeros(data.shape)
            w_sum = np.zeros(data.shape)

            for i in range(len(data)):
                if i < period - 1:
                    continue
                else:
                    for j in range(period):
                        w = np.exp(-(j - m) * (j - m) / (2 * s * s))
                        alma[i] += data[i - period + j] * w
                        w_sum[i] += w
                    alma[i] = alma[i] / w_sum[i]

            return alma

        # get the indicator values using the ALMA function above
        short_ma = pd.Series(
            ALMA(data=alma_data.as_matrix(),
                 period=short_period,
                 offset=0.85,
                 sigma=6))
        long_ma = pd.Series(
            ALMA(data=alma_data.as_matrix(),
                 period=long_period,
                 offset=0.85,
                 sigma=6))

    ###   STRATEGY   ###########################################################################################
    # if the current short moving average value is ABOVE (or equal) the current long moving average value go LONG
    if short_ma.iloc[-1] >= long_ma.iloc[-1]:
        next_position = 1  # LONG
    # if the current short moving average value is BELOW the current long moving average value go SHORT
    if short_ma.iloc[-1] < long_ma.iloc[-2]:
        next_position = -1  # SHORT

    ###   TRADING ENGINE   #####################################################################################
    # print this message when trading is disabled
    if disable_trading == True:
        print('>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<')
        print('>>>        !  CAUTION  !         <<<')
        print('>>>       TRADING DISABLED       <<<')
        print('>>>     TRADES ARE SIMULATED     <<<')
        print('>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<')

    # create a list of open orders of the respective symbol
    # used to check if trailing-stop has been hitted, cancelling old trailing-stop
    if disable_trading == False:
        symbol_orders = [
            order
            for order in use_function[exchange.lower()][1].fetch_open_orders(
                symbol=symbol)
        ]
        # check if there is an open position already (maybe the trailing stop has been hitted so there is no open position anymore)
        if len(symbol_orders) == 0:
            current_position = 0

    print(
        '>>>  TRADE LOG  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
    )
    # if there is an open position
    if current_position != 0:

        if next_position == -1:
            if current_position == -1:
                print('==>  HOLD SHORT  <==')

            if current_position == 1:
                # delete old TRAILING-STOP order
                if set_trailing_stop == True:
                    if disable_trading == False:
                        use_function[exchange.lower()][1].cancel_order(
                            id=symbol_orders[-1]['id'])
                        time.sleep(api_cooldown)
                    print('Old Trailing-Stop Cancelled')

                # if trading is disabled get the first bid price from the order book as current_entry_price
                if disable_trading == True:
                    current_entry_price = round(
                        float(
                            use_function[exchange.lower()][2].fetch_order_book(
                                symbol=symbol, limit=1)['bids'][0][0]),
                        decimals)
                # create SELL order
                if disable_trading == False:
                    use_function[exchange.lower()][1].create_market_sell_order(
                        symbol, amount_crypto * 2, {'type': 'market'})
                    time.sleep(api_cooldown)
                current_position = -1
                print('==>  ENTERED SHORT  <==')

                # create TRAILING-STOP order, BUY
                if set_trailing_stop == True:
                    if disable_trading == False:
                        symbol_trades = [
                            trade for trade in use_function[exchange.lower()]
                            [1].fetch_my_trades(symbol=symbol)
                        ]
                        use_function[exchange.lower()][1].create_order(
                            symbol=symbol,
                            type='trailing-stop',
                            side='buy',
                            amount=amount_crypto,
                            price=round(
                                float(symbol_trades[-1]['price']) *
                                (trailing_stop_pct / 100), 4))
                    print('Trailing-Stop Placed (BUY)')

        if next_position == 1:
            if current_position == 1:
                print('==>  HOLD LONG  <==')

            if current_position == -1:
                # delete old TRAILING-STOP order
                if set_trailing_stop == True:
                    if disable_trading == False:
                        use_function[exchange.lower()][1].cancel_order(
                            id=symbol_orders[-1]['id'])
                        time.sleep(api_cooldown)
                    print('Old Trailing-Stop Cancelled')

                # if trading is disabled get the first ask price from the order book as current_entry_price
                if disable_trading == True:
                    current_entry_price = round(
                        float(
                            use_function[exchange.lower()][2].fetch_order_book(
                                symbol=symbol, limit=1)['asks'][0][0]),
                        decimals)
                # create BUY order
                if disable_trading == False:
                    use_function[exchange.lower()][1].create_market_buy_order(
                        symbol, amount_crypto * 2, {'type': 'market'})
                    time.sleep(api_cooldown)
                current_position = 1
                print('==>  ENTERED LONG  <==')

                # create TRAILING-STOP order, SELL
                if set_trailing_stop == True:
                    if disable_trading == False:
                        symbol_trades = [
                            trade for trade in use_function[exchange.lower()]
                            [1].fetch_my_trades(symbol=symbol)
                        ]
                        use_function[exchange.lower()][1].create_order(
                            symbol=symbol,
                            type='trailing-stop',
                            side='sell',
                            amount=amount_crypto,
                            price=round(
                                float(symbol_trades[-1]['price']) *
                                (trailing_stop_pct / 100), 4))
                    print('Trailing-Stop Placed (SELL)')

    # if there is no position yet or the position was closed within the timeframe (trailing-stop hitted)
    if current_position == 0:

        # set the amount to be traded in respective cryptocurrency as (amount_usd_to_trade) / (current average price of the cryptocurrency)
        amount_crypto = round(
            float(amount_usd_to_trade /
                  use_function[exchange.lower()][2].fetch_ticker(
                      symbol=symbol)['last']), 8)

        if next_position == 1:
            # if trading is disabled get the first ask price from the order book as current_entry_price
            if disable_trading == True:
                current_entry_price = round(
                    float(use_function[exchange.lower()][2].fetch_order_book(
                        symbol=symbol, limit=1)['asks'][0][0]), decimals)
            # create BUY order
            if disable_trading == False:
                use_function[exchange.lower()][1].create_market_buy_order(
                    symbol, amount_crypto, {'type': 'market'})
                time.sleep(api_cooldown)
            current_position = 1
            print('Initial LONG (Market Order)')

            # create TRAILING-STOP order, SELL
            if set_trailing_stop == True:
                if disable_trading == False:
                    symbol_trades = [
                        trade for trade in use_function[exchange.lower()]
                        [1].fetch_my_trades(symbol=symbol)
                    ]
                    use_function[exchange.lower()][1].create_order(
                        symbol=symbol,
                        type='trailing-stop',
                        side='sell',
                        amount=amount_crypto,
                        price=round(
                            float(symbol_trades[-1]['price']) *
                            (trailing_stop_pct / 100), 4))
                print('Initial Trailing-Stop (SELL)')

        if next_position == -1:
            # if trading is disabled get the first bid price from the order book as current_entry_price
            if disable_trading == True:
                current_entry_price = round(
                    float(use_function[exchange.lower()][2].fetch_order_book(
                        symbol=symbol, limit=1)['bids'][0][0]), decimals)
            # create SELL order
            if disable_trading == False:
                use_function[exchange.lower()][1].create_market_sell_order(
                    symbol, amount_crypto, {'type': 'market'})
                time.sleep(api_cooldown)
            current_position = -1
            print('Initial SHORT (Market Order)')

            # create TRAILING-STOP order, BUY
            if set_trailing_stop == True:
                if disable_trading == False:
                    symbol_trades = [
                        trade for trade in use_function[exchange.lower()]
                        [1].fetch_my_trades(symbol=symbol)
                    ]
                    use_function[exchange.lower()][1].create_order(
                        symbol=symbol,
                        type='trailing-stop',
                        side='buy',
                        amount=amount_crypto,
                        price=round(
                            float(symbol_trades[-1]['price']) *
                            (trailing_stop_pct / 100), 4))
                print('Initial Trailing-Stop (BUY)')

    time.sleep(api_cooldown)
    if disable_trading == False:
        current_entry_price = float(
            bitfinex.fetch_my_trades(symbol=symbol,
                                     limit=1)[0]['info']['price'])
    ###   END OF TRADER   ######################################################################################

    ###   LOG OUTPUT   #########################################################################################
    print(
        '>>>  BOT LOG  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
    )
    # only show the full output when the position changes
    if next_position != old_position:
        n_trades += 1
        print('  < ' + symbol + ' | ' + timeframe + ' | ' + exchange +
              ' | Iterations: ' + str(loops_per_timeframe) + ' | Inception: ' +
              inception_time + ' >')
        print('| Strategy: \t\t\t\t' + str(moving_average_type))
        print('| Short Moving Average Period: \t\t' + str(short_period))
        print('| Long Moving Average Period: \t\t' + str(long_period))
        print('| Amount to Trade: \t\t\tUSD ' + str(amount_usd_to_trade))
        if disable_trading == False:
            print('| Trailing Stop: \t\t\t' + str(set_trailing_stop))
            if set_trailing_stop == True:
                print('| Trailing Stop Distance: \t\t' +
                      str(trailing_stop_pct) + '%')
        print('| Date and Time: \t\t\t' + str(
            datetime.datetime.fromtimestamp(int(time.time())).strftime(
                '%d-%m-%Y %H:%M:%S')))
        print()
        if old_position != 0:
            print(' --  Old Position: \t\t\t' +
                  ('LONG' if int(old_position) == 1 else 'SHORT'))
        print(' --  Current Position: \t\t\t' +
              ('LONG' if int(current_position) == 1 else 'SHORT'))
        print(' --  Amount Crypto: \t\t\t' + str(symbol.split('/')[0]) + ' ' +
              str(round(amount_crypto, 5)))
        print(' --  Entry Price (Fee Adj.): \t\t' + str(symbol.split('/')[1]) +
              ' ' + str(
                  round(
                      float(current_entry_price *
                            (1 +
                             (bitfinex_taker_fee / 100))) if next_position ==
                      1 else float(current_entry_price *
                                   (1 -
                                    (bitfinex_taker_fee / 100))), decimals)))
        print(' --  Entry Price: \t\t\t' + str(symbol.split('/')[1]) + ' ' +
              str(current_entry_price))
        print()
        print(' --  Current Price: \t\t\t' + str(symbol.split('/')[1]) + ' ' +
              str(round(df['Close'].iloc[-1], decimals)))
        print(' --  Short Moving Average Value: \t' +
              str(symbol.split('/')[1]) + ' ' +
              str(round(short_ma.iloc[-1], decimals)))
        print(' --  Long Moving Average Value: \t' +
              str(symbol.split('/')[1]) + ' ' +
              str(round(long_ma.iloc[-1], decimals)))
        print()
        # the below is printed only after the first position is exited
        if old_entry_price_adjusted != 0:
            print(' --  Old Entry Price (Fee Adj.): \t' +
                  str(symbol.split('/')[1]) + ' ' +
                  str(round(old_entry_price_adjusted, decimals)))
            adjusted_profit = ((
                ((float(current_entry_price *
                        (1 + (bitfinex_taker_fee / 100))) if next_position == 1
                  else float(current_entry_price *
                             (1 - (bitfinex_taker_fee / 100)))) -
                 old_entry_price_adjusted) / old_entry_price_adjusted) * 100 *
                               int(old_position))
            print(' --  Approximate P/L (Fee Adj.): \t' +
                  str(round(adjusted_profit, decimals)) + '%')
            cumulated_profit += adjusted_profit
            print(' --  Cumulated P/L (Fee Adj.): \t\t' +
                  str(round(cumulated_profit, decimals)) + '%')
        print(' --  Trades since Inception: \t\t' + str(n_trades))
        # if the position changed update the old entry price
        old_entry_price_adjusted = float(
            current_entry_price *
            (1 + (bitfinex_taker_fee / 100))) if next_position == 1 else float(
                current_entry_price * (1 - (bitfinex_taker_fee / 100)))
        # calculate fee expenses per trade (to have it available)
        position_trading_fees = current_entry_price * (1 + (
            (bitfinex_taker_fee * amount_crypto) / 100))
        print()  # leave some space for nicely formatted output

    if next_position == old_position:
        print(' --  Entry Price (Fee Adj.): \t\t' + str(symbol.split('/')[1]) +
              ' ' + str(
                  round(
                      float(current_entry_price *
                            (1 +
                             (bitfinex_taker_fee / 100))) if next_position ==
                      1 else float(current_entry_price *
                                   (1 -
                                    (bitfinex_taker_fee / 100))), decimals)))
        print(' --  Current Price: \t\t\t' + str(symbol.split('/')[1]) + ' ' +
              str(round(df['Close'].iloc[-1], decimals)))
        print(' --  Short Moving Average Value: \t' +
              str(symbol.split('/')[1]) + ' ' +
              str(round(short_ma.iloc[-1], decimals)))
        print(' --  Long Moving Average Value: \t' +
              str(symbol.split('/')[1]) + ' ' +
              str(round(long_ma.iloc[-1], decimals)))
        # print current date and time for reference
        print('| Date and Time: \t\t\t' + str(
            datetime.datetime.fromtimestamp(int(time.time())).strftime(
                '%d-%m-%Y %H:%M:%S')))

    # update value for old_position
    old_position = current_position

    # sleep for ((one timeframe) / (how often to reevaluate the position within the timeframe))
    # - time it took to run one full bot iteration
    time.sleep(((timeframes[timeframe] / loops_per_timeframe) / 1000) -
               (time.time() - start))
Beispiel #9
0
def add_vwma(df, ma):
    l = len(df.close.values)
    df[f'vwma_{ma}'] = pad_left(
        ti.vwma(np.array(df['close']), np.array(df['volume']), ma), l)
Beispiel #10
0
 def compute(self, data_dict):
     close = data_dict.get('close')
     volume = data_dict.get('volume')
     
     return ti.vwma(close, volume, self.per)