class TestBittrexV20PublicAPI(unittest.TestCase): """ Integration tests for the Bittrex public API. These will fail in the absence of an internet connection or if bittrex API goes down """ def setUp(self): self.bittrex = Bittrex(None, None, api_version=API_V2_0) def test_handles_none_key_or_secret(self): self.bittrex = Bittrex(None, None, api_version=API_V2_0) # could call any public method here actual = self.bittrex.get_market_summaries() self.assertTrue(actual['success'], "failed with None key and None secret") self.bittrex = Bittrex("123", None, api_version=API_V2_0) actual = self.bittrex.get_market_summaries() self.assertTrue(actual['success'], "failed with None secret") self.bittrex = Bittrex(None, "123", api_version=API_V2_0) actual = self.bittrex.get_market_summaries() self.assertTrue(actual['success'], "failed with None key") def test_get_currencies(self): actual = self.bittrex.get_currencies() test_basic_response(self, actual, "get_currencies") def test_get_ticker(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.get_ticker, market='BTC-LTC') def test_get_market_summaries(self): actual = self.bittrex.get_market_summaries() test_basic_response(self, actual, "get_market_summaries") def test_get_market_summary(self): actual = self.bittrex.get_market_summary(market='BTC-LTC') test_basic_response(self, actual, "get_market_summary") def test_get_orderbook(self): actual = self.bittrex.get_orderbook('BTC-LTC') test_basic_response(self, actual, "get_orderbook") def test_get_wallet_health(self): actual = self.bittrex.get_wallet_health() test_basic_response(self, actual, "get_wallet_health") self.assertIsInstance(actual['result'], list) @unittest.skip("Endpoint 404s. Is this still a valid 2.0 API?") def test_get_balance_distribution(self): actual = self.bittrex.get_balance_distribution() test_basic_response(self, actual, "get_balance_distribution") self.assertIsInstance(actual['result'], list) def test_get_candles(self): actual = self.bittrex.get_candles('BTC-LTC', tick_interval=TICKINTERVAL_ONEMIN) test_basic_response(self, actual, "test_get_candles") self.assertIsInstance(actual['result'], list) def test_get_latest_candle(self): actual = self.bittrex.get_latest_candle( 'BTC-LTC', tick_interval=TICKINTERVAL_ONEMIN) test_basic_response(self, actual, "test_get_latest_candle") self.assertIsInstance(actual['result'], list)
class TestBittrexV11PublicAPI(unittest.TestCase): """ Integration tests for the Bittrex public API. These will fail in the absence of an internet connection or if bittrex API goes down """ def setUp(self): self.bittrex = Bittrex(None, None, api_version=API_V1_1) def test_handles_none_key_or_secret(self): self.bittrex = Bittrex(None, None) # could call any public method here actual = self.bittrex.get_markets() self.assertTrue(actual['success'], "failed with None key and None secret") self.bittrex = Bittrex("123", None) actual = self.bittrex.get_markets() self.assertTrue(actual['success'], "failed with None secret") self.bittrex = Bittrex(None, "123") actual = self.bittrex.get_markets() self.assertTrue(actual['success'], "failed with None key") def test_get_markets(self): actual = self.bittrex.get_markets() test_basic_response(self, actual, "get_markets") self.assertTrue(isinstance(actual['result'], list), "result is not a list") self.assertTrue(len(actual['result']) > 0, "result list is 0-length") def test_get_currencies(self): actual = self.bittrex.get_currencies() test_basic_response(self, actual, "get_currencies") def test_get_ticker(self): actual = self.bittrex.get_ticker(market='BTC-LTC') test_basic_response(self, actual, "get_ticker") def test_get_market_summaries(self): actual = self.bittrex.get_market_summaries() test_basic_response(self, actual, "get_market_summaries") def test_get_orderbook(self): actual = self.bittrex.get_orderbook('BTC-LTC', depth_type=BUY_ORDERBOOK) test_basic_response(self, actual, "get_orderbook") def test_get_market_history(self): actual = self.bittrex.get_market_history('BTC-LTC') test_basic_response(self, actual, "get_market_history") def test_list_markets_by_currency(self): actual = self.bittrex.list_markets_by_currency('LTC') self.assertListEqual(['BTC-LTC', 'ETH-LTC', 'USDT-LTC'], actual) def test_get_wallet_health(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.get_wallet_health) def test_get_balance_distribution(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.get_balance_distribution) def test_get_candles(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.get_candles, market='BTC-LTC', tick_interval=TICKINTERVAL_ONEMIN) def test_get_latest_candle(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.get_latest_candle, market='BTC-LTC', tick_interval=TICKINTERVAL_ONEMIN)
class CryptoArb(object): """ 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(self): desiredResult = .95 ## ETHEREUM btcResult = 0 LoopNumber = 1 while btcResult < desiredResult: markets = self.bittrex.get_market_summaries() marketCount = len(markets["result"]) print("Start - " + str(LoopNumber)) btcCount = 0 ethCount = 0 ### ~~ Filling the BTC-ALT Matrix ~~ ### # Counting the number of BTC Currency Pairs btcLoopCount = 0 while btcLoopCount < marketCount: if "BTC-" in markets["result"][btcLoopCount]["MarketName"]: btcCount = btcCount + 1 btcLoopCount = btcLoopCount + 1 # Creating the BTC pair-exchange matrix btcCol, btcRow = 2, btcCount BTCMatrix = [[0 for x in range(btcCol)] for y in range(btcRow)] # Filling the BTC Matrix btcLoopCount = 0 btcMatrixRowCount = 0 while btcLoopCount < marketCount: if "BTC-" in markets["result"][btcLoopCount]["MarketName"]: BTCMatrix[btcMatrixRowCount][0] = markets["result"][ btcLoopCount]["MarketName"] BTCMatrix[btcMatrixRowCount][1] = markets["result"][ btcLoopCount]["Ask"] btcMatrixRowCount = btcMatrixRowCount + 1 btcLoopCount = btcLoopCount + 1 ### ~~ Filling the ETH-ALT Matrix ~~ ### # Counting the number of ETH Currency Pairs ethLoopCount = 0 while ethLoopCount < marketCount: if "ETH-" in markets["result"][ethLoopCount]["MarketName"]: ethCount = ethCount + 1 ethLoopCount = ethLoopCount + 1 # Creating the ETH pair-exchange matrix ethCol, ethRow = 2, ethCount ETHMatrix = [[0 for x in range(ethCol)] for y in range(ethRow)] # Filling the ETH Matrix ethLoopCount = 0 ethMatrixRowCount = 0 while ethLoopCount < marketCount: if "ETH-" in markets["result"][ethLoopCount]["MarketName"]: ETHMatrix[ethMatrixRowCount][0] = markets["result"][ ethLoopCount]["MarketName"] ETHMatrix[ethMatrixRowCount][1] = markets["result"][ ethLoopCount]["Bid"] ethMatrixRowCount = ethMatrixRowCount + 1 ethLoopCount = ethLoopCount + 1 btc_ethTick = self.bittrex.get_ticker("BTC-ETH") btc_eth_BTC = btc_ethTick["result"]["Bid"] # ~~~ Comparing Bitcoin Arbitrage Returns ~~~ # arbBTCPairs = [] arbBTCReturn = [] arbBTCTestReturn = [] arbBTCRow = 0 for btcAlt in BTCMatrix: for ethAlt in ETHMatrix: if ethAlt[0][4:] == btcAlt[0][4:]: btcResult = 0 #arbBTCPairs.append(str(btcAlt[0]) + " > " + str(ethAlt[0]) + " > BTC_ETH") arbPath = str(btcAlt[0]) + " > " + str( ethAlt[0]) + " > BTC_ETH" btcAltDiff = 0.0000007 altEthDiff = -0.0000002 ethBtcDiff = -0.000001 # Forumla to check returns print("BTC -> Alt: " + str(btcAlt[1])) btc_altX = float(btcAlt[1] + btcAltDiff) print("Alt -> ETH: " + str(ethAlt[1])) eth_altX = float(ethAlt[1] + altEthDiff) print("ETH -> BTC: " + str(btc_eth_BTC)) btc_ethX = float(btc_eth_BTC + ethBtcDiff) #test1 = float(btcAlt[1] - 0.00000001) #test2 = float(ethAlt[1] - 0.00000001) #test3 = float(btc_eth_BTC - 0.0000004) print( str(btcAlt[0]) + " > " + str(ethAlt[0]) + " > BTC_ETH") btcUnits = 1 print("BTC = " + str(btcUnits)) altUnits = round(((btcUnits / 1.0025) / btc_altX), 8) #testaltUnits = round(((btcUnits / 1.0025) / test1), 8) print("Alt Units = " + str(altUnits) + " (" + str(btc_altX) + ")") #print("Test Alt Units = " + str(testaltUnits) + " (" + str(test1) + ")") ethUnits = round( ((altUnits - (altUnits * 0.0025)) * eth_altX), 8) #testethUnits = round(((testaltUnits - (testaltUnits * 0.0025)) * test2), 8) print("ETH Units = " + str(ethUnits) + " (" + str(eth_altX) + ")") #print("Test ETH Units = " + str(testethUnits) + " (" + str(test2) + ")") btcResult = round( ((ethUnits - (ethUnits * 0.0025)) * btc_ethX), 8) #testbtcResult = round(((testethUnits - (testethUnits * 0.0025)) * test3), 8) print("BTC Result = " + str(btcResult) + " (" + str(btc_ethX) + ")") #print("Test BTC Result = " + str(testbtcResult) + " (" + str(test3) + ")") print("") #arbBTCReturn.append(btcResult) #arbBTCTestReturn.append(testbtcResult) print(btcAlt[0]) if (btcResult ) >= desiredResult and btcAlt[0] != "BTC-SALT": print("!! Desired Result Reached !!") break arbBTCRow = arbBTCRow + 1 if (btcResult) >= desiredResult and btcAlt[0] != "BTC-SALT": break print("") # If desired result is not reached empty the lists to start again if btcResult <= desiredResult: BTCMatrix[:] = [] ETHMatrix[:] = [] arbBTCPairs[:] = [] arbBTCReturn[:] = [] LoopNumber = LoopNumber + 1 # Loops if return isn't good enough i.e. > 1.005 # Loop has been exited because return is good enough # If statement is final check to make sure return is good enough if float(btcResult) > desiredResult and btcAlt[0] != "BTC-SALT": print("Arb Return = " + str(btcResult)) print("begin timer") startTime = time.time() # Path of the arb which yiels return i.e. BTC -> ALT -> ETH -> BTC #print(arbPath) # Getting name of Alt if len(arbPath) == 25: alt = arbPath[4:6] print("Alt = " + alt) elif len(arbPath) == 27: alt = arbPath[4:7] print("Alt = " + alt) elif len(arbPath) == 29: alt = arbPath[4:8] print("Alt = " + alt) elif len(arbPath) == 31: alt = arbPath[4:9] print("Alt = " + alt) else: print("Wrong Number Letters " + len(arbPath)) print("Time elapsed " + str(time.time() - startTime)) # Begin Buy Process orderBTCALTBook = self.bittrex.get_orderbook( "BTC-" + str(alt), "sell") print("") #BTCBal = self.bittrex.get_balance("BTC") #if str(BTCBal["result"]["Balance"]) == "None": # principle = 0 #else: # principle = float(BTCBal["result"]["Balance"]) principle = 0.00065 print("Principle = " + str(principle)) AltQuantity = 0 ETHQuantity = 0 BTCQuantity = 0 market = "BTC-" + alt print("Market = " + market) print("") actBtcAltRate = 0 actAltEthRate = 0 actEthBtcRate = 0 btcOrderCount = 0 while principle > 0: print("BTC -> " + str(alt) + " Order " + str(btcOrderCount + 1) + ": Principle = " + str(principle)) askQuantity = orderBTCALTBook["result"][btcOrderCount][ "Quantity"] askRate = orderBTCALTBook["result"][btcOrderCount]["Rate"] askTotal = askQuantity * askRate print("-- Order Details: --") print("---- Ask Quantity = " + str(askQuantity)) print("---- Ask Rate = " + str(askRate)) print("---- Ask Total = " + str(askTotal)) print("---- Principle = " + str(principle)) print("") if askTotal > principle: print("---- Executing full final trade...") tradeQuantity = math.floor( ((principle / 1.0025) / askRate) * 100000000) / 100000000 print("---- Trade Quantity = " + str(tradeQuantity) + " (" + str(principle / 1.0025) + " / " + str(askRate) + ")") # Execute full or remainder of trade AltQuantity = AltQuantity + tradeQuantity print("---- BUY " + str(AltQuantity) + " " + str(alt) + " @ " + str(askRate) + "BTC = " + str(round((AltQuantity * askRate), 8))) altBuy = self.bittrex.buy_limit(market, AltQuantity, askRate) print("---- " + str(altBuy)) actBtcAltRate = askRate # I can delete this because I have a more accurate below from get_order_history altBuy = True break else: # Execute a portion of the trade print("---- Partial Trade - CANCEL ... ") print("---- BUY " + str(askQuantity) + str(alt) + " @ " + str(askRate) + " BTC = " + str(round((askQuantity * askRate), 8))) AltQuantity = AltQuantity + askQuantity principle = principle - askTotal break #buy = self.bittrex.buy_limit(market, askQuantity, askRate) #print(buy) #principle = (principle * 0.9975) - askTotal # execute trade btcOrderCount = btcOrderCount + 1 print("") print(str(alt) + " Quantity = " + str(AltQuantity)) firstTrade = time.time() - startTime secondTrade = 0 finalTrade = 0 print("Time since arb calc = " + str(firstTrade)) print("") if altBuy == True: orderETHALTBook = self.bittrex.get_orderbook( "ETH-" + str(alt), "buy") market = "ETH-" + alt ogAltQuantity = AltQuantity altOrderCount = 0 while AltQuantity > 0: print( str(alt) + " -> ETH Order " + str(altOrderCount + 1) + ": Principle = " + str(AltQuantity)) bidQuantity = orderETHALTBook["result"][altOrderCount][ "Quantity"] bidRate = orderETHALTBook["result"][altOrderCount]["Rate"] bidTotal = bidQuantity * bidRate print("-- Order Details: --") print("---- Bid Quantity = " + str(bidQuantity)) print("---- Bid Rate = " + str(bidRate)) print("---- Bid Total = " + str(bidTotal)) print("---- Alt Quantity = " + str(AltQuantity)) print("") if bidQuantity > AltQuantity: print("Executing full final trade...") tradeQuantity = math.floor( ((AltQuantity * 0.9975) * bidRate) * 100000000) / 100000000 print("---- Trade Quantity = " + str(tradeQuantity) + " (" + str(AltQuantity) + " * " + str(bidRate) + ")") # Execute full or remainder of trade print("---- SELL " + str(ogAltQuantity) + " " + str(alt) + " @ " + str(bidRate) + "ETH = " + str(tradeQuantity)) ETHQuantity = ETHQuantity + tradeQuantity altSell = self.bittrex.sell_limit( market, ogAltQuantity, bidRate) print("---- " + str(altSell)) actAltEthRate = bidRate # I can delete this because I have a more accurate below from get_order_history altSell = True break else: # Execute a portion of the trade print("---- Executing partial trade... " + str(bidQuantity) + str(alt) + " @ " + str(bidRate) + "ETH = " + str(bidQuantity * bidRate)) ETHQuantity = (ETHQuantity + bidTotal) * 0.9975 sell = self.bittrex.sell_limit(market, bidQuantity, bidRate) print(sell) AltQuantity = AltQuantity - bidQuantity # execute trade print("") altOrderCount = altOrderCount + 1 if altSell == True: print("") print("ETH Quantity = " + str(ETHQuantity)) secondTrade = time.time() - startTime print("Time since arb calc = " + str(secondTrade)) print("") orderBTCETHBook = self.bittrex.get_orderbook( "BTC-ETH", "buy") ogETHQuantity = ETHQuantity market = "BTC-ETH" ethOrderCount = 0 while ETHQuantity > 0: print("ETH -> BTC Order " + str(ethOrderCount + 1) + ": Principle = " + str(ETHQuantity)) bidQuantity = orderBTCETHBook["result"][ethOrderCount][ "Quantity"] bidRate = orderBTCETHBook["result"][ethOrderCount][ "Rate"] bidTotal = bidQuantity * bidRate print("-- Order Details: --") print("---- Bid Quantity = " + str(bidQuantity)) print("---- Bid Rate = " + str(bidRate)) print("---- Bid Total = " + str(bidTotal)) print("---- ETH Quantity = " + str(ETHQuantity)) print("") if bidQuantity > ETHQuantity: print("---- Executing full final trade...") tradeQuantity = math.floor( ((ETHQuantity * 0.9975) * bidRate) * 100000000) / 100000000 print("---- Trade Quantity = " + str(tradeQuantity) + " (" + str(ETHQuantity) + " * " + str(bidRate) + ")") # Execute full or remainder of trade print("---- SELL " + str(ogETHQuantity) + " ETH @ " + str(bidRate) + "BTC = " + str(tradeQuantity)) BTCQuantity = BTCQuantity + tradeQuantity sell = self.bittrex.sell_limit( market, ogETHQuantity, bidRate) print("---- " + str(sell)) actEthBtcRate = bidRate # I can delete this because I have a more accurate below from get_order_history break else: # Execute a portion of the trade print("---- Executing partial trade... " + str(bidQuantity) + "ETH @ " + str(bidRate) + "BTC = " + str(bidQuantity * bidRate)) BTCQuantity = BTCQuantity + bidTotal sell = self.bittrex.sell_limit( market, bidQuantity, bidRate) print(sell) ETHQuantity = ETHQuantity - bidQuantity # execute trade ethOrderCount = ethOrderCount + 1 print(BTCQuantity) finalTrade = time.time() - startTime print("Time since arb calc = " + str(finalTrade)) btcAltMarket = self.bittrex.get_market_summary("BTC-" + str(alt)) btcAltVolume = btcAltMarket["result"][0]["Volume"] altEthMarket = self.bittrex.get_market_summary("ETH-" + str(alt)) altEthVolume = altEthMarket["result"][0]["Volume"] ethBtcMarket = self.bittrex.get_market_summary("BTC-ETH") ethBtcVolume = ethBtcMarket["result"][0]["Volume"] # Grab bittrex Trade Details # 1 - BTC-ALT #tradeDetails = self.bittrex.get_order_history() tradeDetails = self.bittrex.get_order_history() tradeOne = tradeDetails["result"][2] tradeTwo = tradeDetails["result"][1] tradeThree = tradeDetails["result"][0] # Actual Arb Return tradeOneActualValue = tradeOne["Price"] + tradeOne[ "Commission"] tradeThreeActualValue = tradeThree["Price"] + tradeThree[ "Commission"] actualArbReturn = tradeThreeActualValue / tradeOneActualValue # Actual Rates tradeOneActualRate = tradeOne["PricePerUnit"] tradeTwoActualRate = tradeTwo["PricePerUnit"] tradeThreeActualRate = tradeThree["PricePerUnit"] with open('Trade Tracker.csv', 'a', newline='') as csvfile: tracker = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) tracker.writerow([ arbPath, datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S.%f")[:-3], btcResult, actualArbReturn, str(btcAlt[1]), str(btcAltDiff), btcAlt[1] + btcAltDiff, tradeOneActualRate, str(btcAlt[1] - tradeOneActualRate), str(( (btcAlt[1] - tradeOneActualRate) / btcAlt[1]) * 100), str(firstTrade), str(btcAltVolume), str(ethAlt[1]), str(altEthDiff), str(ethAlt[1] + altEthDiff), tradeTwoActualRate, str(ethAlt[1] - tradeTwoActualRate), str(( (ethAlt[1] - tradeTwoActualRate) / ethAlt[1]) * 100), str(secondTrade), str(altEthVolume), str(btc_eth_BTC), str(ethBtcDiff), str(btc_eth_BTC + ethBtcDiff), tradeThreeActualRate, str(btc_eth_BTC - tradeThreeActualRate), str(((btc_eth_BTC - tradeThreeActualRate) / btc_eth_BTC) * 100), str(finalTrade), str(ethBtcVolume) ]) print("Excel Save Successful") db = firebase.database() data = { "Arb Path": arbPath, "Date Time": datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S.%f")[:-3], "Principle": principle, "Actual Return": BTCQuantity, "Expected Arb Return": btcResult, "Actual Arb Return": actualArbReturn, "Trade 1 Quoted Rate": str(btcAlt[1]), "Trade 1 Adjustment": str(btcAltDiff), "Trade 1 Adjusted Quote": btcAlt[1] + btcAltDiff, "Trade 1 Actual Rate": tradeOneActualRate, "Trade 1 Actual-Quote Diff": str(btcAlt[1] - tradeOneActualRate), "Trade 1 Actual-Quote % Diff": str(((btcAlt[1] - tradeOneActualRate) / btcAlt[1]) * 100), "Trade 1 Time From Quote": str(firstTrade), "Trade 1 Market Volume": str(btcAltVolume), "Trade 2 Quoted Rate": str(ethAlt[1]), "Trade 2 Adjustment": str(altEthDiff), "Trade 2 Adjusted Quote": str(ethAlt[1] + altEthDiff), "Trade 2 Actual Rate": tradeTwoActualRate, "Trade 2 Actual-Quote Diff": str(ethAlt[1] - tradeTwoActualRate), "Trade 2 Actual-Quote % Diff": str(((ethAlt[1] - tradeTwoActualRate) / ethAlt[1]) * 100), "Trade 2 Time From Quote": str(secondTrade), "Trade 2 Market Volume": str(altEthVolume), "Trade 3 Quoted Rate": str(btc_eth_BTC), "Trade 3 Adjustment": str(ethBtcDiff), "Trade 3 Adjusted Quote": str(btc_eth_BTC + ethBtcDiff), "Trade 3 Actual Rate": tradeThreeActualRate, "Trade 3 Actual-Quote Diff": str(btc_eth_BTC - tradeThreeActualRate), "Trade 3 Actual-Quote % Diff Rate": str(((btc_eth_BTC - tradeThreeActualRate) / btc_eth_BTC) * 100), "Trade 3 Time From Quote": str(finalTrade), "Trade 3 Market Volume": str(ethBtcVolume) } db.child("Successful Transactions").push(data) else: print("ALT -> ETH Fail") else: print("BTC -> ALT Fail")
class BittrexDriver: fee = 0.0025 name = "Bittrex" def __init__(self, api_key, secret): api_b = '' key_b = '' self.api = Bittrex(api_key, secret) pass def get_market_info(self): # to get data ask and bid for pair market = {} try: tickers = self.api.get_market_summaries() tickers = tickers['result'] for ticker in tickers: pair = ticker['MarketName'].split('-') pair = tuple(pair) market[pair] = (float(ticker['Ask']), float(ticker['Bid'])) except: market = {} return market def get_order(self, pairs): pair = '{0}-{1}'.format(pairs[0], pairs[1]) try: orders = self.api.get_orderbook(pair, 'both') ask_rate = float( orders['result']['sell'][0]['Rate']) # ask-sell rate bid_rate = float(orders['result']['buy'][0]['Rate']) #bid-buy rate ask_quanity = float(orders['result']['sell'][0]['Quantity']) bid_quanity = float(orders['result']['buy'][0]['Quantity']) order = { 'ask_rate': ask_rate, 'ask_quanity': ask_quanity, 'bid_rate': bid_rate, 'bid_quanity': bid_quanity } except: order = { 'ask_rate': '0', 'ask_quanity': '0', 'bid_rate': '0', 'bid_quanity': '0' } return order def get_txFee(self): txfee = list() currencies = self.api.get_currencies() for i in currencies['result']: txfee.append((i['Currency'], i['CurrencyLong'], float(i['TxFee']))) return txfee # create list of tuples(len = 3) 1 - trade, 2- trade name 3 - txFee def create_pairs(self): fee = self.get_txFee() # txfee list of tuples(len = 3) 1 - trade, 2- trade name 3 - txFee firstmarket = ('BTC', 'ETH', 'USDT') listpair = list() for fi in firstmarket: for tx in fee: listpair.append((fi, tx[0])) return listpair # create list of tuples-pair 1 - trade, 2- currency
class BittrexBuysellWorker(object): def __init__(self, key=None, secret=None, token=None): self.EXCHANGE_RATE = 0.9975 # 0.25% for each trading transaction self.api = Bittrex(key, secret) self.token = token try: m = self.api.get_market_summaries() #print m market_list = [] for market in m.get("result"): market_list.append(market.get("MarketName")) #print marketlist except: print "Error: Cannot get market summaries" exit(1) self.market_list = market_list def w_get_api(self): """ Get balance of a coin :return: api Bittrex.py :rtype : Bittrex class """ return self.api def w_get_balance(self, coin): """ Get balance of a coin :return: current balance value :rtype : float """ try: m = self.api.get_balance(coin) print m if (m.get("success")): v = m.get("result").get("Balance") return v if v else 0 else: print("Cannot get {} balance".format(coin)) return ERROR.CMD_UNSUCCESS except: print("Error Account/Connection issue. Get {} balance failed". format(coin)) return ERROR.CONNECTION_FAIL def w_get_market_name(self, coin1, coin2): """ Get marketname for pair of coins :param coin1: String literal for coin 1 (ex: USDT) :param coin2: String literal for coin 2 (ex: XMR) :return: (MarketName, "Buy"/"Sell") :rtype : str """ market = coin1 + "-" + coin2 if market in self.market_list: return (market, "Buy") else: market = coin2 + "-" + coin1 if market in self.market_list: return (market, "Sell") else: print "Error: Invalid coin pair" return (None, None) def w_get_price(self, market, type, unit=0, depth=20): """ Get price Ask Last Bid :param market: String literal for coin1-coin2 (ex: USDT-XMR) :param type: Ask/Last/Bid :param unit: if unit != 0, get price with respect to order book :return: price :rtype : float """ if type is "Last" or "Bid" or "Ask": try: price = self.api.get_marketsummary(market).get( "result")[0].get(type) if type == "Ask": ordertype = "sell" elif type == "Bid": ordertype = "buy" else: #Dont need to check order book for Last return price m = self.api.get_orderbook(market, ordertype, depth) #print m if (m.get("message") != ""): print "Fail to get order book of {}: {}".format( market, m.get("message")) return ERROR.CMD_UNSUCCESS else: order_price_list = m.get("result") #print order_price_list sum_quantity = 0 for o in order_price_list: #print o quantity = o.get("Quantity") price = o.get("Rate") sum_quantity += quantity if (sum_quantity >= unit): return price except: print("Error in get {} price".format(market)) return ERROR.CONNECTION_FAIL else: print("Invalid type of market (Ask/Bid/Last)") return ERROR.PARAMETERS_INVALID '''To do: unit != 0''' def w_get_open_order(self, market=None): """ Get list of uuid of open orders :param market: String literal for coin1-coin2 (ex: USDT-XMR) :return: uuid list :rtype : str """ return self.api.get_open_orders(market) def w_order_buy_sell(self, coin1, coin2, value1, price, timeout, cancel_on_timeout=True): """ Buy/Sell from coin c1 to coin coin2 at price :param coin1: String literal for coin 1 (ex: USDT) :param coin2: String literal for coin 2 (ex: XMR) :param value1: The value of coin1 which is used to buy/sell :param price: buy/sell price, can be Ask, Last or Bid :return: uuid order :rtype : str """ value2_before = self.w_get_balance(coin2) #get current coin2 balance market, type = self.w_get_market_name(coin1, coin2) #print market, type #Buy and sell are seperated from market point of view. if (type == "Buy"): order_buy_sell = self.api.buy_limit quantity = value1 / price * self.EXCHANGE_RATE value2 = quantity * self.EXCHANGE_RATE elif (type) == "Sell": order_buy_sell = self.api.sell_limit quantity = value1 value2 = quantity * price * self.EXCHANGE_RATE else: print "Buy/Sell Error: Invalid market {}-{}".format(coin1, coin2) return ERROR.CMD_INVALID print("@@@ From {} {} buy {} {} at price {}.".format( value1, coin1, value2, coin2, price)) #Process buy/sell within timeout #Several posible cases: # 1. The price is too high/low, no one wants to buy/sell # 2. The connection drops while waiting the result # 3. The quantity is too low -> "INSUFFICIENT_FUNDS" response from server try: m = order_buy_sell(market, quantity, price) if (m.get("success") == True): uuid = m.get("result").get("uuid") process_time = time.time() + timeout while 1: value2_after = self.w_get_balance(coin2) if time.time() > process_time: if cancel_on_timeout: #Cancel order because of timeout self.w_cancel_order(uuid) print "Cancel order!" else: print "Order is still open!" return uuid print "{} transaction was timeout".format(type) return ERROR.TIME_OUT if (value2_after < 0): #Error print "Error: in balance code {}".format(value2_after) return ERROR.CMD_UNSUCCESS if (value2_after - value2_before >= value2 * 0.9): #offset 10% for safety #buy success return uuid elif m.get("message") == "INSUFFICIENT_FUNDS": print("INSUFFICIENT_FUNDS issue") print m return ERROR.PARAMETERS_INVALID else: print m return ERROR.CMD_UNSUCCESS except: print "Error buy/sell. Conection failed." return ERROR.CONNECTION_FAIL def w_cancel_order(self, uuid): """ Cancel an order via uuid :param uuid: order uuid :return: error code :rtype : ERROR """ try: #todo: need check timeout self.api.cancel(uuid) while uuid in self.api.get_open_orders(): print "Wait for cancel order {}".format(uuid) return ERROR.CMD_SUCCESS except: print "Cannot cancel order {}".format(uuid) return ERROR.CONNECTION_FAIL def w_get_price_by_order_book(self, market, ordertype, value, depth=20): """ Get the corresponding price for a given value -> Avoid stuck in buy/sell order :param market: Ex: USDT-XMR :param ordertype: "buy" or "sell" :param value: The value of coin1 which is used to buy/sell :return: uuid order :rtype : str """ return 0
my_bittrex = Bittrex(key, secret) # Get Markets markets = my_bittrex.get_markets() marketsdf = pd.DataFrame.from_dict(markets['result']) # Get Currencies currencies = pd.DataFrame.from_dict(my_bittrex.get_currencies()['result']) currencies_list = currencies[currencies['IsActive'] == True]['Currency'].unique() # Get Ticker ticker = my_bittrex.get_ticker('BTC-LTC') print ticker['result'].head() # Get Market Summaries summaries = my_bittrex.get_market_summaries() summariesdf = pd.DataFrame.from_dict(summaries['result']) print summariesdf.head() # Get Market Summary summary = my_bittrex.get_marketsummary('BTC-LTC') summarydf = pd.DataFrame.from_dict(summary['result']) print summarydf.head() # Get Orderbook orderbook = my_bittrex.get_orderbook('BTC-LTC') orderbookbuydf = pd.DataFrame.from_dict(orderbook['result']['buy']) orderbookselldf = pd.DataFrame.from_dict(orderbook['result']['sell']) print orderbookbuydf.head() print orderbookselldf.head() # Get Market History history = my_bittrex.get_market_history('BTC-LTC') historydf = pd.DataFrame.from_dict(history['result']) print historydf.head()
class CryptoCommander: def __init__(self, poloapicreds=['', ''], bittrexapicreds=['', '']): print( "Initializing Crypto Commander, Intelligent and Responsive Crypto-Currency Platform..." ) print( "Disclaimer!! You have launched this via command line, great caution is advised and the developers are NOT responsible for proper usage or lost coins!" ) print( "Notice - :: :: Bitcoin & Crypto-Currencies are largely untested and come with no assurances! Trade with care. :: ::" ) if poloapicreds == ['', '']: print( "No poloniex credentials found, skipping initialization. This may cause instability!" ) else: try: self.poloniexBot = poloniex(poloapicreds[0], poloapicreds[1]) self.btcBalance, self.btsBalance, self.clamBalance, self.dashBalance, self.dogeBalance, self.ethBalance, self.fctBalance, self.ltcBalance, self.maidBalance, self.strBalance, self.xmrBalance, self.xrpBalance, = Decimal( 0.0), Decimal(0.0), Decimal(0.0), Decimal(0.0), Decimal( 0.0), Decimal(0.0), Decimal(0.0), Decimal( 0.0), Decimal(0.0), Decimal(0.0), Decimal( 0.0), Decimal(0.0) except AttributeError: print( "An error occurred trying to initialize Poloniex functionality." ) if bittrexapicreds == ['', '']: print( "No bittrex credentials detected, skipping initialization. This may cause instability!" ) else: try: self.bittrexBot = Bittrex(bittrexapicreds[0], bittrexapicreds[1]) except AttributeError: print( "An error occurred trying to initialized Bittrex functionality." ) def convert_coinpair_poloniex(self, coinpair): return coinpair.replace('-', '_') def get_tickers_raw(self, market): # A clone of the bittrex get_markets() & poloniex returnTicker commands, in a unified stream. if market == 'poloniex': return self.poloniexBot.returnTicker() elif market == 'bittrex': return self.bittrexBot.get_markets() def get_coinpair_ticker_raw(self, market, coinpair): # Returns raw market information on coin pair on market if market == 'poloniex': coinpair = self.convert_coinpair_poloniex(coinpair) rawtickerdata = self.get_tickers_raw(market) for coinpairdata in rawtickerdata: if coinpairdata == coinpair: return rawtickerdata[coinpairdata] if market == 'bittrex': return self.bittrexBot.get_ticker(coinpair.capitalize()) def getTickerData(self, market, bitcoinMarketsOnly=True, activeOnly=True, printFriendly=False, decimalTypes=True): #if market == 'poloniex: if market == 'bittrex': cryptoCommandTickers = {'BTC': [], 'Other': []} btcMarketsList = cryptoCommandTickers['BTC'] otherMarketsList = cryptoCommandTickers['Other'] stagingList = [] if printFriendly == True: decimalTypes = False for ticker in self.bittrexBot.get_markets()['result']: if ticker != None: stagingList.append([ str(ticker['MarketName']), str(ticker['BaseCurrency']), bool(str(ticker['IsActive'])) ]) for ticker in self.bittrexBot.get_market_summaries()['result']: if ticker != None: for list in stagingList: if list[0] == str(ticker['MarketName']): list.extend([ ticker['High'], ticker['Low'], ticker['Ask'], ticker['Bid'], ticker['Last'], ticker['PrevDay'], ticker['Volume'], ticker['BaseVolume'], (ticker['High'] + ticker['Low'] / 2.0) ]) for list in stagingList: if list[1] == 'BTC': btcMarketsList.append(list) else: otherMarketsList.append(list) if printFriendly == True: for dictobject in cryptoCommandTickers: for list in cryptoCommandTickers[dictobject]: for n, listobject in enumerate(list): if type(listobject) == float: list[n] = format(listobject, '.8f') elif decimalTypes == True: for dictobject in cryptoCommandTickers: for list in cryptoCommandTickers[dictobject]: for n, listobject in enumerate(list): if type(listobject) == float: list[n] = Decimal(format(listobject, '.8f')) return cryptoCommandTickers def getActiveMarketCurrencies(self, market, appendString=''): currentMarketList = [] if market == 'poloniex': rawCoinPairData = self.poloniexBot.api_query('returnTicker') for coinPairData in rawCoinPairData: if str(rawCoinPairData[coinPairData]['isFrozen']) == '0': currentMarketList.append( str(coinPairData).split('_', 1)[1]) if market == 'bittrex': for coinData in self.bittrexBot.get_currencies()['result']: if coinData['IsActive'] == True: currentMarketList.append(appendString + str(coinData['Currency'])) return set(currentMarketList) def getCurrentBalance(self, market, coin): if market == 'poloniex': return self.poloniexBot.returnBalances()[coin.upper()] elif market == 'bittrex': return self.bittrexBot.get_balance(coin)['result']['Balance'] def getTopOrder(self, market, coinPair, buyOrders): if buyOrders == True: if market == 'poloniex': for i in self.poloniexBot.returnOrderBook( coinPair.replace('-', '_'))['bids']: return i elif market == 'bittrex': for i in self.bittrexBot.get_orderbook(coinPair, 'buy')['result']: return i else: print('Not a valid market: ' + str(market)) else: if market == 'poloniex': for i in self.poloniexBot.returnOrderBook( coinPair.replace('-', '_'))['asks']: return i elif market == 'bittrex': for i in self.bittrexBot.get_orderbook(coinPair, 'sell')['results']: return i else: print('Not a valid market: ' + str(market)) def getWalletAddress(self, market, coin): if market == "poloniex" or market == "Poloniex": return self.poloniexBot.api_query('returnDepositAddresses')[coin] elif market == "bittrex" or market == "Bittrex": return self.bittrexBot.get_balance(coin)['result']['CryptoAddress'] def compareMarkets(self, market1, market2): currentActiveMarketsLists = [ self.getActiveMarketCurrencies(market1), self.getActiveMarketCurrencies(market2) ] comparisonList = [] for i in currentActiveMarketsLists[0]: for y in currentActiveMarketsLists[1]: if i == y: comparisonList.append(i) else: continue return comparisonList def getCoinPairPriceDifferencePercent(self, buyPrice, sellPrice): return (((float(buyPrice) - float(sellPrice)) / float(buyPrice)) * 100.00) def arbitrageScan(self, market1, market2, minPercent=0.45): try: arbOpportunitiesList = [] for coinpair in self.doMarketComparison(market1, market2): print("Scanning Coin Pair : " + str(coinpair)) differenceBetweenMarket1and2 = format( self.getCoinPairPriceDifferencePercent( float(self.getTopOrder(market1, coinpair, False, 1)), float(self.getTopOrder(market2, coinpair, True, 1)))) differenceBetweenMarket2and1 = format( self.getCoinPairPriceDifferencePercent( float(self.getTopOrder(market2, coinpair, False, 1)), float(self.getTopOrder(market1, coinpair, True, 1)))) if float(differenceBetweenMarket2and1) < (-.525 - minPercent): if (float(self.getTopOrder(market1, coinpair, True)[0]) * float( self.getTopOrder(market1, coinpair, True)[1]) ) >= float(self.getCurrentBalance(market1, "BTC")): print("Arb Op: " + str(differenceBetweenMarket2and1) + " for coin pair ") print("Info: Bittrex: Buy:: ") print(self.getTopOrder('bittrex', coinpair, True)) print("- Sell:: ") print(self.getTopOrder('bittrex', coinpair, False)) arbOpportunity = (coinpair, "Market2to1", differenceBetweenMarket2and1, 1) arbOpportunitiesList.append(arbOpportunity) else: continue elif float(differenceBetweenMarket1and2) < (-.525 - minPercent): if float( self.getTopOrder('bittrex', coinpair, True, 3)[0] ) * float(self.getTopOrder( 'bittrex', coinpair, True)[1]) >= float( self.getCurrentBalance(market2, "BTC")): print("Arb Op: ") print(str(differenceBetweenMarket1and2)) print("Info: Bittrex: Buy:: ") print(self.getTopOrder('poloniex', coinpair, True)) print("- Sell:: ") print(self.getTopOrder('poloniex', coinpair, False)) print("Info: Poloniex: Buy:: ") print(self.getTopOrder('bittrex', coinpair, True)) print("- Sell:: ") print(self.getTopOrder('bittrex', coinpair, False)) arbOpportunity = (coinpair, "Market1to2", differenceBetweenMarket1and2, 1) arbOpportunitiesList.append(arbOpportunity) else: continue else: print(differenceBetweenMarket1and2 + " or " + differenceBetweenMarket2and1 + " is more than -.7") continue return arbOpportunitiesList except AttributeError: print("Attribute Error") def selectBestOpportunity(self, market1, market2, minPercent=0.45): opportunitiesList = [] while opportunitiesList == []: opportunitiesList = self.arbitrageScan(market1, market2, minPercent) if len(opportunitiesList) != 0: bestOpportunity = opportunitiesList[0] for opportunity in opportunitiesList: if bestOpportunity[2] < opportunity[2]: bestOpportunity = opportunity else: print("No Opportunities Found") bestOpportunity = ("", "", 0.0, 0) return bestOpportunity def activateArbitrage(self, market1, market2, minPercent=0.45): bestArbitrageOpportunity = self.selectBestOpportunity( market1, market2, minPercent) coinName = str(bestArbitrageOpportunity[0]).replace("BTC-", "") if bestArbitrageOpportunity[1] == 'Market1to2': fullTopBuyOrder = self.getTopOrder(market1, bestArbitrageOpportunity[0], False) btcBuyOrderAvailable = (float(fullTopBuyOrder[0]) * float(fullTopBuyOrder[1])) btcBalanceOnMarket = float( self.getCurrentBalance('poloniex', "BTC")) if float(btcBuyOrderAvailable) > float(btcBalanceOnMarket): btcBuyOrderAvailable = float(btcBalanceOnMarket) coinAvailable = float(btcBuyOrderAvailable) / float( fullTopBuyOrder[0]) if market1 == "poloniex" or market1 == "Poloniex": try: if float( self.getTopOrder( market1, bestArbitrageOpportunity[0], False, 0)[0]) * float( self.getTopOrder( market1, bestArbitrageOpportunity[0], False, 0)[1]) < float( self.getBalance('poloniex', 'BTC')): self.poloniexBot.buy( bestArbitrageOpportunity[0].replace("-", "_"), fullTopBuyOrder[0], coinAvailable) print( "Successfully Bought on Poloniex, Attempting to Send to Bittrex Now..." ) time.sleep(3) self.poloniexBot.withdraw( coinName, (self.getCurrentBalance('poloniex', coinName)), self.getWalletAddress('bittrex', coinName)) tempCounter = 0 print(self.getCurrentBalance('bittrex', coinName)) while float(self.getCurrentBalance( 'bittrex', coinName)) < 0.0005: time.sleep(5) tempCounter = tempCounter + 1 if tempCounter > 15: print("Still Awaiting Deposit...") tempCounter = 0 print( "Deposit Confirmed & Active! Preparing to Dump in 5 Seconds" ) time.sleep(5) while float(self.getCurrentBalance(market2, coinName) ) > 0.00050055 or self.getCurrentBalance( market2, coinName) == None: time.sleep(3) self.bittrexBot.sell_limit( bestArbitrageOpportunity[0], self.getCurrentBalance('bittrex', coinName), self.getTopOrder(market2, bestArbitrageOpportunity[0], True, 1)) print( "Finished Selling All the Coins that Could be Sold. Cycle Complete." ) else: print( "The order didnt stay high enough, starting over") self.activateArbitrage(market1, market2, minPercent) except MemoryError: print("Error") if bestArbitrageOpportunity[1] == 'Market2to1': fullTopBuyOrder = self.getTopOrder(market2, bestArbitrageOpportunity[0], False, 0) btcBuyOrderAvailable = (float(fullTopBuyOrder[0]) * float(fullTopBuyOrder[1])) btcBalanceOnMarket = float(self.getCurrentBalance(market2, "BTC")) if btcBuyOrderAvailable > btcBalanceOnMarket: btcBuyOrderAvailable = btcBalanceOnMarket coinAvailable = float(btcBuyOrderAvailable) / float( fullTopBuyOrder[0]) if market2 == "bittrex" or market2 == "Bittrex": try: if float( self.getTopOrder( market1, bestArbitrageOpportunity[0], False, 0)[0]) * float( self.getTopOrder( market1, bestArbitrageOpportunity[0], False, 0)[1]) < float( self.getCurrentBalance( 'bittrex', 'BTC')): print("Buying " + str(bestArbitrageOpportunity[0]) + " " + str(coinAvailable)) buy = self.bittrexBot.buy_limit( bestArbitrageOpportunity[0], coinAvailable, fullTopBuyOrder[0]) print(buy) time.sleep(5) if buy['success'] == True: print( "Successfully Bought on Bittrex, Attempting to Send to Poloniex Now..." ) time.sleep(5) self.bittrexBot.withdraw( coinName, self.getCurrentBalance(market2, coinName), self.getWalletAddress(market1, coinName)) tempCounter = 0 print(self.getCurrentBalance(market1, coinName)) while float( self.getCurrentBalance(market1, coinName) ) < 0.00050055 or self.getCurrentBalance( market1, coinName) == None: time.sleep(5) tempCounter = tempCounter + 1 if tempCounter > 15: print("Still Awaiting Deposit...") tempCounter = 0 print( "Deposit Confirmed and Active! Preparing to Dump in 5 Seconds" ) time.sleep(5) while float( self.getCurrentBalance( market1, coinName)) > 0.00010055: time.sleep(5) self.poloniexBot.sell( str(bestArbitrageOpportunity[0]).replace( "-", "_"), float( self.getTopOrder( market1, bestArbitrageOpportunity[0]. replace("-", "_"), True, 1)), self.getCurrentBalance(market1, coinName)) print( "Attempting to Sell Maximum Amount of Coins that Could be Sold." ) print("Finished Selling all coins. Cycle Complete") else: print("Failed to Buy") return "Failed to Buy" else: print( "The order didn't stay high enough, starting over") self.activateArbitrage(market1, market2, minPercent) except AttributeError: print("Attribute Error, sorry") def getLendingBalances(self): #Only works with Poloniex try: return cryptoCommander.poloniexBot.api_query( 'returnAvailableAccountBalances')['lending'] except KeyError: return [] def getCurrentLoanOffers(self, coin): #Only works with Poloniex ret = urllib2.request.urlopen('http://poloniex.com/public?command=' + 'returnLoanOrders' + '¤cy=' + str(coin)) return json.loads(ret.read()) def getPrimeLendingRate(self, coin, minWeight=Decimal('25.0')): #Only works with Poloniex accumulatedWeight, bestRate = Decimal('0.0'), Decimal('0.0') print(accumulatedWeight) for offer in self.getCurrentLoanOffers(coin)['offers']: if accumulatedWeight < minWeight: print('Accumulated weight is less than 25: ' + str(accumulatedWeight)) accumulatedWeight = accumulatedWeight + Decimal( str(offer['amount'])) else: print('Best rate is: ' + str(offer['rate'])) bestRate = Decimal(str(offer['rate'])) - Decimal('0.000001') break if bestRate < Decimal('0.000001'): bestRate = Decimal('0.000001') return bestRate def getActiveLoans(self): #Only works with Poloniex return self.poloniexBot.api_query('returnActiveLoans') def getOpenLoanOffers(self): #Only works with Poloniex try: return self.poloniexBot.api_query('returnOpenLoanOffers') except KeyError: return [] def cancelLoanOffer(self, currency, orderNumber): #Only works with Poloniex return self.poloniexBot.api_query('cancelLoanOffer', { "currency": currency, "orderNumber": orderNumber }) def cancelAllLoanOffers(self): openLoansDict = self.getOpenLoanOffers() for openLoanCoin in openLoansDict: for dataObject in openLoansDict[openLoanCoin]: self.cancelLoanOffer(openLoanCoin, dataObject[id]) def createLoanOffer(self, currency, amount, duration, autoRenew, lendingRate): return self.poloniexBot.api_query( 'createLoanOffer', { "currency": currency, "amount": amount, "duration": duration, "autoRenew": autoRenew, "lendingRate": lendingRate, }) def checkLendingStagnation(self): openLoansDict = self.getOpenLoanOffers() for openLoanCoin in openLoansDict: for data in openLoansDict[openLoanCoin]: if (datetime.datetime.utcnow() - datetime.datetime.strptime( str(data['date']), '%Y-%m-%d %X') > datetime.timedelta(minutes=2)): print('Cancelling Loan Orders that are stagnant.') self.cancelLoanOffer(openLoanCoin, data['id']) def placeAllLoans(self): balances = self.getLendingBalances() for coin in balances: try: print(balances[coin]) if type(balances[coin] ) != Decimal and balances[coin] > Decimal('0.0'): balances[coin] = Decimal(str(balances[coin])) if type(balances[coin] ) == Decimal and balances[coin] >= Decimal('0.01'): #print "Print currency available is: " + str(balances[coin]) + str(coin) + ", Lending Now." while Decimal(str(balances[coin])) >= Decimal('0.01'): if Decimal(str(balances[coin])) <= Decimal( '0.02') and Decimal(str( balances[coin])) >= Decimal('0.01'): print('lending between 0.01 and 0.02') print( self.createLoanOffer( coin, float(balances[coin]), 2, 0, self.getPrimeLendingRate(coin))) else: primeRate = self.getPrimeLendingRate(coin) print("Prime Rate is: " + str(primeRate)) if primeRate <= Decimal('0.000025') or Decimal( balances[coin]) > Decimal('0.1'): if Decimal(balances[coin]) >= Decimal('10.0'): if Decimal( balances[coin] ) < Decimal('20.0') and Decimal( balances[coin]) > Decimal('10.0'): print('lending between 10 and 20') print( self.createLoanOffer( coin, float(balances[coin]), 2, 0, primeRate)) else: print('lending 10') print( self.createLoanOffer( coin, 10.0, 2, 0, primeRate)) else: if Decimal( balances[coin]) > Decimal('0.1'): if Decimal(balances[coin]) < Decimal( '0.2') and Decimal( balances[coin]) > Decimal( '0.1'): print( 'lending between 0.1 and 0.2') print( self.createLoanOffer( coin, float(balances[coin]), 2, 0, primeRate)) else: print('lending 0.1') print( self.createLoanOffer( coin, 0.1, 2, 0, primeRate)) else: print('lending 0.01') print( self.createLoanOffer( coin, 0.01, 2, 0, primeRate)) else: print('lending 0.01') print( self.createLoanOffer( coin, 0.01, 2, 0, primeRate)) time.sleep(.2) balances = self.getLendingBalances() else: print('No coins available to lend, sorry!') except KeyError: print('All loans for ' + str(coin) + ' actively being lent.') def startLendingAutomation(self): while True: try: while self.getLendingBalances( ) != None and self.getOpenLoanOffers() != None: while any(self.getLendingBalances()) > Decimal( '0.001') or any(self.getOpenLoanOffers()): self.placeAllLoans() time.sleep(150) self.checkLendingStagnation() print('All Done.') except TypeError: print("NOT done")
class Market(object): """ Used to provide analysis of a market on Bittrex. """ def __init__(self, name, bittrex=None): """ :param name: String literal for the market (e.g. BTC-LTC) :type name: str :param bittrex: Instance of Bittrex, potentially with API_KEY and SECRET :type bittrex: Bittrex """ self.name = name self.basis, self.coin = self.name.split("-") if bittrex: self.bittrex = bittrex else: self.bittrex = Bittrex(None, None) @property def summary(self): response = self.bittrex.get_market_summary(self.name) if response['success']: return response['result'][0] raise Exception("Could not retrieve data from Bittrex: {:s}".format( response['message'])) @property def history(self): response = self.bittrex.get_market_history(self.name) if response['success']: df = pd.DataFrame(response['result']) df["TimeStamp"] = pd.to_datetime(df["TimeStamp"]) return df raise Exception("Could not retrieve data from Bittrex: {:s}".format( response['message'])) def _get_orderbook(self, depth_type, depth=20): response = self.bittrex.get_orderbook(self.name, depth_type, depth) if response['success']: return pd.DataFrame(response['result']) raise Exception("Could not retrieve data from Bittrex: {:s}".format( response['message'])) def get_buy_orderbook(self, depth=20): return self._get_orderbook(BUY_ORDERBOOK, depth) def get_sell_orderbook(self, depth=20): return self._get_orderbook(SELL_ORDERBOOK, depth) def get_both_orderbooks(self, depth=20): response = self.bittrex.get_orderbook(self.name, BOTH_ORDERBOOK, depth) if response['success']: return (pd.DataFrame(response['result']['buy']), pd.DataFrame(response['result']['sell'])) raise Exception("Could not retrieve data from Bittrex: {:s}".format( response['message'])) @property def ticker(self): response = self.bittrex.get_ticker(self.name) if response['success']: return response['result'] raise Exception("Could not retrieve data from Bittrex: {:s}".format( response['message'])) def get_price_time_series(self): return self.history[["TimeStamp", "Price"]] def __str__(self): return "{:s}\t{:s}".format(self.name, str(self.ticker))
bot.sendMessage(chat_id=str(last_message['from']['id']), text="\u2757\ufe0f Закупаю... ") while True: last_balance = my_bittrex.get_balance('BTC')['result'] BTC = last_balance['Available'] # доступный для торговли баланс if BTC <= 0.00050000: bot.sendMessage( chat_id=str(last_message['from']['id']), text='Слишком маленький баланс: \nBTC : {:.8f} '.format(BTC)) break # покупает заданную монету while True: sellOrderBook = sorted(my_bittrex.get_orderbook( "BTC-" + last_message['text'])['result']['sell'][0:10], key=lambda k: k['Quantity'], reverse=True) for x in range(0, 10): # баланс БТС выраженный в xCoin < количество монет из книги ордеров if BTC / sellOrderBook[x]['Rate'] < sellOrderBook[x][ 'Quantity']: text = my_bittrex.buy_limit( 'BTC-' + last_message['text'], BTC / sellOrderBook[x]['Rate'] * float(1 - cfg.getfloat('Data', 'commission') / 100), sellOrderBook[x]['Rate']) print( text, BTC / sellOrderBook[x]['Rate'] * float(1 - cfg.getfloat('Data', 'commission') / 100),