Example #1
0
    def execute_coin_balance(self):

        try:
            self.balance_balances()

        except poloniex.PoloniexError as e:
            if 'Withdrawal would exceed your daily withdrawal limit.' in str(
                    e):
                logging.warning('Withdrawal exceeds daily limit.')
                email_client.EmailClient().\
                    notify_me_by_email(title='Coin balancer error: Withdraw exceeds daily limit.',
                                       content='PoloniexError')
            else:
                logging.error('Other Poloniex error happened: %s' % e)

        except TimeoutError:
            logging.warning('Coin balancer time out!\n')

        except BaseException as e:
            logging.warning(
                'Error occurred in coin balancer. Sending email notification: %s'
                % e)
            email_client.EmailClient().notify_me_by_email(
                title='Error occurred in coin balancer.',
                content='Error (%s) occurred.\n Please check code.' % e)
    def transfer(self, from_market, to_market, currency, amount):
        """

        :param from_market:
        :param to_market:
        :param currency: string, standard currency name, refer to config_coin
        :param amount:
        :return:
        """

        if from_market == 'poloniex':
            res = self.transfer_from_poloniex(destination=to_market,
                                              currency=currency,
                                              amount=amount)
        elif from_market == 'huobi_pro':
            res = self.transfer_from_huobi(destination=to_market,
                                           currency=currency,
                                           amount=amount)
        else:
            raise ValueError('from_market parameter error: %s' % from_market)

        email_client.EmailClient().notify_me_by_email(
            title='Transferred %s %s from %s to %s. Status: %s.' %
            (amount, currency, from_market, to_market,
             'Success' if res else 'Fail'))
        return res
Example #3
0
def trade():

    logging.warning('\n\n')
    logging.warning(' ' * 0 + '#####     Trader started.     #####')

    logging.warning('=====     Coin Balancer      =====')
    coin_balancer.CoinBalancer().execute_coin_balance()

    logging.warning('=====     Premium monitor    =====')

    try:
        premiums = premium_calculator.get_premiums_mp()
    except BaseException as err:
        logging.warning('Get Premium failed. %s' % str(err))
        return

    logging.warning('Current premiums: ')
    for currency_pair in premiums:
        premium = premiums[currency_pair]
        premium_threshold = config_trader.get_premium_threshold(
            currency_pair, premium['market_hi'], premium['market_lo'])
        logging.warning(currency_pair + ': ' + str(premiums[currency_pair]) +
                        ' (threshold: ' + premium_threshold + ')')

    # filter premium that is higher than threshold
    filtered_premiums = [
    ]  # each element is a dict containing currency_pair, premium, market_hi and market_lo.
    for currency_pair in premiums:
        premium = premiums[currency_pair]
        premium['currency_pair'] = currency_pair
        premium_threshold = config_trader.get_premium_threshold(
            currency_pair, premium['market_hi'], premium['market_lo'])
        if float(premium['premium']) > float(premium_threshold):
            filtered_premiums.append(premium)

    # sort premium
    filtered_premiums.sort(key=lambda x: float(x['premium']), reverse=True)
    logging.warning('Qualified premiums: %s' % filtered_premiums)

    # execute premium from the highest one, if success then return, else continue on the next one
    for premium in filtered_premiums:
        logging.warning('Sending arbitrage order to trader: %s' % str(premium))
        try:
            status = arbitrage_trader.ArbitrageTrader(
                premium['currency_pair'], premium['market_hi'],
                premium['market_lo'], premium['premium']).arbitrage()
            logging.warning('Arbitrage order finished. Status: %s' % status)
            break
        except BaseException as err:
            if str(err) == 'Execution status: Insufficient Fund!' \
                    or 'Execution halted' in str(err)\
                    or 'Premium' in str(err):
                pass
            else:
                email_client.EmailClient().notify_me_by_email(
                    title='Arbitrage Execution of %s Error: %s' %
                    (premium, err),
                    content='Please handle exception.')

    logging.warning(' ' * 0 + '#####     Trader ended.       #####')
Example #4
0
def profit_report(balances_old, balances_new, premium_report,
                  premium_threshold, market, currency_pair, trade_amount,
                  is_reversed):

    # profit report

    logging.warning('Premium Report: \n%s (threshold: %s)' %
                    (premium_report, premium_threshold))

    assets_old = assets_monitor.AssetsMonitor().cal_assets(balances_old)
    assets_new = assets_monitor.AssetsMonitor().cal_assets(balances_new)

    logging.warning('Assets Report: \n%s' % assets_new)

    profit_report_data = assets_monitor.AssetsMonitor().cal_profits(
        assets_old=assets_old, assets_new=assets_new)
    profit_report_text = str(profit_report_data)
    profit_report_short = profit_report_data['usdt_equ']
    logging.warning('Profit Report: \n%s' % profit_report_text)

    base_currency, quote_currency = currency_pair.split('/')
    prices = unified_client.UnifiedClient(
        config_trader.market_fetch_ticker).get_tickers()
    profit_usdt = float(profit_report_short)
    trade_amount_usdt = float(trade_amount) * \
        float(prices[base_currency + '/USDT'])
    profit_ratio_num = profit_usdt / trade_amount_usdt
    profit_ratio_report = '%.4f %%' % (profit_usdt / trade_amount_usdt * 100)

    logging.warning('Report by email...')

    email_client.EmailClient().notify_me_by_email(
        title=('(Reversed)' if is_reversed else '') +
        'Arbitrage (%s, %s, %s, %s) successfully proceeded!' %
        (currency_pair, market, premium_report, profit_report_short),
        content='Trade amount: %s \nOld balances: \n%s \nNew balances: \n%s\n\n'
        'Premium Report: \n%s\n\nAssets Report:\n%s\n\n Profit Report: \n %s (%s)'
        % (trade_amount, balances_old, balances_new, premium_report,
           assets_new, profit_report_text, profit_ratio_report))

    # save to csv
    trade_recorder.save_trading_result(pair=currency_pair,
                                       market=market,
                                       premium_report=premium_report,
                                       premium_threshold=premium_threshold,
                                       trade_amount=trade_amount,
                                       profit=profit_report_short,
                                       assets=assets_new,
                                       profit_ratio_num=profit_ratio_num,
                                       is_reversed=is_reversed)

    return profit_usdt
def profit_report(balances_old, balances_new, premium_report, premium_threshold,
                  market, currency_pair, trade_amount):

    # profit report

    logging.warning('Premium Report: \n%s (threshold: %s)' % (premium_report, premium_threshold))

    assets_old = assets_monitor.AssetsMonitor().cal_assets(balances_old)
    assets_new = assets_monitor.AssetsMonitor().cal_assets(balances_new)

    logging.warning('Assets Report: \n%s' % assets_new)

    profit_report_data = assets_monitor.AssetsMonitor().cal_profits(assets_old=assets_old,
                                                                    assets_new=assets_new)
    profit_report_text = str(profit_report_data)
    profit_report_short = profit_report_data['usdt_equ']
    logging.warning('Profit Report: \n%s' % profit_report_text)

    base_currency, quote_currency = currency_pair.split('/')
    prices = poloniex_client.PoloniexClient().returnTicker()
    profit_usdt = float(profit_report_short)
    trade_amount_usdt = float(trade_amount) * \
        float(prices['USDT_' + config_coin.currency_name_standard_to_poloniex(base_currency)]['last'])
    profit_ratio_num = profit_usdt / trade_amount_usdt
    profit_ratio_report = '%.4f %%' % (profit_usdt / trade_amount_usdt * 100)

    logging.warning('Report by email...')

    email_client.EmailClient().notify_me_by_email(
        title='Arbitrage (%s, %s, %s, %s) successfully proceeded!' %
              (currency_pair, market, premium_report, profit_report_short),
        content='Trade amount: %s \nOld balances: \n%s \nNew balances: \n%s\n\n'
                'Premium Report: \n%s\n\nAssets Report:\n%s\n\n Profit Report: \n %s (%s)' % (
                    trade_amount, balances_old, balances_new, premium_report, assets_new,
                    profit_report_text, profit_ratio_report))

    # save to csv
    trade_recorder.save_trading_result(pair=currency_pair, market=market,
                                       premium_report=premium_report, premium_threshold=premium_threshold,
                                       trade_amount=trade_amount, profit=profit_report_short,
                                       assets=assets_new, profit_ratio_num=profit_ratio_num)
Example #6
0
    def balance_balances(premiums):

        balances = assets_monitor.AssetsMonitor().get_balances(
            include_frozen=True)
        # balances = assets_monitor.AssetsMonitor().get_balances_async(include_frozen=True)
        logging.info('Current balances:')
        logging.info(balances)

        # for market in balances:
        #     balances[market] = assets_monitor.AssetsMonitor().cal_usdt_equivalent(balances[market])
        #     logging.warning(market + ': \t' + ''.join(
        #         [(currency + ': ' + balances[market][currency] + '\t')
        #          for currency in config_coin.currency_list['standard']]))

        imbalance_ratio = {}
        for market in balances:
            imbalance_ratio[market] = {}
            for currency in config_coin.currency_list['standard']:
                imbalance_ratio[market][currency] = '%.4f' % (
                    float(balances[market][currency]) /
                    float(config_coin.even_level[currency]) - 1.0)
        logging.info('Balance even ratio:')
        for market in imbalance_ratio:
            logging.info(imbalance_ratio[market])

        balance_list = []
        for market_hi, market_lo in config_trader.market_pairs:

            base_currencies = [
                currency for currency in config_coin.currency_list['standard']
                if float(imbalance_ratio[market_hi][currency]) > float(
                    config_coin.imbalance_threshold_hi)
                and float(imbalance_ratio[market_lo][currency]) <
                -float(config_coin.imbalance_threshold_lo)
            ]
            quote_currencies = [
                currency for currency in config_coin.currency_list['standard']
                if float(imbalance_ratio[market_lo][currency]) > float(
                    config_coin.imbalance_threshold_hi)
            ]

            logging.info('Market pair: %s, %s' % (market_hi, market_lo))
            logging.info('Currency pair: %s, %s' %
                         (str(base_currencies), str(quote_currencies)))

            for currency_pair in config_trader.trade_currency_pairs:
                base_currency, quote_currency = currency_pair.split('/')
                if base_currency in base_currencies and quote_currency in quote_currencies:
                    balance_list.append([
                        currency_pair, market_hi, market_lo,
                        config_coin.balance_premium_threshold
                    ])

        logging.warning('Balance list: %s' % str(balance_list))

        if balance_list:
            logging.warning(
                '=====     Coin Balancer (adaptive & reversed arbitrage)      ====='
            )
            balance_list.sort(key=lambda x: float(x[3]))
            premium_cache = premiums
            for i in range(len(balance_list)):
                currency_pair, market_hi, market_lo, threshold = balance_list[
                    i]
                logging.info('Trying to balance %s.' % str(balance_list[i]))
                try:
                    the_premium = [
                        premium for premium in premium_cache
                        if (premium['currency_pair'] == currency_pair
                            and premium['market_hi'] == market_hi
                            and premium['market_lo'] == market_lo)
                    ]
                    # print(the_premium)
                    if not the_premium:
                        continue
                        # premium = premium_calculator.get_premium_mp(currency_pair=currency_pair, market_hi=market_hi,
                        #                                             market_lo=market_lo)
                    else:
                        premium = the_premium[0]
                    # print(premium)
                except BaseException as err:
                    logging.warning('Get premium failed. %s' % str(err))
                    continue
                if float(premium['premium']) > float(threshold):
                    logging.warning(
                        'Premium (%s, threshold: %s) is good for reversed arbitrage.'
                        % (premium, threshold))
                    logging.warning('Sending arbitrage order to trader: %s' %
                                    str(premium))
                    try:
                        status = arbitrage_trader. \
                            ArbitrageTrader(currency_pair, premium['market_hi'],
                                            premium['market_lo'], premium['premium'], premium_threshold=threshold). \
                            arbitrage(is_reversed=True)
                        logging.warning(
                            'Arbitrage order (reversed) finished. Status: %s' %
                            status)
                        break
                    except BaseException as err:
                        if any([
                                err_ignore_message in str(err)
                                for err_ignore_message in
                                config_trader.err_ignore_messages
                        ]):
                            logging.warning(
                                'Arbitrage (reversed) execution error: %s' %
                                err)
                        elif any([
                                err_wait_message in str(err)
                                for err_wait_message in
                                config_trader.err_wait_messages
                        ]):
                            logging.warning('Error of exchange: %s' % str(err))
                            logging.warning('Sleep for 30 seconds.')
                            time.sleep(30)
                        else:
                            email_client.EmailClient().notify_me_by_email(
                                title=
                                'Arbitrage (reversed) Execution of %s Error: %s'
                                % (premium, err),
                                content='Please handle exception.')
                else:
                    logging.info(
                        'Premium (%s) is not high enough (%s) for reversed arbitrage.'
                        % (premium['premium'], threshold))
        else:
            logging.warning('No need to balance coins.')
def trade(balancer_type='soft'):

    res = ''

    logging.warning('\n\n')
    logging.warning(' ' * 0 + '#####     Trader started.     #####')

    # monitor premiums
    logging.warning('=====     Premium monitor    =====')

    try:
        premiums = premium_calculator.get_premiums_async()
    except BaseException as err:
        logging.warning('Get Premium failed. %s' % str(err))
        return

    logging.warning('Current premiums (highest 3): ')
    count = 0
    for premium in premiums:
        if count >= 3:
            break
        premium_threshold = config_trader.premium_threshold
        logging.warning(str(premium) + ' (threshold: ' + premium_threshold + ')')
        count += 1

    # time.sleep(1.0)

    logging.warning('=====     Coin Balancer      =====')
    try:
        coin_balancer.CoinBalancer().balance_balances(premiums)
    except BaseException as err:
        logging.warning('Exception in coin balancer (soft): %s' % str(err))
        if '_handle_timeout' in err or \
           'Error in get_balances.' in err:
            pass
        else:
            email_client.EmailClient().notify_me_by_email(title='Error in coin balancer: %s' % str(err))

    logging.warning('=====      Trader      =====')

    # filter premium that is higher than threshold
    filtered_premiums = []  # each element is a dict containing currency_pair, premium, market_hi and market_lo.
    for premium in premiums:
        premium_threshold = config_trader.premium_threshold
        if float(premium['premium']) > float(premium_threshold):
            filtered_premiums.append(premium)

    # sort premium
    filtered_premiums.sort(key=lambda x: float(x['premium']), reverse=True)
    logging.warning('Qualified premiums: %s' % filtered_premiums)

    # execute premium from the highest one, if success then return, else continue on the next one
    for premium in filtered_premiums:

        currency_pair = premium['currency_pair']
        if currency_pair in delay_list and delay_list[currency_pair] > time.time():
            content = 'Currency pair %s in delay list. Release time: %.0f seconds.' % \
                      (currency_pair, delay_list[currency_pair] - time.time())
            logging.warning(content)
            # email_client.EmailClient().notify_me_by_email(title=content)
            continue

        logging.warning('Sending arbitrage order to trader: %s' % str(premium))
        try:
            status = arbitrage_trader.ArbitrageTrader(premium['currency_pair'], premium['market_hi'],
                                                      premium['market_lo'], premium['premium']).arbitrage()
            logging.warning('Arbitrage order finished. Status: %s' % status)

            if 'Negative profit' in status:
                logging.warning('Negative profit in currency pair %s! ' % currency_pair)
                email_client.EmailClient().notify_me_by_email(title='Abnormal profit in currency pair %s.' %
                                                                    currency_pair)
                res = currency_pair
            break

        except BaseException as err:
            # raise err
            if any([err_ignore_message in str(err) for err_ignore_message in config_trader.err_ignore_messages]):
                logging.warning('Execution error: %s' % str(err))
            elif any([err_wait_message in str(err) for err_wait_message in config_trader.err_wait_messages]):
                logging.warning('Error of exchange: %s' % str(err))
                logging.warning('Sleep for 30 seconds.')
                time.sleep(30)
            else:
                email_client.EmailClient().notify_me_by_email(title='Arbitrage Execution of %s Error: %s' %
                                                              (premium, str(err)), content='Please handle exception.')

    logging.warning(' ' * 0 + '#####     Trader ended.       #####')

    return res
                logging.warning('Error of exchange: %s' % str(err))
                logging.warning('Sleep for 30 seconds.')
                time.sleep(30)
            else:
                email_client.EmailClient().notify_me_by_email(title='Arbitrage Execution of %s Error: %s' %
                                                              (premium, str(err)), content='Please handle exception.')

    logging.warning(' ' * 0 + '#####     Trader ended.       #####')

    return res

if __name__ == '__main__':

    delay_list = dict()

    # coin_balancer_hard.CoinBalancer().execute_coin_balance(even=True)

    while 1:
        try:
            logging.warning('')
            logging.warning('Delay list: %s', str(delay_list))
            err_pair = trade()
            delay_list[err_pair] = time.time() + 60 * float(config_trader.delay)
        except BaseException as e:
            # raise e
            logging.warning('Error occurred in manager: %s' % e)
            email_client.EmailClient().notify_me_by_email(title='Error in arbitrage manager: %s' % e,
                                                          content='Please handle it manually.')

        # time.sleep(10)