Example #1
0
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.DistanceFromTarget >= indexInfo.BalanceThreshold:
                        coinsAboveThreshold[indexedCoin.Ticker] = indexedCoin.DistanceFromTarget
                    elif abs(indexedCoin.DistanceFromTarget) >= indexInfo.BalanceThreshold:
                        coinsEligibleForIncrease[indexedCoin.Ticker] = indexedCoin.DistanceFromTarget

                # 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, percentage_btc_amount, app)
                
    except Exception as e:
        logger.exception(e)
Example #2
0
def supported_coins_task():
    em = ExchangeManager()
    marketData = em.get_tickers()
    btcUsdValue = em.get_btc_usd_value()
    supportedCoins = em.get_supported_pairs(marketData)

    logger.debug("Starting Coins Update Task")

    # First We Update our Supported Market List

    for key in supportedCoins:

        sliced_pair = ''
        if key != 'BTC/USDT':
            sliced_pair = key[:-4]
        else:
            sliced_pair = 'BTC'

        DatabaseManager.create_supported_coin_model(sliced_pair)

        btcTickerVal = 0.0
        usdTickerVal = 0.0

        if key != 'BTC/USDT':
            btcTickerVal = marketData[key]['info']['Ask']
            usdTickerVal = btcUsdValue * btcTickerVal
        else:
            btcTickerVal = 0.0
            usdTickerVal = marketData[key]['info']['Ask']

        if DatabaseManager.create_ticker_model(key, round(btcTickerVal, 8),
                                               round(usdTickerVal, 8),
                                               datetime.datetime.now()):

            #logger.debug("Created Ticker Model - " + key)
            pass
        else:

            if DatabaseManager.update_ticker_model(key, round(btcTickerVal, 8),
                                                   round(usdTickerVal, 8),
                                                   datetime.datetime.now()):
                #logger.debug("Updated Ticker Model - " + key)
                pass
            else:
                logger.error("Failed To Update Ticker Model - " + key)

    logger.info("Coins Update Task Completed")
Example #3
0
class BalanceManager:

    em = ExchangeManager()

    def rebalance_coins(self, coins_above_threshold, coins_below_threshold,
                        celery_app):
        """Sell off coins over threshold. Buy coins below threshold."""
        for over in coins_above_threshold:
            logger.debug("handling %s", over)
            self.handle_coin(over, True, celery_app)
        for under in coins_below_threshold:
            logger.debug("handling %s", under)
            self.handle_coin(under, False, celery_app)

    def handle_coin(self, coin, is_over, celery_app):
        """Handle re-balancing an individual coin."""
        if DatabaseManager.get_coin_lock_model(
                coin) is None and DatabaseManager.get_wallet_trade_lock_model(
                    coin) is None:
            if not coin == "BTC":
                if not self.em.market_active(coin, "BTC"):
                    logger.error("Market for %s/BTC offline", coin)
                    return

            amount = self.calculate_amount(coin, is_over)

            if amount is None:
                return

            if not coin == "BTC":
                self.handle_trade(coin, amount, is_over, celery_app)

        else:
            logger.warning("Coin %s is locked and cannot be traded", coin)

    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 handle_trade(self, coin, amount, is_over, celery_app):
        """Send the appropriate celery message based on buy/sell."""

        string_ticker = coin
        if coin == "BTC":
            string_ticker += "/USDT"
        else:
            string_ticker += "/BTC"
        if self.em.check_min_buy(amount, string_ticker):

            ticker = self.em.get_ticker(string_ticker)
            single_coin_cost = ticker["last"]
            num_coins = round(amount / single_coin_cost, 8)

            DatabaseManager.create_coin_lock_model(coin)
            DatabaseManager.create_wallet_trade_lock_model(coin)

            if is_over is True:
                logger.debug("selling %s", coin)
                celery_app.send_task('Tasks.perform_sell_task',
                                     args=[coin.upper(), num_coins])
            else:
                logger.debug("buying %s", coin)
                celery_app.send_task('Tasks.perform_buy_task',
                                     args=[coin.upper(), num_coins])
        else:
            logger.debug("purchase %s does not meet market minimum")
Example #4
0
from Util import *
from Tasks import *

from managers.DatabaseManager import *
from managers.ExchangeManager import ExchangeManager
from managers.ShowCommandManager import ShowCommandManager
from managers.IndexCommandManager import IndexCommandManager
from managers.DebugCommandManager import DebugCommandManager

from models.TickerModel import TickerModel
from models.IndexInfoModel import IndexInfoModel
from models.IndexedCoinModel import IndexedCoinModel
from models.CoinBalanceModel import CoinBalanceModel
from models.SupportedCoinModel import SupportedCoinModel

em = ExchangeManager()
scm = ShowCommandManager()
icm = IndexCommandManager()
dcm = DebugCommandManager()

class ConDex(cmd.Cmd):
    """Simple command processor example."""

    prompt = 'ConDex> '
    intro = '''                                                                             
               ,----..            ,--.                                       
  ,----..     /   /   \         ,--.'|    ,---,        ,---,. ,--,     ,--,  
 /   /   \   /   .     :    ,--,:  : |  .'  .' `\    ,'  .' | |'. \   / .`|  
|   :     : .   /   ;.  \,`--.'`|  ' :,---.'     \ ,---.'   | ; \ `\ /' / ;  
.   |  ;. /.   ;   /  ` ;|   :  :  | ||   |  .`\  ||   |   .' `. \  /  / .'  
.   ; /--` ;   |  ; \ ; |:   |   \ | ::   : |  '  |:   :  |-,  \  \/  / ./   
Example #5
0
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")
Example #6
0
def perform_buy_task(elgibleTicker, elgibleBuyAmount):

    coinBuyIncomplete = True
    coinBuyRetryCount = 0

    buyOrderUUID = ""

    indexInfo = DatabaseManager.get_index_info_model()

    retryLimit = indexInfo.OrderRetryAmount

    elgibleCoinTicker = DatabaseManager.get_ticker_model(elgibleTicker +
                                                         "/BTC")

    em = ExchangeManager()

    partial_fill_amount = 0
    partial_filled = False

    DatabaseManager.create_coin_lock_model(elgibleTicker)

    while coinBuyIncomplete:

        if coinBuyRetryCount >= retryLimit:
            coinBuyIncomplete = False
            logger.info("Buying of coin " + rebalanceTicker +
                        " failed after " + str(coinBuyRetryCount) +
                        " attempts")
            break
            # Cancel Order
        else:

            if CondexConfig.DEBUG == True:
                logger.debug("Putting in buy order")
            else:
                logger.info("Buying " + str(elgibleBuyAmount) + " of " +
                            elgibleTicker + " at " +
                            str(elgibleCoinTicker.BTCVal))
                buyOrderUUID = em.create_buy_order(
                    elgibleTicker, elgibleBuyAmount,
                    elgibleCoinTicker.BTCVal)['id']
                time.sleep(60 * indexInfo.OrderTimeout)

            # Check order succeded through
            if CondexConfig.DEBUG == True:
                logger.debug("Fetching order")
                coinBuyIncomplete = False
            else:

                order_result = em.fetch_order(buyOrderUUID)
                order_filled_amount = order_result['filled']

                if order_result['status'] == "closed":
                    logger.info("Bought coin " + elgibleTicker + " for " +
                                str(order_result['price']))
                    coinBuyIncomplete = False

                elif (
                        order_filled_amount * elgibleCoinTicker.BTCVal
                ) > CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT and order_result[
                        'status'] == "open":
                    em.cancel_order(buyOrderUUID)
                    logger.debug("Bought partial of coin " +
                                 elgibleCoinTicker + " for " +
                                 str(order_result['price']))
                    coinBuyIncomplete = False

                else:
                    coinBuyRetryCount = coinBuyRetryCount + 1
                    if CondexConfig.DEBUG == True:
                        logger.debug("Canceling buy order")
                    else:
                        try:
                            em.cancel_order(buyOrderUUID)
                        except:
                            coinBuyIncomplete = False
                            pass  # order failed to cancel got filled previously
                        logger.debug("Buy Order Timeout Reached")
                    time.sleep(10)  #Magic Number

    # Delete the locks
    if CondexConfig.DEBUG != True:
        DatabaseManager.delete_coin_lock_model(elgibleTicker)
Example #7
0
def perform_rebalance_task(rebalanceTicker, rebalanceSellAmount, elgibleTicker,
                           elgibleBuyAmount):

    coinSellIncomplete = True
    coinBuyIncomplete = True
    coinSellRetryCount = 0
    coinBuyRetryCount = 0
    coinSellFailed = False

    sellOrderUUID = ""
    buyOrderUUID = ""

    indexInfo = DatabaseManager.get_index_info_model()

    retryLimit = indexInfo.OrderRetryAmount

    rebalanceTickerGainModel = DatabaseManager.get_realized_gain_model(
        rebalanceTicker)
    elgibleCoinTicker = DatabaseManager.get_ticker_model(elgibleTicker +
                                                         "/BTC")

    em = ExchangeManager()

    partial_fill_amount = 0
    partial_filled = False

    if rebalanceTicker != "BTC" and rebalanceTicker != "btc":

        while coinSellIncomplete:

            if coinSellRetryCount >= retryLimit:
                coinSellFailed = True
                coinSellIncomplete = False
                break
                # Cancel Order
            else:

                rebalanceCoinTicker = DatabaseManager.get_ticker_model(
                    rebalanceTicker + "/BTC")

                if CondexConfig.DEBUG == True:
                    logger.info("Placing Sell Order For " + rebalanceTicker +
                                "/BTC")
                else:
                    logger.info("Selling " + str(rebalanceSellAmount) +
                                " of " + rebalanceTicker + " at " +
                                str(rebalanceCoinTicker.BTCVal))
                    sellOrderUUID = em.create_sell_order(
                        rebalanceTicker, rebalanceSellAmount,
                        rebalanceCoinTicker.BTCVal)['id']
                    time.sleep(60 * indexInfo.OrderTimeout)

                # Check order succeded through
                if CondexConfig.DEBUG == True:
                    logger.debug("Fetching order")
                    coinSellIncomplete = False
                else:

                    order_result = em.fetch_order(sellOrderUUID)
                    order_filled_amount = order_result['filled']

                    if order_result['status'] == "closed":
                        logger.debug("Sold coin " + rebalanceTicker + " for " +
                                     str(order_result['price']))
                        coinSellIncomplete = False
                        DatabaseManager.update_realized_gain_model(
                            rebalanceTicker,
                            rebalanceTickerGainModel.RealizedGain +
                            ((order_filled_amount * rebalanceCoinTicker.BTCVal)
                             / indexInfo.TotalBTCVal) * 100)
                    elif (
                            order_filled_amount * rebalanceCoinTicker.BTCVal
                    ) > CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT and order_result[
                            'status'] == "open":
                        em.cancel_order(sellOrderUUID)
                        logger.debug("Sold partial of coin " +
                                     rebalanceTicker + " for " +
                                     str(order_result['price']))
                        coinSellIncomplete = False
                        partial_filled = True
                        partial_fill_amount = order_filled_amount * rebalanceCoinTicker.BTCVal
                        DatabaseManager.update_realized_gain_model(
                            rebalanceTicker,
                            rebalanceTickerGainModel.RealizedGain +
                            ((order_filled_amount * rebalanceCoinTicker.BTCVal)
                             / indexInfo.TotalBTCVal) * 100)
                    else:
                        coinSellRetryCount = coinSellRetryCount + 1
                        if CondexConfig.DEBUG == True:
                            logger.debug("Canceling sell order")
                        else:
                            em.cancel_order(sellOrderUUID)
                            logger.debug("Sell Order Timeout Reached")
                        time.sleep(10)  #Magic Number

    if coinSellFailed:
        logger.info("Sell of coin " + rebalanceTicker + " failed after " +
                    str(coinSellRetryCount) + " attempts")

    else:
        while coinBuyIncomplete:

            if coinBuyRetryCount >= retryLimit:
                coinBuyIncomplete = False
                logger.info("Buying of coin " + rebalanceTicker +
                            " failed after " + str(coinBuyRetryCount) +
                            " attempts")
                break
                # Cancel Order
            else:

                if CondexConfig.DEBUG == True:
                    logger.debug("Putting in buy order")
                else:
                    logger.info("Buying " + str(elgibleBuyAmount) + " of " +
                                elgibleTicker + " at " +
                                str(elgibleCoinTicker.BTCVal))
                    if partial_filled == True:
                        buyOrderUUID = em.create_buy_order(
                            elgibleTicker,
                            partial_fill_amount / elgibleCoinTicker.BTCVal,
                            elgibleCoinTicker.BTCVal)['id']
                    else:
                        buyOrderUUID = em.create_buy_order(
                            elgibleTicker, elgibleBuyAmount,
                            elgibleCoinTicker.BTCVal)['id']
                    time.sleep(60 * indexInfo.OrderTimeout)

                # Check order succeded through
                if CondexConfig.DEBUG == True:
                    logger.debug("Fetching order")
                    coinBuyIncomplete = False
                else:

                    order_result = em.fetch_order(buyOrderUUID)
                    order_filled_amount = order_result['filled']

                    if order_result['status'] == "closed":
                        logger.info("Bought coin " + elgibleTicker + " for " +
                                    str(order_result['price']))
                        coinBuyIncomplete = False

                        if rebalanceTicker == "BTC" or rebalanceTicker == "btc":
                            DatabaseManager.update_realized_gain_model(
                                rebalanceTicker,
                                rebalanceTickerGainModel.RealizedGain +
                                ((order_filled_amount *
                                  elgibleCoinTicker.BTCVal) /
                                 indexInfo.TotalBTCVal) * 100)

                    elif (
                            order_filled_amount * elgibleCoinTicker.BTCVal
                    ) > CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT and order_result[
                            'status'] == "open":
                        em.cancel_order(buyOrderUUID)
                        logger.debug("Bought partial of coin " +
                                     elgibleCoinTicker + " for " +
                                     str(order_result['price']))
                        coinBuyIncomplete = False

                        if rebalanceTicker == "BTC" or rebalanceTicker == "btc":
                            DatabaseManager.update_realized_gain_model(
                                rebalanceTicker,
                                rebalanceTickerGainModel.RealizedGain +
                                ((order_filled_amount *
                                  elgibleCoinTicker.BTCVal) /
                                 indexInfo.TotalBTCVal) * 100)

                    else:
                        coinBuyRetryCount = coinBuyRetryCount + 1
                        if CondexConfig.DEBUG == True:
                            logger.debug("Canceling buy order")
                        else:
                            try:
                                em.cancel_order(buyOrderUUID)
                            except:
                                coinBuyIncomplete = False
                                pass  # order failed to cancel got filled previously
                            logger.debug("Buy Order Timeout Reached")
                        time.sleep(10)  #Magic Number

    # Delete the locks
    if CondexConfig.DEBUG != True:
        DatabaseManager.delete_coin_lock_model(rebalanceTicker)
        DatabaseManager.delete_coin_lock_model(elgibleTicker)
Example #8
0
class BalanceManager:
    """Class to handle dealing with index balances."""

    em = ExchangeManager()

    def rebalance_coins(self, coins_above_threshold, coins_below_threshold,
                        percentage_btc_amount, celery_app):
        """Rebalance the index coins based on percentage from goal."""
        if self.check_coins(coins_above_threshold, coins_below_threshold):
            for coin_above_threshold in coins_above_threshold:

                for coin_below_threshold in coins_below_threshold:

                    if self.check_locks(coin_above_threshold,
                                        coin_below_threshold):
                        self.handle_coin(coin_above_threshold,
                                         coin_below_threshold,
                                         percentage_btc_amount, celery_app)

    def check_coins(self, coins_above_threshold, coins_below_threshold):
        """Make sure there are both coins to sell and coins to buy."""
        if len(coins_above_threshold) >= 1:
            logger.debug("Currently %s avalible for rebalance",
                         len(coins_above_threshold))
            logger.debug(coins_above_threshold)

            if len(coins_below_threshold) >= 1:
                logger.debug("Currently %s  elgible for increase",
                             len(coins_below_threshold))
                logger.debug(coins_below_threshold)
                return True
            else:
                logger.debug("No coins eligible for increase")
        else:
            logger.debug("No coins above threshold")

        return False

    def check_locks(self, coin_above_threshold, coin_below_threshold):
        """Check the coins to make sure neither are currently locked."""
        logger.debug("Checking locks for %s and %s", coin_above_threshold,
                     coin_below_threshold)
        if DatabaseManager.get_coin_lock_model(
                coin_above_threshold) is not None:
            logger.debug("Current Avalible Coin Is Locked - %s",
                         coin_above_threshold)
            return False

        if DatabaseManager.get_coin_lock_model(
                coin_below_threshold) is not None:
            logger.debug("Current Eligible Coin Is Locked - %s",
                         coin_below_threshold)
            return False

        return True

    def check_markets(self, coin_above_threshold, coin_below_threshold):
        """Check the markets and make sure neither are unavailable."""
        logger.debug("Checking markets for %s and %s ", coin_above_threshold,
                     coin_below_threshold)
        market_one_online = False
        market_two_online = False

        if not coin_above_threshold == "BTC":

            if self.em.market_active(coin_above_threshold, "BTC"):
                market_one_online = True
        else:
            market_one_online = True

        if not coin_below_threshold == "BTC":

            if self.em.market_active(coin_below_threshold, "BTC"):
                market_two_online = True
        else:
            market_two_online = True

        if market_one_online and market_two_online:
            return True

        logger.warning("One of the market pairs were offline during rebalance")
        return False

    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 calculate_amounts(self, coin_above_threshold, coin_below_threshold,
                          percentage_btc_amount):
        """Calculate the amounts necessary to buy and sell."""
        rebalance_special_ticker = coin_above_threshold + "/BTC"

        if coin_above_threshold == "BTC":
            rebalance_special_ticker = "BTC/USDT"

        rebalance_coin_ticker_model = DatabaseManager.get_ticker_model(
            rebalance_special_ticker)
        eligible_coin_ticker_model = DatabaseManager.get_ticker_model(
            coin_below_threshold + "/BTC")

        amount_to_sell = 0.0
        amount_to_buy = 0.0
        if coin_above_threshold == "BTC":
            amount_to_sell = percentage_btc_amount
        else:
            btc_val = rebalance_coin_ticker_model.BTCVal
            if btc_val is not None and btc_val > 0:
                amount_to_sell = percentage_btc_amount / btc_val

        if coin_below_threshold == "BTC":
            amount_to_buy = percentage_btc_amount
        else:
            btc_val = eligible_coin_ticker_model.BTCVal
            if btc_val is not None and btc_val > 0:
                amount_to_buy = percentage_btc_amount / btc_val

        return {"rebalance": amount_to_sell, "eligible": amount_to_buy}
Example #9
0
def perform_sell_task(rebalanceTicker, rebalanceSellAmount):

    coinSellIncomplete = True
    coinSellRetryCount = 0
    sellOrderUUID = ""

    indexInfo = DatabaseManager.get_index_info_model()

    retryLimit = indexInfo.OrderRetryAmount

    eligibleCoinTicker = DatabaseManager.get_ticker_model(rebalanceTicker +
                                                          "/BTC")

    em = ExchangeManager()

    try:

        partial_fill_amount = 0
        partial_filled = False

        DatabaseManager.create_coin_lock_model(rebalanceTicker)

        while coinSellIncomplete:

            if coinSellRetryCount >= retryLimit:
                coinSellFailed = True
                coinSellIncomplete = False
                break
                # Cancel Order
            else:

                rebalanceCoinTicker = DatabaseManager.get_ticker_model(
                    rebalanceTicker + "/BTC")

                if CondexConfig.DEBUG == True:
                    logger.info("Placing Sell Order For " + rebalanceTicker +
                                "/BTC")
                else:
                    logger.info("Selling " + str(rebalanceSellAmount) +
                                " of " + rebalanceTicker + " at " +
                                str(rebalanceCoinTicker.BTCVal))
                    sellOrderUUID = em.create_sell_order(
                        rebalanceTicker, rebalanceSellAmount,
                        rebalanceCoinTicker.BTCVal)['id']
                    time.sleep(60 * indexInfo.OrderTimeout)

                # Check order succeded through
                if CondexConfig.DEBUG == True:
                    logger.debug("Fetching order")
                    coinSellIncomplete = False
                else:

                    order_result = em.fetch_order(sellOrderUUID)
                    order_filled_amount = order_result['filled']

                    if order_result['status'] == "closed":
                        logger.debug("Sold coin " + rebalanceTicker + " for " +
                                     str(order_result['price']))
                        coinSellIncomplete = False
                    elif (
                            order_filled_amount * rebalanceCoinTicker.BTCVal
                    ) > CondexConfig.BITTREX_MIN_BTC_TRADE_AMOUNT and order_result[
                            'status'] == "open":
                        em.cancel_order(sellOrderUUID)
                        logger.debug("Sold partial of coin " +
                                     rebalanceTicker + " for " +
                                     str(order_result['price']))
                        coinSellIncomplete = False
                        partial_filled = True
                        partial_fill_amount = order_filled_amount * rebalanceCoinTicker.BTCVal
                    else:
                        coinSellRetryCount = coinSellRetryCount + 1
                        if CondexConfig.DEBUG == True:
                            logger.debug("Canceling sell order")
                        else:
                            em.cancel_order(sellOrderUUID)
                            logger.debug("Sell Order Timeout Reached")
                        time.sleep(10)  #Magic Number
    except Exception as e:
        logger.exception(e)

    finally:
        if CondexConfig.DEBUG != True:
            DatabaseManager.delete_coin_lock_model(rebalanceTicker)
Example #10
0
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")