예제 #1
0
 def test_binance2btrx(self):
     self.assertEqual(aux.binance2btrx({'symbol': 'TIETABTC',
                                    'askPrice': '12',
                                    'bidPrice': '11',
                                    'count': '333',
                                    'highPrice': '15',
                                    'lastPrice': '11.5',
                                    'lowPrice': '10',
                                    'quoteVolume': '1000',
                                    'volume': '100'})
                                    ,{'MarketName': 'TIETABTC',
                                    'Ask': 12.0,
                                    'BaseVolume': 1000.0,
                                    'Bid': 11.0,
                                    'Count': 333.0,
                                    'High': 15.0,
                                    'Last': 11.5,
                                    'Low': 10.0,
                                    'Volume': 100.0})
예제 #2
0
def realtime(exchanges,
             entry_funcs,
             exit_funcs,
             interval=var.default_interval,
             smas=var.default_smas,
             emas=var.default_volume_emas,
             refresh_interval=10,
             simulation=True,
             main_coins=("BTC", "USDT"),
             log_level=1):
    '''
    Bot using realtime data, doesn't need DB or csv files to work.

    Args:
        exchanges(list): list of exchanges.
        entry_funcs(list): list of entry functions to test.
        exit_funcs(list): list of entry functions to test.
        markets(string): list with markets to backtest or empty to run all available markets.
        interval(string): time between measures.
        smas(list): list of SMA values to use.
        emas(list): list of EMA values to use.
        refresh_interval(int): Data refresh rate.
        simulation(bool): Defines if it's running as a simulation or real money mode.
        main_coins(tuple): tuple of main coins.
    '''

    #log_level:
    #   0 - Only presents total.
    #   1 - Writes logs to file.
    #   2 - Writes logs to file and prints on screen.
    #   Default is 2.

    #var.global_log_level = log_level

    signal.signal(signal.SIGINT, signal_handler)

    validate = smas[-1] + 5

    nr_exchanges = len(exchanges)

    if not isinstance(exchanges, list): exchanges = [exchanges]
    if not isinstance(entry_funcs, list): entry_funcs = [entry_funcs]
    if not isinstance(exit_funcs, list): exit_funcs = [exit_funcs]

    portfolio = {}  # Owned coins list.
    coins = {}

    # Bittrex exchange
    if "bittrex" in exchanges:
        if simulation:
            bt = Bittrex('', '')
            print(f"Starting Bot with Bittrex")
        else:
            try:
                bt = RiskManagement(var.ky, var.sct)
            except Exception as e:
                print(f"[Error] Couldn't connect to Bittrex: {e}")
                nr_exchanges -= 1

    # Binance exchange
    if "binance" in exchanges:
        if simulation:

            # T E M P
            try:
                bnb = Binance.set('', '')
                print("Starting Bot with Binance")
            except Exception as e:
                print(f"[Error] Couldn't connect to Binance: {e}")
        else:
            print(
                f"Can't use Binance exchange in real scenario, just simulation."
            )
            sys.exit(1)
            #try:
            #    bnb = RiskManagement(var.ky, var.sct)
            #except Exception as e:
            #    print("[Error] Couldn't connect to Binance", 0, log_level)
            #    nr_exchanges -=1

    if not nr_exchanges:
        sys.exit(1)

    while True:

        start_time = time()

        markets = bt.get_market_summaries()['result']
        markets += bnb.get_ticker()

        for market in markets:

            # Needed to pass unicode to string.
            # Binance
            if 'MarketName' in market:
                market_name = 'BT_' + str(market['MarketName'])
            elif 'symbol' in market:
                market = binance2btrx(market)
                market_name = 'BN_' + market['MarketName']

            # Checks if pair is included in main coins.
            if (market_name.startswith('BT_') and market_name.split('-')[0]) or \
               (market_name.startswith('BN_') and market_name.endswith(main_coins)):

                # Checks if market already exists in analysed coins.
                if market_name in coins:

                    # Checks if has enough data to analyse.
                    if coins[market_name] == validate:
                        locals()[market_name] = pd.DataFrame.append(
                            locals()[market_name], [market]).tail(validate)
                    # If not, adds data and keep going.
                    else:
                        locals()[market_name] = pd.DataFrame.append(
                            locals()[market_name], [market])
                        coins[market_name] += 1
                        continue

                # If not adds coin to system.
                else:
                    locals()[market_name] = pd.DataFrame([market])
                    coins[market_name] = 1
                    continue

                if '-' in market_name:
                    # Renames OpenBuy and OpenSell in Bittrex
                    data = locals()[market_name].rename(index=str,
                                                        columns={
                                                            "OpenBuyOrders":
                                                            "OpenBuy",
                                                            "OpenSellOrders":
                                                            "OpenSell"
                                                        })
                else:
                    data = locals()[market_name]

                # Checks if coin is in portfolio and looks for a sell opportunity.
                if market_name in portfolio:

                    # Needed to make use of stop loss and trailing stop loss functions.
                    if portfolio[market_name]['max_price'] < data.Bid.iloc[-1]:
                        portfolio[market_name]['max_price'] = data.Bid.iloc[-1]

                    if is_time_to_exit(
                            data,
                            exit_funcs,
                            bought_at=portfolio[market_name]['bought_at'],
                            max_price=portfolio[market_name]['max_price'],
                            count=portfolio[market_name]['count']):

                        # implementar binance
                        if not simulation:
                            #REAL
                            sell_res = bt.sell(
                                market_name,
                                portfolio[market_name]['quantity'],
                                data.Bid.iloc[-1])

                            # M U D A R
                            sold_at = sell_res

                            print(f'[SELL]@ {sold_at} > {market_name}')

                            res = ((sold_at - portfolio[market_name]['bought_at'])/\
                                    portfolio[market_name]['bought_at'])*100

                            print(f'[P&L] {market_name}> {res:.2f}%.')

                        # implementar binance
                        else:
                            #SIMULATION
                            #print('> https://bittrex.com/Market/Index?MarketName=' + market_name)

                            print(
                                f'[SELL]@ {data.Bid.iloc[-1]} > {market_name}')

                            res = ((data.Bid.iloc[-1] - portfolio[market_name]['bought_at'])/\
                                    portfolio[market_name]['bought_at'])*100

                            print(f'[P&L] {market_name} > {res:.2f}%.')

                        locals()[market_name].to_csv('df_' + market_name +
                                                     '.csv')
                        del locals()[market_name]
                        del portfolio[market_name]
                        coins.pop(market_name)

                    #if not time to exit, increment count.
                    else:
                        portfolio[market_name]['count'] += 1

                # if the coin is not on portfolio, checks if is time to buy.
                else:
                    if is_time_to_buy(data, entry_funcs):

                        if not simulation:
                            #REAL
                            sucs, msg = bt.buy(market,
                                               data.Ask.iloc[-1] * 1.01)

                            if sucs:
                                portfolio[market_name] = {}
                                portfolio[market_name]['bought_at'] = msg[0]
                                portfolio[market_name]['max_price'] = msg[0]
                                portfolio[market_name]['quantity'] = msg[1]
                                portfolio[market_name]['count'] = 0

                                print(f'[BUY]@ {msg[0]} > {market_name}')

                            else:
                                print(
                                    f"[XXXX] Could not buy @ {data.Ask.iloc[-1] * 1.01} \
                                    [MSG>] {msg}")

                        else:
                            #SIMULATION
                            portfolio[market_name] = {}
                            portfolio[market_name][
                                'bought_at'] = data.Ask.iloc[-1]
                            portfolio[market_name][
                                'max_price'] = data.Ask.iloc[-1]
                            portfolio[market_name]['quantity'] = 1
                            portfolio[market_name]['count'] = 0

                            #print('> https://bittrex.com/Market/Index?MarketName='+market_name)

                            print(f'[BUY]@{data.Ask.iloc[-1]} > {market_name}')

        # In case of processing time is bigger than *refresh_interval* doesn't sleep.
        if refresh_interval - (time() - start_time) > 0:
            sleep(refresh_interval - (time() - start_time))
예제 #3
0
def realtime(exchanges,
             entry_funcs,
             exit_funcs,
             trading_markets=None,
             interval=var.default_interval,
             smas=var.default_smas,
             emas=var.default_volume_emas,
             refresh_interval=10,
             simulation=True,
             main_coins=("BTC", "USDT")):
    """
    Bot using realtime data, doesn't need DB or csv files to work.

    Args:
        exchanges(list): list of exchanges.
        entry_funcs(list): list of entry functions to test.
        exit_funcs(list): list of entry functions to test.
        trading_markets(string): list with markets to backtest or empty
                                to run all available markets.
        interval(string): time between measures.
        smas(list): list of SMA values to use.
        emas(list): list of EMA values to use.
        refresh_interval(int): Data refresh rate.
        simulation(bool): Defines if it's running as a simulation or real money mode.
        main_coins(tuple): tuple of main coins.
    """
    markets = []

    if trading_markets is None:
        trading_markets = []

    signal.signal(signal.SIGINT, signal_handler)

    validate = smas[-1] + 5

    nr_exchanges = len(exchanges)

    if not isinstance(exchanges, list):
        exchanges = [exchanges]
    if not isinstance(entry_funcs, list):
        entry_funcs = [entry_funcs]
    if not isinstance(exit_funcs, list):
        exit_funcs = [exit_funcs]

    portfolio = {}  # Owned coins list.
    coins = {}

    res_abs = 0

    # Bittrex exchange
    if "bittrex" in exchanges:
        log.debug("Starting Bot with Bittrex")
        if simulation:
            log.debug("[MODE] Simulation")
            bt = Bittrex('', '')
            nr_exchanges -= 1
        else:
            log.debug("[MODE] Simulation")
            try:
                bt = Btr(var.btr_ky, var.btr_sct)
            except Exception as e:
                log.error(f"Unable to connect to Bittrex: {e}")
                return 1

    # Binance exchange
    if "binance" in exchanges:
        log.debug("Starting Bot with Binance")
        if simulation:
            log.debug("[MODE] Simulation")
            try:
                bnb = Binance('', '')
                nr_exchanges -= 1
            except Exception as e:
                log.error(f"Unable to connect to Binance: {e}")
        else:
            log.debug("[MODE] Real Money")
            if var.desktop_info:
                desktop_notification({
                    'type': 'info',
                    'title': 'Crypto Algo Trading',
                    'message': '[MODE] Real Money'
                })
            try:
                bnb = Bnb()
            except Exception as e:
                log.error(f"Unable to connect to Binance - {e}")
                return 1

    if not nr_exchanges:
        log.error('sin exchanges Jose')
        sys.exit(1)

    while True:
        start_time = time()

        if "bittrex" in exchanges:
            markets += bt.get_market_summaries()['result']
        if "binance" in exchanges:
            markets += bnb.get_ticker()

        for market in markets:
            if 'MarketName' in market:
                market_name = 'BT_' + str(market['MarketName'])
            elif 'symbol' in market:
                market = binance2btrx(market)
                market_name = 'BN_' + market['MarketName']

            global_market_name = str(market['MarketName'])

            # Check if it's on of the trading pairs.
            if len(trading_markets) > 0:
                if market_name not in trading_markets:
                    continue

            # Checks if pair is included in main coins.
            if (market_name.startswith('BT_') and market_name.split('-')[0] in main_coins) or \
                    (market_name.startswith('BN_') and market_name.endswith(main_coins)):

                # Checks if market already exists in analysed coins.
                if market_name in coins:

                    # Checks if has enough data to analyse.
                    if coins[market_name] == validate:
                        locals()[market_name] = pd.DataFrame.append(
                            locals()[market_name], [market]).tail(validate)
                    # If not, adds data and keep going.
                    else:
                        locals()[market_name] = pd.DataFrame.append(
                            locals()[market_name], [market])
                        coins[market_name] += 1
                        continue

                # If not adds coin to system.
                else:
                    locals()[market_name] = pd.DataFrame([market])
                    coins[market_name] = 1
                    continue

                if '-' in market_name:
                    # Renames OpenBuy and OpenSell in Bittrex
                    data = locals()[market_name].rename(index=str,
                                                        columns={
                                                            "OpenBuyOrders":
                                                            "OpenBuy",
                                                            "OpenSellOrders":
                                                            "OpenSell"
                                                        })
                else:
                    data = locals()[market_name]

                # Checks if coin is in portfolio and looks for a sell opportunity.
                if market_name in portfolio:

                    # Needed to make use of stop loss and trailing stop loss functions.
                    if portfolio[market_name]['max_price'] < data.Bid.iloc[-1]:
                        portfolio[market_name]['max_price'] = data.Bid.iloc[-1]

                    if is_time_to_exit(
                            data,
                            exit_funcs,
                            smas,
                            bought_at=float(
                                portfolio[market_name]['bought_at']),
                            max_price=float(
                                portfolio[market_name]['max_price']),
                            count=portfolio[market_name]['count'],
                            stop=var.stop_type):

                        if not simulation:
                            # Binance market
                            if market_name.startswith('BN_'):
                                # Market Sell
                                success, sell_res = bnb.sell(
                                    market_name.replace('BN_', ''))
                                # portfolio[market_name]['quantity']
                                # data.Bid.iloc[-1])

                                if success:
                                    sold_at = float(
                                        sell_res['fills'][0]['price'])

                            # Bittrex market
                            elif market_name.startswith('BT_'):
                                success, sell_res = bt.sell(
                                    market_name.replace('BT_', ''),
                                    portfolio[market_name]['quantity'],
                                    data.Bid.iloc[-1])
                                if success:
                                    sold_at = sell_res

                            if not success:
                                log.error(f'[ERROR] {sell_res}')
                                continue

                            log.info(
                                f'[SELL] {global_market_name} @ {sold_at}')
                            if var.desktop_info:
                                desktop_notification({
                                    'type':
                                    'sell',
                                    'title':
                                    global_market_name,
                                    'message':
                                    f'Sold @ {sold_at}'
                                })

                            res_abs = (float(sell_res['cummulativeQuoteQty']) /
                                       float(sell_res['executedQty']) -
                                       portfolio[market_name]['bought_at']
                                       ) * float(sell_res['executedQty'])
                            res = (
                                (sold_at - portfolio[market_name]['bought_at'])
                                / portfolio[market_name]['bought_at']) * 100

                        # SIMULATION
                        else:
                            log.info(
                                f'[SELL] {global_market_name} @ {data.Bid.iloc[-1]}'
                            )

                            res = ((data.Bid.iloc[-1] -
                                    portfolio[market_name]['bought_at']) /
                                   portfolio[market_name]['bought_at']) * 100

                        if var.commission:
                            res -= var.bnb_commission
                        log.info(f'[P&L] {global_market_name} > {res:.2f}%')
                        # Hard coded to USDT
                        log.debug(
                            f"[ {'+' if res>0 else '-'} ] {res_abs:.2f} {sell_res['fills'][-1]['commissionAsset']}"
                        )

                        if var.desktop_info:
                            desktop_notification({
                                'type':
                                'P&L',
                                'profit%':
                                res,
                                'profit':
                                res_abs,
                                'title':
                                global_market_name,
                                'message':
                                f"P&L = {res:.2f}% | {res_abs} {sell_res['fills'][-1]['commissionAsset']}"
                            })

                        locals()[market_name].to_csv(
                            f"df_{market_name}-{ctime(time())}.csv")
                        del locals()[market_name]
                        del portfolio[market_name]
                        coins.pop(market_name)

                    # If it's not time to exit, increment count.
                    else:
                        portfolio[market_name]['count'] += 1

                # If the coin is not on portfolio, checks if it's time to buy.
                else:
                    if is_time_to_buy(data, entry_funcs, smas):
                        # REAL
                        if not simulation:
                            # Binance
                            if market_name.startswith('BN_'):
                                # Limit buy
                                # success, msg = bnb.buy(market, data.Ask.iloc[-1]*1.01)
                                # Market buy
                                success, ret = bnb.buy(
                                    market_name.replace('BN_', ''))

                            # Bittrex
                            elif market_name.startswith('BT_'):
                                success, ret = bt.buy(
                                    market_name.replace('BT_', ''),
                                    data.Ask.iloc[-1] * 1.01)

                            if success:
                                # TODO - Implement portfolio for Bittrex
                                portfolio[market_name] = {
                                    'bought_at':
                                    float(ret['fills'][0]['price']),
                                    'max_price':
                                    float(ret['fills'][0]['price']),
                                    'quantity': float(ret['executedQty']),
                                    'count': 0
                                }

                                log.info(
                                    f"[BUY] {global_market_name} @ {portfolio[market_name]['bought_at']}"
                                )
                                if var.desktop_info:
                                    desktop_notification({
                                        'type':
                                        'buy',
                                        'title':
                                        global_market_name,
                                        'message':
                                        f"Buy @ {portfolio[market_name]['bought_at']}"
                                    })

                            elif 'error' in ret:
                                log.info(
                                    f"[ERROR] Unable to buy {global_market_name} @ {data.Ask.iloc[-1]}"
                                )
                                log.info(f"       [MSG] {ret['error']}")

                        # SIMULATION
                        else:
                            portfolio[market_name] = {
                                'bought_at': data.Ask.iloc[-1],
                                'max_price': data.Ask.iloc[-1],
                                'quantity': 1,
                                'count': 0
                            }
                            log.info(
                                f'[BUY] {global_market_name} @ {data.Ask.iloc[-1]}'
                            )

        del markets
        markets = []
        # In case of processing time is bigger than *refresh_interval* doesn't sleep.
        if refresh_interval - (time() - start_time) >= 0:
            sleep(refresh_interval - (time() - start_time))