def get_order_history_binance(key, pair_name, limit=BINANCE_ORDER_HISTORY_LIMIT, last_order_id=None): post_details = get_order_history_binance_post_details( key, pair_name, limit, last_order_id) err_msg = "get_all_orders_binance for {pair_name}".format( pair_name=pair_name) status_code, json_response = send_get_request_with_header( post_details.final_url, post_details.headers, err_msg, timeout=BINANCE_DEAL_TIMEOUT) if get_logging_level() >= LOG_ALL_DEBUG: msg = "get_order_history_binance: {sc} {resp}".format( sc=status_code, resp=json_response) print_to_console(msg, LOG_ALL_DEBUG) log_to_file(msg, DEBUG_LOG_FILE_NAME) historical_orders = [] if status_code == STATUS.SUCCESS: msg = "{fn} - error response - {er}".format( fn=get_order_history_binance.func_name, er=json_response) status_code, historical_orders = get_orders_binance_result_processor( json_response, pair_name, msg) return status_code, historical_orders
def get_tickers_binance_url(pair_name): final_url = BINANCE_GET_TICKER if should_print_debug(): print_to_console(final_url, LOG_ALL_OTHER_STUFF) return final_url
def do_we_have_enough(self, currency_id, threshold): if currency_id in self.available_balance: return self.available_balance[currency_id] > threshold print_to_console("do_we_have_enough: no currency {c_id} within Balance 0_o".format( c_id=get_currency_name_by_id(currency_id)), LOG_ALL_ERRORS) return False
def check_highest_bid_bigger_than_lowest_ask(first_one, second_one, threshold): if not first_one.bid or not second_one.ask: return difference = get_change(first_one.bid, second_one.ask, provide_abs=False) if should_print_debug(): msg = """check_highest_bid_bigger_than_lowest_ask called for threshold = {threshold} BID: {bid:.7f} AKS: {ask:.7f} DIFF: {diff:.7f} """.format(threshold=threshold, bid=first_one.bid, ask=second_one.ask, diff=difference) print_to_console(msg, LOG_ALL_MARKET_RELATED_CRAP) if difference >= threshold: factual_threshold = threshold severity_flag = "" if 5.0 < difference < 10.0: severity_flag = "<b> ! ACT NOW ! </b>" factual_threshold = 5.0 elif difference > 10.0: severity_flag = "<b>!!! ACT IMMEDIATELY !!!</b>" factual_threshold = 10.0 msg = """{severity_flag} highest bid bigger than Lowest ask for more than {num} - <b>{diff:.7f}</b>""".format( severity_flag=severity_flag, num=factual_threshold, diff=difference) return msg, first_one.pair_id, first_one, second_one return ()
def get_balance(self, currency_id): if currency_id in self.available_balance: return self.available_balance.get(currency_id) print_to_console("get_balance: no currency {c_id} within Balance 0_o".format( c_id=get_currency_name_by_id(currency_id)), LOG_ALL_ERRORS) assert False
def process_placed_orders(args): """ Check for new orders placed by ANY of trading bots :param args: :return: """ pg_conn, settings = process_args(args) msg_queue = get_message_queue(host=settings.cache_host, port=settings.cache_port) cnt = 0 while True: order = msg_queue.get_next_order(ORDERS_MSG) if order is not None: save_order_into_pg(order, pg_conn) print_to_console("Saving {} in db".format(order), LOG_ALL_ERRORS) sleep_for(1) cnt += 1 if cnt >= HEARTBEAT_TIMEOUT: cnt = 0 print_to_console("Order storing heartbeat", LOG_ALL_ERRORS)
def add_sell_order_binance(key, pair_name, price, amount): post_details = add_sell_order_binance_url(key, pair_name, price, amount) err_msg = "add_sell_order binance called for {pair} for amount = {amount} " \ "with price {price}".format(pair=pair_name, amount=amount, price=price) # NOTE: Yeah, body must be empty! res = send_post_request_with_header(post_details, err_msg, max_tries=BINANCE_NUM_OF_DEAL_RETRY, timeout=BINANCE_DEAL_TIMEOUT) """ { "orderId": 1373492, "clientOrderId": "e04JGgCpafdrR6O1lOLwgD", "origQty": "1.00000000", "symbol": "RDNBTC", "side": "SELL", "timeInForce": "GTC", "status": "NEW", "transactTime": 1512581721384, "type": "LIMIT", "price": "1.00022220", "executedQty": "0.00000000" } """ if get_logging_level() >= LOG_ALL_MARKET_RELATED_CRAP: print_to_console(res, LOG_ALL_MARKET_RELATED_CRAP) log_to_file(res, "market_utils.log") return res
def log_dont_have_open_orders(cfg): msg = "process_expired_deals - list of open orders from both exchanges is empty, " \ "REMOVING all watched deals - consider them closed!" print_to_console(msg, LOG_ALL_ERRORS) log_to_file(msg, cfg.log_file_name) log_to_file(msg, EXPIRED_ORDER_PROCESSING_FILE_NAME)
def get_order_history_huobi(key, pair_name, time_start=0, time_end=get_now_seconds_utc()): post_details = get_order_history_huobi_post_details( key, pair_name, time_start, time_end) err_msg = "get_all_orders_huobi for {pair_name}".format( pair_name=pair_name) status_code, json_response = send_get_request_with_header( post_details.final_url, post_details.headers, err_msg, timeout=HUOBI_DEAL_TIMEOUT) if get_logging_level() >= LOG_ALL_DEBUG: msg = "get_order_history_huobi: {sc} {resp}".format(sc=status_code, resp=json_response) print_to_console(msg, LOG_ALL_DEBUG) log_to_file(msg, DEBUG_LOG_FILE_NAME) historical_orders = [] if status_code == STATUS.SUCCESS: status_code, historical_orders = get_orders_huobi_result_processor( json_response, pair_name) return status_code, historical_orders
def get_ticker_huobi_url(pair_name): final_url = HUOBI_GET_TICKER + pair_name if should_print_debug(): print_to_console(final_url, LOG_ALL_OTHER_STUFF) return final_url
def cancel_order_huobi(key, order_id): HUOBI_CANCEL_PATH = HUOBI_CANCEL_ORDER + str(order_id) + "/submitcancel" final_url = HUOBI_API_URL + HUOBI_CANCEL_PATH + "?" body = init_body(key) message = _urlencode(body).encode('utf8') msg = "POST\n{base_url}\n{path}\n{msg1}".format(base_url=HUOBI_API_ONLY, path=HUOBI_CANCEL_PATH, msg1=message) signature = sign_string_256_base64(key.secret, msg) body.append(("Signature", signature)) final_url += _urlencode(body).encode('utf8') body = {} post_details = PostRequestDetails(final_url, HUOBI_POST_HEADERS, body) if get_logging_level() >= LOG_ALL_MARKET_RELATED_CRAP: msg = "cancel_order_huobi: url - {url} headers - {headers} body - {body}".format( url=final_url, headers=HUOBI_POST_HEADERS, body=body) print_to_console(msg, LOG_ALL_MARKET_RELATED_CRAP) log_to_file(msg, "market_utils.log") err_msg = "cancel huobi order with id {id}".format(id=order_id) return send_post_request_with_logging(post_details, err_msg)
def log_dublicative_order_book(log_file_name, msg_queue, order_book, prev_order_book): msg = """ <b> !!! WARNING !!! </b> Number of similar asks OR bids are the same for the most recent and cached version of order book for exchange_name {exch} pair_name {pn} cached timest: {ts1} {dt1} recent timest: {ts2} {dt2} Verbose information can be found in logs error & """.format(exch=get_exchange_name_by_id(order_book.exchange_id), pn=get_currency_pair_name_by_exchange_id( order_book.pair_id, order_book.exchange_id), ts1=prev_order_book.timest, dt1=ts_to_string_utc(prev_order_book.timest), ts2=order_book.timest, dt2=ts_to_string_utc(order_book.timest)) msg_queue.add_message(DEAL_INFO_MSG, msg) print_to_console(msg, LOG_ALL_ERRORS) log_to_file(msg, log_file_name) msg = """Cached version of order book: {o} Recent version of order book: {oo} """.format(o=str(prev_order_book), oo=str(order_book)) log_to_file(msg, log_file_name)
def cancel_order_bittrex(key, order_id): # https://bittrex.com/api/v1.1/market/cancel?apikey=API_KEY&uuid=ORDER_UUID final_url = BITTREX_CANCEL_ORDER + key.api_key + "&nonce=" + str( generate_nonce()) body = { "uuid": order_id, } final_url += _urlencode(body) headers = {"apisign": signed_string(final_url, key.secret)} post_details = PostRequestDetails(final_url, headers, body) if get_logging_level() >= LOG_ALL_MARKET_RELATED_CRAP: msg = "cancel_order_bittrex: {res}".format(res=post_details) print_to_console(msg, LOG_ALL_MARKET_RELATED_CRAP) log_to_file(msg, "market_utils.log") err_msg = "cancel bittrex order with id {id}".format(id=order_id) res = send_get_request_with_header(post_details.final_url, post_details.headers, err_msg, timeout=BITTREX_DEAL_TIMEOUT) if get_logging_level() >= LOG_ALL_MARKET_RELATED_CRAP: print_to_console(res, LOG_ALL_MARKET_RELATED_CRAP) log_to_file(res, "market_utils.log") return res
def cancel_order_binance(key, pair_name, order_id): body = { "recvWindow": 5000, "timestamp": get_now_seconds_utc_ms(), "symbol": pair_name, "orderId": order_id } post_details = generate_post_request(BINANCE_CANCEL_ORDER, body, key) if get_logging_level() >= LOG_ALL_MARKET_RELATED_CRAP: msg = "cancel_order_binance: url - {url} headers - {headers} body - {body}".format( url=post_details.final_url, headers=post_details.headers, body=post_details.body) print_to_console(msg, LOG_ALL_MARKET_RELATED_CRAP) log_to_file(msg, "market_utils.log") err_msg = "cancel binance order with id {id}".format(id=order_id) res = send_delete_request_with_header(post_details, err_msg, max_tries=3) if get_logging_level() >= LOG_ALL_MARKET_RELATED_CRAP: print_to_console(res, LOG_ALL_MARKET_RELATED_CRAP) log_to_file(res, "market_utils.log") return res
def log_dont_supported_currency(cfg, exchange_id, pair_id): msg = "Not supported currency {idx}-{name} for {exch}".format( idx=cfg.pair_id, name=pair_id, exch=get_exchange_name_by_id(exchange_id)) print_to_console(msg, LOG_ALL_ERRORS) log_to_file(msg, cfg.log_file_name)
def get_order_book_huobi_url(pair_name): final_url = HUOBI_GET_ORDER_BOOK + pair_name + "&type=step0" if should_print_debug(): print_to_console(final_url, LOG_ALL_DEBUG) return final_url
def forward_new_messages(args): settings = CommonSettings.from_cfg(args.cfg) set_log_folder(settings.log_folder) set_logging_level(settings.logging_level_id) msg_queue = get_message_queue(host=settings.cache_host, port=settings.cache_port) do_we_have_data = False while True: for topic_id in QUEUE_TOPICS: msg = msg_queue.get_message_nowait(topic_id) if msg is not None: do_we_have_data = True notification_id = get_notification_id_by_topic_name(topic_id) err_code = send_single_message(msg, notification_id) if err_code == STATUS.FAILURE: err_msg = """telegram_notifier can't send message to telegram. Message will be re-processed on next iteration. {msg}""".format(msg=msg) log_to_file(err_msg, "telegram_notifier.log") print_to_console(err_msg, LOG_ALL_ERRORS) msg_queue.add_message_to_start(topic_id, msg) sleep_for(1) # # NOTE: it still can lead to throttling by telegram # if not do_we_have_data: sleep_for(1) do_we_have_data = False
def update_min_cap(cfg, deal_cap, processor): cur_timest_sec = get_now_seconds_utc() tickers = get_ticker_for_arbitrage( cfg.pair_id, cur_timest_sec, [cfg.buy_exchange_id, cfg.sell_exchange_id], processor) new_cap = compute_new_min_cap_from_tickers(cfg.pair_id, tickers) if new_cap > 0: msg = "Updating old cap {op}".format(op=deal_cap) log_to_file(msg, CAP_ADJUSTMENT_TRACE_LOG_FILE_NAME) deal_cap.update_min_volume_cap(new_cap, cur_timest_sec) msg = "New cap {op}".format(op=deal_cap) log_to_file(msg, CAP_ADJUSTMENT_TRACE_LOG_FILE_NAME) else: msg = """CAN'T update minimum_volume_cap for {pair_id} at following exchanges: {exch1} {exch2}""".format( pair_id=cfg.pair_id, exch1=get_exchange_name_by_id(cfg.buy_exchange_id), exch2=get_exchange_name_by_id(cfg.sell_exchange_id)) print_to_console(msg, LOG_ALL_ERRORS) log_to_file(msg, cfg.log_file_name) log_to_file(msg, CAP_ADJUSTMENT_TRACE_LOG_FILE_NAME)
def add_buy_order_binance(key, pair_name, price, amount): post_details = add_buy_order_binance_url(key, pair_name, price, amount) err_msg = "add_buy_order_binance called for {pair} for amount = {amount} with price {price}".format( pair=pair_name, amount=amount, price=price) res = send_post_request_with_header(post_details, err_msg, max_tries=BINANCE_NUM_OF_DEAL_RETRY, timeout=BINANCE_DEAL_TIMEOUT) """ { "orderId": 1373289, "clientOrderId": "Is7wGaKBtLBK7JjDkNAJwn", "origQty": "10.00000000", "symbol": "RDNBTC", "side": "BUY", "timeInForce": "GTC", "status": "NEW", "transactTime": 1512581468544, "type": "LIMIT", "price": "0.00022220", "executedQty": "0.00000000" } """ if get_logging_level() >= LOG_ALL_MARKET_RELATED_CRAP: print_to_console(res, LOG_ALL_MARKET_RELATED_CRAP) log_to_file(res, "market_utils.log") return res
def get_history_bittrex_url(pair_name, prev_time, now_time): # https://bittrex.com/api/v1.1/public/getmarkethistory?market=BTC-LTC final_url = BITTREX_GET_HISTORY + pair_name + "&since=" + str(prev_time) if should_print_debug(): print_to_console(final_url, LOG_ALL_OTHER_STUFF) return final_url
def get_order_book_poloniex_url(pair_name): # https://poloniex.com/public?command=returnOrderBook¤cyPair=BTC_NXT&depth=10, depth optional final_url = POLONIEX_GET_ORDER_BOOK + pair_name if should_print_debug(): print_to_console(final_url, LOG_ALL_DEBUG) return final_url
def log_order_book_update_failed_pre_sync(kind, exchange_id, order_book_updates): msg = "Reset stage will be initiated because Orderbook update FAILED during pre-SYNC stage - {kind} - " \ "for {exch_name} Update itself: {upd}".format(kind=kind, exch_name=get_exchange_name_by_id(exchange_id), upd=order_book_updates) log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME) print_to_console(msg, LOG_ALL_ERRORS)
def get_order_book_binance_url(currency): # https://api.binance.com/api/v1/depth?symbol=XMRETH final_url = BINANCE_GET_ORDER_BOOK + currency if should_print_debug(): print_to_console(final_url, LOG_ALL_DEBUG) return final_url
def get_history_huobi_url(pair_name, date_start, date_end): final_url = HUOBI_GET_HISTORY + pair_name + "&size=1000" if should_print_debug(): print_to_console(final_url, LOG_ALL_OTHER_STUFF) return final_url
def get_order_book_bittrex_url(pair_name): # https://bittrex.com/api/v1.1/public/getorderbook?type=both&market=BTC-LTC final_url = BITTREX_GET_ORDER_BOOK + pair_name if should_print_debug(): print_to_console(final_url, LOG_ALL_DEBUG) return final_url
def get_ticker_bittrex_url(pair_name): # https://bittrex.com/api/v1.1/public/getticker?market=BTC-LTC final_url = BITTREX_GET_TICKER + pair_name if should_print_debug(): print_to_console(final_url, LOG_ALL_OTHER_STUFF) return final_url
def log_warn_balance_not_updating(last_balance, msg_queue): msg = """ <b> !!! WARNING !!! </b> BALANCE were not updated for a {tm} seconds! last balance {bl}""".format(tm=BALANCE_EXPIRE_TIMEOUT, bl=last_balance) print_to_console(msg, LOG_ALL_ERRORS) msg_queue.add_message(DEAL_INFO_MSG, msg) log_to_file(msg, "balance.log")
def get_ohlc_poloniex_url(currency, date_start, date_end, period): final_url = POLONIEX_GET_OHLC + currency + "&start=" + str(date_start) + \ "&end=" + str(date_end) + "&period=" + str(period) if should_print_debug(): print_to_console(final_url, LOG_ALL_DEBUG) return final_url
def get_order_book_kraken_url(pair_name): # https://api.kraken.com/0/public/Depth?pair=XETHXXBT final_url = KRAKEN_GET_ORDER_BOOK + pair_name if should_print_debug(): print_to_console(final_url, LOG_ALL_DEBUG) return final_url
def get_ticker_kraken_url(pair_name): # https://api.kraken.com/0/public/Ticker?pair=DASHXBT final_url = KRAKEN_GET_TICKER + pair_name if should_print_debug(): print_to_console(final_url, LOG_ALL_DEBUG) return final_url