Exemplo n.º 1
0
class Bittrex:
    def __init__(self, key, secret):
        self.logger = Logger(__name__)

        try:
            self.client = Client(key, secret, api_version="v2.0")
        except Exception as e:
            self.logger.log(e)
            raise ExchangeException(self.__class__.__name__, e)

    def getBalances(self):
        try:
            result = self.client.get_balances()
            balances = {}

            if not result['success']:
                raise Exception(result['message'])

            for currency in result["result"]:
                name = currency["Currency"]["Currency"]
                value = currency["Balance"]["Balance"]

                if value >= Config.BALANCE_ZERO:
                    balances[name] = value

            return balances
        except Exception as e:
            self.logger.log(e)
            raise ExchangeException(self.__class__.__name__, e)
Exemplo n.º 2
0
class Bittrex:
    def __init__(self, key, secret):
        self.client = Client(key, secret)
        self.logger = Logger(__name__)

    def getBalances(self):
        try:
            result = self.client.get_balances()
            balances = {}

            if not result['success']:
                raise ExchangeException(self.__class__.__name__,
                                        result['message'])

            for currency in result["result"]:
                name = currency["Currency"].encode('utf-8').upper()
                value = currency["Balance"]

                if value > 0.0:
                    balances[name] = value

            return balances
        except Exception as e:
            self.logger.log(e)
            raise ExchangeException(self.__class__.__name__, e.message)
Exemplo n.º 3
0
def show_balances(bot, update):
    if update.message.chat_id in auth.masters_chat_idx:
        my_b = Bittrex(auth.api_key, auth.api_secret)
        balances = my_b.get_balances()
        for currency in balances['result']:
            if currency['Available'] > 0:
                curr = str(currency['Currency'])
                bal = str(currency['Available'])
                update.message.reply_text(curr + '  ' + bal)
    else:
        update.message.reply_text("Не хватает прав. Попробуй другую команду")
Exemplo n.º 4
0
class TestBittrexAccountAPI(unittest.TestCase):
    def setUp(self):
        self.bittrex = Bittrex()

    def test_get_balances(self):
        actual = self.bittrex.get_balances()
        test_basic_response(self, actual, 'get_balances')

    def test_get_balance(self):
        self.assertRaises(TypeError, self.bittrex.get_balance)
        actual = self.bittrex.get_balance('BTC')
        test_basic_response(self, actual, 'get_balance')
        invalid_actual = self.bittrex.get_balance('Invalid currency')
        test_failed_response(self, invalid_actual, 'get_balance')

    def test_get_deposit_address(self):
        self.assertRaises(TypeError, self.bittrex.get_deposit_address)
        actual = self.bittrex.get_deposit_address('BTC')
        test_basic_response(self, actual, 'get_deposit_address')
        invalid_actual = self.bittrex.get_deposit_address('Invalid currency')
        test_failed_response(self, invalid_actual, 'get_deposit_address')

    def test_withdraw(self):
        self.assertRaises(TypeError, self.bittrex.withdraw)

    def test_get_order(self):
        self.assertRaises(TypeError, self.bittrex.get_order)
        actual = self.bittrex.get_order('test')
        test_response_structure(self, actual, 'get_order')

    def test_get_order_history(self):
        actual = self.bittrex.get_order_history()
        test_basic_response(self, actual, 'get_order_history')
        actual = self.bittrex.get_order_history('BTC-LTC')
        test_basic_response(self, actual, 'get_order_history')

    def test_get_withdrawal_historyself(self):
        actual = self.bittrex.get_withdrawal_history()
        test_basic_response(self, actual, 'get_withdrawal_history')
        actual = self.bittrex.get_withdrawal_history('BTC')
        test_basic_response(self, actual, 'get_withdrawal_history')

    def test_get_deposit_history(self):
        actual = self.bittrex.get_deposit_history()
        test_basic_response(self, actual, 'get_deposit_history')
        actual = self.bittrex.get_deposit_history('BTC')
        test_basic_response(self, actual, 'get_deposit_history')
Exemplo n.º 5
0
    def getBalances(self):
        bittrex = Bittrex(api_key=self.key, api_secret=self.secret)
        resp = bittrex.get_balances()

        balance = dict()
        for entry in resp['result']:
            cur = entry['Currency']
            value = entry['Balance']

            if value == 0:
                continue

            if cur not in balance:
                balance[cur] = 0.0
            balance[cur] += value

        logging.debug(resp)

        return balance
Exemplo n.º 6
0
def my_bittrex():
    total = []
    my_b = Bittrex(auth.api_key, auth.api_secret)
    balances = my_b.get_balances()
    for currency in balances['result']:
        if currency['Available'] > 0:
            curr = str(currency['Currency'])
            if curr == 'BTC':
                bal = currency['Available'] - my_btc - foxy_btc
                btc = requests.get('https://api.coinmarketcap.com/v1/ticker/bitcoin/')
                output = btc.json()[0]['price_usd']
                usd = float(output)*bal*0.5
                rub_btc = usd_to_rub(usd)
                total.append(rub_btc)
            elif curr == 'ETH':
                bal = currency['Available'] - my_eth - foxy_eth
                ethereum = requests.get('https://api.coinmarketcap.com/v1/ticker/ethereum/')
                output = ethereum.json()[0]['price_usd']
                usd = float(output)*bal*0.5
                rub_eth = usd_to_rub(usd)
                total.append(rub_eth)
            elif curr == 'DCR':
                bal = currency['Available']
                decred = requests.get('https://api.coinmarketcap.com/v1/ticker/decred/')
                output = decred.json()[0]['price_usd']
                usd = float(output)*bal*0.5
                rub_decred = usd_to_rub(usd)
                total.append(rub_decred)

            elif curr == 'ZEC':
                bal = currency['Available']
                zcash = requests.get('https://api.coinmarketcap.com/v1/ticker/zcash/')
                output = zcash.json()[0]['price_usd']
                usd = float(output)*bal*0.5
                rub_zcash = usd_to_rub(usd)
                total.append(rub_zcash)

        else:
            pass
    


    return int(sum(total))
Exemplo n.º 7
0
class TestBittrexV20AccountAPI(unittest.TestCase):
    """
    Integration tests for the Bittrex Account API.
      * These will fail in the absence of an internet connection or if bittrex API goes down.
      * They require a valid API key and secret issued by Bittrex.
      * They also require the presence of a JSON file called secrets.json.
      It is structured as such:
    {
      "key": "12341253456345",
      "secret": "3345745634234534"
    }
    """
    def setUp(self):
        with open("secrets.json") as secrets_file:
            self.secrets = json.load(secrets_file)
            secrets_file.close()
        self.bittrex = Bittrex(self.secrets['key'],
                               self.secrets['secret'],
                               api_version=API_V2_0)

    def test_handles_invalid_key_or_secret(self):
        self.bittrex = Bittrex('invalidkey',
                               self.secrets['secret'],
                               api_version=API_V2_0)
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'Invalid key, valid secret')

        self.bittrex = Bittrex(None,
                               self.secrets['secret'],
                               api_version=API_V2_0)
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'None key, valid secret')

        self.bittrex = Bittrex(self.secrets['key'],
                               'invalidsecret',
                               api_version=API_V2_0)
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'valid key, invalid secret')

        self.bittrex = Bittrex(self.secrets['key'], None, api_version=API_V2_0)
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'valid key, None secret')

        self.bittrex = Bittrex('invalidkey',
                               'invalidsecret',
                               api_version=API_V2_0)
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'invalid key, invalid secret')

    def test_get_openorders(self):
        actual = self.bittrex.get_open_orders('BTC-LTC')
        test_basic_response(self, actual, "get_openorders")
        self.assertTrue(isinstance(actual['result'], list),
                        "result is not a list")

    def test_get_balances(self):
        actual = self.bittrex.get_balances()
        test_basic_response(self, actual, "get_balances")
        self.assertTrue(isinstance(actual['result'], list),
                        "result is not a list")

    @unittest.skip(
        "the return result is an empty dict.  API bug?  the 2.0 get_balances works as expected"
    )
    def test_get_balance(self):
        actual = self.bittrex.get_balance('BTC')
        test_basic_response(self, actual, "get_balance")
        self.assertTrue(isinstance(actual['result'], dict),
                        "result is not a dict")
        self.assertEqual(
            actual['result']['Currency'], "BTC",
            "requested currency {0:s} does not match returned currency {1:s}".
            format("BTC", actual['result']['Currency']))

    @unittest.skip("my testing account is acting funny this should work")
    def test_get_depositaddress(self):
        actual = self.bittrex.get_deposit_address('BTC')
        test_basic_response(self, actual, "get_deposit_address")

    def test_get_order_history_all_markets(self):
        actual = self.bittrex.get_order_history()
        test_basic_response(self, actual, "get_order_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_order_history_one_market(self):
        actual = self.bittrex.get_order_history(market='BTC-LTC')
        test_basic_response(self, actual, "get_order_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_withdrawlhistory_all_currencies(self):
        actual = self.bittrex.get_withdrawal_history()
        test_basic_response(self, actual, "get_withdrawal_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_withdrawlhistory_one_currency(self):
        actual = self.bittrex.get_withdrawal_history('BTC')
        test_basic_response(self, actual, "get_withdrawal_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_deposithistory_all_currencies(self):
        actual = self.bittrex.get_deposit_history()
        test_basic_response(self, actual, "get_deposit_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_deposithistory_one_currency(self):
        actual = self.bittrex.get_deposit_history('BTC')
        test_basic_response(self, actual, "get_deposit_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_pending_withdrawals_all_currencies(self):
        actual = self.bittrex.get_pending_withdrawals()
        test_basic_response(self, actual, "get_pending_withdrawals")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_pending_withdrawals_one_currency(self):
        actual = self.bittrex.get_pending_withdrawals('BTC')
        test_basic_response(self, actual, "get_pending_withdrawals")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_pending_deposits_all_currencies(self):
        actual = self.bittrex.get_pending_deposits()
        test_basic_response(self, actual, "get_pending_deposits")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_pending_deposits_one_currency(self):
        actual = self.bittrex.get_pending_deposits('BTC')
        test_basic_response(self, actual, "get_pending_deposits")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_generate_deposit_address(self):
        actual = self.bittrex.generate_deposit_address(currency='BTC')
        test_basic_response(self, actual, "generate_deposit_address")
        self.assertIsInstance(actual['result'], list, "result is not a list")
Exemplo n.º 8
0
class TestBittrexV11AccountAPI(unittest.TestCase):
    """
    Integration tests for the Bittrex Account API.
      * These will fail in the absence of an internet connection or if bittrex API goes down.
      * They require a valid API key and secret issued by Bittrex.
      * They also require the presence of a JSON file called secrets.json.
      It is structured as such:
    {
      "key": "12341253456345",
      "secret": "3345745634234534"
    }
    """
    def setUp(self):
        with open("secrets.json") as secrets_file:
            self.secrets = json.load(secrets_file)
            secrets_file.close()
        self.bittrex = Bittrex(self.secrets['key'], self.secrets['secret'])

    def test_handles_invalid_key_or_secret(self):
        self.bittrex = Bittrex('invalidkey', self.secrets['secret'])
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'Invalid key, valid secret')

        self.bittrex = Bittrex(None, self.secrets['secret'])
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'None key, valid secret')

        self.bittrex = Bittrex(self.secrets['key'], 'invalidsecret')
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'valid key, invalid secret')

        self.bittrex = Bittrex(self.secrets['key'], None)
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'valid key, None secret')

        self.bittrex = Bittrex('invalidkey', 'invalidsecret')
        actual = self.bittrex.get_balance('BTC')
        test_auth_basic_failures(self, actual, 'invalid key, invalid secret')

    def test_get_openorders(self):
        actual = self.bittrex.get_open_orders('BTC-LTC')
        test_basic_response(self, actual, "get_openorders")
        self.assertTrue(isinstance(actual['result'], list),
                        "result is not a list")

    def test_get_balances(self):
        actual = self.bittrex.get_balances()
        test_basic_response(self, actual, "get_balances")
        self.assertTrue(isinstance(actual['result'], list),
                        "result is not a list")

    def test_get_balance(self):
        actual = self.bittrex.get_balance('BTC')
        test_basic_response(self, actual, "get_balance")
        self.assertTrue(isinstance(actual['result'], dict),
                        "result is not a dict")
        self.assertEqual(
            actual['result']['Currency'], "BTC",
            "requested currency {0:s} does not match returned currency {1:s}".
            format("BTC", actual['result']['Currency']))

    def test_get_depositaddress(self):
        actual = self.bittrex.get_deposit_address('BTC')
        if not actual['success']:
            self.assertTrue(actual['message'], 'ADDRESS_GENERATING')
        else:
            test_basic_response(self, actual, "get_deposit_address")

    def test_get_order_history_all_markets(self):
        actual = self.bittrex.get_order_history()
        test_basic_response(self, actual, "get_order_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_order_history_one_market(self):
        actual = self.bittrex.get_order_history(market='BTC-LTC')
        test_basic_response(self, actual, "get_order_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_withdrawlhistory_all_currencies(self):
        actual = self.bittrex.get_withdrawal_history()
        test_basic_response(self, actual, "get_withdrawal_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_withdrawlhistory_one_currency(self):
        actual = self.bittrex.get_withdrawal_history('BTC')
        test_basic_response(self, actual, "get_withdrawal_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_deposithistory_all_currencies(self):
        actual = self.bittrex.get_deposit_history()
        test_basic_response(self, actual, "get_deposit_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_deposithistory_one_currency(self):
        actual = self.bittrex.get_deposit_history('BTC')
        test_basic_response(self, actual, "get_deposit_history")
        self.assertIsInstance(actual['result'], list, "result is not a list")

    def test_get_pending_withdrawals(self):
        self.assertRaisesRegexp(Exception, 'method call not available',
                                self.bittrex.get_pending_withdrawals)

    def test_get_pending_deposits(self):
        self.assertRaisesRegexp(Exception, 'method call not available',
                                self.bittrex.get_pending_deposits)

    def test_generate_deposit_address(self):
        self.assertRaisesRegexp(Exception,
                                'method call not available',
                                self.bittrex.generate_deposit_address,
                                currency='BTC')
Exemplo n.º 9
0
def mainrun():
    
    if Path(PATH+'currencyretain.pickle').is_file():
        remaining = pickle.load(open(PATH+'currencyretain.pickle','rb'))
        
    else:
        remaining = OrderedDict()    


    BTX = Bittrex(key=apikey,secret=apisecret)
    
    blockPrint()
    
    balances = BTX.get_balances()['result']
    orders = BTX.get_open_orders()['result']
    
    enablePrint()

    waitingon = []


    for ORDS in orders:
        EX = ORDS["Exchange"]
        TYPE = ORDS["OrderType"]
        
        if (SelltoCurrency in EX) and ('BUY' in TYPE):
            continue
        
        elif (orderwait==1) and (SelltoCurrency not in EX):
            EX = EX.replace(SelltoCurrency+'-','')
            EX = EX.replace('-'+SelltoCurrency,'')
            
            if EX not in EX:
                waitingon.append(EX)
                         
        else:
            continue 
    
    for BAL in balances:
        
        
        Currency = BAL["Currency"]
        Available = BAL["Available"]
        
        if Currency in retainspec.keys():
            retained = retainspec[Currency]
        else:
            retained = retainednorm
        
        if retentionROI == 1:
            ROI = 1.00 + retained + retained**2 + retained**3 + retained**4
        else:
            ROI = ROI
        
      
        if Currency in remaining.keys():
            CurrencyHold = remaining[Currency]
            Available = Available - CurrencyHold
        else:
            CurrencyHold = 0.00
        
        
        if (Currency not in waitingon) and (Currency != SelltoCurrency) and ( (Available + CurrencyHold) > (CurrencyHold + Minimumtradeorder) ):
            
            
            Quantitytosell = (Available-(retained*Available))
            
            blockPrint()
            price = BTX.get_market_history(SelltoCurrency+'-'+Currency)['result'][0]["Price"]
            enablePrint()
            
            #Take into account the initial fee
            zerofeeamount = ( price ) / (1-bidFee)
            
            Netprice = (zerofeeamount*ROI) / (1-askFee)
            
            if (Quantitytosell*price) > Minimumtradeorder:
                
                BTX.sell_limit(SelltoCurrency+'-'+Currency,Quantitytosell,Netprice)
                
                #Make sure to 'Hold' the amount remaining until it goes above this amount.
                remaining[Currency] = retained*Available + CurrencyHold
            
                pickle_out = open(PATH+'currencyretain.pickle','wb')
                pickle.dump(remaining,pickle_out)
                pickle_out.close()                 
                
            else:
                print("Minimum Trade order is: "+ str(Minimumtradeorder) + " " + SelltoCurrency + ", You tried to sell: " + str(Quantitytosell*price) + " " + SelltoCurrency + " Worth.")
Exemplo n.º 10
0
list_currency=[]
list_balance=[]
list_available=[]
list_pending=[]
list_last=[]
list_btcvalue=[]
list_market=[]
list_percent=[]
totalworth=0
i=0
n=0
k=0
btceuro=0
btcusd=0
wallet1=Bittrex(api_key,api_secret)
data=wallet1.get_balances()

#Date
print "\n","=====",time.strftime("%A %d %B %Y %H:%M:%S"),"=====","\n"

#Requesting BTC price
contenteuro=requests.get("https://www.bitstamp.net/api/v2/ticker/btceur/")
contenteuro=contenteuro.json()
btceuro=contenteuro["last"]
contentusd=requests.get("https://www.bitstamp.net/api/v2/ticker/btcusd/")
contentusd=contentusd.json()
btcusd=contentusd["last"]

#BTC percentage
btcfloat=float(btcusd)
btcopen=contentusd["open"]
Exemplo n.º 11
0
class Trader(object):
    """
    Used for handling all trade functionality
    """
    def __init__(self, secrets, settings):
        self.trade_params = settings["tradeParameters"]
        self.pause_params = settings["pauseParameters"]

        self.Bittrex = Bittrex(secrets)
        self.Messenger = Messenger(secrets, settings)
        self.Database = Database()

    def initialise(self):
        """
        Fetch the initial coin pairs to track and to print the header line
        """
        try:
            if len(self.Database.app_data["coinPairs"]) < 1:
                self.Database.store_coin_pairs(self.get_markets("BTC"))
            self.Messenger.print_header(
                len(self.Database.app_data["coinPairs"]))
        except ConnectionError as exception:
            self.Messenger.print_error("connection", [], True)
            logger.exception(exception)
            exit()

    def analyse_pauses(self):
        """
        Checks all the paused buy and sell pairs and the balance notification timer and reactivate the necessary ones
        """
        if self.Database.check_resume(self.pause_params["buy"]["pauseTime"],
                                      "buy"):
            self.Database.store_coin_pairs(self.get_markets("BTC"))
            self.Messenger.print_resume_pause(
                len(self.Database.app_data["coinPairs"]), "buy")
        if "sell" in self.pause_params and self.Database.check_resume(
                self.pause_params["sell"]["pauseTime"], "sell"):
            self.Messenger.print_resume_pause(
                self.Database.app_data["pausedTrackedCoinPairs"], "sell")
            self.Database.resume_sells()
        if "balance" in self.pause_params and self.Database.check_resume(
                self.pause_params["balance"]["pauseTime"], "balance"):
            current_balance = self.Messenger.send_balance_slack(
                self.get_non_zero_balances(),
                self.Database.get_previous_total_balance())
            self.Database.reset_balance_notifier(current_balance)

    def analyse_buys(self):
        """
        Analyse all the un-paused coin pairs for buy signals and apply buys
        """
        trade_len = len(self.Database.trades["trackedCoinPairs"])
        pause_trade_len = len(self.Database.app_data["pausedTrackedCoinPairs"])
        if (trade_len < 1 or pause_trade_len == trade_len
            ) and trade_len < self.trade_params["buy"]["maxOpenTrades"]:
            for coin_pair in self.Database.app_data["coinPairs"]:
                self.buy_strategy(coin_pair)

    def analyse_sells(self):
        """
        Analyse all the un-paused tracked coin pairs for sell signals and apply sells
        """
        for coin_pair in self.Database.trades["trackedCoinPairs"]:
            if coin_pair not in self.Database.app_data[
                    "pausedTrackedCoinPairs"]:
                self.sell_strategy(coin_pair)

    def buy_strategy(self, coin_pair):
        """
        Applies the buy checks on the coin pair and handles the results appropriately

        :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT)
        :type coin_pair: str
        """
        if (len(self.Database.trades["trackedCoinPairs"]) >=
                self.trade_params["buy"]["maxOpenTrades"]
                or coin_pair in self.Database.trades["trackedCoinPairs"]):
            return
        rsi = self.calculate_RSI(coin_pair=coin_pair,
                                 period=14,
                                 unit=self.trade_params["tickerInterval"])
        day_volume = self.get_current_24hr_volume(coin_pair)
        current_buy_price = self.get_current_price(coin_pair, "ask")

        if rsi is None:
            return

        if self.check_buy_parameters(rsi, day_volume, current_buy_price):
            buy_stats = {"rsi": rsi, "24HrVolume": day_volume}
            self.buy(coin_pair, self.trade_params["buy"]["btcAmount"],
                     current_buy_price, buy_stats)
        elif "buy" in self.pause_params and rsi >= self.pause_params["buy"][
                "rsiThreshold"] > 0:
            self.Messenger.print_pause(coin_pair, [rsi, day_volume],
                                       self.pause_params["buy"]["pauseTime"],
                                       "buy")
            self.Database.pause_buy(coin_pair)
        else:
            self.Messenger.print_no_buy(coin_pair, rsi, day_volume,
                                        current_buy_price)

    def sell_strategy(self, coin_pair):
        """
        Applies the sell checks on the coin pair and handles the results appropriately

        :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT)
        :type coin_pair: str
        """
        if (coin_pair in self.Database.app_data["pausedTrackedCoinPairs"]
                or coin_pair not in self.Database.trades["trackedCoinPairs"]):
            return
        rsi = self.calculate_RSI(coin_pair=coin_pair,
                                 period=14,
                                 unit=self.trade_params["tickerInterval"])
        current_sell_price = self.get_current_price(coin_pair, "bid")
        profit_margin = self.Database.get_profit_margin(
            coin_pair, current_sell_price)

        if rsi is None:
            return

        if self.check_sell_parameters(rsi, profit_margin):
            sell_stats = {"rsi": rsi, "profitMargin": profit_margin}
            self.sell(coin_pair, current_sell_price, sell_stats)
        elif "sell" in self.pause_params and profit_margin <= self.pause_params[
                "sell"]["profitMarginThreshold"] < 0:
            self.Messenger.print_pause(coin_pair, [profit_margin, rsi],
                                       self.pause_params["sell"]["pauseTime"],
                                       "sell")
            self.Database.pause_sell(coin_pair)
        else:
            self.Messenger.print_no_sell(coin_pair, rsi, profit_margin,
                                         current_sell_price)

    def check_buy_parameters(self, rsi, day_volume, current_buy_price):
        """
        Used to check if the buy conditions have been met

        :param rsi: The coin pair's current RSI
        :type rsi: float
        :param day_volume: The coin pair's current 24 hour volume
        :type day_volume: float
        :param current_buy_price: The coin pair's current price
        :type current_buy_price: float

        :return: Boolean indicating if the buy conditions have been met
        :rtype : bool
        """
        rsi_check = rsi <= self.trade_params["buy"]["rsiThreshold"]
        day_volume_check = day_volume >= self.trade_params["buy"][
            "24HourVolumeThreshold"]
        current_buy_price_check = current_buy_price >= self.trade_params[
            "buy"]["minimumUnitPrice"]

        return rsi_check and day_volume_check and current_buy_price_check

    def check_sell_parameters(self, rsi, profit_margin):
        """
        Used to check if the sell conditions have been met

        :param rsi: The coin pair's current RSI
        :type rsi: float
        :param profit_margin: The coin pair's current profit margin
        :type profit_margin: float

        :return: Boolean indicating if the sell conditions have been met
        :rtype : bool
        """
        rsi_check = rsi >= self.trade_params["sell"]["rsiThreshold"]
        lower_profit_check = profit_margin >= self.trade_params["sell"][
            "minProfitMarginThreshold"]
        upper_profit_check = profit_margin >= self.trade_params["sell"][
            "profitMarginThreshold"]
        loss_check = ("lossMarginThreshold" in self.trade_params["sell"]
                      and 0 > self.trade_params["sell"]["lossMarginThreshold"]
                      >= profit_margin)

        return (rsi_check and lower_profit_check) or upper_profit_check or (
            rsi_check and loss_check)

    def buy(self, coin_pair, btc_quantity, price, stats, trade_time_limit=2):
        """
        Used to place a buy order to Bittrex. Wait until the order is completed.
        If the order is not filled within trade_time_limit minutes cancel it.

        :param coin_pair: String literal for the market (ex: BTC-LTC)
        :type coin_pair: str
        :param btc_quantity: The amount of BTC to buy with
        :type btc_quantity: float
        :param price: The price at which to buy
        :type price: float
        :param stats: The buy stats object
        :type stats: dict
        :param trade_time_limit: The time in minutes to wait fot the order before cancelling it
        :type trade_time_limit: float
        """
        buy_quantity = round(btc_quantity / price, 8)
        buy_data = self.Bittrex.buy_limit(coin_pair, buy_quantity, price)
        if not buy_data["success"]:
            error_str = self.Messenger.print_error(
                "buy", [coin_pair, buy_data["message"]])
            logger.error(error_str)
            return
        self.Database.store_initial_buy(coin_pair, buy_data["result"]["uuid"])

        buy_order_data = self.get_order(buy_data["result"]["uuid"],
                                        trade_time_limit * 60)
        self.Database.store_buy(buy_order_data["result"], stats)

        self.Messenger.print_buy(coin_pair, price, stats["rsi"],
                                 stats["24HrVolume"])
        self.Messenger.send_buy_slack(coin_pair, stats["rsi"],
                                      stats["24HrVolume"])
        self.Messenger.send_buy_gmail(buy_order_data["result"], stats)
        self.Messenger.play_sw_imperial_march()

    def sell(self, coin_pair, price, stats, trade_time_limit=2):
        """
        Used to place a sell order to Bittrex. Wait until the order is completed.
        If the order is not filled within trade_time_limit minutes cancel it.

        :param coin_pair: String literal for the market (ex: BTC-LTC)
        :type coin_pair: str
        :param price: The price at which to buy
        :type price: float
        :param stats: The buy stats object
        :type stats: dict
        :param trade_time_limit: The time in minutes to wait fot the order before cancelling it
        :type trade_time_limit: float
        """
        trade = self.Database.get_open_trade(coin_pair)
        sell_data = self.Bittrex.sell_limit(coin_pair, trade["quantity"],
                                            price)
        if not sell_data["success"]:
            error_str = self.Messenger.print_error(
                "sell", [coin_pair, sell_data["message"]])
            logger.error(error_str)
            return

        sell_order_data = self.get_order(sell_data["result"]["uuid"],
                                         trade_time_limit * 60)
        # TODO: Handle partial/incomplete sales.
        self.Database.store_sell(sell_order_data["result"], stats)

        self.Messenger.print_sell(coin_pair, price, stats["rsi"],
                                  stats["profitMargin"])
        self.Messenger.send_sell_slack(coin_pair, stats["rsi"],
                                       stats["profitMargin"])
        self.Messenger.send_sell_gmail(sell_order_data["result"], stats)
        self.Messenger.play_sw_theme()

    def get_markets(self, main_market_filter=None):
        """
        Gets all the Bittrex markets and filters them based on the main market filter

        :param main_market_filter: Main market to filter on (ex: BTC, ETH, USDT)
        :type main_market_filter: str

        :return: All Bittrex markets (with filter applied, if any)
        :rtype : list
        """
        markets = self.Bittrex.get_markets()
        if not markets["success"]:
            error_str = self.Messenger.print_error("market", [], True)
            logger.error(error_str)
            exit()

        markets = markets["result"]
        if main_market_filter is not None:
            market_check = main_market_filter + "-"
            markets = py_.filter_(
                markets, lambda market: market_check in market["MarketName"])
        markets = py_.map_(markets, lambda market: market["MarketName"])
        return markets

    def get_current_price(self, coin_pair, price_type):
        """
        Gets current market price for a coin pair

        :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT)
        :type coin_pair: str
        :param price_type: The type of price to get (one of: 'ask', 'bid')
        :type price_type: str

        :return: Coin pair's current market price
        :rtype : float
        """
        coin_summary = self.Bittrex.get_market_summary(coin_pair)
        if not coin_summary["success"]:
            error_str = self.Messenger.print_error("coinMarket", [coin_pair])
            logger.error(error_str)
            return None
        if price_type == "ask":
            return coin_summary["result"][0]["Ask"]
        if price_type == "bid":
            return coin_summary["result"][0]["Bid"]
        return coin_summary["result"][0]["Last"]

    def get_current_24hr_volume(self, coin_pair):
        """
        Gets current 24 hour market volume for a coin pair

        :param coin_pair: Coin pair market to check (ex: BTC-ETH, BTC-FCT)
        :type coin_pair: str

        :return: Coin pair's current 24 hour market volume
        :rtype : float
        """
        coin_summary = self.Bittrex.get_market_summary(coin_pair)
        if not coin_summary["success"]:
            error_str = self.Messenger.print_error("coinMarket", [coin_pair])
            logger.error(error_str)
            return None
        return coin_summary["result"][0]["BaseVolume"]

    def get_closing_prices(self, coin_pair, period, unit):
        """
        Returns closing prices within a specified time frame for a coin pair

        :param coin_pair: String literal for the market (ex: BTC-LTC)
        :type coin_pair: str
        :param period: Number of periods to query
        :type period: int
        :param unit: Ticker interval (one of: 'oneMin', 'fiveMin', 'thirtyMin', 'hour', 'week', 'day', and 'month')
        :type unit: str

        :return: Array of closing prices
        :rtype : list
        """
        historical_data = self.Bittrex.get_historical_data(
            coin_pair, period, unit)
        closing_prices = []
        for i in historical_data:
            closing_prices.append(i["C"])
        return closing_prices

    def get_order(self, order_uuid, trade_time_limit):
        """
        Used to get an order from Bittrex by it's UUID.
        First wait until the order is completed before retrieving it.
        If the order is not completed within trade_time_limit seconds, cancel it.

        :param order_uuid: The order's UUID
        :type order_uuid: str
        :param trade_time_limit: The time in seconds to wait fot the order before cancelling it
        :type trade_time_limit: float

        :return: Order object
        :rtype : dict
        """
        start_time = time.time()
        order_data = self.Bittrex.get_order(order_uuid)
        while time.time() - start_time <= trade_time_limit and order_data[
                "result"]["IsOpen"]:
            time.sleep(10)
            order_data = self.Bittrex.get_order(order_uuid)

        if order_data["result"]["IsOpen"]:
            error_str = self.Messenger.print_error("order", [
                order_uuid, trade_time_limit, order_data["result"]["Exchange"]
            ])
            logger.error(error_str)
            if order_data["result"]["Type"] == "LIMIT_BUY":
                self.Bittrex.cancel(order_uuid)

        return order_data

    def calculate_RSI(self, coin_pair, period, unit):
        """
        Calculates the Relative Strength Index for a coin_pair
        If the returned value is above 75, it's overbought (SELL IT!)
        If the returned value is below 25, it's oversold (BUY IT!)

        :param coin_pair: String literal for the market (ex: BTC-LTC)
        :type coin_pair: str
        :param period: Number of periods to query
        :type period: int
        :param unit: Ticker interval (one of: 'oneMin', 'fiveMin', 'thirtyMin', 'hour', 'week', 'day', and 'month')
        :type unit: str

        :return: RSI
        :rtype : float
        """
        closing_prices = self.get_closing_prices(coin_pair, period * 3, unit)
        count = 0
        change = []
        # Calculating price changes
        for i in closing_prices:
            if count != 0:
                change.append(i - closing_prices[count - 1])
            count += 1
            if count == 15:
                break
        # Calculating gains and losses
        advances = []
        declines = []
        for i in change:
            if i > 0:
                advances.append(i)
            if i < 0:
                declines.append(abs(i))
        average_gain = (sum(advances) / 14)
        average_loss = (sum(declines) / 14)
        new_avg_gain = average_gain
        new_avg_loss = average_loss
        for _ in closing_prices:
            if 14 < count < len(closing_prices):
                close = closing_prices[count]
                new_change = close - closing_prices[count - 1]
                add_loss = 0
                add_gain = 0
                if new_change > 0:
                    add_gain = new_change
                if new_change < 0:
                    add_loss = abs(new_change)
                new_avg_gain = (new_avg_gain * 13 + add_gain) / 14
                new_avg_loss = (new_avg_loss * 13 + add_loss) / 14
                count += 1

        if new_avg_loss == 0:
            return None

        rs = new_avg_gain / new_avg_loss
        new_rs = 100 - 100 / (1 + rs)
        return new_rs

    def get_non_zero_balances(self):
        """
        Gets all non-zero user coin balances in the correct format
        """
        balances_data = self.Bittrex.get_balances()
        if not balances_data["success"]:
            error_str = self.Messenger.print_error("balance")
            logger.error(error_str)
            return
        non_zero_balances = py_.filter_(
            balances_data["result"],
            lambda balance_item: balance_item["Balance"] > 0)
        return py_.map_(non_zero_balances,
                        lambda balance: self.create_balance_object(balance))

    def create_balance_object(self, balance_item):
        """
        Creates a new balance object containing only the relevant values and the BTC value of the coin's balance

        :param balance_item: The Bittrex user balance object for a coin
        :type balance_item: dict
        """
        btc_price = 1
        is_tracked = False
        if balance_item["Currency"] != "BTC":
            coin_pair = "BTC-" + balance_item["Currency"]
            is_tracked = coin_pair in self.Database.trades["trackedCoinPairs"]
            btc_price = self.get_current_price(coin_pair, "bid")

        return py_.assign(
            py_.pick(balance_item, "Currency", "Balance"), {
                "BtcValue": round(btc_price * balance_item["Balance"], 8),
                "IsTracked": is_tracked
            })
Exemplo n.º 12
0
from bittrex import Bittrex
from pymarketcap import *
from twilio.rest import Client
import simplejson as json

apiKeys = json.loads(open("secrets.json").read())
myBittrex = Bittrex(apiKeys['key'], apiKeys['secret'])

cmc = Pymarketcap()

twilio = Client(apiKeys['SID'], apiKeys['AUTH'])

data = json.loads(json.dumps(myBittrex.get_balances()))

deposited = 1297.20

if data["success"]:
    total = 0
    balances = {}
    changes = {}
    for curr in data['result']:
        balance = curr['Balance']
        currency = curr['Currency']
        if balance > 0:
            balances[currency] = balance

    for curr, balance in balances.items():  # get balances
        print(curr, balance)
        cmcData = json.loads(json.dumps(cmc.ticker(curr)))
        usd = cmcData['price_usd']
        total += usd * balance
Exemplo n.º 13
0
class bittrex_private:
    def __init__(self):
        # self.bittrex_public = Bittrex(None, None)  # 公開情報を扱うBittrexオブジェクト
        self.bittrex_private = Bittrex(KEY, SECRET)  # 個人の情報を扱うBittrexオブジェクト

    # トレード履歴を取得
    def get_order_history(self):
        response = self.bittrex_private.get_order_history()
        pprint(response)
        return response

    # 買い注文を出す
    # marketに通貨ペア、quantityに注文する量、rateに価格を指定
    def buy_alt_coin(self, market, quantity, rate):
        response = self.bittrex_private.buy_limit(market=market,
                                                  quantity=quantity,
                                                  rate=rate)
        # 成功なら注文id、失敗ならfalseを返す
        if response['success'] is False:
            print(response)
            return False
        else:
            return response['result']['uuid']

    # 売り注文を出す
    # marketに通貨ペア、quantityに注文する量、rateに価格を指定
    def sell_alt_coin(self, market, quantity, rate):
        response = self.bittrex_private.sell_limit(market=market,
                                                   quantity=quantity,
                                                   rate=rate)
        # 成功なら注文id、失敗ならfalseを返す
        if response['success'] is False:
            print(response)
            return False
        else:
            return response['result']['uuid']

    # 注文をキャンセルする
    def order_cancel(self, uuid):
        response = self.bittrex_private.cancel(uuid=uuid)
        # 成功ならtrue、失敗ならfalseを返す
        print(response)
        return response['success']

    # 注文一覧を取得する
    def get_orders(self):
        order_list = []
        response = self.bittrex_private.get_open_orders()
        if response['success'] is False:
            print(response)
            return False
        else:
            # 注文が1件もない場合
            if len(response['result']) == 0:
                return None

            for item in response['result']:
                # 通貨の種類と量、注文IDを抜き出す
                balance = {}
                balance['market'] = item['Exchange']
                balance['quantity'] = item['Quantity']
                balance['uuid'] = item['OrderUuid']
                order_list.append(balance)

        return order_list

    # 所有している通貨をList型で返す
    def get_balances(self):
        balance_list = []
        response = self.bittrex_private.get_balances()
        if response['success'] is False:
            print(response)
            return False
        else:
            for item in response['result']:
                # 利用可能な通貨量が0の場合はスキップする
                if item['Available'] == 0:
                    continue
                # 通貨の種類と量を抜き出す
                balance = {}
                balance['currency'] = item['Currency']
                balance['available'] = item['Available']
                balance_list.append(balance)

        return balance_list
Exemplo n.º 14
0
class CapitVitaCrypto(CapitVita):
    def __init__(self,
                 home_path='',
                 num_coins=25,
                 mailing_list=[],
                 debug=False):

        self.num_coins = num_coins
        self.mailing_list = mailing_list
        self.coin_list = []
        self.df = []
        self.debug = debug
        self.home_path = home_path
        self.file_path = home_path + 'crypto-data/'
        self.volume_sum = []

        # bittrex
        self.B = Bittrex(key, secret)
        self.b_currencies = [
            x['Currency'] for x in self.B.get_currencies()['result']
        ]  # currencies available to trade in bittrex
        self.market_summaries = self.B.get_market_summaries()['result']
        self.markets = [x['MarketName']
                        for x in self.market_summaries]  # market names
        self.BTC_markets = [
            x for x in self.markets if 'BTC' in x and 'USDT' not in x
        ]
        self.ETH_markets = [
            x for x in self.markets if 'ETH' in x and 'USDT' not in x
        ]
        self.USDT_markets = [x for x in self.markets if 'USDT' in x]
        self.USDT_BTC = [
            x for x in self.market_summaries if x['MarketName'] == 'USDT-BTC'
        ][-1]['Last']
        self.USDT_ETH = [
            x for x in self.market_summaries if x['MarketName'] == 'USDT-ETH'
        ][-1]['Last']

    def get_coin_list(self):
        # get coin list (all coins, some are not tradeable on bittrex)

        url = 'https://www.cryptocompare.com/api/data/coinlist/'
        response = urllib2.urlopen(url)
        data = json.loads(response.read())
        self.coin_list = [
            x.encode('ascii', 'ignore') for x in data['Data'].keys()
        ]
        #print(len(self.coin_list))   # 1507 as of 2017-09-14

    def grab_data(self, coin):
        # get historical OHLC for one cryptocurrency

        url = 'https://min-api.cryptocompare.com/data/histoday?fsym={}&tsym=USD&limit={}&aggregate=1&e=CCCAGG'.format(
            coin, 80)
        response = urllib2.urlopen(url)
        data = json.loads(response.read())

        try:
            self.df = pd.DataFrame(data['Data'])
            self.df['date'] = self.df['time'].apply(
                lambda x: datetime.datetime.fromtimestamp(x))
            #self.df.drop(['time', 'volumefrom'], axis = 1)
            #self.df.columns = ['Adj. Close', 'Adj. High', 'Adj. Low', 'Adj. Open', 'time', 'volumefrom', 'volumeto', 'date']
        except KeyError:
            return False

        self.volume_sum.append(self.df['volumeto'].iloc[-20:].median())

        # generate signals
        self.df['rsi'] = self.RSI(self.df['close'], 14)
        self.df['26 ema'] = self.df['close'].ewm(ignore_na=False,
                                                 min_periods=0,
                                                 adjust=True,
                                                 com=26).mean()
        self.df['12 ema'] = self.df['close'].ewm(ignore_na=False,
                                                 min_periods=0,
                                                 adjust=True,
                                                 com=12).mean()
        self.df['MACD'] = self.df['12 ema'] - self.df['26 ema']
        self.df['MACD signal'] = self.df['MACD'] - self.df['MACD'].ewm(
            ignore_na=False, min_periods=0, adjust=True, com=9).mean()
        self.df['MACD_norm'] = self.normalize(self.df['MACD signal'])
        self.df['MACD_der'] = self.derivative(self.df['MACD_norm'])

    def get_points(self, coin):

        try:

            self.grab_data(coin)  ## get the data and store it in self.df

            if len(self.df) < 20 or self.df['volumeto'].iloc[-20:].median(
            ) < 850000 * 0.8:  # if grab is unsuccessful or below average volume * 0.7, end
                points = {'admin': -500}

            else:
                points = {}

                mb, tb, bb, = self.bbands(self.df['close'])
                if self.df['close'].iloc[-1] < (mb.iloc[-1] + bb.iloc[-1]) / 2:
                    points['admin'] = -500

                # RSI points (max 50)
                points['rsi'] = 50 - round(
                    1.2 * abs(30 - self.df['rsi'].iloc[-1]))

                # MACD points (max 50)
                points['macd1'] = round(
                    25 * self.df['MACD_norm'].iloc[-1] /
                    max([abs(x) for x in self.df['MACD_norm']]))
                points['macd2'] = round(
                    25 * self.df['MACD_der'].iloc[-1] /
                    max([abs(x) for x in self.df['MACD_der']]))

                # candlestick points (max 10)
                candlestickFactor = 1

                patterns = self.detectCandlestickPatterns(
                    self.df['open'][-7:], self.df['close'][-7:],
                    self.df['low'][-7:], self.df['high'][-7:],
                    candlestickFactor)
                points['candlesticks'] = self.rangeLimit(
                    round(sum([x[2] for x in patterns])), -20, 20)

        except BufferError as e:
            #except Exception as e:
            print('problem: {}'.format(e))

        return points

    def find_coins(self, graph=False, bittrex_currencies_only=True):
        # start counting duration of script
        start_time = time.time()

        print('Initiating log...')
        # create log
        ff = open(self.file_path + 'readme.txt', 'w')
        ff.write(str(datetime.datetime.now()))
        ff.write('\n')

        print('Deleting old plots...')
        # delete old files
        os.chdir(self.file_path)
        filelist = glob.glob('*.png')
        for f in filelist:
            os.remove(f)
        os.chdir(self.home_path)

        print('Fetching coin list...')
        if bittrex_currencies_only:
            self.update_B()
            self.coin_list = self.b_currencies
        else:
            self.get_coin_list()
            if self.debug:
                self.coin_list = self.coin_list[:30]

        len_coin_list = len(self.coin_list)
        print('  {} coins.'.format(len_coin_list))
        #print('  Expect script to take approximately {} minutes'.format(round(len_coin_list*1.0613 - 14)/60, 2))

        # grab data in batches
        print('Getting points for {} coins...'.format(len_coin_list))
        coin_points = {}
        for i, coin in enumerate(self.coin_list):
            if i % (len(self.coin_list) / 25) == 0:
                print('{}% done'.format(
                    round(100 * float(i) / len(self.coin_list), 1)))
            try:
                points = self.get_points(coin)
                coin_points[coin] = [sum([points[x] for x in points]), points]
            #except BufferError:
            except Exception as e:
                print('failed {} because {}'.format(coin, e))
        original_len_coin_list = len(coin_points)

        print('Sorting coins...')
        # sort stocks by point system
        sorted_coins = sorted(coin_points.items(),
                              key=itemgetter(1),
                              reverse=True)[:self.num_coins]

        print(sorted_coins)

        if graph:
            print('Graphing coins...')
            for coin in [x[0] for x in sorted_coins]:
                try:
                    self.graph_data(coin, saveLocation=self.file_path)
                except BufferError:
                    #except Exception as e:
                    print('failed {} because {}'.format(coin, e))

        # write into log
        ff.write('Cheap coins to invest in for 2 days ~ 1 week: \n\n')

        ff.write('#\n')
        for i in sorted_coins:
            ff.write(i[0] + ': ' + str(round(i[1][0], 1)) + '  ' +
                     str(i[1][1]) + '\n')
        ff.write('#\n')

        ff.write('\n\n  ' + str(original_len_coin_list) +
                 ' stocks shortened by point system to ' +
                 str(len(sorted_coins)) + ' stocks')

        ff.write("\n\n--- %s seconds ---" %
                 (round(time.time() - start_time, 2)))

        ff.write('\n\n\n  Capit-Vita Crypto Version 1.1  (2017-09-22)\n\n')
        ff.write('  - Buying is confirmed to work\n')
        ff.close()

        #print(self.volume_sum[-20:])
        #print('average volume', sum(self.volume_sum)/len(self.volume_sum))
        # median volumeto: 850k

        # send email
        if len(self.mailing_list) > 0:
            send_email(self.file_path,
                       'Top ' + str(self.num_coins) + ' Coin Prospects',
                       self.mailing_list)

        ###### remove coin types I currently own
        my_coins = [x['Currency'] for x in self.B.get_balances()['result']]
        print('my coins: {}'.format(my_coins))
        print('before: {}'.format([x[0] for x in sorted_coins]))
        sorted_coins = [x for x in sorted_coins if x[0] not in my_coins]
        print('after: {}'.format([x[0] for x in sorted_coins]))

        # save wanted coins
        with open(self.file_path + 'wanted_coins.txt', 'w') as f:
            f.write('{}, '.format([str(x[0]) for x in sorted_coins]))

        return sorted_coins

    def buy_next_coin(self):

        # save wanted_coins
        if os.path.isfile(self.file_path + 'wanted_coins.txt'):
            with open(self.file_path + 'wanted_coins.txt', 'r') as f:
                data = eval(f.readlines()[0][:-2])
        else:
            return False

        print(data)

    def update_B(self):

        self.b_currencies = [
            x['Currency'] for x in self.B.get_currencies()['result']
        ]  # currencies available to trade in bittrex
        self.market_summaries = self.B.get_market_summaries()['result']
        self.markets = [x['MarketName']
                        for x in self.market_summaries]  # market names
        self.BTC_markets = [
            x for x in self.markets if 'BTC' in x and 'USDT' not in x
        ]
        self.ETH_markets = [
            x for x in self.markets if 'ETH' in x and 'USDT' not in x
        ]
        self.USDT_markets = [x for x in self.markets if 'USDT' in x]
        self.USDT_BTC = [
            x for x in self.market_summaries if x['MarketName'] == 'USDT-BTC'
        ][-1]['Last']
        self.USDT_ETH = [
            x for x in self.market_summaries if x['MarketName'] == 'USDT-ETH'
        ][-1]['Last']
        #print len(self.b_currencies) # 277 as of 2017-09-21

    def thing(self):

        BTC_market_prices = []
        ETH_market_prices = []
        ### create value exchange rate
        for currency in self.b_currencies:
            if any(currency in x for x in BTC_markets):
                last_price = [
                    x['Last'] for x in self.market_summaries
                    if x['MarketName'] == 'BTC-{}'.format(currency)
                ]
                if len(last_price) > 0:
                    BTC_market_prices.append('Last price for {} is ${}'.format(
                        currency, round(last_price[0] * USDT_BTC, 2)))
            elif any(currency in x for x in ETH_markets):
                last_price = [
                    x['Last'] for x in self.market_summaries
                    if x['MarketName'] == 'ETH-{}'.format(currency)
                ]
                if len(last_price) > 0:
                    ETH_market_prices.append('Last price for {} is ${}'.format(
                        currency, round(last_price[0] * USDT_ETH, 2)))

        cnt_in = 0
        cnt_not_in = 0
        for currency in self.b_currencies:
            if all(currency not in x
                   for x in self.BTC_markets + self.ETH_markets):
                cnt_not_in += 1
                #print('{} not in any market'.format(currency))
            else:
                cnt_in += 1

        #print(cnt_in, cnt_not_in) #203 in market, 74 out of market as of 2017-09-21

        ### can only buy and sell on existing markets

    def my_coins(self):

        my_coins = [x for x in self.B.get_balances()['result']]
        print(my_coins)
        total = 0
        print('\n\n-----------  My Wallet -----------\n')
        for coin in my_coins:
            if coin['Currency'] == 'BTC':
                print('{} available for {} (${})'.format(
                    coin['Available'], coin['Currency'],
                    round(coin['Available'] * self.USDT_BTC, 2)))
                total += coin['Available'] * self.USDT_BTC
            elif any(coin['Currency'] in x for x in self.BTC_markets):
                BTC_coin_rate = [
                    x['Last'] for x in self.market_summaries
                    if x['MarketName'] == 'BTC-{}'.format(coin['Currency'])
                ][0]
                print('{} available for {} (${})'.format(
                    coin['Available'], coin['Currency'],
                    round(coin['Available'] * self.USDT_BTC * BTC_coin_rate,
                          2)))
                total += coin['Available'] * self.USDT_BTC * BTC_coin_rate
            else:
                print('{} available for {} (${})'.format(
                    coin['Available'], coin['Currency'],
                    'hold'))  ## add ethereum
        #return summary
        return my_coins

    def total_available_USD(self, BTC_ETH_only=True):

        balances = self.B.get_balances()['result']
        total_USD = 0

        for balance in balances:
            if balance['Balance'] > 0:
                if balance['Currency'] == 'BTC':
                    total_USD += balance['Balance'] * self.USDT_BTC
                    print('BTC: {}'.format(balance['Balance'] * self.USDT_BTC))
                elif balance['Currency'] == 'ETH':
                    total_USD += balance['Balance'] * self.USDT_ETH
                    print('ETH: {}'.format(balance['Balance'] * self.USDT_ETH))
                elif not BTC_ETH_only:
                    if any(balance['Currency'] in x for x in self.BTC_markets):
                        to_add = balance['Balance'] * [
                            x['Last']
                            for x in self.market_summaries if x['MarketName']
                            == 'BTC-{}'.format(balance['Currency'])
                        ][0] * self.USDT_BTC
                        total_USD += to_add
                        print('{}: {}'.format(balance['Currency'], to_add))
                    elif any(balance['Currency'] in x
                             for x in self.ETH_markets):
                        to_add = balance['Balance'] * [
                            x['Last']
                            for x in self.market_summaries if x['MarketName']
                            == 'ETH-{}'.format(balance['Currency'])
                        ][0] * self.USDT_ETH
                        total_USD += to_add
                        print('{}: {}'.format(balance['Currency'], to_add))
                # consider only BTC and ETH liquid?

        print('Total available: {}'.format(total_USD))

        return total_USD

    def buy_altcoin(self, coin):

        if any(coin in x['Currency'] for x in self.B.get_balances()['result']):
            print('not buying, already have')
            return False

        if any(coin in x for x in self.BTC_markets):

            market = [x for x in self.BTC_markets if coin in x][0]
            print(market)

            available_USD = self.total_available_USD()
            print('available USD', available_USD)

            increment_USD = available_USD / 20
            print('5% available USD: {}'.format(increment_USD))

            BTC_coin_rate = self.B.get_marketsummary(
                market)['result'][0]['Last']
            print('BTC - {} conversion: {}'.format(coin, BTC_coin_rate))

            print('BTC - USD conversion: {}'.format(self.USDT_BTC))

            print('want to buy {} {} coins'.format(
                increment_USD / self.USDT_BTC / BTC_coin_rate, coin))

            print('buying {}: {}'.format(
                coin,
                self.B.buy_limit(market,
                                 increment_USD / self.USDT_BTC / BTC_coin_rate,
                                 BTC_coin_rate)))  # market, quantity, rate

    def sell_altcoin(self, order):
        # takes a buy order and reverses it (sell)

        coin = order['Exchange'][4:]
        if any(coin in x for x in self.BTC_markets):
            market = [x for x in self.BTC_markets if coin in x][0]
        elif any(coin in x for x in self.ETH_markets):
            market = [x for x in self.ETH_markets if coin in x][0]
        coin_rate = self.B.get_marketsummary(market)['result'][0]['Last']
        quantity = order['Quantity']

        if all(coin not in x['Currency']
               for x in self.B.get_balances()['result']):
            print('cannot sell, do not have')
            return False

        #print('selling {}: {}'.format(market, self.B.sell_limit(market, quantity, coin_rate)))    # market, quantity, rate

    def coin_to_USD(self, order):

        coin = order['Exchange'][4:]

        market = [x for x in self.BTC_markets if coin in x][0]
        BTC_coin_rate = self.B.get_marketsummary(market)['result'][0]['Last']

        if coin == 'BTC':
            return order['Quantity'] * self.USDT_BTC
        elif coin == 'ETH':
            pass
        elif any([coin in x for x in self.BTC_markets]):
            last_price = [
                x['Last'] for x in self.market_summaries
                if coin in x['MarketName']
            ]
            return order['Quantity'] * self.USDT_BTC * BTC_coin_rate
        elif any(coin in x for x in self.ETH_markets):
            pass
        else:
            pass

    def my_coin_price_change(self):

        orders = self.B.get_order_history()['result']

        ## remove orders that I don't own
        orders = [x for x in orders]

        print(orders)

        self.update_B()

        for order in orders:
            bought_at = round(
                order['Quantity'] * order['PricePerUnit'] * self.USDT_BTC, 2)
            currently = round(self.coin_to_USD(order), 2)
            perc_change = round((currently / bought_at - 1) * 100, 1)
            timestamp = datetime.datetime.now() - datetime.datetime.strptime(
                order['TimeStamp'], '%Y-%m-%dT%H:%M:%S.%f')
            print(
                '   bought {} ({} ago) for relative BTC value of ${}, currently ${}: {}% change'
                .format(order['Exchange'][4:], timestamp, bought_at, currently,
                        perc_change))

            ### formula for selling:
            # cost of trade = 0.35% x 2 = 0.7%
            # have an open sell order at 10% -> 9.3% up
            # if simulataneous orders are possible, have an open sell order at -10% -> 10.7% down
            # if the coin is older than 5 days, lower the upper sell limit by 2% to 8% -> 7.3% up
            # every 3 days after that lower by 2% until @ 2%

            lower_limit = -10
            if timestamp < datetime.timedelta(days=5):
                upper_limit = 10
            elif timestamp < datetime.timedelta(days=8):  # approx one week
                upper_limit = 8
            elif timestamp < datetime.timedelta(days=11):
                upper_limit = 6
            elif timestamp < datetime.timedelta(days=14):  # two weeks
                upper_limit = 4
            elif timestamp < datetime.timedelta(days=17):
                upper_limit = 2
            elif timestamp > datetime.timedelta(
                    days=21):  # sell no matter what after 3 weeks
                upper_limit = -10

            if perc_change < lower_limit or perc_change > upper_limit:
                self.sell_altcoin(order)