async def setUp(self): super(AbstractTestOrderBook, self).setUp() # Object creation self.ask = Ask( OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(100, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.invalid_ask = Ask( OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(100, 'BTC'), AssetAmount(30, 'MB')), Timeout(0), Timestamp(0)) self.ask2 = Ask( OrderId(TraderId(b'1' * 20), OrderNumber(1)), AssetPair(AssetAmount(400, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.bid = Bid( OrderId(TraderId(b'2' * 20), OrderNumber(1)), AssetPair(AssetAmount(200, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.invalid_bid = Bid( OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(100, 'BTC'), AssetAmount(30, 'MB')), Timeout(0), Timestamp(0)) self.bid2 = Bid( OrderId(TraderId(b'3' * 20), OrderNumber(1)), AssetPair(AssetAmount(300, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.trade = Trade.propose( TraderId(b'0' * 20), OrderId(TraderId(b'0' * 20), OrderNumber(1)), OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(100, 'BTC'), AssetAmount(30, 'MB')), Timestamp(1462224447117)) self.order_book = OrderBook()
def setUp(self): BaseTestCase.setUp(self) self.ask = Ask( OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp(0), True) self.bid = Ask( OrderId(TraderId(b'1' * 20), OrderNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp(0), False) self.transaction = Transaction( TransactionId(TraderId(b'0' * 20), TransactionNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), OrderId(TraderId(b'0' * 20), OrderNumber(1)), OrderId(TraderId(b'1' * 20), OrderNumber(1)), Timestamp(0)) ask_tx = self.ask.to_block_dict() bid_tx = self.bid.to_block_dict() self.tick_block = MarketBlock() self.tick_block.type = b'ask' self.tick_block.transaction = {'tick': ask_tx} self.cancel_block = MarketBlock() self.cancel_block.type = b'cancel_order' self.cancel_block.transaction = { 'trader_id': 'a' * 20, 'order_number': 1 } self.tx_block = MarketBlock() self.tx_block.type = b'tx_init' self.tx_block.transaction = { 'ask': ask_tx, 'bid': bid_tx, 'tx': self.transaction.to_dictionary() } payment = { 'trader_id': 'a' * 40, 'transaction_number': 3, 'transferred': { 'amount': 3, 'type': 'BTC' }, 'payment_id': 'a', 'address_from': 'a', 'address_to': 'b', 'timestamp': 1234, 'success': True } self.payment_block = MarketBlock() self.payment_block.type = b'tx_payment' self.payment_block.transaction = {'payment': payment}
def setUp(self): yield super(PriceTimeStrategyTestSuite, self).setUp() # Object creation self.ask = Ask( OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.ask2 = Ask( OrderId(TraderId(b'1' * 20), OrderNumber(2)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.ask3 = Ask( OrderId(TraderId(b'0' * 20), OrderNumber(3)), AssetPair(AssetAmount(40000, 'BTC'), AssetAmount(200, 'MB')), Timeout(100), Timestamp.now()) self.ask4 = Ask( OrderId(TraderId(b'1' * 20), OrderNumber(4)), AssetPair(AssetAmount(3000, 'A'), AssetAmount(3000, 'MB')), Timeout(100), Timestamp.now()) self.ask5 = Ask( OrderId(TraderId(b'1' * 20), OrderNumber(4)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'C')), Timeout(100), Timestamp.now()) self.bid = Bid( OrderId(TraderId(b'0' * 20), OrderNumber(5)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.bid2 = Bid( OrderId(TraderId(b'0' * 20), OrderNumber(6)), AssetPair(AssetAmount(6000, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) self.ask_order = Order( OrderId(TraderId(b'9' * 20), OrderNumber(11)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now(), True) self.ask_order2 = Order( OrderId(TraderId(b'9' * 20), OrderNumber(12)), AssetPair(AssetAmount(600, 'BTC'), AssetAmount(60, 'MB')), Timeout(100), Timestamp.now(), True) self.bid_order = Order( OrderId(TraderId(b'9' * 20), OrderNumber(13)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now(), False) self.bid_order2 = Order( OrderId(TraderId(b'9' * 20), OrderNumber(14)), AssetPair(AssetAmount(6000, 'BTC'), AssetAmount(60, 'MB')), Timeout(100), Timestamp.now(), False) self.order_book = OrderBook() self.price_time_strategy = PriceTimeStrategy(self.order_book)
def setUp(self): yield super(MatchingEngineTestSuite, self).setUp() # Object creation self.ask = Ask( OrderId(TraderId(b'2' * 20), OrderNumber(1)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp.now()) self.bid = Bid( OrderId(TraderId(b'4' * 20), OrderNumber(2)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp.now()) self.ask_order = Order( OrderId(TraderId(b'5' * 20), OrderNumber(3)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp.now(), True) self.bid_order = Order( OrderId(TraderId(b'6' * 20), OrderNumber(4)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp.now(), False) self.order_book = OrderBook() self.matching_engine = MatchingEngine( PriceTimeStrategy(self.order_book)) self.ask_count = 2 self.bid_count = 2
def insert_ask(order_book, amount1, amount2): """ Insert an ask in the order book with a specific price and quantity """ new_ask = Ask(OrderId(TraderId(b'2' * 20), OrderNumber(len(order_book.asks) + 1)), AssetPair(AssetAmount(amount1, 'BTC'), AssetAmount(amount2, 'MB')), Timeout(30), Timestamp.now()) order_book.insert_ask(new_ask) return new_ask
def create_ask(self, amount1, amount2): """ Create an ask with a specific price and quantity """ new_ask = Ask( OrderId(TraderId(b'2' * 20), OrderNumber(self.ask_count)), AssetPair(AssetAmount(amount1, 'BTC'), AssetAmount(amount2, 'MB')), Timeout(30), Timestamp.now()) self.ask_count += 1 return new_ask
def test_match_order_other_price(order_book, strategy, bid_order): """ Test whether two ticks with different price types are not matched """ ask = Ask(OrderId(TraderId(b'1' * 20), OrderNumber(4)), AssetPair(AssetAmount(3000, 'A'), AssetAmount(3000, 'MB')), Timeout(100), Timestamp.now()) order_book.insert_ask(ask) assert not strategy.match(bid_order.order_id, bid_order.price, bid_order.available_quantity, False)
def update_ticks(self, ask_order_dict, bid_order_dict, traded_quantity): """ Update ticks according to a TrustChain block containing the status of the ask/bid orders. :type ask_order_dict: dict :type bid_order_dict: dict :type traded_quantity: int """ ask_order_id = OrderId(TraderId(unhexlify(ask_order_dict["trader_id"])), OrderNumber(ask_order_dict["order_number"])) bid_order_id = OrderId(TraderId(unhexlify(bid_order_dict["trader_id"])), OrderNumber(bid_order_dict["order_number"])) self._logger.debug("Updating ticks in order book: %s and %s (traded quantity: %s)", str(ask_order_id), str(bid_order_id), str(traded_quantity)) # Update ask tick ask_exists = self.tick_exists(ask_order_id) if ask_exists and ask_order_dict["traded"] >= self.get_tick(ask_order_id).traded: tick = self.get_tick(ask_order_id) tick.traded = ask_order_dict["traded"] if tick.traded >= tick.assets.first.amount: self.remove_tick(tick.order_id) self.completed_orders.add(tick.order_id) elif not ask_exists and ask_order_dict["traded"] < ask_order_dict["assets"]["first"]["amount"] and \ ask_order_id not in self.completed_orders: new_pair = AssetPair.from_dictionary(ask_order_dict["assets"]) ask = Ask(ask_order_id, new_pair, Timeout(ask_order_dict["timeout"]), Timestamp(ask_order_dict["timestamp"]), traded=ask_order_dict["traded"]) self.insert_ask(ask) elif not ask_exists and ask_order_dict["traded"] >= ask_order_dict["assets"]["first"]["amount"]: self.completed_orders.add(ask_order_id) # Update bid tick bid_exists = self.tick_exists(bid_order_id) if bid_exists and bid_order_dict["traded"] >= self.get_tick(bid_order_id).traded: tick = self.get_tick(bid_order_id) tick.traded = bid_order_dict["traded"] if tick.traded >= tick.assets.first.amount: self.remove_tick(tick.order_id) self.completed_orders.add(tick.order_id) elif not bid_exists and bid_order_dict["traded"] < bid_order_dict["assets"]["first"]["amount"] and \ bid_order_id not in self.completed_orders: new_pair = AssetPair.from_dictionary(bid_order_dict["assets"]) bid = Bid(bid_order_id, new_pair, Timeout(bid_order_dict["timeout"]), Timestamp(bid_order_dict["timestamp"]), traded=bid_order_dict["traded"]) self.insert_bid(bid) elif not bid_exists and bid_order_dict["traded"] >= bid_order_dict["assets"]["first"]["amount"]: self.completed_orders.add(bid_order_id)
def test_match_order_divided(order_book, strategy, ask): """ Test for match order divided over two ticks """ order_book.insert_ask(ask) ask2 = Ask(OrderId(TraderId(b'1' * 20), OrderNumber(2)), AssetPair(AssetAmount(3000, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now()) bid_order2 = Order( OrderId(TraderId(b'9' * 20), OrderNumber(14)), AssetPair(AssetAmount(6000, 'BTC'), AssetAmount(60, 'MB')), Timeout(100), Timestamp.now(), False) order_book.insert_ask(ask2) matching_ticks = strategy.match(bid_order2.order_id, bid_order2.price, bid_order2.available_quantity, False) assert len(matching_ticks) == 2
class TestMarketBlock(BaseTestCase): """ This class contains tests for a TrustChain block as used in the market. """ def setUp(self): BaseTestCase.setUp(self) self.ask = Ask( OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp(0), True) self.bid = Ask( OrderId(TraderId(b'1' * 20), OrderNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp(0), False) self.transaction = Transaction( TransactionId(TraderId(b'0' * 20), TransactionNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), OrderId(TraderId(b'0' * 20), OrderNumber(1)), OrderId(TraderId(b'1' * 20), OrderNumber(1)), Timestamp(0)) ask_tx = self.ask.to_block_dict() bid_tx = self.bid.to_block_dict() self.tick_block = MarketBlock() self.tick_block.type = b'ask' self.tick_block.transaction = {'tick': ask_tx} self.cancel_block = MarketBlock() self.cancel_block.type = b'cancel_order' self.cancel_block.transaction = { 'trader_id': 'a' * 20, 'order_number': 1 } self.tx_block = MarketBlock() self.tx_block.type = b'tx_init' self.tx_block.transaction = { 'ask': ask_tx, 'bid': bid_tx, 'tx': self.transaction.to_dictionary() } payment = { 'trader_id': 'a' * 40, 'transaction_number': 3, 'transferred': { 'amount': 3, 'type': 'BTC' }, 'payment_id': 'a', 'address_from': 'a', 'address_to': 'b', 'timestamp': 1234, 'success': True } self.payment_block = MarketBlock() self.payment_block.type = b'tx_payment' self.payment_block.transaction = {'payment': payment} def test_tick_block(self): """ Test whether a tick block can be correctly verified """ self.assertTrue(self.tick_block.is_valid_tick_block()) self.tick_block.transaction['tick']['timeout'] = -1 self.assertFalse(self.tick_block.is_valid_tick_block()) self.tick_block.transaction['tick']['timeout'] = 3600 self.tick_block.type = b'test' self.assertFalse(self.tick_block.is_valid_tick_block()) self.tick_block.type = b'ask' self.tick_block.transaction['test'] = self.tick_block.transaction.pop( 'tick') self.assertFalse(self.tick_block.is_valid_tick_block()) self.tick_block.transaction['tick'] = self.tick_block.transaction.pop( 'test') self.tick_block.transaction['tick'].pop('timeout') self.assertFalse(self.tick_block.is_valid_tick_block()) self.tick_block.transaction['tick']['timeout'] = "300" self.assertFalse(self.tick_block.is_valid_tick_block()) self.tick_block.transaction['tick']['timeout'] = 300 self.tick_block.transaction['tick']['trader_id'] = 'g' * 21 self.assertFalse(self.tick_block.is_valid_tick_block()) # Make the asset pair invalid assets = self.tick_block.transaction['tick']['assets'] self.tick_block.transaction['tick']['trader_id'] = 'a' * 40 assets['test'] = assets.pop('first') self.assertFalse(self.tick_block.is_valid_tick_block()) assets['first'] = assets.pop('test') assets['first']['test'] = assets['first'].pop('amount') self.assertFalse(self.tick_block.is_valid_tick_block()) assets['first']['amount'] = assets['first']['test'] assets['second']['test'] = assets['second'].pop('amount') self.assertFalse(self.tick_block.is_valid_tick_block()) assets['second']['amount'] = assets['second']['test'] assets['first']['amount'] = 3.4 self.assertFalse(self.tick_block.is_valid_tick_block()) assets['first']['amount'] = 2**64 self.assertFalse(self.tick_block.is_valid_tick_block()) assets['first']['amount'] = 3 assets['second']['type'] = 4 self.assertFalse(self.tick_block.is_valid_tick_block()) def test_cancel_block(self): """ Test whether a cancel block can be correctly verified """ self.assertTrue(self.cancel_block.is_valid_cancel_block()) self.cancel_block.type = b'cancel' self.assertFalse(self.cancel_block.is_valid_cancel_block()) self.cancel_block.type = b'cancel_order' self.cancel_block.transaction.pop('trader_id') self.assertFalse(self.cancel_block.is_valid_cancel_block()) self.cancel_block.transaction['trader_id'] = 3 self.assertFalse(self.cancel_block.is_valid_cancel_block()) def test_tx_init_done_block(self): """ Test whether a tx_init/tx_done block can be correctly verified """ self.assertTrue(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.type = b'test' self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.type = b'tx_init' self.tx_block.transaction['test'] = self.tx_block.transaction.pop( 'ask') self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['ask'] = self.tx_block.transaction.pop( 'test') self.tx_block.transaction['ask']['timeout'] = 3.44 self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['ask']['timeout'] = 3 self.tx_block.transaction['bid']['timeout'] = 3.44 self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['bid']['timeout'] = 3 self.tx_block.transaction['tx'].pop('trader_id') self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['tx']['trader_id'] = 'a' * 40 self.tx_block.transaction['tx']['test'] = 3 self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['tx'].pop('test') self.tx_block.transaction['tx']['trader_id'] = 'a' self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['tx']['trader_id'] = 'a' * 40 self.tx_block.transaction['tx']['assets']['first']['amount'] = 3.4 self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['tx']['assets']['first']['amount'] = 3 self.tx_block.transaction['tx']['transferred']['first']['amount'] = 3.4 self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) self.tx_block.transaction['tx']['transferred']['first']['amount'] = 3 self.tx_block.transaction['tx']['transaction_number'] = 3.4 self.assertFalse(self.tx_block.is_valid_tx_init_done_block()) def test_tx_payment_block(self): """ Test whether a tx_payment block can be correctly verified """ self.assertTrue(self.payment_block.is_valid_tx_payment_block()) self.payment_block.type = b'test' self.assertFalse(self.payment_block.is_valid_tx_payment_block()) self.payment_block.type = b'tx_payment' self.payment_block.transaction[ 'test'] = self.payment_block.transaction.pop('payment') self.assertFalse(self.payment_block.is_valid_tx_payment_block()) self.payment_block.transaction[ 'payment'] = self.payment_block.transaction.pop('test') self.payment_block.transaction['payment'].pop('address_to') self.assertFalse(self.payment_block.is_valid_tx_payment_block()) self.payment_block.transaction['payment']['address_to'] = 'a' self.payment_block.transaction['payment']['test'] = 'a' self.assertFalse(self.payment_block.is_valid_tx_payment_block()) self.payment_block.transaction['payment'].pop('test') self.payment_block.transaction['payment']['address_to'] = 3 self.assertFalse(self.payment_block.is_valid_tx_payment_block()) self.payment_block.transaction['payment']['address_to'] = 'a' self.payment_block.transaction['payment']['trader_id'] = 'a' * 39 self.assertFalse(self.payment_block.is_valid_tx_payment_block()) def test_is_valid_asset_pair(self): """ Test the method to verify whether an asset pair is valid """ self.assertFalse(MarketBlock.is_valid_asset_pair({'a': 'b'})) self.assertFalse( MarketBlock.is_valid_asset_pair({ 'first': { 'amount': 3, 'type': 'DUM1' }, 'second': { 'amount': 3 } })) self.assertFalse( MarketBlock.is_valid_asset_pair({ 'first': { 'type': 'DUM1' }, 'second': { 'amount': 3, 'type': 'DUM2' } })) self.assertFalse( MarketBlock.is_valid_asset_pair({ 'first': { 'amount': "4", 'type': 'DUM1' }, 'second': { 'amount': 3, 'type': 'DUM2' } })) self.assertFalse( MarketBlock.is_valid_asset_pair({ 'first': { 'amount': 4, 'type': 'DUM1' }, 'second': { 'amount': "3", 'type': 'DUM2' } })) self.assertFalse( MarketBlock.is_valid_asset_pair({ 'first': { 'amount': -4, 'type': 'DUM1' }, 'second': { 'amount': 3, 'type': 'DUM2' } }))
def ask2(): return Ask(OrderId(TraderId(b'1' * 20), OrderNumber(1)), AssetPair(AssetAmount(400, 'BTC'), AssetAmount(30, 'MB')), Timeout(100), Timestamp.now())
def bid(): return Ask(OrderId(TraderId(b'1' * 20), OrderNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp(0), False)
def ask(): return Ask(OrderId(TraderId(b'0' * 20), OrderNumber(1)), AssetPair(AssetAmount(30, 'BTC'), AssetAmount(30, 'MB')), Timeout(30), Timestamp(0), True)