예제 #1
0
    def on_public(self, compressed_data):
        msg = process_message(compressed_data)
        # FIXME Howdy DK - is this check promissing FAST?
        if not self.order_book_is_received and "orderBook" in compressed_data:
            self.order_book_is_received = True
            order_book_delta = parse_socket_order_book_poloniex(
                msg, self.pair_id)
        else:
            order_book_delta = parse_socket_update_poloniex(msg)

        if order_book_delta is None:
            #
            # Poloniex tend to send heartbeat messages: [1010]
            # When no messages have been sent out for one second, the server will send a heartbeat message as follows.
            # Absence of heartbeats indicates a protocol or networking issue and the client application is expected
            # to close the socket and try again.
            #
            str_msg = str(msg)

            if "1010" in str_msg:
                self.last_heartbeat_ts = get_now_seconds_utc()
            else:
                err_msg = "Poloniex - cant parse update from message: {msg}".format(
                    msg=str_msg)
                log_to_file(err_msg, SOCKET_ERRORS_LOG_FILE_NAME)
        else:
            self.last_heartbeat_ts = get_now_seconds_utc()
            self.on_update(EXCHANGE.POLONIEX, order_book_delta)
예제 #2
0
def test_time_epoch():
    t = get_now_seconds_utc()
    t1 = get_now_seconds_local()
    t2 = generate_nonce()
    print "utc", t
    print "local", t1
    print "nonce", t2
예제 #3
0
def check_deal_placements():
    if not YES_I_KNOW_WHAT_AM_I_DOING:
        die_hard("check_deal_placements may issue a real trade!")

    create_time = get_now_seconds_utc()
    fake_order_book_time1 = -10
    fake_order_book_time2 = -20
    deal_volume = 5
    pair_id = CURRENCY_PAIR.BTC_TO_ARDR

    sell_exchange_id = EXCHANGE.POLONIEX
    buy_exchange_id = EXCHANGE.BITTREX

    difference = "difference is HUGE"
    file_name = "test.log"

    msg_queue = get_message_queue()

    processor = ConnectionPool(pool_size=2)

    trade_at_first_exchange = Trade(DEAL_TYPE.SELL, sell_exchange_id, pair_id,
                                    0.00000001, deal_volume,
                                    fake_order_book_time1, create_time)

    trade_at_second_exchange = Trade(DEAL_TYPE.BUY, buy_exchange_id, pair_id,
                                     0.00004, deal_volume,
                                     fake_order_book_time2, create_time)

    trade_pairs = TradePair(trade_at_first_exchange, trade_at_second_exchange,
                            fake_order_book_time1, fake_order_book_time2,
                            DEAL_TYPE.DEBUG)

    init_deals_with_logging_speedy(trade_pairs, difference, file_name,
                                   processor, msg_queue)
예제 #4
0
def test_trade_history_huobi_methods():

    load_keys(API_KEY_PATH)
    key = get_key_by_exchange(EXCHANGE.HUOBI)

    time_end = get_now_seconds_utc()
    time_start = 0  # time_end - POLL_TIMEOUT

    pair_name = get_currency_pair_to_huobi(CURRENCY_PAIR.BTC_TO_LSK)

    huobi_orders_by_pair = get_order_history_huobi(key, pair_name, time_start,
                                                   time_end)

    for pair_id in huobi_orders_by_pair:
        pair_name = get_currency_pair_to_huobi(pair_id)
        print "PAIR NAME: ", pair_name
        for b in huobi_orders_by_pair[pair_id]:
            print b

    res, order_history = get_order_history_huobi(key, pair_name, time_start,
                                                 time_end)
    if len(order_history) > 0:
        for b in order_history:
            print b
    pg_conn = init_pg_connection(_db_host=DB_HOST,
                                 _db_port=DB_PORT,
                                 _db_name=DB_NAME)

    load_recent_huobi_trades_to_db(pg_conn,
                                   time_start,
                                   time_end,
                                   unique_only=True)
예제 #5
0
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)
예제 #6
0
def get_tickers():
    all_tickers = {}

    timest = get_now_seconds_utc()

    bittrex_tickers = {}
    for pair_name in BITTREX_CURRENCY_PAIRS:
        ticker = get_ticker_bittrex(pair_name, timest)
        if ticker is not None:
            bittrex_tickers[ticker.pair_id] = ticker
    all_tickers[EXCHANGE.BITTREX] = bittrex_tickers

    kraken_tickers = {}
    for pair_name in KRAKEN_CURRENCY_PAIRS:
        ticker = get_ticker_kraken(pair_name, timest)
        if ticker is not None:
            kraken_tickers[ticker.pair_id] = ticker
    all_tickers[EXCHANGE.KRAKEN] = kraken_tickers

    huobi_tickers = {}
    for pair_name in HUOBI_CURRENCY_PAIRS:
        ticker = get_ticker_huobi(pair_name, timest)
        if ticker is not None:
            huobi_tickers[ticker.pair_id] = ticker
    all_tickers[EXCHANGE.HUOBI] = huobi_tickers

    # NOTE: poloniex return all tickers by single call
    poloniex_tickers = get_tickers_poloniex(POLONIEX_CURRENCY_PAIRS, timest)
    all_tickers[EXCHANGE.POLONIEX] = poloniex_tickers

    # NOTE: binance return all tickers by single call
    binance_tickers = get_tickers_binance(BINANCE_CURRENCY_PAIRS, timest)
    all_tickers[EXCHANGE.BINANCE] = binance_tickers

    return all_tickers
예제 #7
0
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
예제 #8
0
def get_order_book_sync_and_slow():

    all_order_book = defaultdict(list)

    timest = get_now_seconds_utc()

    for currency in POLONIEX_CURRENCY_PAIRS:
        order_book = get_order_book_poloniex(currency, timest)
        if order_book is not None:
            all_order_book[EXCHANGE.POLONIEX].append(order_book)

    for currency in KRAKEN_CURRENCY_PAIRS:
        order_book = get_order_book_kraken(currency, timest)
        if order_book is not None:
            all_order_book[EXCHANGE.KRAKEN].append(order_book)

    for currency in BITTREX_CURRENCY_PAIRS:
        order_book = get_order_book_bittrex(currency, timest)
        if order_book is not None:
            all_order_book[EXCHANGE.BITTREX].append(order_book)

    for currency in BINANCE_CURRENCY_PAIRS:
        order_book = get_order_book_binance(currency, timest)
        if order_book is not None:
            all_order_book[EXCHANGE.BINANCE].append(order_book)

    for currency in HUOBI_CURRENCY_PAIRS:
        order_book = get_order_book_huobi(currency, timest)
        if order_book is not None:
            all_order_book[EXCHANGE.HUOBI].append(order_book)

    return all_order_book
예제 #9
0
def get_balance_poloniex(key):
    """
    https://poloniex.com/tradingApi
    {'Key': 'QN6SDFQG-XVG2CGG3-WDDG2WDV-VXZ7MYL3',
    'Sign': '368a800fcd4bc0f0d95151ed29c9f84ddf6cae6bc366d3105db1560318da72aa82281b5ea52f4d4ec929dd0eabc7339fe0e7dc824bf0f1c64e099344cd6e74d0'}
    {'nonce': 1508507033330, 'command': 'returnCompleteBalances'}

    {"LTC":{"available":"5.015","onOrders":"1.0025","btcValue":"0.078"},"NXT:{...} ... }

    """

    post_details = get_balance_poloniex_post_details(key)

    err_msg = "check poloniex balance called"

    timest = get_now_seconds_utc()
    error_code, res = send_post_request_with_header(
        post_details,
        err_msg,
        max_tries=POLONIEX_NUM_OF_DEAL_RETRY,
        timeout=POLONIEX_DEAL_TIMEOUT)

    if error_code == STATUS.SUCCESS:
        res = Balance.from_poloniex(timest, res)

    return error_code, res
예제 #10
0
def get_history_time_fast():
    end_time = get_now_seconds_utc()
    start_time = end_time - POLL_PERIOD_SECONDS
    processor = ConnectionPool()

    trade_history = get_history_speedup(start_time, end_time, processor)
    return trade_history
예제 #11
0
 def test_kraken_trade_history_retrieval(self):
     today = get_now_seconds_utc()
     yesterday = today - 24 * 3600
     for pair_name in KRAKEN_CURRENCIES:
         trade_history = get_history_kraken(pair_name, yesterday, today)
         for entry in trade_history:
             if entry:
                 self.assertEquals(type(entry), TradeHistory)
예제 #12
0
 def test_poloniex_trade_history_retrieval(self):
     today = get_now_seconds_utc()
     yesterday = today - 24 * 3600
     for pair_name in POLONIEX_CURRENCY_PAIRS:
         trade_history = get_history_poloniex(pair_name, yesterday, today)
         for entry in trade_history:
             if entry:
                 self.assertEquals(type(entry), TradeHistory)
예제 #13
0
 def test_binance_trade_history_retrieval(self):
     today = get_now_seconds_utc()
     yesterday = today - 24 * 3600
     for pair_name in BINANCE_CURRENCY_PAIRS:
         trade_history = get_history_binance(pair_name, yesterday, today)
         for entry in trade_history:
             if entry:
                 self.assertEquals(type(entry), TradeHistory)
예제 #14
0
 def test_kraken_ohlc_retrieval(self):
     date_end = get_now_seconds_utc()
     date_start = date_end - 900
     for pair_name in KRAKEN_CURRENCIES:
         period = 15
         candles = get_ohlc_kraken(pair_name, date_start, date_end, period)
         for candle in candles:
             if candle:
                 self.assertEquals(type(candle), Candle)
예제 #15
0
 def test_huobi_ohlc_retrieval(self):
     date_end = get_now_seconds_utc()
     date_start = date_end - 900
     for currency in HUOBI_CURRENCY_PAIRS:
         period = "15min"
         candles = get_ohlc_huobi(currency, date_start, date_end, period)
         for candle in candles:
             if candle:
                 self.assertEquals(type(candle), Candle)
예제 #16
0
 def test_binance_ohlc_retrieval(self):
     date_end = get_now_seconds_utc()
     date_start = date_end - 900
     for currency in BINANCE_CURRENCY_PAIRS:
         period = "15m"
         candles = get_ohlc_binance(currency, date_start, date_end, period)
         for candle in candles:
             if candle:
                 self.assertEquals(type(candle), Candle)
예제 #17
0
 def test_bittrex_ohlc_retrieval(self):
     date_end = get_now_seconds_utc()
     date_start = date_end - 900
     for pair_name in BITTREX_CURRENCY_PAIRS:
         period = "thirtyMin"
         candles = get_ohlc_bittrex(pair_name, date_start, date_end, period)
         for candle in candles:
             if candle:
                 self.assertEquals(type(candle), Candle)
예제 #18
0
    def subscribe(self):

        if self.should_run:
            die_hard("Poloniex - another subcription thread running?")

        if get_logging_level() == LOG_ALL_TRACE:
            msg = "Poloniex - call subscribe!"
            log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)
            print_to_console(msg, LOG_ALL_MARKET_RELATED_CRAP)

        self.should_run = True

        if get_logging_level() == LOG_ALL_TRACE:
            websocket.enableTrace(True)

        # Create connection
        try:
            self.ws = create_connection(POLONIEX_WEBSCOKET_URL,
                                        enable_multithread=True)
            self.ws.settimeout(15)
        except Exception as e:
            msg = 'Poloniex - connect ws error - {}, retry...'.format(str(e))
            print_to_console(msg, LOG_ALL_ERRORS)
            self.disconnect()

            return

        # actual subscription in dedicated thread
        # self.on_open()
        self.ws.send(self.subscribe_string)
        log_conect_to_websocket("Poloniex")

        # event loop for processing responce
        while self.should_run:
            try:
                compressed_data = self.ws.recv()
                self.on_public(compressed_data)
            except Exception as e:

                log_error_on_receive_from_socket("Poloniex", e)

                break

            if self.last_heartbeat_ts:
                # During last 5 seconds - no heartbeats no any updates
                ts_now = get_now_seconds_utc()
                if ts_now - self.last_heartbeat_ts > POLONIEX_WEBSOCKET_TIMEOUT:
                    log_heartbeat_is_missing("Poloniex",
                                             POLONIEX_WEBSOCKET_TIMEOUT,
                                             self.last_heartbeat_ts, ts_now)

                    break

        log_subscription_cancelled("Poloniex")

        self.disconnect()
예제 #19
0
def log_to_file(data, file_name, log_dir=None):
    if log_dir is None:
        log_dir = get_log_folder()
    full_path = os.path.join(log_dir, file_name)
    with open(full_path, 'a') as the_file:
        ts = get_now_seconds_utc()
        pid = os.getpid()
        the_file.write("{ts}: PID: {pid} {data}\n".format(ts=ts,
                                                          pid=pid,
                                                          data=str(data)))
예제 #20
0
def place_order_by_market_rate(expired_order, msg_queue, priority_queue,
                               min_volume, balance, order_book, log_file_name):
    max_volume = determine_maximum_volume_by_balance(expired_order.pair_id,
                                                     expired_order.trade_type,
                                                     expired_order.volume,
                                                     expired_order.price,
                                                     balance)

    max_volume = round_volume(expired_order.exchange_id, max_volume,
                              expired_order.pair_id)

    if max_volume < min_volume:

        log_too_small_volume(expired_order, max_volume, min_volume, msg_queue)

        return

    expired_order.volume = max_volume
    expired_order.create_time = get_now_seconds_utc()

    msg = "Replace EXPIRED order with new one - {tt}".format(tt=expired_order)
    err_code, json_document = init_deal(expired_order, msg)

    log_expired_order_replacement_result(expired_order, json_document,
                                         msg_queue)

    if err_code == STATUS.SUCCESS:

        expired_order.execute_time = get_now_seconds_utc()
        expired_order.order_book_time = long(order_book.timest)
        expired_order.order_id = parse_order_id(expired_order.exchange_id,
                                                json_document)

        msg_queue.add_order(ORDERS_MSG, expired_order)

        priority_queue.add_order_to_watch_queue(ORDERS_EXPIRE_MSG,
                                                expired_order)

        log_placing_new_deal(expired_order, msg_queue, log_file_name)
    else:
        log_cant_placing_new_deal(expired_order, msg_queue)

        msg_queue.add_order(FAILED_ORDERS_MSG, expired_order, log_file_name)
예제 #21
0
 def test_poloniex_ohlc_retrieval(self):
     date_end = get_now_seconds_utc()
     date_start = date_end - 900
     for pair_name in POLONIEX_CURRENCY_PAIRS:
         period = 14400
         candles = get_ohlc_poloniex(pair_name, date_start, date_end,
                                     period)
         for candle in candles:
             if candle:
                 self.assertEquals(type(candle), Candle)
예제 #22
0
def load_trade_history(args):
    """
        Retrieve executed trades from ALL exchanges via REST api
        and save into db

        Those data later will be used for analysis
        of profitability of trading and bot's performance

    :param args: period, exchanges, connection details
    :return:
    """

    pg_conn, settings = process_args(args)

    log_initial_settings(
        "Starting trade history retrieval for bots using following exchanges: \n",
        settings.exchanges)

    if args.start_time is None or args.end_time is None:
        end_time = get_now_seconds_utc()
        start_time = end_time - 24 * 3600
    else:
        end_time = parse_time(args.end_time, '%Y-%m-%d %H:%M:%S')
        start_time = parse_time(args.start_time, '%Y-%m-%d %H:%M:%S')

    if start_time == end_time or end_time <= start_time:
        die_hard("Wrong time interval provided! {ts0} - {ts1}".format(
            ts0=start_time, ts1=end_time))

    load_keys(settings.key_path)

    while True:
        for exchange_id in settings.exchanges:
            method = get_trade_retrieval_method_by_exchange(exchange_id)
            method(pg_conn, start_time, end_time)
            sleep_for(1)

        print_to_console("Trade retrieval heartbeat", LOG_ALL_DEBUG)

        sleep_for(TRADE_POLL_TIMEOUT)

        end_time = get_now_seconds_utc()
        start_time = end_time - 24 * 3600
예제 #23
0
def get_orders_kraken(key):

    timest = get_now_seconds_utc()
    error_code_1, open_orders = get_open_orders_kraken(key)
    error_code_2, closed_orders = get_order_history_kraken(key)

    if error_code_1 == STATUS.FAILURE or error_code_2 == STATUS.FAILURE:
        return STATUS.FAILURE, None

    return STATUS.SUCCESS, OrderState(EXCHANGE.KRAKEN, timest, open_orders,
                                      closed_orders)
예제 #24
0
def get_order_book(exchange_id, pair_id):
    timest = get_now_seconds_utc()

    pair_name = get_currency_pair_name_by_exchange_id(pair_id, exchange_id)
    if pair_name is None:
        print "UNSUPPORTED COMBINATION OF PAIR ID AND EXCHANGE", pair_id, exchange_id
        assert pair_name is None

    method = get_order_book_method_by_exchange_id(exchange_id)

    return method(pair_name, timest)
예제 #25
0
def get_order_history_poloniex(key, pair_name, time_start=0, time_end=get_now_seconds_utc(), limit=POLONIEX_ORDER_HISTORY_LIMIT):
    post_details = get_order_history_poloniex_post_details(key, pair_name, time_start, time_end, limit)

    err_msg = "get poloniex order history for time interval for pp={pp}".format(pp=post_details)

    status_code, json_document = send_post_request_with_header(post_details, err_msg, max_tries=POLONIEX_NUM_OF_DEAL_RETRY)
    historical_orders = []
    if status_code == STATUS.SUCCESS:
        status_code, historical_orders = get_order_history_poloniex_result_processor(json_document, pair_name)

    return status_code, historical_orders
예제 #26
0
def log_last_balances(exchanges_ids, cache, msg_queue):
    timest = get_now_seconds_utc()
    ttl = "At ts={ts} what we have at cache".format(ts=timest)
    print_to_console(ttl, LOG_ALL_ERRORS)
    log_to_file(ttl, "balance.log")
    for idx in exchanges_ids:
        some_balance = cache.get_balance(idx)
        if some_balance is None or (
                timest - some_balance.last_update) > BALANCE_EXPIRE_TIMEOUT:
            log_warn_balance_not_updating(some_balance, msg_queue)
        else:
            log_balance_updated(idx, some_balance)
예제 #27
0
def test_expired_deal_placement():
    load_keys(API_KEY_PATH)
    priority_queue = get_priority_queue()
    ts = get_now_seconds_utc()
    order = Trade(DEAL_TYPE.SELL, EXCHANGE.BINANCE, CURRENCY_PAIR.BTC_TO_STRAT, price=0.001, volume=5.0,
                  order_book_time=ts, create_time=ts, execute_time=ts, order_id='whatever')

    msg = "Replace existing order with new one - {tt}".format(tt=order)
    err_code, json_document = init_deal(order, msg)
    print json_document
    order.order_id = parse_order_id(order.exchange_id, json_document)
    priority_queue.add_order_to_watch_queue(ORDERS_EXPIRE_MSG, order)
예제 #28
0
def return_with_no_change(json_document, corresponding_trade):

    corresponding_trade.execute_time = get_now_seconds_utc()

    try:
        corresponding_trade.order_id = dao.parse_order_id(
            corresponding_trade.exchange_id, json_document)
    except Exception, e:
        log_to_file(
            "Cant parse order_id! for following document"
            "failed with exception - {}".format(e), "parce_order_id.log")
        log_to_file(json_document, "parce_order_id.log")
예제 #29
0
def print_top10(exchange_id, order_book_buy, order_book_sell):
    header = "Number of threads: {tn} Last update {ts} {td} from {up_exch_name}\n" \
             "\n{buy_exchange}\t\t\t\t\t\t\t\t\t{sell_exchange}\n".\
        format(tn=threading.active_count(), ts=get_now_seconds_utc(),
               td=ts_to_string_utc(get_now_seconds_utc()),
               up_exch_name=get_exchange_name_by_id(exchange_id),
               buy_exchange=get_exchange_name_by_id(order_book_buy.exchange_id),
               sell_exchange=get_exchange_name_by_id(order_book_sell.exchange_id)
    )
    os.system('clear')

    print(header)

    print(BIDS_HEADLINE)
    lb1 = len(order_book_buy.bid)
    lb2 = len(order_book_sell.bid)
    for idx in xrange(0, 10):
        if idx < lb1:
            print order_book_buy.bid[idx],
        else:
            print None,
        print ORDER_BOOK_DELIMITER,
        if idx < lb2:
            print order_book_sell.bid[idx]
        else:
            print None

    print(ASKS_HEADLINE)
    la1 = len(order_book_buy.ask)
    la2 = len(order_book_sell.ask)
    for idx in xrange(0, 10):
        if idx < la1:
            print order_book_buy.ask[idx],
        else:
            print None
        print ORDER_BOOK_DELIMITER,
        if idx < la2:
            print order_book_sell.ask[idx]
        else:
            print None
예제 #30
0
    def update_balance(self):

        while self.update_balance_run_flag:
            cur_timest_sec = get_now_seconds_utc()
            self.balance_state = get_updated_balance_arbitrage(cfg, self.balance_state, self.local_cache)

            if self.balance_state.expired(cur_timest_sec, self.buy_exchange_id, self.sell_exchange_id,
                                          BALANCE_EXPIRED_THRESHOLD):
                log_balance_expired_errors(cfg, self.msg_queue, self.balance_state)

                assert False

            sleep_for(self.balance_update_timeout)