コード例 #1
0
    def from_huobi(cls, json_document, pair_name, timest):
        """
        "tick": {
            "id": 1489464585407,
            "ts": 1489464585407,
            "bids": [
              [7964, 0.0678], // [price, amount]
              [7963, 0.9162],
              [7961, 0.1],
            ],
            "asks": [
              [7979, 0.0736],
              [7980, 1.0292],
            ]

        :param pair_name:
        :param timest:
        :return:
        """

        sell_bids = [
            Deal(price=entry[0], volume=entry[1])
            for entry in json_document.get("asks", [])
        ]
        buy_bids = [
            Deal(price=entry[0], volume=entry[1])
            for entry in json_document.get("bids", [])
        ]

        pair_id = get_currency_pair_from_huobi(pair_name)

        sequence_id = long(json_document["version"])

        return OrderBook(pair_id, timest, sell_bids, buy_bids, EXCHANGE.HUOBI,
                         sequence_id)
コード例 #2
0
    def __init__(self,
                 trade_type,
                 exchange_id,
                 pair_id,
                 price,
                 volume,
                 order_book_time,
                 create_time,
                 execute_time=None,
                 order_id=None,
                 trade_id=None,
                 executed_volume=None,
                 arbitrage_id=-13):

        Deal.__init__(self, price, volume)

        self.trade_type = int(trade_type)
        self.exchange_id = int(exchange_id)
        self.pair_id = int(pair_id)
        self.order_book_time = long(order_book_time)
        self.create_time = long(create_time)
        self.execute_time = long(
            execute_time) if execute_time is not None else execute_time
        self.order_id = order_id
        self.trade_id = trade_id
        self.executed_volume = Decimal(
            executed_volume
        ) if executed_volume is not None else executed_volume
        self.arbitrage_id = long(arbitrage_id)
コード例 #3
0
    def from_row(cls, db_row, asks_rows, sell_rows):
        # id, pair_id, exchange_id, timest, date_time
        # id, order_book_id, price, volume

        currency_pair_id = db_row[1]
        exchange_id = db_row[2]
        timest = db_row[3]

        ask_bids = [Deal(entry[2], entry[3]) for entry in asks_rows]
        sell_bids = [Deal(entry[2], entry[3]) for entry in sell_rows]

        return OrderBook(currency_pair_id, timest, ask_bids, sell_bids,
                         exchange_id)
コード例 #4
0
def parse_socket_update_huobi(order_book_delta, pair_id):
    if "tick" not in order_book_delta:
        return None

    order_book_delta = order_book_delta["tick"]

    sequence_id = long(order_book_delta["version"])

    asks = [Deal(price=b[0], volume=b[1]) for b in order_book_delta.get("asks", [])]
    bids = [Deal(price=b[0], volume=b[1]) for b in order_book_delta.get("bids", [])]

    timest_ms = get_now_seconds_utc_ms()
        
    return OrderBook(pair_id, timest_ms, asks, bids, EXCHANGE.HUOBI, sequence_id)
コード例 #5
0
    def from_kraken(cls, json_document, currency, timest):
        """
        {"error":[],"result":{"XETHXXBT":{"asks":[["0.081451","0.200",1501690777],["0.081496","163.150",1501691124]
        "bids":[["0.080928","0.100",1501691107],["0.080926","0.255",1501691110]
        """

        sell_bids = [
            Deal(entry[0], entry[1]) for entry in json_document["asks"]
        ]
        buy_bids = [
            Deal(entry[0], entry[1]) for entry in json_document["bids"]
        ]

        pair_id = get_currency_pair_from_kraken(currency)

        return OrderBook(pair_id, timest, sell_bids, buy_bids, EXCHANGE.KRAKEN)
コード例 #6
0
    def from_binance(cls, json_document, currency, timest):
        """
        "lastUpdateId":1668114,"bids":[["0.40303000","22.00000000",[]],],"asks":[["0.41287000","1.00000000",[]]
        """

        sell_bids = [
            Deal(price=entry[0], volume=entry[1])
            for entry in json_document.get("asks", [])
        ]
        buy_bids = [
            Deal(price=entry[0], volume=entry[1])
            for entry in json_document.get("bids", [])
        ]

        pair_id = get_currency_pair_from_binance(currency)

        sequence_id = long(json_document["lastUpdateId"])

        return OrderBook(pair_id, timest, sell_bids, buy_bids,
                         EXCHANGE.BINANCE, sequence_id)
コード例 #7
0
    def from_poloniex(cls, json_document, currency, timest):
        """
        {"asks":[["0.00006604",11590.35669799],["0.00006606",25756.70896058]],
        "bids":[["0.00006600",46771.47390146],["0.00006591",25268.665],],
        "isFrozen":"0","seq":41049600}
        """

        sell_bids = [
            Deal(entry[0], entry[1]) for entry in json_document["asks"]
        ]
        buy_bids = [
            Deal(entry[0], entry[1]) for entry in json_document["bids"]
        ]

        pair_id = get_currency_pair_from_poloniex(currency)

        sequence_id = long(json_document["seq"])

        return OrderBook(pair_id, timest, sell_bids, buy_bids,
                         EXCHANGE.POLONIEX, sequence_id)
コード例 #8
0
def parse_socket_update_binance(order_book_delta):
    """
        How to manage a local order book correctly
        Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth
        Buffer the events you receive from the stream
        Get a depth snapshot from **https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000"
        Drop any event where u is <= lastUpdateId in the snapshot
        The first processed should have U <= lastUpdateId+1 AND u >= lastUpdateId+1
        While listening to the stream, each new event's U should be equal to the previous event's u+1
        The data in each event is the absolute quantity for a price level
        If the quantity is 0, remove the price level
        Receiving an event that removes a price level that is not in your local order book can happen and is normal.

        4

        "U": 157,           // First update ID in event
        "u": 160,           // Final update ID in event

        {"e": "depthUpdate", "E": 1527861613915, "s": "DASHBTC", "U": 45790140, "u": 45790142,
        "b": [["0.04073500", "2.02000000", []], ["0.04073200", "0.00000000", []]],
        "a": [["0.04085300", "0.00000000", []]]}

        :param order_book_delta:
        :return:
    """

    timest_ms = get_now_seconds_utc_ms()

    sequence_id = long(order_book_delta["U"])
    sequence_id_end = long(order_book_delta["u"])

    asks = [Deal(a[0], a[1]) for a in order_book_delta["a"]]
    bids = [Deal(b[0], b[1]) for b in order_book_delta["b"]]
    trades_sell = []
    trades_buy = []

    return OrderBookUpdate(sequence_id, bids, asks, timest_ms, trades_sell,
                           trades_buy, sequence_id_end)
コード例 #9
0
    def from_bittrex(cls, json_document, currency, timest):
        """
        {"success":true,"message":"","result":{"buy":[{"Quantity":12.76073322,"Rate":0.01557999},{"Quantity":12.01802925,"Rate":0.01557998}
        "sell":[{"Quantity":0.38767680,"Rate":0.01560999},{"Quantity":2.24182363,"Rate":0.01561999}
        """

        sell_bids = []
        if "sell" in json_document and json_document["sell"] is not None:
            for b in json_document["sell"]:
                sell_bids.append(Deal(b["Rate"], b["Quantity"]))

        buy_bids = []
        if "buy" in json_document and json_document["buy"] is not None:
            for b in json_document["buy"]:
                buy_bids.append(Deal(b["Rate"], b["Quantity"]))

        pair_id = get_currency_pair_from_bittrex(currency)

        # DK FIXME! not exactly but Rest API doesnt offer any viable options :/
        sequence_id = get_now_seconds_utc_ms()

        return OrderBook(pair_id, timest, sell_bids, buy_bids,
                         EXCHANGE.BITTREX, sequence_id)
コード例 #10
0
    def setUp(self):
        set_logging_level(LOG_ALL_ERRORS)

        self.first = Deal(0.03172795, 0.1)
        self.non_present = Deal(10.1, 0.1)
        self.deal_update = Deal(0.03172801, 0.4)

        unsorted = [
            self.first,
            Deal(0.03172796, 0.2),
            Deal(0.03172798, 0.3), self.deal_update,
            Deal(0.03173, 0.5)
        ]

        self.asks = sorted(unsorted, key=lambda x: x.price, reverse=False)
        self.bids = sorted(unsorted, key=lambda x: x.price, reverse=True)
コード例 #11
0
def parse_socket_order_book_poloniex(order_book_snapshot, pair_id):
    """

    :param order_book_snapshot:

    [
        <channel id>,
        <sequence number>,
        [
            [
                "i",
                    {
                        "currencyPair": "<currency pair name>",
                        "orderBook": [
                        {
                            "<lowest ask price>": "<lowest ask size>",
                            "<next ask price>": "<next ask size>",
                            …
                        },
                        {
                            "<highest bid price>": "<highest bid size>",
                            "<next bid price>": "<next bid size>",
                            …
                        }
                        ]
                    }
            ]
        ]
    ]


    order_book_snapshot[2][0][1]["orderBook"][0]

    Example:
    [
        148,
        573963482,
        [
            [
                "i",
                {
                    "currencyPair": "BTC_ETH",
                    "orderBook": [
                    {
                        "0.08964203": "0.00225904",
                        "0.04069708": "15.37598559",
                        ...
                    },
                     {
                        "0.03496358": "0.32591524",
                        "0.02020000": "0.50000000",
                        ...
                    }
                    ]
                }
            ]
        ]
    ]

    :param pair_id:
    :return:
    """

    timest_ms = get_now_seconds_utc_ms()

    sequence_id = long(order_book_snapshot[1])

    asks = []
    for k, v in order_book_snapshot[2][0][1]["orderBook"][0].iteritems():
        asks.append(Deal(k, v))

    bids = []
    for k, v in order_book_snapshot[2][0][1]["orderBook"][1].iteritems():
        bids.append(Deal(k, v))

    return OrderBook(pair_id, timest_ms, asks, bids, EXCHANGE.POLONIEX,
                     sequence_id)
コード例 #12
0
def parse_socket_update_poloniex(order_book_delta):
    """
                Message format for ticker
                [
                    1002,                             Channel
                    null,                             Unknown
                    [
                        121,                          CurrencyPairID
                        "10777.56054438",             Last
                        "10800.00000000",             lowestAsk
                        "10789.20000001",             highestBid
                        "-0.00860373",                percentChange
                        "72542984.79776118",          baseVolume
                        "6792.60163706",              quoteVolume
                        0,                            isForzen
                        "11400.00000000",             high24hr
                        "9880.00000009"               low24hr
                    ]
                ]

                [1002,null,[158,"0.00052808","0.00053854","0.00052926","0.05571659","4.07923480","7302.01523251",0,"0.00061600","0.00049471"]]

                So the columns for orders are
                    messageType -> t/trade, o/order
                    tradeID -> only for trades, just a number
                    orderType -> 1/bid,0/ask
                    rate
                    amount
                    time
                    sequence
                148 is code for BTCETH, yeah there is no documentation.. but when trades occur You can figure out.
                Bid is always 1, cause You add something new..

                PairId, Nonce, orders\trades deltas:
                [24,219199090,[["o",1,"0.04122908","0.01636493"],["t","10026908",0,"0.04122908","0.00105314",1527880700]]]
                [24,219201009,[["o",0,"0.04111587","0.00000000"],["o",0,"0.04111174","1.52701255"]]]
                [24,219164304,[["o",1,"0.04064791","0.01435233"],["o",1,"0.04068034","0.16858384"]]]

                :param order_book_delta:
                :return:
            """

    asks = []
    bids = []
    trades_sell = []
    trades_buy = []

    # We suppose that bid and ask are sorted in particular order:
    # for bids - highest - first
    # for asks - lowest - first
    if len(order_book_delta) < 3:
        return None

    timest_ms = get_now_seconds_utc_ms()

    sequence_id = long(order_book_delta[1])

    delta = order_book_delta[2]
    for entry in delta:
        if entry[0] == POLONIEX_WEBSOCKET_ORDER:
            new_deal = Deal(entry[2], entry[3])

            # If it is just orders - we insert in a way to keep sorted order
            if entry[1] == POLONIEX_WEBSOCKET_ORDER_ASK:
                asks.append(new_deal)
            elif entry[1] == POLONIEX_WEBSOCKET_ORDER_BID:
                bids.append(new_deal)
            else:
                msg = "Poloniex socket update parsing - {update} total: {ttt}".format(
                    update=entry, ttt=order_book_delta)
                log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)
        elif entry[0] == POLONIEX_WEBSOCKET_TRADE:

            # FIXME NOTE:   this is ugly hack to avoid creation of custom objects
            #               and at the same Deal object contains lt method that
            #               used by bisect for efficient binary search in sorted list
            new_deal = Deal(entry[3], entry[4])

            # For trade - vice-versa we should update opposite arrays:
            # in case we have trade with type bid -> we will update orders at ask
            # in case we have trade with type ask -> we will update orders at bid

            if entry[2] == POLONIEX_WEBSOCKET_ORDER_BID:
                trades_sell.append(new_deal)
            elif entry[2] == POLONIEX_WEBSOCKET_ORDER_ASK:
                trades_buy.append(new_deal)
            else:
                msg = "Poloniex socket update parsing - {wtf}".format(
                    wtf=entry)
                log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)
        else:
            msg = "Poloniex socket update parsing - UNKNOWN TYPE - {wtf}".format(
                wtf=entry)
            log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)

    # FIXME NOTE: during update we are not using trades_sell\trades_buy at all - so probably
    # better not to use them at all

    return OrderBookUpdate(sequence_id, bids, asks, timest_ms, trades_sell,
                           trades_buy)
コード例 #13
0
def parse_socket_order_book_bittrex(order_book_snapshot, pair_id):
    """
    :param: order_book_snapshot stringified json of following format:
        Bittrex order book format:
        "S" = "Sells"
        "Z" = "Buys"
        "M" = "MarketName"
        "f" = "Fills"
        "N" = "Nonce"

        For fills:
        "F" = "FillType": FILL | PARTIAL_FILL
        "I" = "Id"
        "Q" = "Quantity"
        "P" = "Price"
        "t" = "Total"
        "OT" = "OrderType": BUY | SELL
        "T" = "TimeStamp"

        {
            "S": [
                {
                    "Q": 4.29981987,
                    "R": 0.04083123
                },
                {
                    "Q": 0.59844883,
                    "R": 0.04083824
                }],
            "Z": [
                {
                    "Q": 10.8408461,
                    "R": 0.04069406
                },
                {
                    "Q": 0.9,
                    "R": 0.04069405
                }],
            "M": null,
            "f": [
                {
                    "F": "FILL",
                    "I": 274260522,
                    "Q": 0.37714445,
                    "P": 0.04083123,
                    "t": 0.01539927,
                    "OT": "BUY",
                    "T": 1535772645920
                },
                {
                    "F": "PARTIAL_FILL",
                    "I": 274260519,
                    "Q": 1.75676,
                    "P": 0.04069406,
                    "t": 0.07148969,
                    "OT": "SELL",
                    "T": 1535772645157
                }],
            "N": 28964
        }

    :return: newly assembled OrderBook object
    """

    timest_ms = get_now_seconds_utc_ms()

    sequence_id = long(order_book_snapshot["N"])

    sells = order_book_snapshot["S"]
    asks = []
    for new_sell in sells:
        asks.append(Deal(new_sell["R"], new_sell["Q"]))

    buys = order_book_snapshot["Z"]
    bids = []
    for new_buy in buys:
        bids.append(Deal(new_buy["R"], new_buy["Q"]))

    # DK WTF NOTE: ignore for now
    # fills = order_book_snapshot["f"]

    return OrderBook(pair_id, timest_ms, asks, bids, EXCHANGE.BITTREX,
                     sequence_id)
コード例 #14
0
def parse_socket_update_bittrex(order_book_delta):
    """

    https://bittrex.github.io/#callback-for-1

        "S" = "Sells"
        "Z" = "Buys"
        "Q" = "Quantity"
        "R" = "Rate"
        "TY" = "Type"
        The Type key can be one of the following values: 0 = ADD, 1 = REMOVE, 2 = UPDATE

        "M" = "MarketName"
        "N" = "Nonce"

        "f" = "Fills"

        3 {u'S': [],
            u'Z': [{u'Q': 0.0, u'R': 0.04040231, u'TY': 1}, {u'Q': 0.78946119, u'R': 0.00126352, u'TY': 0}],
            u'M': u'BTC-DASH',
            u'f': [],
            u'N': 15692}

        3 {u'S': [],
            u'Z': [{u'Q': 1.59914865, u'R': 0.040436, u'TY': 0}, {u'Q': 0.0, u'R': 0.04040232, u'TY': 1}],
            u'M': u'BTC-DASH',
            u'f': [],
            u'N': 15691}


        u'f': [
            {u'Q': 0.11299437,
                u'R': 0.042135,
                u'OT': u'BUY',
                u'T': 1527961548500},
                {u'Q': 0.39487459, u'R': 0.04213499, u'OT': u'BUY', u'T': 1527961548500}],

        :param order_book_delta
        :return:
    """

    timest_ms = get_now_seconds_utc_ms()

    sequence_id = long(order_book_delta["N"])

    asks = []
    bids = []
    trades_sell = []
    trades_buy = []

    sells = order_book_delta["S"]
    buys = order_book_delta["Z"]
    fills = order_book_delta["f"]

    for new_sell in sells:

        new_deal = Deal(new_sell["R"], new_sell["Q"])

        if "TY" not in new_sell:
            msg = "Bittrex socket update - within SELL array some weird format - no TY - {wtf}".format(
                wtf=new_sell)
            log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)
            continue

        type_update = int(new_sell["TY"])

        if type_update in [
                BittrexParameters.BITTREX_ORDER_ADD,
                BittrexParameters.BITTREX_ORDER_UPDATE
        ]:
            asks.append(new_deal)
        elif type_update == BittrexParameters.BITTREX_ORDER_REMOVE:
            asks.append(Deal(new_sell["R"], 0))
        else:
            msg = "Bittrex socket un-supported sells format? {wtf}".format(
                wtf=new_sell)
            log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)

    for new_buy in buys:

        new_deal = Deal(new_buy["R"], new_buy["Q"])

        if "TY" not in new_buy:
            msg = "Bittrex socket update - within BUYS array some weird format - no TY - {wtf}".format(
                wtf=new_buy)
            log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)
            continue

        type_update = int(new_buy["TY"])

        if type_update in [
                BittrexParameters.BITTREX_ORDER_ADD,
                BittrexParameters.BITTREX_ORDER_UPDATE
        ]:
            bids.append(new_deal)
        elif type_update == BittrexParameters.BITTREX_ORDER_REMOVE:
            bids.append(Deal(new_buy["R"], 0))
        else:
            msg = "Bittrex socket un-supported buys format? {wtf}".format(
                wtf=new_buy)
            log_to_file(msg, SOCKET_ERRORS_LOG_FILE_NAME)

    return OrderBookUpdate(sequence_id, bids, asks, timest_ms, trades_sell,
                           trades_buy)