from models.CoinbasePro import PublicAPI

model = PublicAPI()
resp = model.authAPI('GET', 'products/BTC-GBP/candles?granularity=3600')
print(resp)
Ejemplo n.º 2
0
def executeJob(sc, market, granularity, tradingData=pd.DataFrame()):
    """Trading bot job which runs at a scheduled interval"""
    global action, buy_count, buy_sum, failsafe, iterations, last_action, last_buy, last_df_index, sell_count, sell_sum, x_since_buy, x_since_sell

    # increment iterations
    iterations = iterations + 1

    if is_sim == 0:
        # retrieve the market data
        api = PublicAPI()
        tradingData = api.getHistoricalData(market, granularity)

    # analyse the market data
    tradingDataCopy = tradingData.copy()
    technicalAnalysis = TechnicalAnalysis(tradingDataCopy)
    technicalAnalysis.addAll()
    df = technicalAnalysis.getDataFrame()

    if len(df) != 300:
        # data frame should have 300 rows, if not retry
        print('error: data frame length is < 300 (' + str(len(df)) + ')')
        logging.error('error: data frame length is < 300 (' + str(len(df)) +
                      ')')
        s.enter(300, 1, executeJob, (sc, market, granularity))

    if is_sim == 1:
        # with a simulation df_last will iterate through data
        df_last = df.iloc[iterations - 1:iterations]
    else:
        # df_last contains the most recent entry
        df_last = df.tail(1)

    price = float(df_last['close'].values[0])
    ema12gtema26 = bool(df_last['ema12gtema26'].values[0])
    ema12gtema26co = bool(df_last['ema12gtema26co'].values[0])
    macdgtsignal = bool(df_last['macdgtsignal'].values[0])
    macdgtsignalco = bool(df_last['macdgtsignalco'].values[0])
    ema12ltema26 = bool(df_last['ema12ltema26'].values[0])
    ema12ltema26co = bool(df_last['ema12ltema26co'].values[0])
    macdltsignal = bool(df_last['macdltsignal'].values[0])
    macdltsignalco = bool(df_last['macdltsignalco'].values[0])
    obv = float(df_last['obv'].values[0])
    obv_pc = float(df_last['obv_pc'].values[0])

    # candlestick detection
    hammer = bool(df_last['hammer'].values[0])
    inverted_hammer = bool(df_last['inverted_hammer'].values[0])
    hanging_man = bool(df_last['hanging_man'].values[0])
    shooting_star = bool(df_last['shooting_star'].values[0])
    three_white_soldiers = bool(df_last['three_white_soldiers'].values[0])
    three_black_crows = bool(df_last['three_black_crows'].values[0])
    morning_star = bool(df_last['morning_star'].values[0])
    evening_star = bool(df_last['evening_star'].values[0])
    three_line_strike = bool(df_last['three_line_strike'].values[0])
    abandoned_baby = bool(df_last['abandoned_baby'].values[0])
    morning_doji_star = bool(df_last['morning_doji_star'].values[0])
    evening_doji_star = bool(df_last['evening_doji_star'].values[0])
    two_black_gapping = bool(df_last['two_black_gapping'].values[0])

    # criteria for a buy signal
    if ((ema12gtema26co == True and macdgtsignal == True
         and macdgtsignal > 0.1) or
        (ema12gtema26 == True and macdgtsignal == True and x_since_buy > 0
         and x_since_buy <= 2)) and last_action != 'BUY':
        action = 'BUY'
    # criteria for a sell signal
    elif ((ema12ltema26co == True and macdltsignal == True) or
          (ema12ltema26 == True and macdltsignal == True and x_since_sell > 0
           and x_since_sell <= 2)) and last_action not in ['', 'SELL']:
        action = 'SELL'
        failsafe = False
    # anything other than a buy or sell, just wait
    else:
        action = 'WAIT'

    # loss failsafe sell < -5%
    if last_buy > 0 and last_action == 'BUY':
        change_pcnt = ((price / last_buy) - 1) * 100
        if (change_pcnt < -5):
            action = 'SELL'
            x_since_buy = 0
            failsafe = True
            log_text = '! Loss Failsafe Triggered (< -5%)'
            print(log_text, "\n")
            logging.warning(log_text)

    # polling is every 5 minutes (even for hourly intervals), but only process once per interval
    if (last_df_index != df_last.index.format()):
        ts_text = str(df_last.index.format()[0])

        precision = 2
        if cryptoMarket == 'XLM':
            precision = 4

        price_text = 'Price: ' + str(
            truncate(float(df_last['close'].values[0]), precision))
        ema_text = compare(df_last['ema12'].values[0],
                           df_last['ema26'].values[0], 'EMA12/26', precision)
        macd_text = compare(df_last['macd'].values[0],
                            df_last['signal'].values[0], 'MACD', precision)
        obv_text = compare(df_last['obv_pc'].values[0], 0.1, 'OBV %',
                           precision)
        counter_text = '[I:' + str(iterations) + ',B:' + str(
            x_since_buy) + ',S:' + str(x_since_sell) + ']'

        if hammer == True:
            log_text = '* Candlestick Detected: Hammer ("Weak - Reversal - Bullish Signal - Up")'
            print(log_text, "\n")
            logging.debug(log_text)

        if shooting_star == True:
            log_text = '* Candlestick Detected: Shooting Star ("Weak - Reversal - Bearish Pattern - Down")'
            print(log_text, "\n")
            logging.debug(log_text)

        if hanging_man == True:
            log_text = '* Candlestick Detected: Hanging Man ("Weak - Continuation - Bearish Pattern - Down")'
            print(log_text, "\n")
            logging.debug(log_text)

        if inverted_hammer == True:
            log_text = '* Candlestick Detected: Inverted Hammer ("Weak - Continuation - Bullish Pattern - Up")'
            print(log_text, "\n")
            logging.debug(log_text)

        if three_white_soldiers == True:
            log_text = '*** Candlestick Detected: Three White Soldiers ("Strong - Reversal - Bullish Pattern - Up")'
            print(log_text, "\n")
            logging.debug(log_text)

        if three_black_crows == True:
            log_text = '* Candlestick Detected: Three Black Crows ("Strong - Reversal - Bearish Pattern - Down")'
            print(log_text, "\n")
            logging.debug(log_text)

        if morning_star == True:
            log_text = '*** Candlestick Detected: Morning Star ("Strong - Reversal - Bullish Pattern - Up")'
            print(log_text, "\n")
            logging.debug(log_text)

        if evening_star == True:
            log_text = '*** Candlestick Detected: Evening Star ("Strong - Reversal - Bearish Pattern - Down")'
            print(log_text, "\n")
            logging.debug(log_text)

        if three_line_strike == True:
            log_text = '** Candlestick Detected: Three Line Strike ("Reliable - Reversal - Bullish Pattern - Up")'
            print(log_text, "\n")
            logging.debug(log_text)

        if abandoned_baby == True:
            log_text = '** Candlestick Detected: Abandoned Baby ("Reliable - Reversal - Bullish Pattern - Up")'
            print(log_text, "\n")
            logging.debug(log_text)

        if morning_doji_star == True:
            log_text = '** Candlestick Detected: Morning Doji Star ("Reliable - Reversal - Bullish Pattern - Up")'
            print(log_text, "\n")
            logging.debug(log_text)

        if evening_doji_star == True:
            log_text = '** Candlestick Detected: Evening Doji Star ("Reliable - Reversal - Bearish Pattern - Down")'
            print(log_text, "\n")
            logging.debug(log_text)

        if two_black_gapping == True:
            log_text = '*** Candlestick Detected: Two Black Gapping ("Reliable - Reversal - Bearish Pattern - Down")'
            print(log_text, "\n")
            logging.debug(log_text)

        ema_co_prefix = ''
        ema_co_suffix = ''
        if ema12gtema26co == True:
            ema_co_prefix = '*^ '
            ema_co_suffix = ' ^*'
        elif ema12ltema26co == True:
            ema_co_prefix = '*v '
            ema_co_suffix = ' v*'
        elif ema12gtema26 == True:
            ema_co_prefix = '^ '
            ema_co_suffix = ' ^'
        elif ema12ltema26 == True:
            ema_co_prefix = 'v '
            ema_co_suffix = ' v'

        macd_co_prefix = ''
        macd_co_suffix = ''
        if macdgtsignalco == True:
            macd_co_prefix = '*^ '
            macd_co_suffix = ' ^*'
        elif macdltsignalco == True:
            macd_co_prefix = '*v '
            macd_co_suffix = ' v*'
        elif macdgtsignal == True:
            macd_co_prefix = '^ '
            macd_co_suffix = ' ^'
        elif macdltsignal == True:
            macd_co_prefix = 'v '
            macd_co_suffix = ' v'

        obv_prefix = ''
        obv_suffix = ''
        if (obv_pc > 0.1):
            obv_prefix = '^ '
            obv_suffix = ' ^'
        else:
            obv_prefix = 'v '
            obv_suffix = ' v'

        if is_verbose == 0:
            if last_action != '':
                output_text = ts_text + ' | ' + price_text + ' | ' + ema_co_prefix + ema_text + ema_co_suffix + ' | ' + macd_co_prefix + macd_text + macd_co_suffix + ' | ' + obv_prefix + obv_text + obv_suffix + ' | ' + action + ' ' + counter_text + ' | Last Action: ' + last_action
            else:
                output_text = ts_text + ' | ' + price_text + ' | ' + ema_co_prefix + ema_text + ema_co_suffix + ' | ' + macd_co_prefix + macd_text + macd_co_suffix + ' | ' + obv_prefix + obv_text + obv_suffix + ' | ' + action + ' ' + counter_text

            if last_action == 'BUY':
                # calculate last buy minus fees
                fee = last_buy * 0.005
                last_buy_minus_fees = last_buy + fee

                margin = str(
                    truncate((((price - last_buy_minus_fees) / price) * 100),
                             2)) + '%'
                output_text += ' | ' + margin

            logging.debug(output_text)
            print(output_text)
        else:
            logging.debug('-- Iteration: ' + str(iterations) + ' --')
            logging.debug('-- Since Last Buy: ' + str(x_since_buy) + ' --')
            logging.debug('-- Since Last Sell: ' + str(x_since_sell) + ' --')

            if last_action == 'BUY':
                margin = str(truncate(
                    (((price - last_buy) / price) * 100), 2)) + '%'
                logging.debug('-- Margin: ' + margin + '% --')

            logging.debug('price: ' +
                          str(truncate(float(df_last['close'].values[0]), 2)))
            logging.debug('ema12: ' +
                          str(truncate(float(df_last['ema12'].values[0]), 2)))
            logging.debug('ema26: ' +
                          str(truncate(float(df_last['ema26'].values[0]), 2)))
            logging.debug('ema12gtema26co: ' + str(ema12gtema26co))
            logging.debug('ema12gtema26: ' + str(ema12gtema26))
            logging.debug('ema12ltema26co: ' + str(ema12ltema26co))
            logging.debug('ema12ltema26: ' + str(ema12ltema26))
            logging.debug('macd: ' +
                          str(truncate(float(df_last['macd'].values[0]), 2)))
            logging.debug('signal: ' +
                          str(truncate(float(df_last['signal'].values[0]), 2)))
            logging.debug('macdgtsignal: ' + str(macdgtsignal))
            logging.debug('macdltsignal: ' + str(macdltsignal))
            logging.debug('obv: ' + str(obv))
            logging.debug('obv_pc: ' + str(obv_pc) + '%')
            logging.debug('action: ' + action)

            # informational output on the most recent entry
            print('')
            print(
                '================================================================================'
            )
            txt = '        Iteration : ' + str(iterations)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '   Since Last Buy : ' + str(x_since_buy)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Since Last Sell : ' + str(x_since_sell)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '        Timestamp : ' + str(df_last.index.format()[0])
            print('|', txt, (' ' * (75 - len(txt))), '|')
            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '            EMA12 : ' + str(
                truncate(float(df_last['ema12'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '            EMA26 : ' + str(
                truncate(float(df_last['ema26'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '   Crossing Above : ' + str(ema12gtema26co)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Above : ' + str(ema12gtema26)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '   Crossing Below : ' + str(ema12ltema26co)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Below : ' + str(ema12ltema26)
            print('|', txt, (' ' * (75 - len(txt))), '|')

            if (ema12gtema26 == True and ema12gtema26co == True):
                txt = '        Condition : EMA12 is currently crossing above EMA26'
            elif (ema12gtema26 == True and ema12gtema26co == False):
                txt = '        Condition : EMA12 is currently above EMA26 and has crossed over'
            elif (ema12ltema26 == True and ema12ltema26co == True):
                txt = '        Condition : EMA12 is currently crossing below EMA26'
            elif (ema12ltema26 == True and ema12ltema26co == False):
                txt = '        Condition : EMA12 is currently below EMA26 and has crossed over'
            else:
                txt = '        Condition : -'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '             MACD : ' + str(
                truncate(float(df_last['macd'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '           Signal : ' + str(
                truncate(float(df_last['signal'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Above : ' + str(macdgtsignal)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Below : ' + str(macdltsignal)
            print('|', txt, (' ' * (75 - len(txt))), '|')

            if (macdgtsignal == True and macdgtsignalco == True):
                txt = '        Condition : MACD is currently crossing above Signal'
            elif (macdgtsignal == True and macdgtsignalco == False):
                txt = '        Condition : MACD is currently above Signal and has crossed over'
            elif (macdltsignal == True and macdltsignalco == True):
                txt = '        Condition : MACD is currently crossing below Signal'
            elif (macdltsignal == True and macdltsignalco == False):
                txt = '        Condition : MACD is currently below Signal and has crossed over'
            else:
                txt = '        Condition : -'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '              OBV : ' + str(truncate(obv, 4))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '       OBV Change : ' + str(obv_pc) + '%'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            if (obv_pc >= 2):
                txt = '        Condition : Large positive volume changes'
            elif (obv_pc < 2 and obv_pc >= 0):
                txt = '        Condition : Positive volume changes'
            else:
                txt = '        Condition : Negative volume changes'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '           Action : ' + action
            print('|', txt, (' ' * (75 - len(txt))), '|')
            print(
                '================================================================================'
            )
            if last_action == 'BUY':
                txt = '           Margin : ' + margin + '%'
                print('|', txt, (' ' * (75 - len(txt))), '|')
                print(
                    '================================================================================'
                )

        # increment x since buy
        if (ema12gtema26 == True and failsafe == False):
            x_since_buy = x_since_buy + 1
        # increment x since sell
        elif (ema12ltema26 == True):
            x_since_sell = x_since_sell + 1

        # if a buy signal
        if action == 'BUY':
            buy_count = buy_count + 1

            # reset x since sell
            x_since_sell = 0

            last_buy = price

            # if live
            if is_live == 1:
                if is_verbose == 0:
                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | ' + price_text +
                                 ' | BUY')
                    print("\n", ts_text, '|', market, granularity, '|',
                          price_text, '| BUY', "\n")
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing LIVE Buy Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                # connect to coinbase pro api (authenticated)
                model = AuthAPI(config['api_key'], config['api_secret'],
                                config['api_pass'], config['api_url'])
                # execute a live market buy
                resp = model.marketBuy(market,
                                       float(account.getBalance(fiatMarket)))
                logging.info(resp)
                #logging.info('attempt to buy ' + resp['specified_funds'] + ' (' + resp['funds'] + ' after fees) of ' + resp['product_id'])
            # if not live
            else:
                if is_verbose == 0:
                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | ' + price_text +
                                 ' | BUY')
                    print("\n", ts_text, '|', market, granularity, '|',
                          price_text, '| BUY', "\n")
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing TEST Buy Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                #print(df_last[['close','ema12','ema26','ema12gtema26','ema12gtema26co','macd','signal','macdgtsignal','obv','obv_pc']])

            if save_graphs == 1:
                tradinggraphs = TradingGraphs(technicalAnalysis)
                ts = datetime.now().timestamp()
                filename = 'BTC-GBP_3600_buy_' + str(ts) + '.png'
                tradinggraphs.renderEMAandMACD(24, 'graphs/' + filename, True)

        # if a sell signal
        elif action == 'SELL':
            sell_count = sell_count + 1

            # reset x since buy
            x_since_buy = 0

            # if live
            if is_live == 1:
                if is_verbose == 0:
                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | ' + price_text +
                                 ' | SELL')
                    print("\n", ts_text, '|', market, granularity, '|',
                          price_text, '| SELL', "\n")
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing LIVE Sell Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                # connect to Coinbase Pro API live
                model = AuthAPI(config['api_key'], config['api_secret'],
                                config['api_pass'], config['api_url'])
                # execute a live market sell
                resp = model.marketSell(
                    market, float(account.getBalance(cryptoMarket)))
                logging.info(resp)
                #logging.info('attempt to sell ' + resp['size'] + ' of ' + resp['product_id'])
            # if not live
            else:
                if is_verbose == 0:
                    sell_price = float(
                        str(
                            truncate(float(df_last['close'].values[0]),
                                     precision)))
                    last_buy_price = float(
                        str(truncate(float(last_buy), precision)))
                    buy_sell_diff = round(
                        np.subtract(sell_price, last_buy_price), precision)
                    buy_sell_margin_no_fees = str(
                        truncate(
                            (((sell_price - last_buy_price) / sell_price) *
                             100), 2)) + '%'

                    # calculate last buy minus fees
                    buy_fee = last_buy_price * 0.005
                    last_buy_price_minus_fees = last_buy_price + buy_fee

                    buy_sell_margin_fees = str(
                        truncate((((sell_price - last_buy_price_minus_fees) /
                                   sell_price) * 100), 2)) + '%'

                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | SELL | ' +
                                 str(sell_price) + ' | BUY | ' +
                                 str(last_buy_price) + ' | DIFF | ' +
                                 str(buy_sell_diff) + ' | MARGIN NO FEES | ' +
                                 str(buy_sell_margin_no_fees) +
                                 ' | MARGIN FEES | ' +
                                 str(buy_sell_margin_fees))
                    print("\n", ts_text, '|', market, granularity, '| SELL |',
                          str(sell_price), '| BUY |', str(last_buy_price),
                          '| DIFF |', str(buy_sell_diff), '| MARGIN NO FEES |',
                          str(buy_sell_margin_no_fees), '| MARGIN FEES |',
                          str(buy_sell_margin_fees), "\n")

                    buy_sum = buy_sum + last_buy_price_minus_fees
                    sell_sum = sell_sum + sell_price
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing TEST Sell Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
            #print(df_last[['close','ema12','ema26','ema12ltema26','ema12ltema26co','macd','signal','macdltsignal','obv','obv_pc']])

            if save_graphs == 1:
                tradinggraphs = TradingGraphs(technicalAnalysis)
                ts = datetime.now().timestamp()
                filename = 'BTC-GBP_3600_buy_' + str(ts) + '.png'
                tradinggraphs.renderEMAandMACD(24, 'graphs/' + filename, True)

        # last significant action
        if action in ['BUY', 'SELL']:
            last_action = action

        last_df_index = df_last.index.format()

        if iterations == 300:
            print("\nSimulation Summary\n")

            if buy_count > sell_count:
                # calculate last buy minus fees
                fee = last_buy * 0.005
                last_buy_minus_fees = last_buy + fee

                buy_sum = buy_sum + (float(
                    truncate(float(df_last['close'].values[0]), precision)) -
                                     last_buy_minus_fees)

            print('   Buy Count :', buy_count)
            print('  Sell Count :', sell_count, "\n")
            print('   Buy Total :', buy_sum)
            print('  Sell Total :', sell_sum)
            print(
                '      Margin :',
                str(truncate(
                    (((sell_sum - buy_sum) / sell_sum) * 100), 2)) + '%', "\n")
    else:
        # decrement ignored iteration
        iterations = iterations - 1

    # if live
    if is_live == 1:
        # save csv with orders for market that are 'done'
        orders = account.getOrders(market, '', 'done')
        orders.to_csv('orders.csv', index=False)

    if is_sim == 1:
        if iterations < 300:
            if sim_speed == 'fast':
                # fast processing
                executeJob(sc, market, granularity, tradingData)
            else:
                # slow processing
                s.enter(1, 1, executeJob,
                        (sc, market, granularity, tradingData))

    else:
        # poll every 5 minutes
        s.enter(300, 1, executeJob, (sc, market, granularity))
import pandas as pd
from models.Trading import TechnicalAnalysis
from models.CoinbasePro import PublicAPI

api = PublicAPI()
data = api.getHistoricalData('BTC-GBP', 3600)

ta = TechnicalAnalysis(data)
ta.addAll()
#ta.addChangePct()
#ta.addCMA()
#ta.addSMA(20)
#ta.addSMA(50)
#ta.addSMA(200)
#ta.addEMA(12)
#ta.addEMA(26)
#ta.addRSI(14)
#ta.addMACD()
#ta.addOBV()
#ta.addEMABuySignals()
#ta.addMACDBuySignals()
#ta.addCandleHammer()
#ta.addCandleInvertedHammer()
#ta.addCandleShootingStar()
#ta.addCandleHangingMan()
#ta.addCandleThreeWhiteSoldiers()
#ta.addCandleThreeBlackCrows()
#ta.addCandleDojo()
#ta.addCandleThreeLineStrike()
#ta.addCandleTwoBlackGapping()
#ta.addCandleEveningStar()
Ejemplo n.º 4
0
    # if live
    if is_live == 1:
        # if live, ensure sufficient funds to place next buy order
        if (last_action == '' or last_action
                == 'SELL') and account.getBalance(fiatMarket) == 0:
            raise Exception('Insufficient ' + fiatMarket +
                            ' funds to place next buy order!')
        # if live, ensure sufficient crypto to place next sell order
        elif last_action == 'BUY' and account.getBalance(cryptoMarket) == 0:
            raise Exception('Insufficient ' + cryptoMarket +
                            ' funds to place next sell order!')

    s = sched.scheduler(time.time, time.sleep)
    # run the first job immediately after starting
    if is_sim == 1:
        api = PublicAPI()
        tradingData = api.getHistoricalData(market, granularity)
        executeJob(s, market, granularity, tradingData)
    else:
        executeJob(s, market, granularity)

    s.run()

# catches a keyboard break of app, exits gracefully
except KeyboardInterrupt:
    print(datetime.now(), 'closed')
    try:
        sys.exit(0)
    except SystemExit:
        os._exit(0)
def test_instantiate_publicapi_without_error():
    exchange = PublicAPI()
    assert type(exchange) is PublicAPI
Ejemplo n.º 6
0
from models.PyCryptoBot import PyCryptoBot
from models.Binance import PublicAPI as BPublicAPI
from models.CoinbasePro import PublicAPI as CBPublicAPI

# Coinbase Pro time
api = CBPublicAPI()
ts = api.getTime()
print(ts)

app = PyCryptoBot(exchange='coinbasepro')
ts = api.getTime()
print(ts)

# Binance Live time
api = BPublicAPI()
ts = api.getTime()
print(ts)

app = PyCryptoBot(exchange='binance')
ts = api.getTime()
print(ts)
Ejemplo n.º 7
0
def executeJob(sc, market, granularity, tradingData=pd.DataFrame()):
    """Trading bot job which runs at a scheduled interval"""
    global action, iterations, x_since_buy, x_since_sell, last_action, last_df_index

    # increment iterations
    iterations = iterations + 1

    if is_sim == 0:
        # retrieve the market data
        api = PublicAPI()
        tradingData = api.getHistoricalData(market, granularity)

    # analyse the market data
    tradingDataCopy = tradingData.copy()
    technicalAnalysis = TechnicalAnalysis(tradingDataCopy)
    technicalAnalysis.addAll()
    df = technicalAnalysis.getDataFrame()

    if len(df) != 300:
        # data frame should have 300 rows, if not retry
        print('error: data frame length is < 300 (' + str(len(df)) + ')')
        logging.error('error: data frame length is < 300 (' + str(len(df)) +
                      ')')
        s.enter(300, 1, executeJob, (sc, market, granularity))

    if is_sim == 1:
        # with a simulation df_last will iterate through data
        df_last = df.iloc[iterations - 1:iterations]
    else:
        # df_last contains the most recent entry
        df_last = df.tail(1)

    ema12gtema26 = bool(df_last['ema12gtema26'].values[0])
    ema12gtema26co = bool(df_last['ema12gtema26co'].values[0])
    macdgtsignal = bool(df_last['macdgtsignal'].values[0])
    macdgtsignalco = bool(df_last['macdgtsignalco'].values[0])
    ema12ltema26 = bool(df_last['ema12ltema26'].values[0])
    ema12ltema26co = bool(df_last['ema12ltema26co'].values[0])
    macdltsignal = bool(df_last['macdltsignal'].values[0])
    macdltsignalco = bool(df_last['macdltsignalco'].values[0])
    obv = float(df_last['obv'].values[0])
    obv_pc = float(df_last['obv_pc'].values[0])

    # criteria for a buy signal
    if ((ema12gtema26co == True and macdgtsignal == True and obv_pc > 0.1) or
        (ema12gtema26 == True and macdgtsignal == True and obv_pc > 0.1
         and x_since_buy > 0 and x_since_buy <= 2)) and last_action != 'BUY':
        action = 'BUY'
    # criteria for a sell signal
    elif (ema12ltema26co == True
          and macdltsignal == True) and last_action not in ['', 'SELL']:
        action = 'SELL'
    # anything other than a buy or sell, just wait
    else:
        action = 'WAIT'

    # polling is every 5 minutes (even for hourly intervals), but only process once per interval
    if (last_df_index != df_last.index.format()):
        ts_text = str(df_last.index.format()[0])
        price_text = 'Price: ' + str(
            truncate(float(df_last['close'].values[0]), 2))
        ema_text = compare(df_last['ema12'].values[0],
                           df_last['ema26'].values[0], 'EMA12/26')
        macd_text = compare(df_last['macd'].values[0],
                            df_last['signal'].values[0], 'MACD')
        obv_text = compare(df_last['obv_pc'].values[0], 0, 'OBV %')
        counter_text = '[I:' + str(iterations) + ',B:' + str(
            x_since_buy) + ',S:' + str(x_since_sell) + ']'

        ema_co_prefix = ''
        ema_co_suffix = ''
        if ema12gtema26co == True or ema12ltema26co == True:
            ema_co_prefix = '* '
            ema_co_suffix = ' *'

        macd_co_prefix = ''
        macd_co_suffix = ''
        if macdgtsignalco == True or macdltsignalco == True:
            macd_co_prefix = '* '
            macd_co_suffix = ' *'

        if is_verbose == 0:
            output_text = ts_text + ' | ' + price_text + ' | ' + ema_co_prefix + ema_text + ema_co_suffix + ' | ' + macd_co_prefix + macd_text + macd_co_suffix + ' | ' + obv_text + ' | ' + action + ' ' + counter_text
            logging.debug(output_text)
            print(output_text)
        else:
            logging.debug('-- Iteration: ' + str(iterations) + ' --')
            logging.debug('-- Since Last Buy: ' + str(x_since_buy) + ' --')
            logging.debug('-- Since Last Sell: ' + str(x_since_sell) + ' --')

            logging.debug('price: ' +
                          str(truncate(float(df_last['close'].values[0]), 2)))
            logging.debug('ema12: ' +
                          str(truncate(float(df_last['ema12'].values[0]), 2)))
            logging.debug('ema26: ' +
                          str(truncate(float(df_last['ema26'].values[0]), 2)))
            logging.debug('ema12gtema26co: ' + str(ema12gtema26co))
            logging.debug('ema12gtema26: ' + str(ema12gtema26))
            logging.debug('ema12ltema26co: ' + str(ema12ltema26co))
            logging.debug('ema12ltema26: ' + str(ema12ltema26))
            logging.debug('macd: ' +
                          str(truncate(float(df_last['macd'].values[0]), 2)))
            logging.debug('signal: ' +
                          str(truncate(float(df_last['signal'].values[0]), 2)))
            logging.debug('macdgtsignal: ' + str(macdgtsignal))
            logging.debug('macdltsignal: ' + str(macdltsignal))
            logging.debug('obv: ' + str(obv))
            logging.debug('obv_pc: ' + str(obv_pc) + '%')
            logging.debug('action: ' + action)

            # informational output on the most recent entry
            print('')
            print(
                '================================================================================'
            )
            txt = '        Iteration : ' + str(iterations)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '   Since Last Buy : ' + str(x_since_buy)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Since Last Sell : ' + str(x_since_sell)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '        Timestamp : ' + str(df_last.index.format()[0])
            print('|', txt, (' ' * (75 - len(txt))), '|')
            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '            EMA12 : ' + str(
                truncate(float(df_last['ema12'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '            EMA26 : ' + str(
                truncate(float(df_last['ema26'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '   Crossing Above : ' + str(ema12gtema26co)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Above : ' + str(ema12gtema26)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '   Crossing Below : ' + str(ema12ltema26co)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Below : ' + str(ema12ltema26)
            print('|', txt, (' ' * (75 - len(txt))), '|')

            if (ema12gtema26 == True and ema12gtema26co == True):
                txt = '        Condition : EMA12 is currently crossing above EMA26'
            elif (ema12gtema26 == True and ema12gtema26co == False):
                txt = '        Condition : EMA12 is currently above EMA26 and has crossed over'
            elif (ema12ltema26 == True and ema12ltema26co == True):
                txt = '        Condition : EMA12 is currently crossing below EMA26'
            elif (ema12ltema26 == True and ema12ltema26co == False):
                txt = '        Condition : EMA12 is currently below EMA26 and has crossed over'
            else:
                txt = '        Condition : -'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '             MACD : ' + str(
                truncate(float(df_last['macd'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '           Signal : ' + str(
                truncate(float(df_last['signal'].values[0]), 2))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Above : ' + str(macdgtsignal)
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '  Currently Below : ' + str(macdltsignal)
            print('|', txt, (' ' * (75 - len(txt))), '|')

            if (macdgtsignal == True and macdgtsignalco == True):
                txt = '        Condition : MACD is currently crossing above Signal'
            elif (macdgtsignal == True and macdgtsignalco == False):
                txt = '        Condition : MACD is currently above Signal and has crossed over'
            elif (macdltsignal == True and macdltsignalco == True):
                txt = '        Condition : MACD is currently crossing below Signal'
            elif (macdltsignal == True and macdltsignalco == False):
                txt = '        Condition : MACD is currently below Signal and has crossed over'
            else:
                txt = '        Condition : -'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '              OBV : ' + str(truncate(obv, 4))
            print('|', txt, (' ' * (75 - len(txt))), '|')
            txt = '       OBV Change : ' + str(obv_pc) + '%'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            if (obv_pc >= 2):
                txt = '        Condition : Large positive volume changes'
            elif (obv_pc < 2 and obv_pc >= 0):
                txt = '        Condition : Positive volume changes'
            else:
                txt = '        Condition : Negative volume changes'
            print('|', txt, (' ' * (75 - len(txt))), '|')

            print(
                '--------------------------------------------------------------------------------'
            )
            txt = '           Action : ' + action
            print('|', txt, (' ' * (75 - len(txt))), '|')
            print(
                '================================================================================'
            )

        if last_action == 'BUY':
            x_since_buy = x_since_buy + 1
        elif last_action == 'SELL':
            x_since_sell = x_since_sell + 1

        # if a buy signal
        if action == 'BUY':
            # increment x since buy
            x_since_buy = x_since_buy + 1

            # reset x since sell
            x_since_sell = 0

            # if live
            if is_live == 1:
                if is_verbose == 0:
                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | ' + price_text +
                                 ' | BUY')
                    print(ts_text, '|', market, granularity, '|', price_text,
                          '| BUY')
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing LIVE Buy Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                # connect to coinbase pro api (authenticated)
                model = AuthAPI(config['api_key'], config['api_secret'],
                                config['api_pass'], config['api_url'])
                # execute a live market buy
                resp = model.marketBuy(market,
                                       float(account.getBalance(fiatMarket)))
                logging.info(resp)
                #logging.info('attempt to buy ' + resp['specified_funds'] + ' (' + resp['funds'] + ' after fees) of ' + resp['product_id'])
            # if not live
            else:
                if is_verbose == 0:
                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | ' + price_text +
                                 ' | BUY')
                    print(ts_text, '|', market, granularity, '|', price_text,
                          '| BUY')
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing TEST Buy Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
            #print(df_last[['close','ema12','ema26','ema12gtema26','ema12gtema26co','macd','signal','macdgtsignal','obv','obv_pc']])

        # if a sell signal
        elif action == 'SELL':
            # increment x since buy
            x_since_sell = x_since_sell + 1

            # reset x since buy
            x_since_buy = 0

            # if live
            if is_live == 1:
                if is_verbose == 0:
                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | ' + price_text +
                                 ' | SELL')
                    print(ts_text, '|', market, granularity, '|', price_text,
                          '| SELL')
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing LIVE Sell Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                # connect to Coinbase Pro API live
                model = AuthAPI(config['api_key'], config['api_secret'],
                                config['api_pass'], config['api_url'])
                # execute a live market sell
                resp = model.marketSell(
                    market, float(account.getBalance(cryptoMarket)))
                logging.info(resp)
                #logging.info('attempt to sell ' + resp['size'] + ' of ' + resp['product_id'])
            # if not live
            else:
                if is_verbose == 0:
                    logging.info(ts_text + ' | ' + market + ' ' +
                                 str(granularity) + ' | ' + price_text +
                                 ' | SELL')
                    print(ts_text, '|', market, granularity, '|', price_text,
                          '| SELL')
                else:
                    print(
                        '--------------------------------------------------------------------------------'
                    )
                    print(
                        '|                      *** Executing TEST Sell Order ***                        |'
                    )
                    print(
                        '--------------------------------------------------------------------------------'
                    )
            #print(df_last[['close','ema12','ema26','ema12ltema26','ema12ltema26co','macd','signal','macdltsignal','obv','obv_pc']])

        # last significant action
        if action in ['BUY', 'SELL']:
            last_action = action

        last_df_index = df_last.index.format()

    # if live
    if is_live == 1:
        # save csv with orders for market that are 'done'
        orders = account.getOrders(market, '', 'done')
        orders.to_csv('orders.csv', index=False)

    if is_sim == 1:
        if iterations < 300:
            if sim_speed == 'fast':
                # fast processing
                executeJob(sc, market, granularity, tradingData)
            else:
                # slow processing
                s.enter(1, 1, executeJob,
                        (sc, market, granularity, tradingData))
    else:
        # poll every 5 minutes
        s.enter(300, 1, executeJob, (sc, market, granularity))
Ejemplo n.º 8
0
    # if live
    if is_live == 1:
        # if live, ensure sufficient funds to place next buy order
        if (last_action == '' or last_action
                == 'SELL') and account.getBalance(fiatMarket) == 0:
            raise Exception('Insufficient ' + fiatMarket +
                            ' funds to place next buy order!')
        # if live, ensure sufficient crypto to place next sell order
        elif last_action == 'BUY' and account.getBalance(cryptoMarket) == 0:
            raise Exception('Insufficient ' + cryptoMarket +
                            ' funds to place next sell order!')

    s = sched.scheduler(time.time, time.sleep)
    # run the first job immediately after starting
    if is_sim == 1:
        api = PublicAPI()

        if sim_speed in ['fast-sample', 'slow-sample']:
            tradingData = pd.DataFrame()

            attempts = 0
            while len(tradingData) != 300 and attempts < 10:
                endDate = datetime.now() - timedelta(hours=random.randint(
                    0, 8760 * 3))  # 3 years in hours
                startDate = endDate - timedelta(hours=300)
                tradingData = api.getHistoricalData(market, granularity,
                                                    startDate.isoformat(),
                                                    endDate.isoformat())
                attempts += 1

            if len(tradingData) != 300: