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
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. #####')
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)
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)