"minimalS": mins, } if midpoints[-1] < pt: border, aorder, bResp, aResp = "None", "None", "None", "None" try: if askImpact <= 0 or (askImpact < bidImpact and askImpact < askIM - (askIS * askAggression)): if minp < bid - askImpact and mins > ref and mins < ref * 1.5: aorder = str( "MINIMAL client.create_sell_order(" + str(ticker) + "," + str(minp) + "," + str(mins * 1.03) + ")") write['aorder'] = aorder print("MINIMAL client.create_sell_order(", ticker, minp, str((mins / np.mean([bid, minp])))[:6], ")") aResp = client.create_sell_order(ticker, minp, str((mins / np.mean([bid, minp])))[:6]) print("Restored bid:", client.create_buy_order(ticker, bid, str(100))) write['aResp'] = aResp quantity += mins * 0.95 execSells += 1 else: aorder = str( "NON_MINIMAL client.create_sell_order(" + str(ticker) + ',' + str(bid - askImpact) + ',' + str(ref * 1.03) + ")") write['aorder'] = aorder print("NON_MINIMAL client.create_sell_order(", ticker, bid - askImpact, str((ref / np.mean([bid, bid - askImpact])))[:6], ")") aResp = client.create_sell_order(ticker, bid - askImpact, str((ref / np.mean([bid, bid - askImpact])))[ :6]) print("Restored bid:", client.create_buy_order(ticker, bid, str(100))) write['aResp'] = aResp
bid = orderBook["BUY"][0][0] ask = orderBook["SELL"][0][0] spread = calcSpread(bid, ask) print("SPREAD: " + str(spread) + "%") if spread > minSpread: # get our active orders to check quantity and price points orders = client.get_active_orders(pair) noBuys = len(orders["BUY"]) == 0 noSells = len(orders["SELL"]) == 0 if noBuys and noSells: # place orders print("Placing new set of orders...") client.create_buy_order(pair, bid + disp, orderSize) client.create_sell_order(pair, ask - disp, orderSize) print("Orders placed") #else: # if there is a buy order and it is less than the bid, replace it #if len(orders["BUY"]) > 0 and orders["BUY"][0][2] < bid: # orderID = orders["BUY"][0][5] # print("Cancelling buy order...") # client.cancel_order(orderID, "BUY", pair) # print("Buy order cancelled") # print("Placing new buy order...") # client.create_buy_order(pair, bid + disp, orderSize) # print("Buy order placed") # if there is a sell order and it is more than the ask, replace it #if len(orders["SELL"]) > 0 and orders["SELL"][0][2] > ask:
if timeCnt % ovAgg == 0 and midpoints[-1] < pt: border, aorder, bResp, aResp = "None", "None", "None", "None" if askImpact <= askIM - (askIS * askAggression): aorder = str("NON_MINIMALclient.create_sell_order(" + str(ticker) + str(bid - askImpact) + str(ref * 1.03) + ")") write['aorder'] = aorder print( "NON_MINIMAL client.create_sell_order(", ticker, bid - askImpact, str((ref * 1.03 / np.mean([bid, bid - askImpact])))[:6], ")") aResp = client.create_sell_order( ticker, bid - askImpact, str((ref * 1.03 / np.mean([bid, bid - askImpact])))[:6]) write['aResp'] = aResp quantity += ref * 1.03 execTrades += 1 if bidImpact >= bidIM + (bidIS * bidAggression): border = str("NON_MAXIMAL client.create_buy_order(" + str(ticker) + "," + str(ask + bidImpact) + "," + str(ref * 1.03) + ")") write['border'] = border print( "NON_MAXIMAL client.create_buy_order(", ticker, ask + bidImpact, str(ref * 1.03 / np.mean([ask, ask + bidImpact]))[:6], ")")
def main(): print("========== ArbBot - "+ symbol + '-' + symbol_base + ' [' + conf('general.instance_name') +"] ========== "+str(dt)) actions = checkTelegramMessages() maxNow = getTradeMaxNow(symbol) bg = bitgrail.Bitgrail(conf('BitGrail.ApiKey'),conf('BitGrail.Secret')) kc_client = Client(conf('KuCoin.ApiKey'),conf('KuCoin.Secret')) bgm = bitgrail_mimic.Bitgrail_mimic() bgm.set_coin(symbol=symbol,symbol_base=symbol_base) if(conf('BitGrail.checkWithdrawals','bool')) and (random.randrange(10) > 5): if(bgm.checkWithdrawals(symbol)): print "BitGrail "+symbol+" withdrawals are open." telegramBot.text_message(symbol+" withdrawals just opened up on BitGrail!",topic="Mon.BG."+symbol+"_Withdrawals") else: print "BitGrail "+symbol+" withdrawals under maintenance." telegramBot.text_message(symbol+" withdrawals just became deactivated again! (under maintenance)",topic="Mon.BG."+symbol+"_Withdrawals") bg_balance = bgm.getBalance() print("\n========== Balances ==========") balanceStr = '' if(symbol in bg_balance): lastDealPrice = float(getConfig('cache','lastDealPrice')) coinValueBaseCurrency = bg_balance[symbol] * lastDealPrice total_in_BaseCurrency = coinValueBaseCurrency+bg_balance[symbol_base] balanceStr = "BitGrail: "+str(round(bg_balance[symbol_base],5)).ljust(8)+" "+symbol_base+" + "+str(round(bg_balance[symbol],5)).ljust(8)+" "+symbol+" = "+str(round(total_in_BaseCurrency,5)).ljust(8)+" "+symbol_base+"\n" balances = kc_client.get_all_balances() kc_balance = {} for balance in balances: if(balance['coinType'] == symbol_base): kc_balance[symbol_base] = balance['balance'] if(balance['coinType'] == symbol): if(balance['balance'] == False): balance['balance'] = 0.0 kc_balance[symbol] = balance['balance'] if(symbol in kc_balance): coinValueBaseCurrency2 = kc_balance[symbol] * lastDealPrice total_in_BaseCurrency2 = coinValueBaseCurrency2+kc_balance[symbol_base] balanceStr = balanceStr + "KuCoin: "+str(round(kc_balance[symbol_base],5)).ljust(8)+" "+symbol_base+" + "+str(round(kc_balance[symbol],5)).ljust(8)+" "+symbol+" = "+str(round(total_in_BaseCurrency2,5)).ljust(8)+" "+symbol_base+"\n" balanceStr = balanceStr + "Grand total: "+str(round(bg_balance[symbol_base]+kc_balance[symbol_base],5)).ljust(8)+" "+symbol_base+" + "+str(round(bg_balance[symbol]+kc_balance[symbol],5)).ljust(8)+" "+symbol+" = "+str(round(total_in_BaseCurrency+total_in_BaseCurrency2,5)).ljust(8)+" "+symbol_base+"\n" btc_gains = bg_balance[symbol_base]+kc_balance[symbol_base] btc_gains-= conf('general.starting_balance_btc','float') coin_gains = bg_balance[symbol]+kc_balance[symbol] coin_gains-= float(getConfig(symbol,'starting_balance')) drift_max = 1.5 * float(getConfig(symbol,'max_per_trade')) if(abs(coin_gains) > drift_max): msg = "The amount of coins has drifted by "+str(coin_gains)+" "+symbol msg += ". This is more than the allowed "+str(drift_max)+" "+symbol+". " telegramBot.text_message(msg,topic = "coin_drift") updateLimits(symbol,0,abortReason="CoinDriftedBy"+str(coin_gains)+symbol) else: telegramBot.text_message("Coin drift acceptable again.",topic = "coin_drift") balanceStr = str(balanceStr + symbol_base+" gains: ").ljust(14)+str(round(btc_gains,5)).ljust(8)+" "+symbol_base+" (about € "+str(round(btc_gains*BTCEUR,2))+") + "+str(round(coin_gains,4))+" "+symbol+"\n" print balanceStr ch_s = "===== BALANCE CHANGE =====\n" if(float(getConfig(symbol,'KC_last_balance')) != kc_balance[symbol]): ch_s += "KuCoin balance changed from "+getConfig(symbol,'KC_last_balance_base')+" to "+str(kc_balance[symbol_base])+" "+symbol_base + "\n" + balanceStr telegramBot.text_message(ch_s) print(ch_s + "\n") elif(float(getConfig(symbol,'BG_last_balance_base')) != bg_balance[symbol_base]): ch_s += "BitGrail balance changed from "+getConfig(symbol,'BG_last_balance_base')+" to "+str(bg_balance[symbol_base])+" "+symbol_base + "\n" + balanceStr telegramBot.text_message(ch_s) print(ch_s + "\n") elif(float(getConfig(symbol,'KC_last_balance')) != kc_balance[symbol]): ch_s += "KuCoin balance changed from "+getConfig(symbol,'KC_last_balance')+" to "+str(kc_balance[symbol])+" "+symbol + "\n" + balanceStr telegramBot.text_message(ch_s) print(ch_s + "\n") elif(float(getConfig(symbol,'BG_last_balance')) != bg_balance[symbol]): ch_s += "BitGrail balance changed from "+getConfig(symbol,'BG_last_balance')+" to "+str(bg_balance[symbol])+" "+symbol + "\n" + balanceStr telegramBot.text_message(ch_s) print(ch_s + "\n") setConfig(symbol,'KC_last_balance_base',kc_balance[symbol_base]) setConfig(symbol,'BG_last_balance_base',bg_balance[symbol_base]) setConfig(symbol,'KC_last_balance',kc_balance[symbol]) setConfig(symbol,'BG_last_balance',bg_balance[symbol]) ticker = bg.get("ticker",symbol_base+'-'+symbol) tBG = {'sell': float(ticker['ask']), 'buy': float(ticker['bid'])} ps = "========== Prices ==========\n" spread = 100 * round((tBG['sell'] - tBG['buy'])/tBG['buy'],2) ps += "BitGrail sell: "+str(tBG['sell']).ljust(10)+"\n" ps += "BitGrail buy: "+str(tBG['buy']).ljust(10)+" (spread: "+str(spread)+"%)\n" ticker = kc_client.get_tick(symbol+'-'+symbol_base) setConfig('cache','lastDealPrice',float(((ticker['lastDealPrice']+tBG['sell']+tBG['buy'])/3))) tKC = {} tKC['sell'] = float(ticker['sell']) tKC['buy'] = float(ticker['buy']) spread = 100 * round((tKC['sell'] - tKC['buy'])/tKC['buy'],2) ps += "KuCoin buy: "+str(tKC['buy']).ljust(10)+" \n" ps += "KuCoin sell: "+str(tKC['sell']).ljust(10)+" (spread: "+str(spread)+"%)" print(ps) if('sendBalance' in actions): telegramBot.text_message(balanceStr + "\n" + ps) print("\n========== Trade ==========") # cheapness_punchline, cheapness_details = compareCheapness(('BitGrail',tBG['sell'],tBG['buy']),('KuCoin',tKC['sell'],tKC['buy'])) # telegramBot.text_message(cheapness_punchline,topic="Mon.Cheapness",msg_full=cheapness_details) # Buy on KuCoin, sell on BitGrail profit_BaseSymbol = tBG['buy'] - tKC['sell'] profit1 = profit_BaseSymbol/tKC['sell']*100 profit1 -= 0.2 + 0.1 # remove fees margin = profit1 - min_perc_profit['KC'] traded, traded_amount, conclusion = (False, 0.0, "NO_ACTION") if(profit1 >= min_perc_profit['KC']): profit = profit1 conclusion = "KC->BG" print("On KuCoin you can buy "+symbol+" for "+str(tKC['sell'])+" which sells for "+str(tBG['buy'])+" on BitGrail ("+str(round(profit1,2))+"% profit).") print("On KuCoin you can buy "+symbol+" for € "+str(tKC['sell']*BTCEUR)+" which sells for €"+str(tBG['buy']*BTCEUR)+" on BitGrail ("+str(round(profit1,2))+"% profit).") maxNow = tradeCap(margin,maxNow,availableForSale = bg_balance[symbol]) if(maxNow > conf('general.min_trade_size','float')) and conf('general.trading_enabled','bool'): maxLeftTotal = getTradeLeftTotal(symbol) print("Most I can trade now is: "+str(maxNow)+" "+symbol+" of "+str(maxLeftTotal)+" total.") if(conf('KuCoin.disable_buy','bool')): print("Not allowed to buy from KuCoin. Skipping trade.") exit() if(conf('BitGrail.disable_sell','bool')): print("Not allowed to sell to BitGrail. Skipping trade.") exit() # Update limits (whatever happens next) updateLimits(symbol,maxNow) # Get buy price on market A (KC) buyAt = tKC['sell']*1.01 # asking price to get it at instantly # TODO: check order book if enough is actually available at that price! # Get selling price on market B (BG) sellAt = tBG['buy']*0.99 # price people already want to buy it at # Place order on market A (KC) if(buyAt > sellAt): s = "I'm paying more on BitGrail than I'm getting from the sale on KuCoin (buyAt: "+str(buyAt)+", sellAt: "+str(sellAt)+")!" print(s) telegramBot.text_message(s) print("kc_client.create_buy_order("+symbol+'-'+symbol_base+", "+str(buyAt)+", "+str(maxNow)+")") traded = True traded_amount = maxNow s = "Buying "+str(maxNow)+" "+symbol+" on KuCoin at "+str(buyAt) + ": " buy_order_result = kc_client.create_buy_order(symbol+'-'+symbol_base, str(buyAt), str(maxNow)) if('orderOid' in buy_order_result): print "Order placed: "+buy_order_result['orderOid'] s = s + "Order placed.\n" else: print "Order on KC probably wasnt placed! Server response: " pp.pprint(buy_order_result) err = "KC order placement failed." updateLimits(symbol,0,abortReason=err) telegramBot.text_message(s + balanceStr + err) quit("Dude, fix me! I guess I'll be nice and not sell your coins on the the other exchange.") # Place order on market B (BG) print("Creating sell order on BitGrail of "+str(maxNow)+" "+symbol+" at "+str(sellAt)) balance = bgm.getBalance() if(balance[symbol] < maxNow): warning = "Whoa... I'm not going to short "+symbol+". I almost tried to sell "+str(maxNow)+" but I have a balance of "+str(balance[symbol])+" on BitGrail. Capping to that." s = s + warning print warning maxNow = min(maxNow,balance[symbol]) result = bgm.createOrder(symbol_base+'-'+symbol,'sell',maxNow,sellAt) print("BG result:",result) s = s + "\nBitGrail sell order of "+str(maxNow)+" "+symbol+" placed at "+str(sellAt)+" "+symbol_base+". " s = s + "\nProfit "+str(round(profit1,1))+"% >= "+str(min_perc_profit['KC'])+"%.\n" s = s + balanceStr s = s + "Result: " + str(result) telegramBot.text_message(s + "\n" + graphURL) else: if(conf('general.trading_enabled','bool')): print("Not allowed to trade this small amount!") else: print("Not allowed to trade anymore!") else: print("KC->BG profit below "+str(min_perc_profit['KC'])+"%:\t"+str(round(profit1,2))+"%") # Buy on BitGrail, sell on KuCoin profit_BaseSymbol = tKC['buy'] - tBG['sell'] profit2 = profit_BaseSymbol/tBG['sell']*100 profit2 -= 0.2 + 0.1 # remove fees margin = profit2 - min_perc_profit['BG'] if(profit2 >= min_perc_profit['BG']): conclusion = "BitGrail is CHEAPER!" print("On BitGrail you can buy "+symbol+" for "+str(tBG['sell'])+" which sells for "+str(tKC['buy'])+" on KuCoin ("+str(round(profit2,2))+"% profit).") print("On BitGrail you can buy "+symbol+" for € "+str(tBG['sell']*BTCEUR)+" which sells for € "+str(tKC['buy']*BTCEUR)+" on KuCoin ("+str(round(profit2,2))+"% profit).") maxNow = tradeCap(margin,maxNow,availableForSale = kc_balance[symbol]) if(maxNow > conf('general.min_trade_size','float')) and conf('general.trading_enabled','bool'): maxLeftTotal = getTradeLeftTotal(symbol) print("Most I can trade now is: "+str(maxNow)+" "+symbol+" of "+str(maxLeftTotal)+" total.") if(conf('BitGrail.disable_buy','bool')): print("Not allowed to buy from BitGrail. Skipping trade.") exit() if(conf('KuCoin.disable_sell','bool')): print("Not allowed to sell to KuCoin. Skipping trade.") exit() # Update limits (whatever happens next) updateLimits(symbol,maxNow) # Get buy price on market A (BG) buyAt = tBG['sell']*1.01 # asking price to get it at instantly # TODO: check order book if enough is actually available at that price! # Get selling price on market B (KC) sellAt = tKC['buy']*0.99 # price people already want to buy it at # Place buy order on market A (BG) if(tBG['sell'] > tKC['buy']): s = "would potentially have paid more to buy that I'd get to sell. Not doing anything!" print(s) telegramBot.text_message(s) else: traded = True traded_amount = -maxNow s = "BitGrail: creating buy order of "+str(maxNow)+" "+symbol+" at "+str(buyAt)+"." print(s) bg_balance = bgm.getBalance() if(bg_balance[symbol_base] < maxNow * buyAt): s = s + "Not enough coins.\n" print "Crap. I ran out of "+symbol_base+" on the exchange... Want to buy: "+str(maxNow)+" for "+str(maxNow * buyAt)+" BTC but I have a balance of "+str(bg_balance[symbol_base])+" "+symbol_base+" on BitGrail." print("\nI N S E R T C O I N\n") quit("I'll stop purchasing now.") result = bgm.createOrder(symbol_base+'-'+symbol,'buy',maxNow,buyAt) print("BG result:",result) s = s + "\nResult: "+str(result) # Place sell order on market B (KC) print("kc_client.create_sell_order("+symbol_base+'-'+symbol+", "+str(sellAt)+", "+str(maxNow)+")") sell_order_result = kc_client.create_sell_order(symbol+'-'+symbol_base, str(sellAt), str(maxNow)) # { u'orderOid': u'5a54f203de88b3646e127e2f'} if('orderOid' in sell_order_result): s = s + "\nKuCoin sell order of "+str(maxNow)+" "+symbol+" placed at "+str(sellAt)+" "+symbol_base+"." s = s + "\nProfit "+str(round(profit2,1))+"% >= "+str(min_perc_profit['BG'])+"%.\n" s = s + balanceStr print "Order placed: "+sell_order_result['orderOid'] else: print "Order probably wasnt placed! Server response: " updateLimits(symbol,0,abortReason="KC sell order placement failed?") pp.pprint(sell_order_result) s = s + balanceStr s = s + "\nFailure: "+str(sell_order_result) telegramBot.text_message(s + "\n" + graphURL) else: if(conf('general.trading_enabled','bool')): print("Not allowed to trade this small amount!") else: print("Not allowed to trade anymore!") else: print("BG->KC profit below "+str(min_perc_profit['BG'])+"%:\t"+str(round(profit2,2))+"%") # time bitgrail_sell bitgrail_buy kcoin_sell kcoin_buy profitKC2BG profitBG2KC traded logCSV([dt,tBG['sell'],tBG['buy'],tKC['sell'],tKC['buy'],str(round(profit1,2))+"%",str(round(profit2,2))+"%",traded_amount])
rpx_eth_bid = rpx_eth_orders['BUY'][0][0] rpx_eth_ask = rpx_eth_orders['SELL'][0][0] rpx_btc_bid = rpx_btc_orders['BUY'][0][0] rpx_btc_ask = rpx_btc_orders['SELL'][0][0] # If RPX is cheaper in ETH if rpx_btc_bid / (rpx_eth_ask * eth_btc_ask) > 1.003: print 'Trade started...' rpx_amount = .005 / rpx_eth_ask print 'Buying RPX...' client.create_buy_order('RPX-ETH', rpx_eth_ask, rpx_amount) wait_until_filled('RPX-ETH') print 'Selling RPX...' client.create_sell_order('RPX-BTC', rpx_btc_bid, rpx_amount) wait_until_filled('RPX-BTC') print 'Buying ETH...' client.create_buy_order('ETH-BTC', eth_btc_ask, rpx_amount * rpx_btc_bid / eth_btc_ask) wait_until_filled('ETH-BTC') # IF RPX is cheaper in BTC elif (rpx_eth_bid * eth_btc_bid) / rpx_btc_ask > 1.003: print 'Trade started...' print 'Selling ETH...' client.create_sell_order('ETH-BTC', eth_btc_bid, 0.005) wait_until_filled('ETH-BTC') print 'Buying RPX...' btc_balance = client.get_coin_balance('BTC')['balance'] client.create_buy_order('RPX-BTC', rpx_btc_ask,
class KucoinWrapper(BaseExchangeWrapper): INTERVAL_MAP = { CandleTicks.one_minute : Client.RESOLUTION_1MINUTE, CandleTicks.five_minutes : Client.RESOLUTION_5MINUTES, CandleTicks.thirty_minutes : Client.RESOLUTION_30MINUTES, CandleTicks.one_hour : Client.RESOLUTION_1HOUR, CandleTicks.one_day : Client.RESOLUTION_1DAY, } TIME_SINCE_MAP = { CandleTicks.one_minute : "1 hour ago", CandleTicks.five_minutes : "5 hours ago", CandleTicks.thirty_minutes : "26 hours ago", CandleTicks.one_hour : "52 hours ago", CandleTicks.one_day : "60 days ago", } ORDER_TYPE_MAPPINGS = { 'BUY' : OrderType.limit_buy, 'SELL' : OrderType.limit_sell, } def __init__(self, api_key, api_secret): BaseExchangeWrapper.__init__(self) self._handle = Client(api_key, api_secret) self._filters = {} self._load_markets() def _perform_request(self, request_lambda): try: return request_lambda() except KucoinAPIException as ex: raise ExchangeAPIException('Failed to perform request: {0}'.format(ex.message)) def _load_currencies(self): result = self._perform_request(lambda: self._handle.get_coin_list()) for coin in result: self.add_currency( Currency( coin['coin'], coin['name'], coin['confirmationCount'], coin['withdrawFeeRate'] # check if this is right ) ) def _load_markets(self): self._load_currencies() result = self._perform_request(lambda: self._handle.get_trading_symbols()) for market in result: self.add_market(market['coinTypePair'], market['coinType']) def _make_symbol(self, base_currency_code, market_currency_code): return '{0}-{1}'.format(market_currency_code, base_currency_code) def _process_paged_request(self, make_request, callback): page = 1 limit = 50 data = self._perform_request(lambda: make_request(limit=limit, page=page)) while len(data['datas']) > 0: for entry in data['datas']: callback(entry) page += 1 data = make_request(limit=limit, page=page) def get_market_state(self, base_currency_code, market_currency_code): symbol = self._make_symbol(base_currency_code, market_currency_code) data = self._perform_request(lambda: self._handle.get_tick(symbol)) return MarketState(data['sell'], data['buy'], data['lastDealPrice']) def get_orderbook(self, base_currency_code, market_currency_code): symbol = self._make_symbol(base_currency_code, market_currency_code) data = self._perform_request(lambda: self._handle.get_order_book(symbol)) buy_orderbook = Orderbook() sell_orderbook = Orderbook() for item in data['BUY']: buy_orderbook.add_order(Order(item[0], item[1])) for item in data['SELL']: sell_orderbook.add_order(Order(item[0], item[1])) return (buy_orderbook, sell_orderbook) def get_candles(self, base_currency_code, market_currency_code, interval, limit): symbol = self._make_symbol(base_currency_code, market_currency_code) since = KucoinWrapper.TIME_SINCE_MAP[interval] kucoin_interval = KucoinWrapper.INTERVAL_MAP[interval] data = self._perform_request( lambda: self._handle.get_historical_klines_tv(symbol, kucoin_interval, since) ) output = [] for i in data: output.append(Candle( i[3], # Low i[2], # High i[1], # Open i[4], # Close dateparser.parse(str(i[0])) )) return output def get_wallets(self): output = [] self._process_paged_request( self._handle.get_all_balances, lambda entry: output.append(Wallet( entry['coinType'], entry['balance'], entry['balance'] - entry['freezeBalance'], entry['freezeBalance'] )) ) return output def get_wallet(self, currency_code): self.check_valid_currency(currency_code) data = self._perform_request(lambda: self._handle.get_coin_balance(currency_code)) return Wallet( self._currencies[currency_code], data['balance'], data['balance'] - data['freezeBalance'], data['freezeBalance'] ) def get_deposit_history(self, currency_code): request = lambda limit, page: self._handle.get_deposits( currency_code, limit=limit, page=page ) output = [] self._process_paged_request( request, lambda entry: output.append(Transfer( self._currencies[entry['coinType']], entry['amount'], entry['outerWalletTxid'], # is this right? 1 if entry['status'] == 'FINISHED' else 0, 0, # cost entry['status'] == 'CANCEL', dataparser.parse(str(entry['createdAt'])) )) ) return output def get_withdrawal_history(self, currency_code): request = lambda limit, page: self._handle.get_withdrawals( currency_code, limit=limit, page=page ) output = [] self._process_paged_request( request, lambda entry: output.append(Transfer( self._currencies[entry['coinType']], entry['amount'], entry['outerWalletTxid'], # is this right? 0, entry['fee'], entry['status'] == 'CANCEL', dataparser.parse(str(entry['createdAt'])) )) ) return output def get_open_orders(self): raise ExchangeAPIException('Not implemented') def get_order_history(self): output = [] self._process_paged_request( self._handle.get_dealt_orders, lambda entry: output.append(TradeOrder( data['orderOid'], self._currencies[base_currency], self._currencies[market_currency], None, # Date open dateparser.parse(str(data['createdAt'])), data['amount'], 0, # Amount remaining data['dealPrice'], data['dealPrice'], KucoinWrapper.ORDER_TYPE_MAPPINGS[data['direction']] )) ) return output def buy(self, base_currency_code, market_currency_code, amount, rate): symbol = self._make_symbol(base_currency_code, market_currency_code) result = self._perform_request(lambda: self._handle.create_buy_order(symbol, rate, amount)) return result['orderOid'] def sell(self, base_currency_code, market_currency_code, amount, rate): symbol = self._make_symbol(base_currency_code, market_currency_code) result = self._perform_request(lambda: self._handle.create_sell_order(symbol, rate, amount)) return result['orderOid'] def cancel_order(self, base_currency_code, market_currency_code, order_id): self._perform_request(lambda: self._handle.cancel_order(order_id, None)) def withdraw(self, currency_code, amount, address, address_tag): if address_tag: raise ExchangeAPIException('Address tag not supported') self._perform_request( lambda: self._handle.create_withdrawal(currency_code, amount, address) ) def get_deposit_address(self, currency_code): result = self._perform_request(lambda: self._handle.get_deposit_address(currency_code)) return CryptoAddress( currency_code, result['address'], None ) def transfers_needs_asset(self): return True
logging.info("Last sell price: " + str(price)) openOrders = (client.get_active_orders(tokenPair)) balance = client.get_coin_balance(currency) balance = (float(balance['balanceStr']) + float(extCoinBalance)) buyAmount = determine_buy_amount(balance) buyPrice = determine_initial_buy_price(price) logging.info("setting buy of " + str(buyAmount) + " at " + str(buyPrice)) logging.info( client.create_buy_order(tokenPair, buyPrice, buyAmount)) sellAmount = determine_sell_amount(balance) sellPrice = determine_initial_sell_price(price) logging.info("setting sell of " + str(sellAmount) + " at " + str(sellPrice)) logging.info( client.create_sell_order(tokenPair, sellPrice, sellAmount)) else: logging.info("No orders present...setting to ticker price") balance = client.get_coin_balance(currency) balance = (float(balance['balanceStr']) + float(extCoinBalance)) buyAmount = determine_buy_amount(balance) price = (client.get_tick(tokenPair)['lastDealPrice']) buyPrice = determine_initial_buy_price(price) print(buyPrice) logging.info("setting buy of " + str(buyAmount) + " at " + str(buyPrice)) logging.info( client.create_buy_order(tokenPair, buyPrice, buyAmount)) sellAmount = determine_sell_amount(balance) sellPrice = determine_initial_sell_price(price) logging.info("setting sell of " + str(sellAmount) + " at " +
class KucoinClient(AbstractClient): def __init__(self, listener): self.exchange = 'kucoin' self.trade_fee = Decimal(0.001) self.client = Client(api_keys.kucoin[0], api_keys.kucoin[1]) super(KucoinClient, self).__init__(listener) self.get_all_balances() def _buy(self, symbol, price, amount): result = self.client.create_buy_order(symbol, price, amount) self.open_orders[symbol] = [str(result['orderOid']), 'BUY', symbol] def _sell(self, symbol, price, amount): result = self.client.create_sell_order(symbol, price, amount) self.open_orders[symbol] = [str(result['orderOid']), 'SELL', symbol] def _cancel(self, symbol): order = self.open_orders.pop(symbol) self.client.cancel_order(order[0], order[1], symbol=order[2]) time.sleep(1) if not self.is_order_fulfilled(order[0]): raise Exception("cancelled order not fulfilled!") def is_order_fulfilled(self, orderOid): try: for data in self.client.get_dealt_orders()['datas']: if data['orderOid'] == orderOid: return True except (KucoinRequestException, KucoinAPIException) as e: print datetime.now(), "[Kucoin] is order fulfilled error", str( e).replace('\r\n', '') self.errors += 1 return False def get_all_balances(self): # Kucoin paginates the coin balances and we can only retrieve 20 coins per page page = 1 while True: try: result = self.client.get_all_balances_paged(limit=20, page=page) for balance in result['datas']: self.coin_balances[str(balance['coinType'])] = Decimal( str(balance['balance']) ) # + Decimal(balance['freezeBalance']) page = result['currPageNo'] + 1 if page > result['pageNos']: break except (KucoinRequestException, KucoinAPIException) as e: print datetime.now(), "[Kucoin] get all balances error:", str( e).replace('\r\n', '') self.errors += 1 break return self.coin_balances # Gets the buy/sell price and amount for one symbol at a time (inefficient). def _market_poll(self): result = {'success': False} result['client'] = self result['timestamp'] = int(time.time() * 1000) result['coinpairs'] = {} threads = [] for symbol in self.exchange_symbols: thread = threading.Thread(target=self._symbol_poll, args=[symbol, result]) thread.start() threads.append(thread) for thread in threads: thread.join() if len(result['coinpairs']) > 0: result['success'] = True return result def _symbol_poll(self, symbol, result): try: data = self.client.get_order_book(symbol, limit=1) if data['BUY'] is not None and data['SELL'] is not None: result['coinpairs'][self._get_arbitrager_coinpair(symbol)] = { 'buy': Decimal(str(data['BUY'][0][0])), 'buyAmount': Decimal(str(data['BUY'][0][1])), 'sell': Decimal(str(data['SELL'][0][0])), 'sellAmount': Decimal(str(data['SELL'][0][1])) } except (KucoinRequestException, KucoinAPIException) as e: print datetime.now(), "[Kucoin] market poll error", str(e).replace( '\r\n', '') self.errors += 1 # Gets the buy/sell price for all the symbols with one query but does not contain buy/sell amount (useless). @DeprecationWarning def market_poll_no_amount(self): threading.Timer(Consts.POLL_INTERVAL, self.market_poll_no_amount).start() timestamp = int(time.time() * 1000) try: coins = self.client.get_trading_symbols() if self.verbose: now = int(time.time() * 1000) print datetime.now( ), "[Kucoin] market_poll took", now - timestamp, "ms." except (KucoinRequestException, KucoinAPIException) as e: print datetime.now(), "[Kucoin] market poll error", str(e).replace( '\r\n', ' ') result = {'success': False} result['client'] = self return result result = {'success': True} result['client'] = self result['timestamp'] = timestamp result['coinpairs'] = {} for coin in coins: symbol = coin['symbol'] if symbol in self.exchange_symbols: result['coinpairs'][self._get_arbitrager_coinpair(symbol)] = { 'buy': Decimal(str(coin['buy'])), 'sell': Decimal(str(coin['sell'])) } # result['timestamp'] = coin['datetime'] if self.callback is None: print result else: self.callback(result)