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 calculate_allocation(): mon = assets_monitor.AssetsMonitor() balance = mon.get_assets() # logging.warning(balance) balance = mon.cal_usdt_equivalent(balance) logging.warning(balance) total_portion = sum(map(lambda x: float(x), config_coin.currency_ratio.values())) # logging.warning(total_portion) amount_per_portion = float(balance['usdt_equ']) / total_portion # logging.warning(amount_per_portion) prices = unified_client.UnifiedClient(config_trader.market_fetch_ticker).get_tickers() # logging.warning(prices) allocation = {} for currency in config_coin.currency_list['standard']: if currency != 'USDT': pair = currency.upper() + '/USDT' allocation[currency] = float(amount_per_portion * float(config_coin.currency_ratio[currency])) \ / float(prices[pair]) else: allocation[currency] = float(amount_per_portion * float(config_coin.currency_ratio[currency])) allocation[currency] = '%.8f' % allocation[currency] # logging.warning(allocation) return allocation
def balance_balances(): balances = assets_monitor.AssetsMonitor().get_balances_mp( include_frozen=False) logging.warning('Current balances:') for market in balances: logging.warning(market + ': \t' + ''.join( [(currency + ': ' + balances[market][currency] + '\t') for currency in config_coin.currency_list['standard']])) for currency in config_coin.currency_list['standard']: # logging.warning('Checking %s.' % currency) min_balance = None min_market = None max_balance = None max_market = None for market in config_trader.market_list: balance = balances[market][currency] if not min_balance or float(balance) < float(min_balance): min_balance = balance min_market = market if not max_balance or float(balance) > float(max_balance): max_balance = balance max_market = market if min_market == max_market: logging.warning('Caution: min_market == max_market.') break low_level = config_coin.low_level[currency] if float(min_balance) < float(low_level): logging.warning( '%s balance (%s) in %s market is below low level (%s), needs transfer.' % (currency, min_balance, min_market, low_level)) amount = '%.2f' % ((float(max_balance) - float(low_level)) * float(config_coin.transfer_ratio)) logging.warning('Transfer amount: %s' % amount) if float(amount) < float(config_coin.min_transfer[currency]): logging.warning('Amount smaller than min amount (%s).' % config_coin.min_transfer[currency]) else: status = coin_transfer.CoinTransfer().transfer( max_market, min_market, currency=currency, amount=amount) logging.warning( 'Transferred %s %s from %s to %s, status: %s' % (amount, currency, max_market, min_market, status)) else: logging.warning('No need to transfer %s.' % currency)
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 calculate_amount_to_allocation(ratio=False): mon = assets_monitor.AssetsMonitor() balance = mon.get_assets() allocation = calculate_allocation() res = {} for currency in config_coin.currency_list['standard']: res[currency] = '%.8f' % (float(allocation[currency]) - float(balance[currency])) if not ratio else \ '%.8f' % (float(balance[currency]) / float(allocation[currency])) logging.warning(res) return res
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.')
mon = assets_monitor.AssetsMonitor() balance = mon.get_assets() allocation = calculate_allocation() res = {} for currency in config_coin.currency_list['standard']: res[currency] = '%.8f' % (float(allocation[currency]) - float(balance[currency])) if not ratio else \ '%.8f' % (float(balance[currency]) / float(allocation[currency])) logging.warning(res) return res if __name__ == '__main__': pass logging.warning('Allocation:') calculate_even_level() logging.warning('Amount to allocation:') calculate_amount_to_allocation() logging.warning('Ratio to allocation:') calculate_amount_to_allocation(ratio=True) logging.warning('Balances:') a = assets_monitor.AssetsMonitor() a.print_assets(a.get_balances_async()) print(a.cal_usdt_equivalent(a.get_balance('huobipro'))) print(a.cal_usdt_equivalent(a.get_balance('poloniex'))) print(a.cal_usdt_equivalent(a.get_balance('okex')))
def arbitrage(self, base_currency_trade_amount='', amount_margin=''): if not amount_margin: amount_margin = '0.03' # set margin to make sure enough balance if not base_currency_trade_amount: base_currency_trade_amount = config_trader.get_trade_size( self.base_currency) # record balance, check balance, execute arbitrage, calculate profit, report, record. logging.warning('=' * 50 + ' S T A R T ' + '=' * 50) logging.warning('Executing positive premium arbitrage:') # Phase 1: record balances logging.warning('Phase 1: Record balances:') balances_old = assets_monitor.AssetsMonitor().get_balances_mp() logging.warning('Current balances (before arbitrage): %s' % balances_old) # Phase 2: check balances and verify premium logging.warning('Phase 2: Get balances and verify trade amount:') logging.warning('%s trade amount: %s' % (self.currency_pair, base_currency_trade_amount)) logging.warning('Current %s balance in %s: %s' % (self.base_currency, self.market_hi, balances_old[self.market_hi][self.base_currency])) logging.warning('Current %s balance in %s: %s' % (self.quote_currency, self.market_lo, balances_old[self.market_lo][self.quote_currency])) base_currency_affordable_amount = '%.8f' % \ (float(balances_old[self.market_lo][self.quote_currency]) / float(premium_calculator.get_price_in_size( market=self.market_lo, currency_pair=self.currency_pair)['ask']) ) logging.warning('Affordable %s amount in %s: %s' % (self.base_currency, self.market_lo, base_currency_affordable_amount)) base_currency_max_amount = min( float(balances_old[self.market_hi][self.base_currency]), float(base_currency_affordable_amount)) logging.warning('Maximum %s trade amount: %.4f ' % (self.base_currency, base_currency_max_amount)) if float(base_currency_trade_amount) < base_currency_max_amount * ( 1 - float(amount_margin)): logging.warning('Balance verification: PASS!') else: logging.warning('Not enough balance to trade!') raise BaseException('Execution status: Insufficient Fund!') # Verify premium, if not over threshold, halt execution. logging.warning('Verifying premium.') try: premium = premium_calculator.get_premium_mp( currency_pair=self.currency_pair)['premium'] except BaseException as err: logging.warning('Getting premium failed. Error: %s' % err) return '' threshold = self.premium_threshold if float(premium) < float(threshold): logging.warning( 'Premium (%s) below threshold (%s). Halt execution.' % (premium, threshold)) raise BaseException( 'Premium (%s) below threshold (%s). Execution halted.' % (premium, threshold)) # Phase 3: Sell in market_hi and buy in market_lo logging.warning('Phase 3: Sell %s in %s and buy %s in %s' % (self.base_currency, self.market_hi, self.base_currency, self.market_lo)) pool = Pool() logging.warning( 'Selling %s in %s: amount = %s' % (self.base_currency, self.market_hi, base_currency_trade_amount)) pool.apply_async(trade_operator.trade_operator, args=(self.market_hi, self.currency_pair, 'sell', base_currency_trade_amount)) # trade_operator.trade_operator(self.market_hi, self.currency_pair, 'sell', base_currency_trade_amount) logging.warning( 'Buying %s in %s: amount = %s' % (self.base_currency, self.market_lo, base_currency_trade_amount)) pool.apply_async(trade_operator.trade_operator, args=(self.market_lo, self.currency_pair, 'buy', base_currency_trade_amount)) # trade_operator.trade_operator(self.market_lo, self.currency_pair, 'buy', base_currency_trade_amount) pool.close() pool.join() logging.warning('Arbitrage successfully proceeded! %s amount = %s' % (self.base_currency, base_currency_trade_amount)) # Phase 4: Report logging.warning('Phase 4: Report') logging.warning('Getting balances:') balances_new = assets_monitor.AssetsMonitor().get_balances_mp() logging.warning('Current balances (after arbitrage): %s' % balances_new) # profit report trade_report.profit_report(balances_old, balances_new, self.premium_report, self.premium_threshold, self.market_hi + '/' + self.market_lo, self.currency_pair, base_currency_trade_amount) logging.warning('=' * 50 + ' E N D ' + '=' * 50) return 'Arbitrage trader finished execution.'
file_exists = os.path.isfile(FILENAME) with open(FILENAME, 'a' if file_exists else 'w') as csvfile: fieldnames = result.keys() writer = csv.DictWriter(csvfile, fieldnames=fieldnames) if not file_exists: writer.writeheader() writer.writerow(result) logging.warning('Trading result Saved.') except BaseException as e: logging.warning('Error occurred when saving trading result: %s' % e) if __name__ == '__main__': pass from aux import assets_monitor FILENAME = '../log/trade_record.csv' save_trading_result(pair='Test Pair', market='Test Market', premium_report='0.02', premium_threshold='0.12', trade_amount='2.00', profit='21.39', assets=assets_monitor.AssetsMonitor().get_assets())