# -*- coding: utf-8 -*-

# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code

import ccxt.async_support
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
import hashlib
from ccxt.base.types import Any, Balances, Int, Market, Order, OrderBook, Position, Str, Strings, Trade
from ccxt.async_support.base.ws.client import Client
from typing import List
from ccxt.base.errors import AuthenticationError
from ccxt.base.errors import ArgumentsRequired
from ccxt.base.errors import BadRequest
from ccxt.base.errors import RateLimitExceeded
from ccxt.base.precise import Precise


class astros(ccxt.async_support.astros):

    def describe(self) -> Any:
        return self.deep_extend(super(astros, self).describe(), {
            'has': {
                'ws': True,
                'createOrderWs': False,
                'editOrderWs': False,
                'fetchOpenOrdersWs': False,
                'fetchOrderWs': False,
                'cancelOrderWs': False,
                'cancelOrdersWs': False,
                'cancelAllOrdersWs': False,
                'watchBalance': True,
                'watchMyTrades': True,
                'watchOHLCV': True,
                'watchOHLCVForSymbols': False,
                'watchOrderBook': True,
                'watchOrderBookForSymbols': False,
                'watchOrders': False,
                'watchTicker': False,
                'watchTickers': False,
                'watchBidsAsks': False,
                'watchTrades': True,
                'watchTradesForSymbols': False,
                'watchPositions': True,
            },
            'urls': {
                'api': {
                    'ws': 'wss://dasprkkzjjkl7.cloudfront.net/api/market/ws',
                },
            },
            'options': {
                'tradesLimit': 1000,
                'OHLCVLimit': 1000,
                'timeframes': {
                    '1m': '1MIN',
                    '3m': '3MIN',
                    '5m': '5MIN',
                    '15m': '15MIN',
                    '30m': '30MIN',
                    '1h': '1HOUR',
                    # '2h': '2H',
                    '4h': '4HOUR',
                    # '6h': '6H',
                    '8h': '8HOUR',
                    '12h': '12HOUR',
                    '1d': '1DAY',
                    # '3d': '3D',
                    # '1w': '1W',
                    # '1M': '1M',
                },
                'watchOrderBook': {
                    'checksum': True,
                },
                'watchTrades': {
                    'ignoreDuplicates': True,
                },
            },
            'streaming': {
            },
            'exceptions': {
                'ws': {
                    'exact': {
                        '30001': BadRequest,  # {"event":"error","code":30001,"msg":"instType:sp,channel:candleNone,instId:BTCUSDT doesn't exist"}
                        '30002': AuthenticationError,  # illegal request
                        '30003': BadRequest,  # invalid op
                        '30004': AuthenticationError,  # requires login
                        '30005': AuthenticationError,  # login failed
                        '30006': RateLimitExceeded,  # too many requests
                        '30007': RateLimitExceeded,  # request over limit,connection close
                        '30011': AuthenticationError,  # invalid ACCESS_KEY
                        '30012': AuthenticationError,  # invalid ACCESS_PASSPHRASE
                        '30013': AuthenticationError,  # invalid ACCESS_TIMESTAMP
                        '30014': BadRequest,  # Request timestamp expired
                        '30015': AuthenticationError,  # {event: 'error', code: 30015, msg: 'Invalid sign'}
                        '30016': BadRequest,  # {event: 'error', code: 30016, msg: 'Param error'}
                    },
                    'broad': {},
                },
            },
        })

    async def subscribe(self, event, messageHash, subscriptionHash, params={}):
        # requestId = str(self.request_id())
        url = self.urls['api']['ws']
        timestamp = str(Date.now())
        signature = self.hmac(timestamp, self.secret, hashlib.sha256)
        request: dict = {
            'method': 'SUBSCRIBE',
            'apiKey': self.apiKey,
            'signType': '1',
            'signature': signature,
            'event': event,
            'timestamp': timestamp,
        }
        message = self.extend(request, params)
        return await self.watch(url, messageHash, message, subscriptionHash)

    def request_id(self):
        requestId = self.sum(self.safe_integer(self.options, 'requestId', 0), 1)
        self.options['requestId'] = requestId
        return requestId

    def ping(self, client: Client):
        return 'ping'

    def handle_pong(self, client: Client, message):
        client.lastPong = self.milliseconds()

    def handle_error_message(self, client: Client, message):
        #
        #    {
        #        "id": "1",
        #        "type": "error",
        #        "code": 415,
        #        "data": "type is not supported"
        #    }
        #
        data = self.safe_string(message, 'data', '')
        if data == 'token is expired':
            type = 'public'
            if client.url.find('connectId=private') >= 0:
                type = 'private'
            self.options['urls'][type] = None
        self.handle_errors(None, None, client.url, None, None, data, message, None, None)

    def handle_message(self, client: Client, message):
        event = self.safe_string(message, 'event', 'other')
        if event.endswith('_res'):
            # Subscription success returns
            return
        methods: dict = {
            # 'heartbeat': self.handleHeartbeat,
            # 'welcome': self.handleSystemStatus,
            # 'ack': self.handleSubscriptionStatus,
            # 'message': self.handleSubject,
            # 'pong': self.handle_pong,
            # 'error': self.handle_error_message,
            'api_entrust': self.handle_orders,
            'api_position': self.handle_positions,
            'api_kline': self.handle_ohlcv,
            'api_depth': self.handle_order_book,
            # 'api_trade': self.handle_trades,
            'api_account': self.handle_balance,
            'api_spot_deals': self.handle_trades,
            'api_deal_user': self.handle_my_trade,
        }
        method = self.safe_value(methods, event)
        if method is not None:
            method(client, message)

    def handle_balance(self, client: Client, message):
        # {
        #     "data": {
        #         "availableAmount": "999757.863799",
        #         "coinId": 4,
        #         "frozenAmount": "241.506568",
        #         "logId": 0,
        #         "operateAmount": "0.00",
        #         "symbol": "USD"
        #     },
        #     "event": "api_account",
        #     "success": True,
        #     "symbol": "USD"
        # }
        messageHash = 'api_account'
        data = self.safe_value(message, 'data', {})
        timestamp = Date.now()
        self.balance['timestamp'] = timestamp
        self.balance['datetime'] = self.iso8601(timestamp)
        self.balance['info'] = data
        currencyId = self.safe_string(data, 'symbol')
        code = self.safe_currency_code(currencyId)
        account = self.account()
        available = self.safe_string(data, 'availableAmount')
        frozen = self.safe_string(data, 'frozenAmount')
        account['free'] = available
        account['used'] = frozen
        account['total'] = str(Number(available) + Number(frozen))
        self.balance[code] = account
        self.balance = self.safe_balance(self.balance)
        client.resolve(self.balance, messageHash)

    async def watch_balance(self, params={}) -> Balances:
        """
        watch balance and get the amount of funds available for trading or funds locked in orders
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
        """
        # await self.load_markets()
        event = 'api_account'
        symbol = self.safe_string(params, 'symbol')
        if symbol is None:
            symbol = 'USD'
            params['symbol'] = symbol
        messageHash = event + '.' + symbol
        subscribeHash = messageHash
        return await self.subscribe(event, messageHash, subscribeHash, params)

    async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
        """
        watches historical candlestick data containing the open, high, low, close price, and the volume of a market
        :param str symbol: unified symbol of the market to fetch OHLCV data for
        :param str timeframe: the length of time each candle represents
        :param int [since]: timestamp in ms of the earliest candle to fetch
        :param int [limit]: the maximum amount of candles to fetch
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns int[][]: A list of candles ordered, open, high, low, close, volume
        """
        await self.load_markets()
        event = 'api_kline'
        market = self.market(symbol)
        symbol = market['info']['symbol']
        interval = self.safe_string(self.timeframes, timeframe, timeframe)
        messageHash = 'api_kline.' + market['id'] + '.kline.' + interval
        params['pair'] = symbol
        params['period'] = interval
        ohlcv = await self.subscribe(event, messageHash, messageHash, params)
        if self.newUpdates:
            limit = ohlcv.getLimit(symbol, limit)
        return self.filter_by_since_limit(ohlcv, since, limit, 0, True)

    def handle_ohlcv(self, client: Client, message):
        # {
        #     "contractPairId": 1,
        #     "data": {
        #         "amount": 0,
        #         "close": 2322.53,
        #         "contractPairId": 1,
        #         "count": 0,
        #         "hight": 2322.53,
        #         "low": 2322.53,
        #         "open": 2322.53,
        #         "period": "1MIN",
        #         "quantity": 0,
        #         "time": 1725870900000
        #     },
        #     "event": "api_kline",
        #     "period": "1MIN",
        #     "success": True
        # }
        data = self.safe_value(message, 'data', {})
        marketId = self.safe_string(data, 'contractPairId')
        market = self.safe_market(marketId)
        symbol = market['symbol']
        interval = self.safe_string(data, 'period')
        timeframe = self.find_timeframe(interval)
        self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
        stored = self.safe_value(self.ohlcvs[symbol], timeframe)
        if stored is None:
            limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
            stored = ArrayCacheByTimestamp(limit)
            self.ohlcvs[symbol][timeframe] = stored
        tick = self.safe_value(message, 'tick')
        parsed = self.parse_ohlcv(tick, market)
        messageHash = 'api_kline.' + market['id'] + '.kline.' + interval
        stored.append(parsed)
        client.resolve(stored, messageHash)

    def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
        # {
        #     "amount": 0,
        #     "close": 2322.53,
        #     "contractPairId": 1,
        #     "count": 0,
        #     "hight": 2322.53,
        #     "low": 2322.53,
        #     "open": 2322.53,
        #     "period": "1MIN",
        #     "quantity": 0,
        #     "time": 1725870900000
        # }
        return [
            self.safe_timestamp(ohlcv, 'time'),
            self.safe_number(ohlcv, 'open'),
            self.safe_number(ohlcv, 'hight'),
            self.safe_number(ohlcv, 'low'),
            self.safe_number(ohlcv, 'close'),
            self.safe_number(ohlcv, 'amount'),
        ]

    async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
        """
        watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
        :param str symbol: unified symbol of the market to fetch the order book for
        :param int [limit]: the maximum amount of order book entries to return
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
        """
        await self.load_markets()
        event = 'api_depth'
        market = self.market(symbol)
        symbol = market['symbol']
        messageHash = event + '.' + symbol
        params['pair'] = symbol
        orderbook = await self.subscribe(event, messageHash, messageHash, params)
        return orderbook.limit()

    def handle_order_book(self, client: Client, message):
        # {
        #     "data": {
        #         "asks": [
        #             {
        #                 "price": "2341.78",
        #                 "quantity": "13.673"
        #             },
        #             {
        #                 "price": "2345.03",
        #                 "quantity": "2.456"
        #             }
        #         ],
        #         "bids": [
        #             {
        #                 "price": "2311.4",
        #                 "quantity": "7.043"
        #             },
        #             {
        #                 "price": "2289.71",
        #                 "quantity": "10.261"
        #             }
        #         ]
        #     },
        #     "event": "api_depth",
        #     "pair": "ETH-USD",
        #     "success": True
        # }
        marketId = self.safe_string(message, 'pair')
        market = self.safe_market(marketId)
        symbol = market['symbol']
        event = 'api_depth'
        messageHash = event + '.' + symbol
        timestamp = Date.now()
        if not (symbol in self.orderbooks):
            self.orderbooks[symbol] = self.order_book({})
        orderbook = self.orderbooks[symbol]
        orderbook.reset({})
        bids = []
        asks = []
        data = self.safe_value(message, 'data', {})
        asks_res = self.safe_value(data, 'asks', [])
        bids_res = self.safe_value(data, 'bids', [])
        for i in range(0, len(asks_res)):
            entry = asks_res[i]
            price = self.safe_float(entry, 'price')
            quantity = self.safe_float(entry, 'quantity')
            asks.append([price, quantity])
        for i in range(0, len(bids_res)):
            entry = bids_res[i]
            price = self.safe_float(entry, 'price')
            quantity = self.safe_float(entry, 'quantity')
            bids.append([price, quantity])
        bids = self.sort_by(bids, 0, True)
        asks = self.sort_by(asks, 0)
        orderbook['bids'].storeArray(bids)
        orderbook['asks'].storeArray(asks)
        datetime = self.iso8601(timestamp)
        orderbook['symbol'] = symbol
        orderbook['timestamp'] = timestamp
        orderbook['datetime'] = datetime
        orderbook['nonce'] = timestamp
        client.resolve(orderbook, messageHash)

    async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
        """
        get the list of most recent trades for a particular symbol
        :param str symbol: unified symbol of the market to fetch trades for
        :param int [since]: timestamp in ms of the earliest trade to fetch
        :param int [limit]: the maximum amount of trades to fetch
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
        """
        event = 'api_spot_deals'
        await self.load_markets()
        market = self.market(symbol)
        symbol = market['symbol']
        params['pair'] = symbol
        messageHash = 'trade.' + symbol
        trades = await self.subscribe(event, messageHash, messageHash, params)
        if self.newUpdates:
            limit = trades.getLimit(symbol, limit)
        return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)

    def handle_trades(self, client: Client, message):
        # {
        #     "contractPairId": 1,
        #     "data": {
        #         "amount": 2530.3042,
        #         "contractMatchPairId": 19868235,
        #         "contractPairId": 1,
        #         "direction": False,
        #         "pair": "ETH-USD",
        #         "price": 2321.38,
        #         "quantity": 1.09,
        #         "time": "08:40:47",
        #         "timestamp": 1725871247000
        #     },
        #     "event": "api_spot_deals",
        #     "pair": "ETH-USD",
        #     "success": True
        # }
        data = self.safe_dict(message, 'data', {})
        marketId = self.safe_string(data, 'contractPairId')
        market = self.safe_market(marketId)
        symbol = market['symbol']
        if not (symbol in self.trades):
            limit = self.safe_integer(self.options, 'tradesLimit', 1000)
            stored = ArrayCache(limit)
            self.trades[symbol] = stored
        cache = self.trades[symbol]
        trade = self.parse_ws_trade(data, market)
        cache.append(trade)
        messageHash = 'trades.' + symbol
        client.resolve(cache, messageHash)

    def parse_ws_trade(self, trade, market=None):
        # {
        #     "amount": 2530.3042,
        #     "contractMatchPairId": 19868235,
        #     "contractPairId": 1,
        #     "direction": False,
        #     "pair": "ETH-USD",
        #     "price": 2321.38,
        #     "quantity": 1.09,
        #     "time": "08:40:47",
        #     "timestamp": 1725871247000
        # }
        timestamp = self.safe_integer_product(trade, 'timestamp', Date.now())
        direction = self.safe_bool(trade, 'direction')
        id = self.safe_integer(trade, 'contractMatchPairId')
        return self.safe_trade({
            'info': trade,
            'id': id,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
            'symbol': self.safe_string(market, 'symbol'),
            'order': None,
            'type': None,
            'side': self.parse_ws_trade_side(direction),
            'takerOrMaker': None,
            'price': self.safe_string(trade, 'price'),
            'amount': self.safe_string(trade, 'quantity'),
            'cost': self.safe_string(trade, 'amount'),
            'fee': {
                'currency': None,
                'cost': None,
                'rate': None,
            },
        }, market)

    def parse_ws_trade_side(self, direction):
        if direction:
            return 'buy'
        return 'sell'

    async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
        """
        watches information on multiple trades made by the user
        :param str symbol: unified market symbol of the market trades were made in
        :param int [since]: the earliest time in ms to fetch trades for
        :param int [limit]: the maximum number of trade structures to retrieve
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :param str [params.method]: '/spotMarket/tradeOrders' or '/spot/tradeFills' default is '/spotMarket/tradeOrders'
        :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
        """
        event = 'api_spot_deals'
        await self.load_markets()
        market = self.market(symbol)
        symbol = market['symbol']
        params['pair'] = symbol
        messageHash = 'myTrades.' + symbol
        trades = await self.subscribe(event, messageHash, messageHash, params)
        if self.newUpdates:
            limit = trades.getLimit(symbol, limit)
        return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)

    def handle_my_trade(self, client: Client, message):
        # {
        #     "data": {
        #         "contractPairId": 1,
        #         "currentEntrustId": 180641687,
        #         "dealAmount": "46.698",
        #         "dealPrice": "2334.9",
        #         "dealQuantity": "0.02",
        #         "dealTime": "1725871432612",
        #         "direction": "LONG",
        #         "feeAmt": "0.028018",
        #         "feeCoin": "USD",
        #         "isClose": False,
        #         "isTaker": True,
        #         "matchId": 19868419,
        #         "matchType": 1,
        #         "symbol": "ETH-USD",
        #         "clientOrderId":"1725871431488"
        #     },
        #     "event": "api_deal_user",
        #     "success": True
        # }
        if self.myTrades is None:
            limit = self.safe_integer(self.options, 'tradesLimit', 1000)
            self.myTrades = ArrayCacheBySymbolById(limit)
        data = self.safe_dict(message, 'data', {})
        marketId = self.safe_string(data, 'contractPairId')
        market = self.safe_market(marketId)
        parsed = self.parse_ws_my_trade(data)
        myTrades = self.myTrades
        myTrades.append(parsed)
        messageHash = 'myTrades'
        client.resolve(self.myTrades, messageHash)
        symbolSpecificMessageHash = messageHash + '.' + market['symbol']
        client.resolve(self.myTrades, symbolSpecificMessageHash)

    def parse_ws_my_trade(self, trade, market=None):
        # {
        #     "contractPairId": 1,
        #     "currentEntrustId": 180641687,
        #     "dealAmount": "46.698",
        #     "dealPrice": "2334.9",
        #     "dealQuantity": "0.02",
        #     "dealTime": "1725871432612",
        #     "direction": "LONG",
        #     "feeAmt": "0.028018",
        #     "feeCoin": "USD",
        #     "isClose": False,
        #     "isTaker": True,
        #     "matchId": 19868419,
        #     "matchType": 1,
        #     "symbol": "ETH-USD",
        #     "clientOrderId":"1725871431488"
        # }
        timestamp = self.safe_integer_product(trade, 'dealTime', Date.now())
        direction = self.safe_string(trade, 'direction')
        isTaker = self.safe_bool(trade, 'isTaker')
        return self.safe_trade({
            'info': trade,
            'id': timestamp,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
            'symbol': self.safe_string(market, 'symbol'),
            'order': self.safe_string(trade, 'currentEntrustId'),
            'type': None,
            'side': self.parseDirectionSide(direction),
            'takerOrMaker': self.parseTakerOrMaker(isTaker),
            'price': self.safe_string(trade, 'dealPrice'),
            'amount': self.safe_string(trade, 'dealQuantity'),
            'cost': self.safe_string(trade, 'dealAmount'),
            'fee': {
                'currency': self.safe_string(trade, 'feeCoin'),
                'cost': self.safe_string(trade, 'feeAmt'),
                'rate': None,
            },
        }, market)

    async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
        """
        watch all open positions
        :param str[]|None symbols: list of unified market symbols
        :param int [since]: the earliest time in ms to fetch positions for
        :param int [limit]: the maximum number of positions to retrieve
        :param dict params: extra parameters specific to the exchange API endpoint
        :param str [params.instType]: one of 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES', default is 'USDT-FUTURES'
        :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
        """
        event = 'api_position'
        await self.load_markets()
        if symbols is None:
            raise ArgumentsRequired(self.id + ' watchPositions() requires an array argument for symbols')
        if len(symbols) != 1:
            raise ArgumentsRequired(self.id + ' watchPositions() requires an array argument for symbols with exactly one element')
        symbol = symbols[0]
        market = self.market(symbol)
        symbol = market['symbol']
        params['pair'] = symbol
        messageHash = 'positions.' + symbol
        newPositions = await self.subscribe(event, messageHash, messageHash, params)
        if self.newUpdates:
            return newPositions
        return self.filter_by_symbols_since_limit(newPositions, symbols, since, limit, True)

    def handle_positions(self, client: Client, message):
        # {
        #     "data": {
        #         "canClosedQuantity": "0.06",
        #         "changeType": "NEW",
        #         "contractPairId": 1,
        #         "currentQuantity": "0.06",
        #         "direction": "LONG",
        #         "marginAmount": "39.890168",
        #         "marginCallAmount": "7.5",
        #         "openingPrice": "2300.045",
        #         "operateQuantity": "0",
        #         "positionId": 4796701,
        #         "positionType": 3,
        #         "symbol": "ETH-USD"
        #     },
        #     "event": "api_position",
        #     "success": True
        # }
        data = self.safe_value(message, 'data', {})
        symbol = self.safe_string(data, 'symbol')
        market = self.market(symbol)
        if self.positions is None:
            self.positions = ArrayCacheBySymbolBySide()
        cache = self.positions
        newPositions = []
        position = self.parse_position(data, market)
        newPositions.append(position)
        cache.append(position)
        messageHash = 'positions.' + symbol
        client.resolve(newPositions, messageHash)

    def parse_ws_position(self, position, market=None):
        # {
        #     "canClosedQuantity": "0.06",
        #     "changeType": "NEW",
        #     "contractPairId": 1,
        #     "currentQuantity": "0.06",
        #     "direction": "LONG",
        #     "marginAmount": "39.890168",
        #     "marginCallAmount": "7.5",
        #     "openingPrice": "2300.045",
        #     "operateQuantity": "0",
        #     "positionId": 4796701,
        #     "positionType": 3,
        #     "symbol": "ETH-USD"
        # }
        marketId = self.safe_string(position, 'symbol')
        marginModeId = self.safe_integer(position, 'positionType')
        openingPrice = self.safe_number(position, 'openingPrice')
        marginMode = self.get_supported_mapping(marginModeId, {
            '4': 'cross',
            '3': 'isolated',
        })
        changeType = self.safe_string(position, 'changeType')
        liquidationPrice = None
        if changeType == 'LIQUIDATE':
            liquidationPrice = openingPrice
        timestamp = Date.now()
        contractSize = None
        if market is not None:
            contractSize = market['contractSize']
        direction = self.safe_string(position, 'direction')
        side = self.parseDirectionSide(direction)
        return self.safe_position({
            'info': position,
            'id': self.safe_string(position, 'positionId'),
            'symbol': self.safe_symbol(marketId, market),
            'notional': None,
            'marginMode': marginMode,
            'liquidationPrice': liquidationPrice,
            'entryPrice': openingPrice,
            'unrealizedPnl': None,
            'percentage': None,
            'contracts': self.safe_number(position, 'currentQuantity'),
            'contractSize': contractSize,
            'markPrice': None,
            'side': side,
            'hedged': False,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
            'maintenanceMargin': None,
            'maintenanceMarginPercentage': None,
            'collateral': None,
            'initialMargin': self.safe_number(position, 'marginAmount'),
            'initialMarginPercentage': None,
            'leverage': None,
            'marginRatio': None,
        })

    async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
        """
        watches information on an order made by the user
        :param str symbol: unified symbol of the market the order was made in
        :param int [since]: timestamp in ms of the earliest order to watch
        :param int [limit]: the maximum amount of orders to watch
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :param str [params.channel]: choose what channel to use. Can open_order or order_history.
        :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
        """
        event = 'api_entrust'
        await self.load_markets()
        market = self.market(symbol)
        symbol = market['symbol']
        params['pair'] = symbol
        messageHash = event + '.' + symbol
        orders = await self.subscribe(event, messageHash, messageHash, params)
        if self.newUpdates:
            limit = orders.getLimit(symbol, limit)
        return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)

    def handle_orders(self, client: Client, message):
        # {
        #     "data": {
        #         "changeType": "NEW",
        #         "clientOrderId": "1725870680532",
        #         "contractPairId": 1,
        #         "currentEntrustId": 180632923,
        #         "dealAmount": "0.00",
        #         "dealQuantity": "0",
        #         "direction": "LONG",
        #         "isClose": False,
        #         "isMarket": False,
        #         "lever": 1,
        #         "matchType": 1,
        #         "price": "2000",
        #         "quantity": "0.02",
        #         "symbol": "ETH-USD"
        #     },
        #     "event": "api_entrust",
        #     "success": True
        # }
        data = self.safe_dict(message, 'data', {})
        event = 'api_entrust'
        symbol = self.safe_string(data, 'symbol')
        market = self.market(symbol)
        messageHash = event + '.' + market['symbol']
        stored = self.orders
        if stored is None:
            limit = self.safe_integer(self.options, 'ordersLimit', 1000)
            stored = ArrayCacheBySymbolById(limit)
            self.orders = stored
        order = self.parse_order(data, market)
        stored.append(order)
        client.resolve(stored, messageHash)

    def parse_order(self, order: dict, market: Market = None) -> Order:
        # {
        #     "changeType": "NEW",
        #     "clientOrderId": "1725870680532",
        #     "contractPairId": 1,
        #     "currentEntrustId": 180632923,
        #     "dealAmount": "0.00",
        #     "dealQuantity": "0",
        #     "direction": "LONG",
        #     "isClose": False,
        #     "isMarket": False,
        #     "lever": 1,
        #     "matchType": 1,
        #     "price": "2000",
        #     "quantity": "0.02",
        #     "symbol": "ETH-USD"
        # }
        id = self.safe_string(order, 'currentEntrustId')
        filled = self.safe_string(order, 'dealQuantity')
        quantity = self.safe_string(order, 'quantity')
        status = self.parse_order_status(self.safe_string(order, 'changeType'), filled, quantity)
        isMarket = self.safe_bool(order, 'isMarket')
        type = self.parseOrderType(isMarket)
        direction = self.safe_string(order, 'direction')
        side = self.parseDirectionSide(direction)
        symbolRaw = self.safe_string(order, 'symbol')
        if market is None:
            market = self.market(symbolRaw)
        symbol = market['symbol']
        timestamp = Date.now()
        price = self.safe_string(order, 'price')
        remaining = Precise.string_sub(quantity, filled)
        if status != 'CANCELED':
            remaining = str(0)
        amount = self.safe_string(order, 'quantity', Precise.string_add(filled, remaining))
        cost = Precise.string_mul(price, amount)
        # if type == 'market':
        #     price = None
        # }
        clientOrderId = self.safe_string(order, 'clientOrderId')
        matchType = self.safe_integer(order, 'matchType')
        timeInForce = self.parse_time_in_force(matchType)
        return self.safe_order({
            'id': id,
            'info': order,
            'clientOrderId': clientOrderId,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
            'lastTradeTimestamp': None,
            'symbol': symbol,
            'type': type,
            'timeInForce': timeInForce,
            'side': side,
            'status': status,
            'price': price,
            'triggerPrice': None,
            'amount': amount,
            'filled': filled,
            'remaining': remaining,
            'average': None,
            'cost': cost,
            'fee': None,
            'trades': None,
        }, market)
