def handle_coin(self, coin_above_threshold, coin_below_threshold, percentage_btc_amount, celery_app): """Handle buying and selling these coins.""" logger.debug("Handling sell/buy for %s and %s", coin_above_threshold, coin_below_threshold) coin_balance = DatabaseManager.get_coin_balance_model( coin_above_threshold) amounts = self.calculate_amounts(coin_above_threshold, coin_below_threshold, percentage_btc_amount) amount_to_sell = amounts["rebalance"] amount_to_buy = amounts["eligible"] if coin_balance.TotalCoins >= amount_to_sell: if self.check_markets(coin_above_threshold, coin_below_threshold): DatabaseManager.create_coin_lock_model(coin_above_threshold) DatabaseManager.create_coin_lock_model(coin_below_threshold) logger.info("Performing Rebalance %s %s - %s %s", coin_above_threshold.upper(), amount_to_sell, coin_below_threshold.upper(), amount_to_buy) celery_app.send_task('Tasks.perform_rebalance_task', args=[ coin_above_threshold.upper(), amount_to_sell, coin_below_threshold.upper(), amount_to_buy ]) else: logger.error("Failed to sell coins - we do not have enough of %s", coin_above_threshold)
def perform_algo_task(): balanceManager = BalanceManager() coinsAboveThreshold = {} coinsEligibleForIncrease = {} em = ExchangeManager() indexInfo = DatabaseManager.get_index_info_model() try: if indexInfo.Active == True: percentage_btc_amount = indexInfo.TotalBTCVal * ( indexInfo.BalanceThreshold / 100) logger.debug("Percentage_to_btc_amount: " + str(percentage_btc_amount)) if percentage_btc_amount <= CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT: logger.debug("Current BTC Threshold Value To Low - " + str(percentage_btc_amount)) else: # Generate our winners/losers list for indexedCoin in DatabaseManager.get_all_index_coin_models(): if indexedCoin.Ticker != "BTC": coinBalance = DatabaseManager.get_coin_balance_model( indexedCoin.Ticker) coin_off_percent = indexedCoin.get_percent_from_coin_target( coinBalance, indexInfo.TotalBTCVal) if coin_off_percent >= indexInfo.BalanceThreshold: coinsAboveThreshold[ indexedCoin.Ticker] = coin_off_percent elif abs(coin_off_percent ) >= indexInfo.BalanceThreshold: coinsEligibleForIncrease[ indexedCoin.Ticker] = coin_off_percent # Sort our tables coinsAboveThreshold = Util.tuple_list_to_dict( sorted(coinsAboveThreshold.items(), key=lambda pair: pair[1], reverse=True)) coinsEligibleForIncrease = Util.tuple_list_to_dict( sorted(coinsEligibleForIncrease.items(), key=lambda pair: pair[1], reverse=True)) balanceManager.rebalance_coins(coinsAboveThreshold, coinsEligibleForIncrease, app) except Exception as e: logger.exception(e)
def calculate_amount(self, coin, is_over): """Figure out how much to buy/sell. Method should look up current value of each coin as trades fired previously could modify the balance. Includes minimum trade check. Returns None if amount doesn't meet trade threshold. """ index_info = DatabaseManager.get_index_info_model() coin_balance = DatabaseManager.get_coin_balance_model(coin) indexed_coin = DatabaseManager.get_index_coin_model(coin) amount = None off = indexed_coin.get_percent_from_coin_target( coin_balance, index_info.TotalBTCVal) logger.info( "coin off percentage is %s with current coin balance of %s", off, coin_balance.BTCBalance) if coin_balance.BTCBalance > 0: if is_over is True: logger.info( "Coin %s over threshold, calculating off percentage", coin) if off > 100: amount = round(coin_balance.BTCBalance * (1 / (off / 100)), 8) else: amount = round(coin_balance.BTCBalance * off / 100, 8) else: logger.info( "Coin %s under threshold, calculating off percentage", coin) amount = round( (coin_balance.BTCBalance / (1 - (abs(off) / 100))) - coin_balance.BTCBalance, 8) logger.info("Amount calculated as %s", amount) if amount == None or amount == 0: logger.info( "Zero amount detected for %s. Attemping to buy 2x the minimum order.", coin) pair_string = coin if pair_string == "BTC": pair_string += "/USDT" else: pair_string += "/BTC" min_buy = self.em.get_min_buy_btc(pair_string) if min_buy is not None: amount = round(min_buy * 2, 8) else: logger.info( "Zero amount of coin %s and market info cannot be found") amount = None if amount is not None: logger.info( "checking to see if amount %s is greater than trade threshold %s", amount, CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT) over_threshold = float(amount) >= float( CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT) if over_threshold is True: if is_over is False: logger.info("checking to see if %s is available in BTC", amount) balance_available = 0.0 btc_balance = DatabaseManager.get_coin_balance_model("BTC") btc_indexed_coin = DatabaseManager.get_index_coin_model( "BTC") btc_off = btc_indexed_coin.get_percent_from_coin_target( btc_balance, index_info.TotalBTCVal) if btc_off <= 0: return None balance_available = round( btc_balance.BTCBalance * (btc_off / 100), 8) logger.info("Available BTC balance %s", balance_available) if balance_available >= amount: return amount #See if 1x the threshold is available single_threshold_amount = round( amount / (index_info.BalanceThreshold / 100), 8) if not single_threshold_amount >= em.get_min_buy_btc( pair_string): single_threshold_amount = em.get_min_buy_btc( pair_string) * 2 if balance_available >= single_threshold_amount and float( single_threshold_amount) >= float( CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT): return single_threshold_amount else: amount = None logger.warning( "The amount to trade %s not available currently", amount) else: logger.info("selling %s %s to BTC/USDT", amount, coin) else: logger.warning("Coin %s amount %s not over trade threshold", coin, amount) amount = None return amount
def wallet_update_task(): em = ExchangeManager() walletData = em.get_balance() btcUsdValue = em.get_btc_usd_value() totalBtcValue = 0.0 logger.info("Starting Wallet Update Task") for key in DatabaseManager.get_all_supported_coin_models(): btcbalance = 0.0 usdBalance = 0.0 totalCoins = None fullTicker = key.Ticker + "/BTC" if key.Ticker == 'BTC': fullTicker = 'BTC/USDT' tickerModel = DatabaseManager.get_ticker_model(fullTicker) try: btcbalance = walletData[key.Ticker]['total'] * tickerModel.BTCVal totalCoins = walletData[key.Ticker]['total'] usdBalance = btcUsdValue * btcbalance except: btcbalance = 0.0 totalCoins = 0.0 if key.Ticker == 'BTC': btcbalance = walletData[key.Ticker]['total'] usdBalance = btcUsdValue * btcbalance indexedCoin = DatabaseManager.get_index_coin_model(key.Ticker) if indexedCoin is not None: totalBtcValue = totalBtcValue + btcbalance if DatabaseManager.create_coin_balance_model(key.Ticker, btcbalance, usdBalance, totalCoins, datetime.datetime.now()): #logger.debug("Created Coin Balance Model - " + key.Ticker) pass else: if DatabaseManager.update_coin_balance_model( key.Ticker, btcbalance, btcUsdValue * btcbalance, totalCoins, datetime.datetime.now()): #logger.debug("Updated Coin Balance Model - " + key.Ticker) pass else: logger.error("Failed Update Coin Balance Model - " + key.Ticker) totalUnrealizeGain = 0.0 totalRealizedGain = 0.0 for key in DatabaseManager.get_all_supported_coin_models(): coinBalance = DatabaseManager.get_coin_balance_model(key.Ticker) indexedCoin = DatabaseManager.get_index_coin_model(key.Ticker) realizedGainModel = DatabaseManager.get_realized_gain_model(key.Ticker) if indexedCoin is not None: if DatabaseManager.update_index_coin_model( indexedCoin.Ticker, indexedCoin.DesiredPercentage, (coinBalance.BTCBalance / totalBtcValue) * 100, ((coinBalance.BTCBalance / totalBtcValue) * 100) - indexedCoin.DesiredPercentage, indexedCoin.Locked): totalUnrealizeGain = totalUnrealizeGain + ( ((coinBalance.BTCBalance / totalBtcValue) * 100) - indexedCoin.DesiredPercentage) totalRealizedGain = totalRealizedGain + realizedGainModel.RealizedGain logger.debug("Total unrealized gain - " + str(totalUnrealizeGain)) logger.debug("Updated Indexed Coin Model - " + indexedCoin.Ticker) else: logger.error("Failed To Update Indexed Coin Model - " + indexedCoin.Ticker) indexInfo = DatabaseManager.get_index_info_model() totalUnrealizeGain = totalUnrealizeGain if DatabaseManager.update_index_info_model( indexInfo.Active, totalBtcValue, btcUsdValue * totalBtcValue, totalRealizedGain, totalUnrealizeGain, indexInfo.BalanceThreshold, indexInfo.OrderTimeout, indexInfo.OrderRetryAmount, indexInfo.RebalanceTickSetting): logger.debug("Updated Index Info Model") else: logger.error("Failed To Update Index Info Model") logger.info("Wallet Update Task Completed")
def perform_algo_task(): coinsAboveThreshold = {} coinsElgibleForIncrease = {} indexInfo = DatabaseManager.get_index_info_model() if indexInfo.Active == True: percentage_btc_amount = indexInfo.TotalBTCVal * ( indexInfo.BalanceThreshold / 100) logger.debug("Percentage_to_btc_amount: " + str(percentage_btc_amount)) if percentage_btc_amount <= CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT: logger.debug("Current BTC Threshold Value To Low - " + str(percentage_btc_amount)) else: # Generate our winners/lossers list for indexedCoin in DatabaseManager.get_all_index_coin_models(): if indexedCoin.UnrealizedGain >= indexInfo.BalanceThreshold: coinsAboveThreshold[ indexedCoin.Ticker] = indexedCoin.UnrealizedGain elif indexedCoin.UnrealizedGain <= indexInfo.BalanceThreshold: coinsElgibleForIncrease[ indexedCoin.Ticker] = indexedCoin.UnrealizedGain # Sort our tables coinsAboveThreshold = Util.tuple_list_to_dict( sorted(coinsAboveThreshold.iteritems(), key=lambda (k, v): (v, k), reverse=True)) coinsElgibleForIncrease = Util.tuple_list_to_dict( sorted(coinsElgibleForIncrease.iteritems(), key=lambda (k, v): (v, k), reverse=True)) if len(coinsAboveThreshold) >= 1: logger.debug("Currently " + str(len(coinsAboveThreshold)) + " avalible for rebalance") logger.debug(coinsAboveThreshold) if len(coinsElgibleForIncrease) >= 1: logger.debug("Currently " + str(len(coinsElgibleForIncrease)) + " elgible for increase") logger.debug(coinsElgibleForIncrease) for akey in coinsAboveThreshold: # Check to see if we still have coins to increase if len(coinsElgibleForIncrease) >= 1: elgibleCoinTicker = coinsElgibleForIncrease.keys( )[0] rebalanceCoinLocked = False elgibleCoinLocked = False if DatabaseManager.get_coin_lock_model(akey): rebalanceCoinLocked = True if DatabaseManager.get_coin_lock_model( elgibleCoinTicker): rebalanceCoinLocked = True if rebalanceCoinLocked == False and elgibleCoinLocked == False: indexCoinInfo = DatabaseManager.get_index_coin_model( akey) coinBalance = DatabaseManager.get_coin_balance_model( akey) rebalanceSpecialTicker = akey + "/BTC" if akey == "BTC": rebalanceSpecialTicker = "BTC/USDT" rebalanceCoinTickerModel = DatabaseManager.get_ticker_model( rebalanceSpecialTicker) elgibleCoinTickerModel = DatabaseManager.get_ticker_model( elgibleCoinTicker + "/BTC") amountOfRebalanceToSell = 0.0 if akey == "BTC": amountOfRebalanceToSell = percentage_btc_amount else: amountOfRebalanceToSell = percentage_btc_amount / rebalanceCoinTickerModel.BTCVal amountOfEligbleToBuy = percentage_btc_amount / elgibleCoinTickerModel.BTCVal if coinBalance.TotalCoins >= amountOfRebalanceToSell: DatabaseManager.create_coin_lock_model( akey) DatabaseManager.create_coin_lock_model( elgibleCoinTicker) logger.info("Performing Rebalance " + akey.upper() + " " + str(amountOfRebalanceToSell) + " - " + elgibleCoinTicker.upper() + " " + str(amountOfEligbleToBuy)) #perform_rebalance_task.s(akey.upper(), amountOfRebalanceToSell, elgibleCoinTicker.upper(), amountOfEligbleToBuy) app.send_task( 'Tasks.perform_rebalance_task', args=[ akey.upper(), amountOfRebalanceToSell, elgibleCoinTicker.upper(), amountOfEligbleToBuy ]) # Need to remove the eligbile coin from dictireonary del coinsElgibleForIncrease[ elgibleCoinTicker] else: logger.error( "Failed to sell coins - we do not have enough of " + str(akey)) else: logger.debug("One of the coins where locked") else: logger.debug("No coins eligible for increase") else: logger.debug("No coins above threshold")
def wallet_update_task(): em = ExchangeManager() walletData = em.get_balance() btcUsdValue = em.get_btc_usd_value() totalBtcValue = 0.0 logger.info("Starting Wallet Update Task") logger.debug("Checking Wallet Locks") walletLockDeleteList = [] # Clear up the wallet locks. for walletLockModel in DatabaseManager.get_all_wallet_trade_lock_models(): if DatabaseManager.get_coin_lock_model(walletLockModel.Ticker) == None: walletLockDeleteList.append(walletLockModel.Ticker) for walletLockTicker in walletLockDeleteList: DatabaseManager.delete_wallet_trade_lock_model(walletLockTicker) for key in DatabaseManager.get_all_supported_coin_models(): btcbalance = 0.0 usdBalance = 0.0 totalCoins = None tickerModel = get_ticker(key) try: btcbalance = walletData[key.Ticker]['total'] * tickerModel.BTCVal totalCoins = walletData[key.Ticker]['total'] usdBalance = btcUsdValue * btcbalance except: btcbalance = 0.0 totalCoins = 0.0 if key.Ticker == 'BTC': btcbalance = walletData[key.Ticker]['total'] usdBalance = btcUsdValue * btcbalance indexedCoin = DatabaseManager.get_index_coin_model(key.Ticker) if indexedCoin is not None: totalBtcValue = totalBtcValue + btcbalance if DatabaseManager.create_coin_balance_model(key.Ticker, btcbalance, usdBalance, totalCoins, datetime.datetime.now()): #logger.debug("Created Coin Balance Model - " + key.Ticker) pass else: if DatabaseManager.update_coin_balance_model( key.Ticker, btcbalance, btcUsdValue * btcbalance, totalCoins, datetime.datetime.now()): #logger.debug("Updated Coin Balance Model - " + key.Ticker) pass else: logger.error("Failed Update Coin Balance Model - " + key.Ticker) totalUnrealizedGain = 0.0 totalRealizedGain = 0.0 for key in DatabaseManager.get_all_supported_coin_models(): tickerModel = get_ticker(key) coinBalance = DatabaseManager.get_coin_balance_model(key.Ticker) indexedCoin = DatabaseManager.get_index_coin_model(key.Ticker) if indexedCoin is not None: if DatabaseManager.update_index_coin_model( indexedCoin.Ticker, indexedCoin.DesiredPercentage, indexedCoin.get_distance_from_target( coinBalance, totalBtcValue), indexedCoin.Locked): logger.debug("Updated Indexed Coin Model - " + indexedCoin.Ticker) else: logger.error("Failed To Update Indexed Coin Model - " + indexedCoin.Ticker) indexInfo = DatabaseManager.get_index_info_model() if DatabaseManager.update_index_info_model(indexInfo.Active, totalBtcValue, btcUsdValue * totalBtcValue, indexInfo.BalanceThreshold, indexInfo.OrderTimeout, indexInfo.OrderRetryAmount, indexInfo.RebalanceTickSetting): logger.debug("Updated Index Info Model") else: logger.error("Failed To Update Index Info Model") logger.info("Wallet Update Task Completed")