示例#1
0
 def __init__(self):
     super(ExchangeListener, self).__init__()
     # So I don't love having the public client call here but it seems like a reasonable place to init the book
     # using the level 3 feed to seed the order book
     public_client = PublicClient()
     seed_book = public_client.get_product_order_book('BTC-USD', level=3)
     self.order_book = OrderBook(seed_book=seed_book)
示例#2
0
def test_kraken_checksum():
    # This checksum is from the kraken docs
    ob = OrderBook(max_depth=10, checksum_format='KRAKEN')
    asks = [["0.05005", "0.00000500", "1582905487.684110"],
            ["0.05010", "0.00000500", "1582905486.187983"],
            ["0.05015", "0.00000500", "1582905484.480241"],
            ["0.05020", "0.00000500", "1582905486.645658"],
            ["0.05025", "0.00000500", "1582905486.859009"],
            ["0.05030", "0.00000500", "1582905488.601486"],
            ["0.05035", "0.00000500", "1582905488.357312"],
            ["0.05040", "0.00000500", "1582905488.785484"],
            ["0.05045", "0.00000500", "1582905485.302661"],
            ["0.05050", "0.00000500", "1582905486.157467"]]

    bids = [["0.05000", "0.00000500", "1582905487.439814"],
            ["0.04995", "0.00000500", "1582905485.119396"],
            ["0.04990", "0.00000500", "1582905486.432052"],
            ["0.04980", "0.00000500", "1582905480.609351"],
            ["0.04975", "0.00000500", "1582905476.793880"],
            ["0.04970", "0.00000500", "1582905486.767461"],
            ["0.04965", "0.00000500", "1582905481.767528"],
            ["0.04960", "0.00000500", "1582905487.378907"],
            ["0.04955", "0.00000500", "1582905483.626664"],
            ["0.04950", "0.00000500", "1582905488.509872"]]

    for a in asks:
        ob.asks[Decimal(a[0])] = Decimal(a[1])

    for b in bids:
        ob.bids[Decimal(b[0])] = Decimal(b[1])

    assert ob.checksum() == 974947235
示例#3
0
 def try_to_get_ask(book: OrderBook, ask_id: int) -> str:
     try:
         book.get_ask(ask_id)
     except ValueError as err:
         return err.__str__()
     except Exception as exp:
         return exp.__str__()
示例#4
0
 def try_to_set_ask(book: OrderBook, price: float, quantity: int) -> str:
     try:
         book.set_ask(price, quantity)
     except ValueError as err:
         return err.__str__()
     except Exception as exp:
         return exp.__str__()
示例#5
0
 def try_to_del_bid(book: OrderBook, bid_id: int) -> str:
     try:
         book.del_bid(bid_id)
     except ValueError as err:
         return err.__str__()
     except Exception as exp:
         return exp.__str__()
示例#6
0
def test_get_best_bid_price_with_no_ask():
    book = OrderBook()
    order_stream1 = '1568390201|abbb11|a|AAPL|S|209.00000|100'
    order_stream2 = '1568390202|abbb13|a|AAPL|S|220.00000|1000'
    book.process_order(order_stream1)
    book.process_order(order_stream2)

    assert book.best_bid_and_ask('AAPL') == (0, 220)
示例#7
0
def test_get_bid_and_ask_for_missing_ticker():
    book = OrderBook()
    order_stream1 = '1568390201|abbb11|a|AAPL|S|209.00000|100'
    order_stream2 = '1568390202|abbb13|a|AAPL|S|220.00000|1000'
    book.process_order(order_stream1)
    book.process_order(order_stream2)

    assert book.best_bid_and_ask('ZZZZ') == (0, 0)
示例#8
0
def test_orderbook_init():
    with pytest.raises(TypeError):
        OrderBook('a')

    with pytest.raises(TypeError):
        OrderBook(blah=3)

    with pytest.raises(TypeError):
        OrderBook(max_depth='a')
示例#9
0
def test_add_order_missing_details():
    order_stream = '1568390243|abbb11|a|AAPL|B|209.00000'
    book = OrderBook()
    book.process_order(order_stream)

    assert book.exception_queue == [[
        'Invalid order string', '1568390243', 'abbb11', 'a', 'AAPL', 'B',
        '209.00000'
    ]]
    with pytest.raises(KeyError):
        book.orders['abbb11']
示例#10
0
 def __init__(self, name, addr, balance, base_cur, desired_cur):
     self.name = name
     self.exchange = Exchange(name, addr, balance)
     self.book = OrderBook(base_cur, desired_cur)
     self.exchange.book = self.book
     self.graph = Graph(self.exchange)
     self.traders = {}
     self.html = ''
     self.display_graph = False
     self.clearing_price = np.random.uniform(20, 50)
     self.first_time = True
示例#11
0
def test_orderbook_setitem():
    ob = OrderBook()

    data = requests.get(
        "https://api.pro.coinbase.com/products/BTC-USD/book?level=2").json()
    ob.bids = {Decimal(price): size for price, size, _ in data['bids']}
    ob.asks = {Decimal(price): size for price, size, _ in data['asks']}

    assert ob.bids.index(0)[0] < ob.asks.index(0)[0]
    assert ob.bids.index(-1)[0] < ob.asks.index(-1)[0]

    assert ob.bids.index(-1)[0] < ob.bids.index(0)[0]
    assert ob.asks.index(-1)[0] > ob.asks.index(0)[0]
示例#12
0
def test_add_order():
    order_stream = '1568390243|abbb11|a|AAPL|B|209.00000|100'
    book = OrderBook()
    book.process_order(order_stream)

    assert book.orders['abbb11'] == {
        'timestamp': 1568390243,
        'id': 'abbb11',
        'action': 'a',
        'ticker': 'AAPL',
        'side': 'B',
        'price': 209,
        'size': 100
    }
示例#13
0
def test_okcoin_checksum():
    ob = OrderBook(checksum_format='OKCOIN')

    asks = {
        Decimal("3366.8"): Decimal("9"),
        Decimal("3368"): Decimal("8"),
        Decimal("3372"): Decimal("8")
    }
    bids = {Decimal("3366.1"): Decimal("7")}
    expected = 831078360

    ob.bids = bids
    ob.asks = asks

    assert ob.checksum() == expected
示例#14
0
def test_update_order():
    order_stream1 = '1568390243|abbb11|a|AAPL|B|209.00000|100'
    order_stream2 = '1568390244|abbb11|u|101'
    book = OrderBook()
    book.process_order(order_stream1)
    book.process_order(order_stream2)

    assert book.orders['abbb11'] == {
        'timestamp': 1568390244,
        'id': 'abbb11',
        'action': 'u',
        'ticker': 'AAPL',
        'side': 'B',
        'price': 209,
        'size': 101
    }
示例#15
0
    def setUp(self):
        self.lp_2_gateway = deque()
        self.ob_2_ts = deque()
        self.ts_2_om = deque()
        self.ms_2_om = deque()
        self.om_2_ts = deque()
        self.gw_2_om = deque()
        self.om_2_gw = deque()

        self.liquidityProvider = LiquidityProvider(self.lp_2_gateway)
        self.bookBuilder = OrderBook(self.lp_2_gateway, self.ob_2_ts)
        self.tradingStrategy = TradingStrategy(self.ob_2_ts, self.ts_2_om,
                                               self.om_2_ts)
        self.marketSimulator = MarketSimulator(self.om_2_gw, self.gw_2_om)
        self.orderManager = OrderManager(self.ts_2_om, self.om_2_ts,
                                         self.om_2_gw, self.gw_2_om)
示例#16
0
def test_cancel_for_invalid_order():
    order_stream1 = '1568390243|abbb11|a|AAPL|B|209.00000|100'
    order_stream2 = '1568390244|ZZZZZZ|c'
    book = OrderBook()
    book.process_order(order_stream1)
    book.process_order(order_stream2)

    assert book.orders['abbb11'] == {
        'timestamp': 1568390243,
        'id': 'abbb11',
        'action': 'a',
        'ticker': 'AAPL',
        'side': 'B',
        'price': 209,
        'size': 100
    }
    assert book.exception_queue == [[
        'Cancel for non existent order', '1568390244', 'ZZZZZZ', 'c'
    ]]
示例#17
0
def populate_orderbook():
    ob = OrderBook()

    data = requests.get(
        "https://api.pro.coinbase.com/products/BTC-USD/book?level=2").json()
    for side, d in data.items():
        if side == 'bids':
            for price, size, _ in d:
                ob.bids[Decimal(price)] = size
        elif side == 'asks':
            for price, size, _ in d:
                ob.asks[Decimal(price)] = size

    assert ob.bids.index(0)[0] < ob.asks.index(0)[0]
    assert ob.bids.index(-1)[0] < ob.asks.index(-1)[0]

    assert ob.bids.index(-1)[0] < ob.bids.index(0)[0]
    assert ob.asks.index(-1)[0] > ob.asks.index(0)[0]

    return ob
示例#18
0
    def __init__(self, accounts, products):
        self.accounts = accounts
        self.products = products

        self.order_books = {
            product: OrderBook(product)
            for product in products
        }
        self.orders_dict = {}  # key = (account, product, side), value = price

        self.transaction_history = []
示例#19
0
def setup(json_file='demo.json'):
    '''
    '''
    with open(json_file) as json_data:
        data = json.load(json_data)

    bids = TradeObject(data['bids'])
    asks = TradeObject(data['asks'], 'asks')

    order_book = OrderBook(bids, asks)
    return order_book
class MarketOperator:

	def __init__(self):
		self.book = OrderBook()
		self.next_id = 0

	def get_public_key(self):
		return str(self.book.public_key.n)

	def get_encrypted_book(self):
		return self.book.get_encrypted_book()

	def get_unencrypted_book(self):
		return self.book.get_unencrypted_book()

	def submit_bid(self, price_ciphertext, qty_ciphertext, price_nonce, qty_nonce):
		self.book.add_bid(Order(self.book, price_ciphertext, qty_ciphertext, price_nonce, qty_nonce, "bid", self.next_id))
		self.next_id = self.next_id + 1

	def submit_ask(self, price_ciphertext, qty_ciphertext, price_nonce, qty_nonce):
		self.book.add_ask(Order(self.book, price_ciphertext, qty_ciphertext, price_nonce, qty_nonce, "ask", self.next_id))
		self.next_id = self.next_id + 1

	def get_history(self):
		s = ""
		for action in self.book.history:
			s += action + '\n'
		return s
示例#21
0
def test_get_best_bid_and_ask_prices():
    book = OrderBook()
    order_stream1 = '1568390201|abbb11|a|AAPL|B|209.00000|100'
    order_stream2 = '1568390202|abbb12|a|AAPL|S|210.00000|10'
    order_stream3 = '1568390202|abbb13|a|AAPL|B|220.00000|1000'
    order_stream4 = '1568390202|abbb14|a|AAPL|S|230.00000|500'
    book.process_order(order_stream1)
    book.process_order(order_stream2)
    book.process_order(order_stream3)
    book.process_order(order_stream4)

    assert book.best_bid_and_ask('AAPL') == (209, 230)
示例#22
0
def test_orderbook_setitem_invalid():
    ob = OrderBook()

    with pytest.raises(ValueError):
        ob[123] = {}

    with pytest.raises(ValueError):
        ob['invalid'] = {}

    with pytest.raises(ValueError):
        del ob['bids']

    with pytest.raises(ValueError):
        ob['bids'] = 'a'
示例#23
0
class Engine(object):
    def __init__(self):
        self.order_book = OrderBook()
        self.ts = 0

    def execute(self, message):
        self.ts += 1
        try:
            order_action = parse_input_message(message, self.ts)
            if order_action.action_type == ACTION_TYPE_ADD_ORDER:
                trades = self.order_book.add_order(order_action.order)
                for trade in trades:
                    output_trade(trade)
            elif order_action.action_type == ACTION_TYPE_CANCEL_ORDER:
                self.order_book.cancel_order(order_action.order_id)
        except WrongInputFormatException:
            sys.stderr.write('Wrong input format: {}\n'.format(message))
        except WrongMessageTypeException:
            sys.stderr.write('Wrong message type: {}\n'.format(message))
        except UnknownOrderException:
            sys.stderr.write('Unknown order: {}\n'.format(message))
        except DuplicateOrderException:
            sys.stderr.write('Duplicate order: {}\n'.format(message))
示例#24
0
def test_ftx_checksum():
    BID = 'bid'
    ASK = 'ask'

    r = requests.get(
        "https://ftx.com/api/markets/BTC-PERP/orderbook?depth=100")
    r.raise_for_status()
    ftx_data = json.loads(r.text, parse_float=Decimal)

    def ftx_checksum(book):
        bid_it = reversed(book[BID])
        ask_it = iter(book[ASK])

        bids = [f"{bid}:{book[BID][bid]}" for bid in bid_it]
        asks = [f"{ask}:{book[ASK][ask]}" for ask in ask_it]

        if len(bids) == len(asks):
            combined = [val for pair in zip(bids, asks) for val in pair]
        elif len(bids) > len(asks):
            combined = [
                val for pair in zip(bids[:len(asks)], asks) for val in pair
            ]
            combined += bids[len(asks):]
        else:
            combined = [
                val for pair in zip(bids, asks[:len(bids)]) for val in pair
            ]
            combined += asks[len(bids):]

        computed = ":".join(combined).encode()
        return zlib.crc32(computed)

    ob = OrderBook(checksum_format='FTX')

    book = {
        BID:
        sd({
            Decimal(update[0]): Decimal(update[1])
            for update in ftx_data['result']['bids']
        }),
        ASK:
        sd({
            Decimal(update[0]): Decimal(update[1])
            for update in ftx_data['result']['asks']
        })
    }
    ob.bids = {
        Decimal(update[0]): Decimal(update[1])
        for update in ftx_data['result']['bids']
    }
    ob.asks = {
        Decimal(update[0]): Decimal(update[1])
        for update in ftx_data['result']['asks']
    }

    ob.checksum() == ftx_checksum(book)
示例#25
0
def main():
    lp_2_gateway = deque()
    ob_2_ts = deque()
    ts_2_om = deque()
    om_2_ts = deque()
    gw_2_om = deque()
    om_2_gw = deque()

    lp = LiquidityProvider(lp_2_gateway)
    ob = OrderBook(lp_2_gateway, ob_2_ts)
    ts = TradingStrategy(ob_2_ts, ts_2_om, om_2_ts)
    ms = MarketSimulator(om_2_gw, gw_2_om)
    om = OrderManager(ts_2_om, om_2_ts, om_2_gw, gw_2_om)

    lp.read_tick_data_from_data_source()

    while len(lp_2_gateway) > 0:
        ob.handle_order_from_gateway()
        ts.handle_input_from_bb()
        om.handle_input_from_ts()
        ms.handle_order_from_gw()
        om.handle_input_from_market()
        ts.handle_response_from_om()
        lp.read_tick_data_from_data_source()
def retrieve_order_data(book_data, pair, agg_data):
    """
    Get spread, midpoint, and liquidity from book data. The information represents the status of the OrderBook at
    specific time. Time of retrieving is the last moment in each minute defined in aggregated market data (agg_data).

    :param book_data: order book data containing all limit order arrivals
    :type book_data: pandas.DataFrame
    :param pair: pair name of two currencies
    :type pair: str
    :param agg_data: minute level aggregated market information data
    :type agg_data: pandas.DataFrame
    :return: a minute level aggregated market information data with spread, midpoint, and liquidity added
    :rtype: pandas.DataFrame
    """
    # filter order data based on pair
    book_data_sub = book_data.loc[book_data["pair"] == pair]
    book_data_sub.reset_index(drop=True, inplace=True)
    # print(book_data_sub.head())
    order_book = OrderBook()
    agg_index = 0
    for i in range(len(book_data_sub)):
        # update order book
        order_book.update_order(book_data_sub["price"][i],
                                book_data_sub["amount"][i])
        # get the time of next order
        if i + 1 < len(book_data_sub):
            next_time = book_data_sub["servert"][i + 1]
        # book data reached to the end, set next time as last time
        else:
            next_time = book_data_sub["servert"][i]
        curr_end_time = agg_data["period_end_time"][agg_index]
        # record data to agg_data when (1) next time surpasses the end time of current period and agg_data has at least
        # two rows unfilled. (2) agg_data reaches to the last row.
        # In case (2) the last row of agg_data will keep updating until book data depletes
        if ((next_time > curr_end_time) and
            (agg_index < len(agg_data))) or (agg_index == len(agg_data) - 1):
            # get info from order book
            curr_spread = order_book.get_spread()
            curr_midpoint = order_book.get_midpoint()
            curr_bid_liquidity, curr_ask_liquidity = order_book.get_liquidity()
            # fill in values into agg data
            agg_data["spread"][agg_index] = curr_spread
            agg_data["midpoint"][agg_index] = curr_midpoint
            agg_data["liquidity_bid"][agg_index] = curr_bid_liquidity
            agg_data["liquidity_ask"][agg_index] = curr_ask_liquidity
            # when agg_data reaches to the last row, index stop moving forward
            if agg_index < len(agg_data) - 1:
                agg_index += 1

    return agg_data
示例#27
0
def profile_orderbook():
    ob = OrderBook()

    for side, d in data.items():
        if side == 'bids':
            for price, size, _ in d:
                ob.bids[Decimal(price)] = size
        elif side == 'asks':
            for price, size, _ in d:
                ob.asks[Decimal(price)] = size
    ob.to_dict()
示例#28
0
def books_from_lines_v1(lines, debug=False, end=None, drop_out_of_order=False):
    currBook = None
    # keep track of which side the book starts on,
    # if that side repeats we've reached a new book
    startSide = None
    nLine = 0
    nBooks = 0

    keep_out_of_order = not drop_out_of_order
    maxTimestamp = None
    book_list = []
    for line in lines:
        if end and nBooks > end:
            break
        nLine += 1
        if line[0:9] == "ORDERBOOK":
            nBooks += 1
            if currBook is not None:
                if keep_out_of_order or currBook.last_update_time == maxTimestamp:
                    book_list.append(currBook)
            timestr = line[10:]
            lastUpdateTime = parse_datetime_opt(timestr)
            if maxTimestamp is None or lastUpdateTime > maxTimestamp:
                maxTimestamp = lastUpdateTime

            currBook = OrderBook(day=None,
                                 last_update_time=lastUpdateTime,
                                 last_update_monotonic=None,
                                 bids=[],
                                 offers=[],
                                 actions=[])
        else:
            row = line.split(',')
            side = row[obc.SIDE]
            entry = Order(
                timestamp=parse_datetime_opt(row[obc.TIMESTAMP]),
                side=side,
                level=int(row[obc.LEVEL]),
                price=float(row[obc.PRICE]),
                size=long(row[obc.SIZE]),
                #orderdepthcount = int(row[obc.ORDERDEPTHCOUNT])
                #ccy = row[obc.CURRENCY]
            )
            if (side == obc.BID): currBook.bids.append(entry)
            elif (side == obc.OFFER): currBook.offers.append(entry)
    return book_list
示例#29
0
def test_orderbook_keys():
    ob = OrderBook()

    ob['bids'][1] = 1
    ob['BIDS'][1] = 2
    ob['bid'][1] = 3
    ob['BID'][1] = 4

    assert ob.bids.to_dict() == {1: 4}
    assert ob.bid.to_dict() == {1: 4}

    ob['asks'][1] = 1
    ob['ASKS'][1] = 2
    ob['ask'][1] = 3
    ob['ASK'][1] = 4

    assert ob.asks.to_dict() == {1: 4}
    assert ob.ask.to_dict() == {1: 4}
 def test_market_data_check_max_ask_print_size_limiter(self):
     order_book = OrderBook(DEFAULT_TRADING_PAIR, 2, 2)
     orders = [generate_order_obj(type=OrderType.ASK) for _ in range(5)]
     for ord in orders:
         order_book.add_order(ord)
     old_market_data = order_book.market_data
     orders = sorted(orders, key=lambda i: i.price)
     delete_order = orders[0]
     order_book.remove_order(delete_order.id)
     assert order_book.market_data != old_market_data
     expected_data = self.expected_market_data(
         asks=self.aggregate_orders(orders[1:3]))
     assert order_book.market_data == expected_data
示例#31
0
 def _run_order_book(self):
     os.system('clear')
     from order_book import OrderBook
     
     order_book = OrderBook()
     order_book.print_table()