Example #1
0
    def test_cancel_order(self):

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL, "/api/v2/orders",
                                         FixtureBeaxy.TEST_CANCEL_BUY_ORDER)

            self.web_app.update_response("delete", PRIVET_API_BASE_URL, "/api/v2/orders/open/435118B0-A7F7-40D2-A409-820E8FC342A2", '')

        amount: Decimal = Decimal("0.01")

        self.assertGreater(self.market.get_balance("BTC"), 0.00005)
        trading_pair = "DASH-BTC"

        # make worst price so order wont be executed
        price: Decimal = self.market.get_price(trading_pair, True) * Decimal('0.5')
        quantized_amount: Decimal = self.market.quantize_order_amount(trading_pair, amount)

        order_id, exch_order_id = self.place_order(
            True, trading_pair, quantized_amount, OrderType.LIMIT, price,
            [(3, FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER_COMPLETED)]
        )
        [order_completed_event] = self.run_parallel(self.market_logger.wait_for(BuyOrderCreatedEvent))

        if API_MOCK_ENABLED:
            MockWebSocketServerFactory.send_str_threadsafe(BeaxyConstants.TradingApi.WS_BASE_URL,
                                                           FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER_CANCELED, delay=3)

        self.cancel_order(trading_pair, order_id, exch_order_id)
        [order_cancelled_event] = self.run_parallel(self.market_logger.wait_for(OrderCancelledEvent))
        order_cancelled_event: OrderCancelledEvent = order_cancelled_event
        self.assertEqual(order_cancelled_event.order_id, order_id)
Example #2
0
    def test_cancel_order(self):
        self.assertGreater(self.market.get_balance("USDC"), 16000)
        trading_pair = "WETH-USDC"
        bid_price: Decimal = self.market.get_price(trading_pair, True)
        amount: Decimal = Decimal("40.0")

        # Intentionally setting price far away from best ask
        client_order_id = self.place_order(True, "WETH-USDC", amount,
                                           OrderType.LIMIT_MAKER,
                                           bid_price * Decimal('0.5'), 10001,
                                           FixtureDydx.BUY_LIMIT_ORDER,
                                           FixtureDydx.WS_AFTER_BUY_1)
        self.run_parallel(asyncio.sleep(1.0))
        self.market.cancel(trading_pair, client_order_id)
        if API_MOCK_ENABLED:
            MockWebSocketServerFactory.send_json_threadsafe(
                self._ws_user_url, FixtureDydx.WS_AFTER_CANCEL_BUY, delay=0.1)
        [order_cancelled_event] = self.run_parallel(
            self.market_logger.wait_for(OrderCancelledEvent))

        order_cancelled_event: OrderCancelledEvent = order_cancelled_event

        self.run_parallel(asyncio.sleep(6.0))
        self.assertEqual(0, len(self.market.limit_orders))
        self.assertEqual(client_order_id, order_cancelled_event.order_id)
Example #3
0
 def place_order(self, is_buy, trading_pair, amount, order_type, price,
                 nonce, post_resp, ws_resp):
     global EXCHANGE_ORDER_ID
     order_id, exch_order_id = None, None
     if API_MOCK_ENABLED:
         exch_order_id = f"BITTREX_{EXCHANGE_ORDER_ID}"
         EXCHANGE_ORDER_ID += 1
         self._t_nonce_mock.return_value = nonce
         resp = post_resp.copy()
         resp["id"] = exch_order_id
         side = 'buy' if is_buy else 'sell'
         resp["direction"] = side.upper()
         resp["type"] = order_type.name.upper()
         if order_type == OrderType.LIMIT:
             del resp["limit"]
         self.web_app.update_response("post", API_BASE_URL, "/v3/orders",
                                      resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type,
                                     price)
     if API_MOCK_ENABLED:
         resp = ws_resp.copy()
         resp["content"]["o"]["OU"] = exch_order_id
         MockWebSocketServerFactory.send_json_threadsafe(WS_BASE_URL,
                                                         resp,
                                                         delay=1.0)
     return order_id, exch_order_id
Example #4
0
    def test_limit_makers_unfilled(self):
        if API_MOCK_ENABLED:
            return
        trading_pair = "ETH-USDC"
        bid_price: Decimal = self.market.get_price(trading_pair,
                                                   True) * Decimal("0.5")
        ask_price: Decimal = self.market.get_price(trading_pair, False) * 2
        amount: Decimal = 10 / bid_price
        quantized_amount: Decimal = self.market.quantize_order_amount(
            trading_pair, amount)

        # Intentionally setting invalid price to prevent getting filled
        quantize_bid_price: Decimal = self.market.quantize_order_price(
            trading_pair, bid_price * Decimal("0.7"))
        quantize_ask_price: Decimal = self.market.quantize_order_price(
            trading_pair, ask_price * Decimal("1.5"))

        order_id, exch_order_id = self.place_order(
            True, trading_pair, quantized_amount, OrderType.LIMIT_MAKER,
            quantize_bid_price, 10001, FixtureCoinbasePro.OPEN_BUY_LIMIT_ORDER,
            FixtureCoinbasePro.WS_ORDER_OPEN)
        [order_created_event] = self.run_parallel(
            self.market_logger.wait_for(BuyOrderCreatedEvent))
        order_created_event: BuyOrderCreatedEvent = order_created_event
        self.assertEqual(order_id, order_created_event.order_id)

        order_id_2, exch_order_id_2 = self.place_order(
            False, trading_pair, quantized_amount, OrderType.LIMIT_MAKER,
            quantize_ask_price, 10002,
            FixtureCoinbasePro.OPEN_SELL_LIMIT_ORDER,
            FixtureCoinbasePro.WS_ORDER_OPEN)
        [order_created_event] = self.run_parallel(
            self.market_logger.wait_for(SellOrderCreatedEvent))
        order_created_event: BuyOrderCreatedEvent = order_created_event
        self.assertEqual(order_id_2, order_created_event.order_id)

        self.run_parallel(asyncio.sleep(1))

        if API_MOCK_ENABLED:
            self.web_app.update_response("delete", API_BASE_URL,
                                         f"/orders/{exch_order_id}",
                                         exch_order_id)
            self.web_app.update_response("delete", API_BASE_URL,
                                         f"/orders/{exch_order_id_2}",
                                         exch_order_id_2)
        [cancellation_results] = self.run_parallel(self.market.cancel_all(5))
        if API_MOCK_ENABLED:
            resp = FixtureCoinbasePro.WS_ORDER_CANCELLED.copy()
            resp["order_id"] = exch_order_id
            MockWebSocketServerFactory.send_json_threadsafe(WS_BASE_URL,
                                                            resp,
                                                            delay=0.1)
            resp = FixtureCoinbasePro.WS_ORDER_CANCELLED.copy()
            resp["order_id"] = exch_order_id_2
            MockWebSocketServerFactory.send_json_threadsafe(WS_BASE_URL,
                                                            resp,
                                                            delay=0.11)
        for cr in cancellation_results:
            self.assertEqual(cr.success, True)
Example #5
0
    def test_prevent_duplicated_orders(self):
        config_path: str = "test_config"
        strategy_name: str = "test_strategy"
        sql: SQLConnectionManager = SQLConnectionManager(SQLConnectionType.TRADE_FILLS, db_path=self.db_path)
        buy_id: Optional[str] = None
        recorder: MarketsRecorder = MarketsRecorder(sql, [self.market], config_path, strategy_name)
        recorder.start()

        try:
            # Perform the same order twice which should produce the same exchange_order_id
            # Try to buy 1 LINK from the exchange, and watch for completion event.
            bid_price: Decimal = self.market.get_price("LINK-ETH", True)
            amount: Decimal = 1
            buy_id = self.place_order(True, "LINK-ETH", amount, OrderType.LIMIT, bid_price, self.get_current_nonce(),
                                      FixtureBinance.BUY_LIMIT_ORDER, FixtureBinance.WS_AFTER_BUY_1,
                                      FixtureBinance.WS_AFTER_BUY_2)
            [buy_order_completed_event] = self.run_parallel(self.market_logger.wait_for(BuyOrderCompletedEvent))

            self.market_logger.clear()

            # Simulate that order is still in in_flight_orders
            order_json = {"client_order_id": buy_id,
                          "exchange_order_id": str(FixtureBinance.WS_AFTER_BUY_2['t']),
                          "trading_pair": "LINK-ETH",
                          "order_type": "MARKET",
                          "trade_type": "BUY",
                          "price": bid_price,
                          "amount": amount,
                          "last_state": "NEW",
                          "executed_amount_base": "0",
                          "executed_amount_quote": "0",
                          "fee_asset": "LINK",
                          "fee_paid": "0.0"}
            self.market.restore_tracking_states({buy_id: order_json})
            self.market.in_flight_orders.get(buy_id).trade_id_set.add(str(FixtureBinance.WS_AFTER_BUY_2['t']))
            # Simulate incoming responses as if buy_id is executed again
            data = self.fixture(FixtureBinance.WS_AFTER_BUY_2, c=buy_id)
            MockWebSocketServerFactory.send_json_threadsafe(self._ws_user_url, data, delay=0.11)
            # Will wait, but no order filled event should be triggered because order is ignored
            self.run_parallel(asyncio.sleep(1))
            # Query the persisted trade logs
            trade_fills: List[TradeFill] = recorder.get_trades_for_config(config_path)
            buy_fills: List[TradeFill] = [t for t in trade_fills if t.trade_type == "BUY"]
            exchange_trade_id = FixtureBinance.WS_AFTER_BUY_2['t']
            self.assertEqual(len([bf for bf in buy_fills if int(bf.exchange_trade_id) == exchange_trade_id]), 1)

            buy_id = None

        finally:
            if buy_id is not None:
                self.market.cancel("LINK-ETH", buy_id)
                self.run_parallel(self.market_logger.wait_for(OrderCancelledEvent))

            recorder.stop()
            os.unlink(self.db_path)
Example #6
0
    def setUpClass(cls):
        global MAINNET_RPC_URL

        cls.ev_loop = asyncio.get_event_loop()

        if API_MOCK_ENABLED:
            cls.web_app = MockWebServer.get_instance()
            cls.web_app.add_host_to_mock(cls.base_api_url, ["/api/v1/ping", "/api/v1/time", "/api/v1/ticker/24hr"])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local

            cls._req_patcher = unittest.mock.patch.object(requests.Session, "request", autospec=True)
            cls._req_url_mock = cls._req_patcher.start()
            cls._req_url_mock.side_effect = MockWebServer.reroute_request
            cls.web_app.update_response("get", cls.base_api_url, "/api/v3/account", FixtureBinance.BALANCES)
            cls.web_app.update_response("get", cls.base_api_url, "/api/v1/exchangeInfo",
                                        FixtureBinance.MARKETS)
            cls.web_app.update_response("get", cls.base_api_url, "/wapi/v3/tradeFee.html",
                                        FixtureBinance.TRADE_FEES)
            cls.web_app.update_response("post", cls.base_api_url, "/api/v1/userDataStream",
                                        FixtureBinance.LISTEN_KEY)
            cls.web_app.update_response("put", cls.base_api_url, "/api/v1/userDataStream",
                                        FixtureBinance.LISTEN_KEY)
            cls.web_app.update_response("get", cls.base_api_url, "/api/v1/depth",
                                        FixtureBinance.LINKETH_SNAP, params={'symbol': 'LINKETH'})
            cls.web_app.update_response("get", cls.base_api_url, "/api/v1/depth",
                                        FixtureBinance.ZRXETH_SNAP, params={'symbol': 'ZRXETH'})
            cls.web_app.update_response("get", cls.base_api_url, "/api/v3/myTrades",
                                        {}, params={'symbol': 'ZRXETH'})
            cls.web_app.update_response("get", cls.base_api_url, "/api/v3/myTrades",
                                        {}, params={'symbol': 'LINKETH'})
            ws_base_url = "wss://stream.binance.com:9443/ws"
            cls._ws_user_url = f"{ws_base_url}/{FixtureBinance.LISTEN_KEY['listenKey']}"
            MockWebSocketServerFactory.start_new_server(cls._ws_user_url)
            MockWebSocketServerFactory.start_new_server(f"{ws_base_url}/linketh@depth/zrxeth@depth")
            cls._ws_patcher = unittest.mock.patch("websockets.connect", autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = MockWebSocketServerFactory.reroute_ws_connect

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.binance.binance_exchange.get_tracking_nonce")
            cls._t_nonce_mock = cls._t_nonce_patcher.start()
        cls.current_nonce = 1000000000000000
        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: BinanceExchange = BinanceExchange(API_KEY, API_SECRET, ["LINK-ETH", "ZRX-ETH"], True)
        print("Initializing Binance market... this will take about a minute.")
        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
        cls.clock.add_iterator(cls.market)
        cls.stack: contextlib.ExitStack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Example #7
0
    def place_order(self, is_buy, trading_pair, amount, order_type, price, ws_resps=[]):
        global EXCHANGE_ORDER_ID
        order_id, exch_order_id = None, None

        if is_buy:
            order_id = self.market.buy(trading_pair, amount, order_type, price)
        else:
            order_id = self.market.sell(trading_pair, amount, order_type, price)
        if API_MOCK_ENABLED:
            for delay, ws_resp in ws_resps:
                MockWebSocketServerFactory.send_str_threadsafe(BeaxyConstants.TradingApi.WS_BASE_URL, ws_resp, delay=delay)
        return order_id, exch_order_id
Example #8
0
 def cancel_order(self, trading_pair, order_id, exchange_order_id,
                  fixture_ws):
     if API_MOCK_ENABLED:
         self.web_app.update_response("delete", API_BASE_URL,
                                      f"/orders/{exchange_order_id}",
                                      exchange_order_id)
     self.market.cancel(trading_pair, order_id)
     if API_MOCK_ENABLED:
         resp = fixture_ws.copy()
         resp["order_id"] = exchange_order_id
         MockWebSocketServerFactory.send_json_threadsafe(WS_BASE_URL,
                                                         resp,
                                                         delay=0.1)
Example #9
0
    def test_limit_makers_unfilled(self):

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL, "/api/v2/orders",
                                         FixtureBeaxy.TEST_UNFILLED_ORDER1)

        self.assertGreater(self.market.get_balance("BTC"), 0.00005)
        trading_pair = "DASH-BTC"

        current_bid_price: Decimal = self.market.get_price(trading_pair, True) * Decimal('0.8')
        quantize_bid_price: Decimal = self.market.quantize_order_price(trading_pair, current_bid_price)
        bid_amount: Decimal = Decimal('0.01')
        quantized_bid_amount: Decimal = self.market.quantize_order_amount(trading_pair, bid_amount)

        current_ask_price: Decimal = self.market.get_price(trading_pair, False)
        quantize_ask_price: Decimal = self.market.quantize_order_price(trading_pair, current_ask_price)
        ask_amount: Decimal = Decimal('0.01')
        quantized_ask_amount: Decimal = self.market.quantize_order_amount(trading_pair, ask_amount)

        order_id1, exch_order_id_1 = self.place_order(
            True, trading_pair, quantized_bid_amount, OrderType.LIMIT, quantize_bid_price,
            [(3, FixtureBeaxy.TEST_UNFILLED_ORDER1_WS_ORDER_CREATED)]
        )
        [order_created_event] = self.run_parallel(self.market_logger.wait_for(BuyOrderCreatedEvent))
        order_created_event: BuyOrderCreatedEvent = order_created_event
        self.assertEqual(order_id1, order_created_event.order_id)

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL, "/api/v2/orders",
                                         FixtureBeaxy.TEST_UNFILLED_ORDER2)

        order_id2, exch_order_id_2 = self.place_order(
            False, trading_pair, quantized_ask_amount, OrderType.LIMIT, quantize_ask_price,
            [(3, FixtureBeaxy.TEST_UNFILLED_ORDER2_WS_ORDER_CREATED)]
        )
        [order_created_event] = self.run_parallel(self.market_logger.wait_for(SellOrderCreatedEvent))
        order_created_event: BuyOrderCreatedEvent = order_created_event
        self.assertEqual(order_id2, order_created_event.order_id)

        if API_MOCK_ENABLED:
            MockWebSocketServerFactory.send_str_threadsafe(BeaxyConstants.TradingApi.WS_BASE_URL,
                                                           FixtureBeaxy.TEST_UNFILLED_ORDER1_WS_ORDER_CANCELED, delay=3)
            MockWebSocketServerFactory.send_str_threadsafe(BeaxyConstants.TradingApi.WS_BASE_URL,
                                                           FixtureBeaxy.TEST_UNFILLED_ORDER2_WS_ORDER_CANCELED, delay=3)

            self.web_app.update_response("delete", PRIVET_API_BASE_URL, "/api/v1/orders", "")

        self.run_parallel(asyncio.sleep(1))
        [cancellation_results] = self.run_parallel(self.market.cancel_all(5))
        for cr in cancellation_results:
            self.assertEqual(cr.success, True)
Example #10
0
 def place_order(self, is_buy, trading_pair, amount, order_type, price, nonce, fixture_resp,
                 fixture_ws_1 = None, fixture_ws_2 = None):
     order_id = None
     if API_MOCK_ENABLED:
         resp = self.order_response(fixture_resp, nonce, 'buy' if is_buy else 'sell', trading_pair)
         self.web_app.update_response("post", self.base_api_url, "/api/v3/order", resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type, price)
     if API_MOCK_ENABLED and fixture_ws_1 is not None and fixture_ws_2 is not None:
         exchange_order_id = str(resp['orderId'])
         data = self.fixture(fixture_ws_1, c=order_id, i=exchange_order_id)
         MockWebSocketServerFactory.send_json_threadsafe(self._ws_user_url, data, delay=0.1)
         data = self.fixture(fixture_ws_2, c=order_id, i=exchange_order_id)
         MockWebSocketServerFactory.send_json_threadsafe(self._ws_user_url, data, delay=0.11)
     return order_id
Example #11
0
    def test_cancel_all(self):

        if API_MOCK_ENABLED:
            self.web_app.update_response("delete", PRIVET_API_BASE_URL, "/api/v2/orders/open/435118B0-A7F7-40D2-A409-820E8FC342A2", '')

        self.assertGreater(self.market.get_balance("BTC"), 0.00005)
        self.assertGreater(self.market.get_balance("DASH"), 0.01)
        trading_pair = "DASH-BTC"

        # make worst price so order wont be executed
        current_bid_price: Decimal = self.market.get_price(trading_pair, True) * Decimal('0.5')
        quantize_bid_price: Decimal = self.market.quantize_order_price(trading_pair, current_bid_price)
        bid_amount: Decimal = Decimal('0.01')
        quantized_bid_amount: Decimal = self.market.quantize_order_amount(trading_pair, bid_amount)

        # make worst price so order wont be executed
        current_ask_price: Decimal = self.market.get_price(trading_pair, False) * Decimal('2')
        quantize_ask_price: Decimal = self.market.quantize_order_price(trading_pair, current_ask_price)
        ask_amount: Decimal = Decimal('0.01')
        quantized_ask_amount: Decimal = self.market.quantize_order_amount(trading_pair, ask_amount)

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL, "/api/v2/orders",
                                         FixtureBeaxy.TEST_CANCEL_ALL_ORDER1)

        _, exch_order_id_1 = self.place_order(True, trading_pair, quantized_bid_amount, OrderType.LIMIT_MAKER,
                                              quantize_bid_price)

        if API_MOCK_ENABLED:
            self.web_app.update_response("post", PRIVET_API_BASE_URL, "/api/v2/orders",
                                         FixtureBeaxy.TEST_CANCEL_ALL_ORDER2)

        _, exch_order_id_2 = self.place_order(False, trading_pair, quantized_ask_amount, OrderType.LIMIT_MAKER,
                                              quantize_ask_price)
        self.run_parallel(asyncio.sleep(1))

        [cancellation_results] = self.run_parallel(self.market.cancel_all(5))

        if API_MOCK_ENABLED:
            MockWebSocketServerFactory.send_str_threadsafe(BeaxyConstants.TradingApi.WS_BASE_URL,
                                                           FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER1_CANCELED, delay=3)
            MockWebSocketServerFactory.send_str_threadsafe(BeaxyConstants.TradingApi.WS_BASE_URL,
                                                           FixtureBeaxy.TEST_CANCEL_BUY_WS_ORDER2_CANCELED, delay=3)

        for cr in cancellation_results:
            self.assertEqual(cr.success, True)
Example #12
0
    def test_limit_makers_unfilled(self):
        self.assertGreater(self.market.get_balance("USDC"), 16000)
        trading_pair = "WETH-USDC"
        amount: Decimal = Decimal("40.0")
        bid_price: Decimal = self.market.get_price(trading_pair, True)
        buy_order_id: str = self.place_order(True, "WETH-USDC", amount,
                                             OrderType.LIMIT_MAKER,
                                             bid_price * Decimal('0.5'), 10001,
                                             FixtureDydx.BUY_LIMIT_MAKER_ORDER,
                                             FixtureDydx.WS_AFTER_BUY_1)
        self.run_parallel(asyncio.sleep(6.0))
        self.market.cancel(trading_pair, buy_order_id)

        if API_MOCK_ENABLED:
            MockWebSocketServerFactory.send_json_threadsafe(
                self._ws_user_url, FixtureDydx.WS_AFTER_CANCEL_BUY, delay=0.1)
        [order_cancelled_event] = self.run_parallel(
            self.market_logger.wait_for(OrderCancelledEvent))
Example #13
0
 def setUpClass(cls) -> None:
     cls.ev_loop: asyncio.AbstractEventLoop = asyncio.get_event_loop()
     cls.ws_server = MockWebSocketServerFactory.start_new_server(
         "wss://www.google.com/ws/")
     cls._patcher = unittest.mock.patch("websockets.connect", autospec=True)
     cls._mock = cls._patcher.start()
     cls._mock.side_effect = MockWebSocketServerFactory.reroute_ws_connect
     # need to wait a bit for the server to be available
     asyncio.get_event_loop().run_until_complete(asyncio.sleep(0.2))
Example #14
0
 def setUpClass(cls) -> None:
     cls.ws_server = MockWebSocketServerFactory.start_new_server(
         "wss://www.google.com/ws/")
     cls._patcher = unittest.mock.patch(
         "aiohttp.client.ClientSession.ws_connect", autospec=True)
     cls._mock = cls._patcher.start()
     cls._mock.side_effect = MockWebSocketServerFactory.reroute_ws_connect
     # need to wait a bit for the server to be available
     ev_loop.run_until_complete(
         asyncio.wait_for(cls.ws_server.wait_til_started(), 1))
Example #15
0
    def setUpClass(cls):
        cls.ev_loop = asyncio.get_event_loop()
        trading_pair = "ETH-USDC"
        if API_MOCK_ENABLED:
            cls.web_app = MockWebServer.get_instance()
            cls.web_app.add_host_to_mock(
                API_BASE_URL,
                ["/time", "/products", f"/products/{trading_pair}/book"])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local
            cls.web_app.update_response("get", API_BASE_URL, "/accounts",
                                        FixtureCoinbasePro.BALANCES)
            cls.web_app.update_response("get", API_BASE_URL, "/fees",
                                        FixtureCoinbasePro.TRADE_FEES)
            cls.web_app.update_response("get", API_BASE_URL, "/orders",
                                        FixtureCoinbasePro.ORDERS_STATUS)

            MockWebSocketServerFactory.start_new_server(WS_BASE_URL)
            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = MockWebSocketServerFactory.reroute_ws_connect

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.coinbase_pro.coinbase_pro_exchange.get_tracking_nonce"
            )
            cls._t_nonce_mock = cls._t_nonce_patcher.start()
        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: CoinbaseProExchange = CoinbaseProExchange(
            API_KEY, API_SECRET, API_PASSPHRASE, trading_pairs=[trading_pair])
        print(
            "Initializing Coinbase Pro market... this will take about a minute."
        )
        cls.clock.add_iterator(cls.market)
        cls.stack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Example #16
0
 def place_order(self, is_buy, trading_pair, amount, order_type, price,
                 nonce, fixture_resp, fixture_ws):
     order_id, exch_order_id = None, None
     if API_MOCK_ENABLED:
         self._t_nonce_mock.return_value = nonce
         side = 'buy' if is_buy else 'sell'
         resp = fixture_resp.copy()
         exch_order_id = resp["id"]
         resp["side"] = side
         self.web_app.update_response("post", API_BASE_URL, "/orders", resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type,
                                     price)
     if API_MOCK_ENABLED:
         resp = fixture_ws.copy()
         resp["order_id"] = exch_order_id
         resp["side"] = side
         MockWebSocketServerFactory.send_json_threadsafe(WS_BASE_URL,
                                                         resp,
                                                         delay=0.1)
     return order_id, exch_order_id
Example #17
0
 def place_order(self,
                 is_buy,
                 trading_pair,
                 amount,
                 order_type,
                 price,
                 nonce,
                 fixture_resp,
                 fixture_ws_1=None,
                 fixture_ws_2=None,
                 fixture_ws_3=None):
     order_id = None
     if API_MOCK_ENABLED:
         resp = self.order_response(fixture_resp, nonce,
                                    'buy' if is_buy else 'sell',
                                    trading_pair)
         self.web_app.update_response("post", self.base_api_url,
                                      "/v2/orders", resp)
     if is_buy:
         order_id = self.market.buy(trading_pair, amount, order_type, price)
     else:
         order_id = self.market.sell(trading_pair, amount, order_type,
                                     price)
     if API_MOCK_ENABLED and fixture_ws_1 is not None:
         self.web_app.update_response("get",
                                      self.base_api_url,
                                      "/v2/fills",
                                      FixtureDydx.FILLS,
                                      params={
                                          "orderId": order_id,
                                          "limit": 100
                                      })
         data = self.fixture(fixture_ws_1, id=order_id)
         MockWebSocketServerFactory.send_json_threadsafe(self._ws_user_url,
                                                         data,
                                                         delay=0.1)
         if fixture_ws_2 is not None:
             data = self.fixture(fixture_ws_2, id=order_id)
             MockWebSocketServerFactory.send_json_threadsafe(
                 self._ws_user_url, data, delay=0.11)
         if fixture_ws_3 is not None:
             MockWebSocketServerFactory.send_json_threadsafe(
                 self._ws_user_url, fixture_ws_3, delay=0.1)
     return order_id
Example #18
0
    def test_order_saving_and_restoration(self):
        config_path: str = "test_config"
        strategy_name: str = "test_strategy"
        sql: SQLConnectionManager = SQLConnectionManager(
            SQLConnectionType.TRADE_FILLS, db_path=self.db_path)
        order_id: Optional[str] = None
        trading_pair: str = "WETH-USDC"

        recorder: MarketsRecorder = MarketsRecorder(sql, [self.market],
                                                    config_path, strategy_name)
        recorder.start()
        try:
            self.assertEqual(0, len(self.market.tracking_states))
            self.assertGreater(self.market.get_balance("USDC"), 16000)
            amount: Decimal = Decimal("40.0")
            current_bid_price: Decimal = self.market.get_price(
                trading_pair, True)
            bid_price: Decimal = Decimal("0.5") * current_bid_price
            quantize_bid_price: Decimal = self.market.quantize_order_price(
                trading_pair, bid_price)
            order_id = self.place_order(True, trading_pair, amount,
                                        OrderType.LIMIT, quantize_bid_price,
                                        10001, FixtureDydx.BUY_LIMIT_ORDER,
                                        FixtureDydx.WS_AFTER_BUY_1)

            [order_created_event] = self.run_parallel(
                self.market_logger.wait_for(BuyOrderCreatedEvent))
            order_created_event: BuyOrderCreatedEvent = order_created_event

            self.assertEqual(order_id, order_created_event.order_id)

            # Verify tracking states
            self.assertEqual(1, len(self.market.tracking_states))
            self.assertEqual(order_id,
                             list(self.market.tracking_states.keys())[0])

            # Verify orders from recorder
            recorded_orders: List[
                Order] = recorder.get_orders_for_config_and_market(
                    config_path, self.market)
            self.assertEqual(1, len(recorded_orders))
            self.assertEqual(order_id, recorded_orders[0].id)

            # Verify saved market states
            saved_market_states: MarketState = recorder.get_market_states(
                config_path, self.market)
            self.assertIsNotNone(saved_market_states)
            self.assertIsInstance(saved_market_states.saved_state, dict)
            self.assertGreater(len(saved_market_states.saved_state), 0)

            # Close out the current market and start another market.
            self.clock.remove_iterator(self.market)

            for event_tag in self.market_events:
                self.market.remove_listener(event_tag, self.market_logger)

            self.market: DydxExchange = DydxExchange(
                dydx_eth_private_key=PRIVATE_KEY,
                dydx_node_address=NODE_ADDRESS,
                poll_interval=10.0,
                trading_pairs=[trading_pair],
                trading_required=True)
            for event_tag in self.market_events:
                self.market.add_listener(event_tag, self.market_logger)
            recorder.stop()
            recorder = MarketsRecorder(sql, [self.market], config_path,
                                       strategy_name)
            recorder.start()
            saved_market_states = recorder.get_market_states(
                config_path, self.market)
            self.clock.add_iterator(self.market)
            self.assertEqual(0, len(self.market.limit_orders))
            self.assertEqual(0, len(self.market.tracking_states))
            self.market.restore_tracking_states(
                saved_market_states.saved_state)
            self.assertEqual(1, len(self.market.limit_orders))
            self.assertEqual(1, len(self.market.tracking_states))

            # Cancel the order and verify that the change is saved.
            self.run_parallel(asyncio.sleep(5.0))
            self.market.cancel(trading_pair, order_id)
            if API_MOCK_ENABLED:
                MockWebSocketServerFactory.send_json_threadsafe(
                    self._ws_user_url,
                    FixtureDydx.WS_AFTER_CANCEL_BUY,
                    delay=0.1)
            self.run_parallel(self.market_logger.wait_for(OrderCancelledEvent))
            order_id = None
            self.assertEqual(0, len(self.market.limit_orders))
            self.assertEqual(0, len(self.market.tracking_states))
            saved_market_states = recorder.get_market_states(
                config_path, self.market)
            self.assertEqual(0, len(saved_market_states.saved_state))
        finally:
            if order_id is not None:
                self.market.cancel(trading_pair, order_id)
                if API_MOCK_ENABLED:
                    MockWebSocketServerFactory.send_json_threadsafe(
                        self._ws_user_url,
                        FixtureDydx.WS_AFTER_CANCEL_BUY,
                        delay=0.1)
                self.run_parallel(
                    self.market_logger.wait_for(OrderCancelledEvent))

            recorder.stop()
Example #19
0
    def setUpClass(cls):
        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
        if API_MOCK_ENABLED:

            cls.web_app = MockWebServer.get_instance()
            cls.web_app.add_host_to_mock(cls.base_api_url, [])

            cls.web_app.start()

            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())

            cls._req_patcher = mock.patch.object(requests.Session,
                                                 "request",
                                                 autospec=True)
            cls._req_url_mock = cls._req_patcher.start()
            cls._req_url_mock.side_effect = MockWebServer.reroute_request

            cls.web_app.update_response("get",
                                        cls.base_api_url,
                                        f"/v1/accounts/{WALLET_ADDRESS}",
                                        FixtureDydx.BALANCES,
                                        params={'number': f'{ACCOUNT_NUMBER}'})

            cls.web_app.update_response("get", cls.base_api_url, "/v2/markets",
                                        FixtureDydx.MARKETS)
            cls.web_app.update_response("get", cls.base_api_url,
                                        "/v1/orderbook/WETH-USDC",
                                        FixtureDydx.WETHUSDC_SNAP)
            cls._buy_order_exchange_id = "0xb0751a113c759779ff5fd6a53b37b26211a9\
              f8845d443323b9f877f32d9aafd9"

            cls._sell_order_exchange_id = "0x03dfd18edc2f26fc9298edcd28ca6cad4971\
              bd1f44d40253d5154b0d1f217680"

            cls.web_app.update_response(
                "delete", cls.base_api_url,
                f"/v2/orders/{cls._buy_order_exchange_id}",
                FixtureDydx.CANCEL_ORDER_BUY)
            cls.web_app.update_response(
                "delete", cls.base_api_url,
                f"/v2/orders/{cls._sell_order_exchange_id}",
                FixtureDydx.CANCEL_ORDER_SELL)
            ws_base_url = "wss://api.dydx.exchange/v1/ws"
            cls._ws_user_url = f"{ws_base_url}"
            MockWebSocketServerFactory.start_new_server(cls._ws_user_url)
            MockWebSocketServerFactory.start_new_server(f"{ws_base_url}")
            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = MockWebSocketServerFactory.reroute_ws_connect

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.dydx.\
                dydx_exchange.get_tracking_nonce")
            cls._t_nonce_mock = cls._t_nonce_patcher.start()

        cls.market: DydxExchange = DydxExchange(
            dydx_eth_private_key=PRIVATE_KEY,
            dydx_node_address=NODE_ADDRESS,
            poll_interval=10.0,
            trading_pairs=['WETH-USDC'],
            trading_required=True)

        print("Initializing Dydx market... ")
        cls.clock.add_iterator(cls.market)
        cls.stack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Example #20
0
    def setUpClass(cls):

        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()

        if API_MOCK_ENABLED:

            cls.web_app = MockWebServer.get_instance()
            cls.web_app.add_host_to_mock(PRIVET_API_BASE_URL, [])
            cls.web_app.add_host_to_mock(PUBLIC_API_BASE_URL, [])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local
            cls.web_app.update_response("get", PUBLIC_API_BASE_URL,
                                        "/api/v2/symbols",
                                        FixtureBeaxy.SYMBOLS)
            cls.web_app.update_response("get", PUBLIC_API_BASE_URL,
                                        "/api/v2/symbols/DASHBTC/book",
                                        FixtureBeaxy.TRADE_BOOK)
            cls.web_app.update_response("get", PUBLIC_API_BASE_URL,
                                        "/api/v2/symbols/DASHBTC/rate",
                                        FixtureBeaxy.EXCHANGE_RATE)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/health", FixtureBeaxy.HEALTH)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/wallets",
                                        FixtureBeaxy.BALANCES)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/tradingsettings",
                                        FixtureBeaxy.TRADE_SETTINGS)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/orders/open",
                                        FixtureBeaxy.ORDERS_OPEN_EMPTY)
            cls.web_app.update_response("get", PRIVET_API_BASE_URL,
                                        "/api/v2/orders/closed",
                                        FixtureBeaxy.ORDERS_CLOSED_EMPTY)

            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_exchange.get_tracking_nonce"
            )
            cls._t_nonce_mock = cls._t_nonce_patcher.start()

            MockWebSocketServerFactory.url_host_only = True
            MockWebSocketServerFactory.start_new_server(
                BeaxyConstants.TradingApi.WS_BASE_URL)
            MockWebSocketServerFactory.start_new_server(
                BeaxyConstants.PublicApi.WS_BASE_URL)

            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = MockWebSocketServerFactory.reroute_ws_connect

            cls._auth_confirm_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth._BeaxyAuth__login_confirm"
            )
            cls._auth_confirm_mock = cls._auth_confirm_patcher.start()
            cls._auth_session_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth._BeaxyAuth__get_session_data"
            )
            cls._auth_session_mock = cls._auth_session_patcher.start()
            cls._auth_session_mock.return_value = {
                "sign_key": 123,
                "session_id": '123'
            }
            cls._auth_headers_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth.get_token"
            )
            cls._auth_headers_mock = cls._auth_headers_patcher.start()
            cls._auth_headers_mock.return_value = '123'
            cls._auth_poll_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.beaxy.beaxy_auth.BeaxyAuth._auth_token_polling_loop"
            )
            cls._auth_poll_mock = cls._auth_poll_patcher.start()

        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: BeaxyExchange = BeaxyExchange(API_KEY,
                                                  API_SECRET,
                                                  trading_pairs=["DASH-BTC"])

        if API_MOCK_ENABLED:

            async def mock_status_polling_task():
                pass

            # disable status polling as it will make orders update inconsistent from mock view
            cls.market._status_polling_task = asyncio.ensure_future(
                mock_status_polling_task())
            cls.ev_loop.run_until_complete(cls.market._update_balances())

        print("Initializing Beaxy market... this will take about a minute.")
        cls.clock.add_iterator(cls.market)
        cls.stack: contextlib.ExitStack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")
Example #21
0
    def setUpClass(cls):
        cls.ev_loop: asyncio.BaseEventLoop = asyncio.get_event_loop()
        if API_MOCK_ENABLED:
            cls.web_app = MockWebServer.get_instance()
            cls.web_app.add_host_to_mock(API_BASE_URL, [])
            cls.web_app.start()
            cls.ev_loop.run_until_complete(cls.web_app.wait_til_started())
            cls._patcher = mock.patch("aiohttp.client.URL")
            cls._url_mock = cls._patcher.start()
            cls._url_mock.side_effect = cls.web_app.reroute_local
            cls.web_app.update_response("get", API_BASE_URL, "/v3/ping",
                                        FixtureBittrex.PING)
            cls.web_app.update_response("get", API_BASE_URL, "/v3/markets",
                                        FixtureBittrex.MARKETS)
            cls.web_app.update_response("get", API_BASE_URL,
                                        "/v3/markets/tickers",
                                        FixtureBittrex.MARKETS_TICKERS)
            cls.web_app.update_response("get", API_BASE_URL, "/v3/balances",
                                        FixtureBittrex.BALANCES)
            cls.web_app.update_response("get", API_BASE_URL, "/v3/orders/open",
                                        FixtureBittrex.ORDERS_OPEN)
            cls._t_nonce_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.bittrex.bittrex_exchange.get_tracking_nonce"
            )
            cls._t_nonce_mock = cls._t_nonce_patcher.start()

            cls._us_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.bittrex.bittrex_api_user_stream_data_source."
                "BittrexAPIUserStreamDataSource._transform_raw_message",
                autospec=True)
            cls._us_mock = cls._us_patcher.start()
            cls._us_mock.side_effect = _transform_raw_message_patch

            cls._ob_patcher = unittest.mock.patch(
                "hummingbot.connector.exchange.bittrex.bittrex_api_order_book_data_source."
                "BittrexAPIOrderBookDataSource._transform_raw_message",
                autospec=True)
            cls._ob_mock = cls._ob_patcher.start()
            cls._ob_mock.side_effect = _transform_raw_message_patch

            MockWebSocketServerFactory.url_host_only = True
            ws_server = MockWebSocketServerFactory.start_new_server(
                WS_BASE_URL)
            cls._ws_patcher = unittest.mock.patch("websockets.connect",
                                                  autospec=True)
            cls._ws_mock = cls._ws_patcher.start()
            cls._ws_mock.side_effect = MockWebSocketServerFactory.reroute_ws_connect
            ws_server.add_stock_response(
                "queryExchangeState",
                FixtureBittrex.WS_ORDER_BOOK_SNAPSHOT.copy())

        cls.clock: Clock = Clock(ClockMode.REALTIME)
        cls.market: BittrexExchange = BittrexExchange(
            bittrex_api_key=API_KEY,
            bittrex_secret_key=API_SECRET,
            trading_pairs=["ETH-USDT"])

        print("Initializing Bittrex market... this will take about a minute. ")
        cls.clock.add_iterator(cls.market)
        cls.stack = contextlib.ExitStack()
        cls._clock = cls.stack.enter_context(cls.clock)
        cls.ev_loop.run_until_complete(cls.wait_til_ready())
        print("Ready.")