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
async def get_price_in_size_async(market='', currency_pair='', size='', margin='0'): base_currency, quote_currency = currency_pair.split('/') if not size: size = config_trader.trade_size[base_currency] if margin != 0: size = '%.8f' % (float(size) * (1 + float(margin))) client = unified_client.UnifiedClient(market, True) try: res = await client.get_ticker_with_size_async( base_currency, quote_currency, base_currency_trade_size=size) except BaseException as err: return err res['market'] = market res['currency_pair'] = currency_pair return res
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 get_price_in_size(market='', currency_pair='', size='', margin='0'): """ Return avgPrice given size. :param market: 'huobipro', 'poloniex' :param currency_pair: string, standard currency pair format, e.g. 'ETH/BTC', refer to coin configuration :param size: string, default value is from trader configuration :param margin: string, default is 0, to add additional size (margin) :return: dict, {'bid': string, 'ask': string} """ base_currency, quote_currency = currency_pair.split('/') if not size: size = config_trader.get_trade_size(base_currency) if margin != 0: size = '%.8f' % (float(size) * (1 + float(margin))) return unified_client.UnifiedClient(market).get_ticker_with_size(base_currency, quote_currency, base_currency_trade_size=size)
def cal_profits(assets_old=None, assets_new=None, limited=True): res = {} for currency in assets_new: if not limited or currency in config_coin.currency_list['standard']: res[currency] = '%.8f' % (float(assets_new[currency]) - float(assets_old[currency])) prices = unified_client.UnifiedClient( config_trader.market_fetch_ticker).get_tickers() usdt_equ = 0 for currency in res: if currency != 'USDT': pair = currency.upper() + '/USDT' usdt_equ += float(res[currency]) * float(prices[pair]) else: usdt_equ += float(res[currency]) res['usdt_equ'] = '%.2f' % usdt_equ return res
def cal_usdt_equivalent(balance, limited=True): res = {} for currency in balance: if not limited or currency in config_coin.currency_list['standard']: res[currency] = '%.8f' % float(balance[currency]) prices = unified_client.UnifiedClient( config_trader.market_fetch_ticker).get_tickers() usdt_equ = 0 for currency in res: if float(res[currency]) > 0: if currency != 'USDT': pair = currency.upper() + '/USDT' usdt_equ += float(res[currency]) * float(prices[pair]) else: usdt_equ += float(res[currency]) res['usdt_equ'] = '%.2f' % usdt_equ return res
def arbitrage(self, base_currency_trade_amount='', amount_margin='', is_reversed=False): 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.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:') try: # balances_old = assets_monitor.AssetsMonitor().get_balances() balances_old = assets_monitor.AssetsMonitor().get_balances_async() except BaseException as err: logging.warning('Getting balances failed. Error: %s' % err) return 'Halted due to getting balances fail.' # 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_async(currency_pair=self.currency_pair, market_hi=self.market_hi, market_lo=self.market_lo)['premium'] except BaseException as err: logging.warning('Getting premium failed. Error: %s' % err) return 'Halted due to getting premium fail.' 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(2) logging.warning('Selling %s in %s: amount = %s' % (self.base_currency, self.market_hi, base_currency_trade_amount)) pool.apply_async(unified_client.UnifiedClient(self.market_hi).sell_coin, args=(self.base_currency, self.quote_currency, 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(unified_client.UnifiedClient(self.market_lo).buy_coin, args=(self.base_currency, self.quote_currency, 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() pool.terminate() 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() balances_new = assets_monitor.AssetsMonitor().get_balances_async() # logging.warning('Current balances (after arbitrage): %s' % balances_new) # profit report profit_usdt = 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, is_reversed) logging.warning('=' * 50 + ' E N D ' + '=' * 50) if not is_reversed and profit_usdt < 0.0: # error of premium, delay for some time return 'Arbitrage trader finished execution. Negative profit!' return 'Arbitrage trader finished execution.'
size='', margin='0', async=False): if async: return get_price_in_size_async(market, currency_pair, size, margin) base_currency, quote_currency = currency_pair.split('/') if not size: size = config_trader.trade_size[base_currency] if margin != 0: size = '%.8f' % (float(size) * (1 + float(margin))) return unified_client.UnifiedClient(market).get_ticker_with_size( base_currency, quote_currency, base_currency_trade_size=size) async def get_price_in_size_async(market='', currency_pair='', size='', margin='0'): base_currency, quote_currency = currency_pair.split('/') if not size: size = config_trader.trade_size[base_currency] if margin != 0: size = '%.8f' % (float(size) * (1 + float(margin)))
def get_balance(market='', include_frozen=True): res = unified_client.UnifiedClient(market).get_balances( all_currency=include_frozen) res['market'] = market return res
def save_trading_result(pair='N/A', market='N/A', premium_report='N/A', premium_threshold='N/A', trade_amount='N/A', profit='N/A', assets=None, profit_ratio_num=0.0, is_reversed=False): logging.warning('Save trading result...') currency_list = config_coin.currency_list['standard'] if not assets: assets = {} result = OrderedDict() try: result['time (GMT)'] = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) result['time (local)'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) result['time zone'] = time.strftime("%z", time.gmtime()) result['reversed'] = str(is_reversed) result['pair'] = pair result['market'] = market result['premium'] = premium_report result['threshold'] = premium_threshold result['amount'] = trade_amount result['profit'] = profit result['profit_ratio'] = '%.4f' % profit_ratio_num for currency in currency_list: result[ currency] = assets[currency] if currency in assets else 'N/A' try: prices = unified_client.UnifiedClient( config_trader.market_fetch_ticker).get_tickers() for currency in currency_list: result[currency + ' price in USDT'] = \ prices[currency + '/USDT'] \ if currency != 'USDT' else '1.00' if 'N/A' in [result[currency] for currency in currency_list]: result['total assets in USDT'] = 'N/A' result['total assets in BTC'] = 'N/A' else: result['total assets in USDT'] = '%.2f' % sum([ float(result[currency]) * float(result[currency + ' price in USDT']) for currency in currency_list ]) result['total assets in BTC'] = \ '%.4f' % (float(result['total assets in USDT']) / float(result['BTC price in USDT'])) except BaseException as e: logging.warning('Fetching prices failed: %s' % e) 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)