Esempio n. 1
0
    def setUp(self) -> None:
        super().setUp()

        self.ev_loop = asyncio.get_event_loop()

        self.base_asset = "BTC"
        self.quote_asset = "USDT"
        self.trading_pair = f"{self.base_asset}-{self.quote_asset}"
        self.ex_trading_pair = f"{self.base_asset}/{self.quote_asset}"

        self.log_records = []
        self.listening_task = None
        self.async_task: Optional[asyncio.Task] = None

        self.throttler = AsyncThrottler(CONSTANTS.RATE_LIMITS)
        self.api_factory = build_api_factory(throttler=self.throttler)

        self.data_source = AscendExAPIOrderBookDataSource(
            api_factory=self.api_factory,
            throttler=self.throttler,
            trading_pairs=[self.trading_pair])
        self.data_source.logger().setLevel(1)
        self.data_source.logger().addHandler(self)

        self.mocking_assistant = NetworkMockingAssistant()
        self.resume_test_event = asyncio.Event()

        AscendExAPIOrderBookDataSource._trading_pair_symbol_map = bidict(
            {self.ex_trading_pair: f"{self.base_asset}-{self.quote_asset}"})
Esempio n. 2
0
 async def get_last_traded_prices(
         cls,
         trading_pairs: List[str],
         domain: str = "com",
         api_factory: Optional[WebAssistantsFactory] = None,
         throttler: Optional[AsyncThrottler] = None) -> Dict[str, float]:
     """
     Return a dictionary the trading_pair as key and the current price as value for each trading pair passed as
     parameter
     :param trading_pairs: list of trading pairs to get the prices for
     :param domain: which Binance domain we are connecting to (the default value is 'com')
     :param api_factory: the instance of the web assistant factory to be used when doing requests to the server.
     If no instance is provided then a new one will be created.
     :param throttler: the instance of the throttler to use to limit request to the server. If it is not specified
     the function will create a new one.
     :return: Dictionary of associations between token pair and its latest price
     """
     local_api_factory = api_factory or build_api_factory()
     rest_assistant = await local_api_factory.get_rest_assistant()
     local_throttler = throttler or cls._get_throttler_instance()
     tasks = [
         cls._get_last_traded_price(t_pair, domain, rest_assistant,
                                    local_throttler)
         for t_pair in trading_pairs
     ]
     results = await safe_gather(*tasks)
     return {
         t_pair: result
         for t_pair, result in zip(trading_pairs, results)
     }
Esempio n. 3
0
    async def _init_trading_pair_symbols(
            cls,
            domain: str = "com",
            api_factory: Optional[WebAssistantsFactory] = None,
            throttler: Optional[AsyncThrottler] = None):
        """
        Initialize mapping of trade symbols in exchange notation to trade symbols in client notation
        """
        mapping = bidict()

        local_api_factory = api_factory or build_api_factory()
        rest_assistant = await local_api_factory.get_rest_assistant()
        local_throttler = throttler or cls._get_throttler_instance()
        url = binance_utils.public_rest_url(
            path_url=CONSTANTS.EXCHANGE_INFO_PATH_URL, domain=domain)
        request = RESTRequest(method=RESTMethod.GET, url=url)

        try:
            async with local_throttler.execute_task(
                    limit_id=CONSTANTS.EXCHANGE_INFO_PATH_URL):
                response: RESTResponse = await rest_assistant.call(
                    request=request)
                if response.status == 200:
                    data = await response.json()
                    for symbol_data in filter(
                            binance_utils.is_exchange_information_valid,
                            data["symbols"]):
                        mapping[symbol_data[
                            "symbol"]] = f"{symbol_data['baseAsset']}-{symbol_data['quoteAsset']}"
        except Exception as ex:
            cls.logger().error(
                f"There was an error requesting exchange info ({str(ex)})")

        cls._trading_pair_symbol_map[domain] = mapping
Esempio n. 4
0
    async def get_all_mid_prices(domain="com") -> Dict[str, Decimal]:
        """
        Returns the mid price of all trading pairs, obtaining the information from the exchange. This functionality is
        required by the market price strategy.
        :param domain: Domain to use for the connection with the exchange (either "com" or "us"). Default value is "com"
        :return: Dictionary with the trading pair as key, and the mid price as value
        """
        local_api_factory = build_api_factory()
        rest_assistant = await local_api_factory.get_rest_assistant()
        throttler = BinanceAPIOrderBookDataSource._get_throttler_instance()

        url = binance_utils.public_rest_url(
            path_url=CONSTANTS.TICKER_PRICE_CHANGE_PATH_URL, domain=domain)
        request = RESTRequest(method=RESTMethod.GET, url=url)

        async with throttler.execute_task(
                limit_id=CONSTANTS.TICKER_PRICE_CHANGE_PATH_URL):
            resp: RESTResponse = await rest_assistant.call(request=request)
            resp_json = await resp.json()

        ret_val = {}
        for record in resp_json:
            try:
                pair = await BinanceAPIOrderBookDataSource.trading_pair_associated_to_exchange_symbol(
                    symbol=record["symbol"], domain=domain)
                ret_val[pair] = ((Decimal(record.get("bidPrice", "0")) +
                                  Decimal(record.get("askPrice", "0"))) /
                                 Decimal("2"))
            except KeyError:
                # Ignore results for pairs that are not tracked
                continue
        return ret_val
Esempio n. 5
0
 def __init__(self,
              trading_pairs: List[str],
              domain="com",
              api_factory: Optional[WebAssistantsFactory] = None,
              throttler: Optional[AsyncThrottler] = None):
     super().__init__(trading_pairs)
     self._order_book_create_function = lambda: OrderBook()
     self._domain = domain
     self._throttler = throttler or self._get_throttler_instance()
     self._api_factory = api_factory or build_api_factory()
     self._rest_assistant: Optional[RESTAssistant] = None
     self._ws_assistant: Optional[WSAssistant] = None
     self._message_queue: Dict[str,
                               asyncio.Queue] = defaultdict(asyncio.Queue)
Esempio n. 6
0
    def __init__(self,
                 auth: BinanceAuth,
                 domain: str = "com",
                 api_factory: Optional[WebAssistantsFactory] = None,
                 throttler: Optional[AsyncThrottler] = None):
        super().__init__()
        self._auth: BinanceAuth = auth
        self._current_listen_key = None
        self._last_recv_time: float = 0
        self._domain = domain
        self._throttler = throttler or self._get_throttler_instance()
        self._api_factory = api_factory or build_api_factory()
        self._rest_assistant: Optional[RESTAssistant] = None
        self._ws_assistant: Optional[WSAssistant] = None

        self._listen_key_initialized_event: asyncio.Event = asyncio.Event()
        self._last_listen_key_ping_ts = 0