# -*- 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 from ccxt.base.types import Any, Int, Market, Order, OrderBook, Position, Str, Strings, Ticker, Trade from ccxt.async_support.base.ws.client import Client from typing import List from ccxt.base.errors import ExchangeError from ccxt.base.errors import BadRequest class deepcoin(ccxt.async_support.deepcoin): def describe(self) -> Any: return self.deep_extend(super(deepcoin, self).describe(), { 'has': { 'ws': True, 'watchTicker': True, 'watchMarkPrice': False, 'watchMarkPrices': False, 'watchTickers': False, 'watchBidsAsks': False, 'watchOrderBook': True, 'watchTrades': True, 'watchTradesForSymbols': False, 'watchOrderBookForSymbols': False, 'watchBalance': False, 'watchLiquidations': False, 'watchLiquidationsForSymbols': False, 'watchMyLiquidations': False, 'watchMyLiquidationsForSymbols': False, 'watchOHLCV': True, 'watchOHLCVForSymbols': False, 'watchOrders': True, 'watchMyTrades': True, 'watchPositions': True, 'watchFundingRate': False, 'watchFundingRates': False, 'createOrderWs': False, 'editOrderWs': False, 'cancelOrderWs': False, 'cancelOrdersWs': False, 'cancelAllOrdersWs': False, 'unWatchTicker': True, 'unWatchTrades': True, 'unWatchOHLCV': True, 'unWatchOrderBook': True, }, 'urls': { 'api': { 'ws': { 'public': { 'spot': 'wss://stream.deepcoin.com/streamlet/trade/public/spot?platform=api', 'swap': 'wss://stream.deepcoin.com/streamlet/trade/public/swap?platform=api', }, 'private': 'wss://stream.deepcoin.com/v1/private', }, }, }, 'options': { 'lastRequestId': None, 'listenKey': None, 'listenKeyExpiryTimestamp': None, 'authenticate': { 'method': 'privateGetDeepcoinListenkeyExtend', # refresh existing listen key or 'privateGetDeepcoinListenkeyAcquire' - get a new one }, 'timeframes': { '1m': '1m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1h', '4h': '4h', '12h': '12h', '1d': '1d', '1w': '1w', '1M': '1o', '1y': '1y', }, }, 'streaming': { 'ping': self.ping, }, }) def ping(self, client: Client): url = client.url if url.find('private') >= 0: client.lastPong = self.milliseconds() # prevent automatic disconnects on private channel return 'ping' def handle_pong(self, client: Client, message): client.lastPong = self.milliseconds() return message def request_id(self): previousValue = self.safe_integer(self.options, 'lastRequestId', 0) newValue = self.sum(previousValue, 1) self.options['lastRequestId'] = newValue return newValue def create_public_request(self, market: Market, requestId: float, topicID: str, suffix: str = '', unWatch: bool = False): marketId = market['symbol'] # spot markets use symbol with slash if market['type'] == 'swap': marketId = market['baseId'] + market['quoteId'] # swap markets use symbol without slash action = '1' # subscribe if unWatch: action = '0' # unsubscribe request = { 'sendTopicAction': { 'Action': action, 'FilterValue': 'DeepCoin_' + marketId + suffix, 'LocalNo': requestId, 'ResumeNo': -1, # -1 from the end, 0 from the beginning 'TopicID': topicID, }, } return request async def watch_public(self, market: Market, messageHash: str, topicID: str, params: dict = {}, suffix: str = '') -> Any: url = self.urls['api']['ws']['public'][market['type']] requestId = self.request_id() request = self.create_public_request(market, requestId, topicID, suffix) subscription = { 'subHash': messageHash, 'id': requestId, } return await self.watch(url, messageHash, self.deep_extend(request, params), messageHash, subscription) async def un_watch_public(self, market: Market, messageHash: str, topicID: str, params: dict = {}, subscription: dict = {}, suffix: str = '') -> Any: url = self.urls['api']['ws']['public'][market['type']] requestId = self.request_id() client = self.client(url) existingSubscription = self.safe_dict(client.subscriptions, messageHash) if existingSubscription is None: raise BadRequest(self.id + ' no subscription for ' + messageHash) subId = self.safe_integer(existingSubscription, 'id') request = self.create_public_request(market, subId, topicID, suffix, True) # unsubscribe message uses the same id original subscribe message unsubHash = 'unsubscribe::' + messageHash subscription = self.extend(subscription, { 'subHash': messageHash, 'unsubHash': unsubHash, 'symbols': [market['symbol']], 'id': requestId, }) return await self.watch(url, unsubHash, self.deep_extend(request, params), unsubHash, subscription) async def watch_private(self, messageHash: str, params: dict = {}) -> Any: listenKey = await self.authenticate() url = self.urls['api']['ws']['private'] + '?listenKey=' + listenKey return await self.watch(url, messageHash, None, 'private', params) async def authenticate(self, params={}): self.check_required_credentials() time = self.milliseconds() listenKeyExpiryTimestamp = self.safe_integer(self.options, 'listenKeyExpiryTimestamp', time) expired = (time - listenKeyExpiryTimestamp) > 60000 # 1 minute before expiry listenKey = self.safe_string(self.options, 'listenKey') response = None if listenKey is None: response = await self.privateGetDeepcoinListenkeyAcquire(params) elif expired: method = self.safe_string(self.options, 'method', 'privateGetDeepcoinListenkeyExtend') getNewKey = (method == 'privateGetDeepcoinListenkeyAcquire') if getNewKey: response = await self.privateGetDeepcoinListenkeyAcquire(params) else: request: dict = { 'listenkey': listenKey, } response = await self.privateGetDeepcoinListenkeyExtend(self.extend(request, params)) if response is not None: data = self.safe_dict(response, 'data', {}) listenKey = self.safe_string(data, 'listenkey') listenKeyExpiryTimestamp = self.safe_timestamp(data, 'expire_time') self.options['listenKey'] = listenKey self.options['listenKeyExpiryTimestamp'] = listenKeyExpiryTimestamp return listenKey async def watch_ticker(self, symbol: str, params={}) -> Ticker: """ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market https://www.deepcoin.com/docs/publicWS/latestMarketData :param str symbol: unified symbol of the market to fetch the ticker for :param dict [params]: extra parameters specific to the exchange API endpoint :returns dict: a `ticker structure ` """ await self.load_markets() market = self.market(symbol) messageHash = 'ticker' + '::' + market['symbol'] return await self.watch_public(market, messageHash, '7', params) async def un_watch_ticker(self, symbol: str, params={}) -> Any: """ unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market https://www.deepcoin.com/docs/publicWS/latestMarketData :param str symbol: unified symbol of the market to fetch the ticker for :param dict [params]: extra parameters specific to the exchange API endpoint :returns dict: a `ticker structure ` """ await self.load_markets() market = self.market(symbol) messageHash = 'ticker' + '::' + market['symbol'] subscription = { 'topic': 'ticker', } return await self.un_watch_public(market, messageHash, '7', params, subscription) def handle_ticker(self, client: Client, message): # # a: 'PO', # m: 'Success', # tt: 1760913034780, # mt: 1760913034780, # r: [ # { # d: { # I: 'BTC/USDT', # U: 1760913034742, # PF: 0, # E: 0, # O: 108479.9, # H: 109449.9, # L: 108238, # V: 789.3424915, # T: 43003872.3705223, # N: 109345, # M: 87294.7, # D: 0, # V2: 3086.4496105, # T2: 332811624.339836, # F: 0, # C: 0, # BP1: 109344.9, # AP1: 109345.2 # } # } # ] # response = self.safe_list(message, 'r', []) first = self.safe_dict(response, 0, {}) data = self.safe_dict(first, 'd', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) parsedTicker = self.parse_ws_ticker(data, market) messageHash = 'ticker' + '::' + symbol self.tickers[symbol] = parsedTicker client.resolve(parsedTicker, messageHash) def parse_ws_ticker(self, ticker: dict, market: Market = None) -> Ticker: # # { # I: 'BTC/USDT', # U: 1760913034742, # PF: 0, # E: 0, # O: 108479.9, # H: 109449.9, # L: 108238, # V: 789.3424915, # T: 43003872.3705223, # N: 109345, # M: 87294.7, # D: 0, # V2: 3086.4496105, # T2: 332811624.339836, # F: 0, # C: 0, # BP1: 109344.9, # AP1: 109345.2 # } # timestamp = self.safe_integer(ticker, 'U') high = self.safe_number(ticker, 'H') low = self.safe_number(ticker, 'L') open = self.safe_number(ticker, 'O') last = self.safe_number(ticker, 'N') bid = self.safe_number(ticker, 'BP1') ask = self.safe_number(ticker, 'AP1') baseVolume = self.safe_number(ticker, 'V') quoteVolume = self.safe_number(ticker, 'T') if market['inverse']: temp = baseVolume baseVolume = quoteVolume quoteVolume = temp return self.safe_ticker({ 'symbol': market['symbol'], 'timestamp': timestamp, 'datetime': self.iso8601(timestamp), 'high': high, 'low': low, 'bid': bid, 'bidVolume': None, 'ask': ask, 'askVolume': None, 'vwap': None, 'open': open, 'close': last, 'last': last, 'previousClose': None, 'change': None, 'percentage': None, 'average': None, 'baseVolume': baseVolume, 'quoteVolume': quoteVolume, 'info': ticker, }, market) async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]: """ watches information on multiple trades made in a market https://www.deepcoin.com/docs/publicWS/lastTransactions :param str symbol: unified market symbol of the market trades were made in :param int [since]: the earliest time in ms to fetch orders for :param int [limit]: the maximum number of trade structures to retrieve :param dict [params]: extra parameters specific to the exchange API endpoint :returns dict[]: a list of `trade structures ` """ await self.load_markets() market = self.market(symbol) messageHash = 'trades' + '::' + market['symbol'] trades = await self.watch_public(market, messageHash, '2', params) if self.newUpdates: limit = trades.getLimit(symbol, limit) return self.filter_by_since_limit(trades, since, limit, 'timestamp', True) async def un_watch_trades(self, symbol: str, params={}): """ unWatches the list of most recent trades for a particular symbol https://www.deepcoin.com/docs/publicWS/lastTransactions :param str symbol: unified symbol of the market to fetch trades for :param dict [params]: extra parameters specific to the exchange API endpoint :returns dict[]: a list of `trade structures ` """ await self.load_markets() market = self.market(symbol) messageHash = 'trades' + '::' + market['symbol'] subscription = { 'topic': 'trades', } return await self.un_watch_public(market, messageHash, '2', params, subscription) def handle_trades(self, client: Client, message): # # { # "a": "PMT", # "b": 0, # "tt": 1760968672380, # "mt": 1760968672380, # "r": [ # { # "d": { # "TradeID": "1001056452325378", # "I": "BTC/USDT", # "D": "1", # "P": 111061, # "V": 0.00137, # "T": 1760968672 # } # } # ] # } # response = self.safe_list(message, 'r', []) first = self.safe_dict(response, 0, {}) data = self.safe_dict(first, 'd', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) if not (symbol in self.trades): limit = self.safe_integer(self.options, 'tradesLimit', 1000) self.trades[symbol] = ArrayCache(limit) strored = self.trades[symbol] if data is not None: trade = self.parse_ws_trade(data, market) strored.append(trade) messageHash = 'trades' + '::' + symbol client.resolve(strored, messageHash) def parse_ws_trade(self, trade: dict, market: Market = None) -> Trade: # # watchTrades # { # "TradeID": "1001056452325378", # "I": "BTC/USDT", # "D": "1", # "P": 111061, # "V": 0.00137, # "T": 1760968672 # } # # watchMyTrades # { # "A": "9256245", # "CC": "USDT", # "CP": 0, # "D": "0", # "F": 0.152, # "I": "DOGE/USDT", # "IT": 1761048103, # "M": "9256245", # "OS": "1001437462198486", # "P": 0.19443, # "T": 14.77668, # "TI": "1001056459096708", # "TT": 1761048103, # "V": 76, # "f": "DOGE", # "l": 1, # "m": "1", # "o": "0" # } # direction = self.safe_string(trade, 'D') timestamp = self.safe_timestamp_2(trade, 'TT', 'T') matchRole = self.safe_string(trade, 'm') fee = None feeCost = self.safe_string(trade, 'F') if feeCost is not None: fee = { 'cost': feeCost, 'currency': self.safe_currency_code(self.safe_string(trade, 'f')), } return self.safe_trade({ 'info': trade, 'timestamp': timestamp, 'datetime': self.iso8601(timestamp), 'symbol': market['symbol'], 'id': self.safe_string_2(trade, 'TradeID', 'TI'), 'order': self.safe_string(trade, 'OS'), 'type': None, 'takerOrMaker': self.handle_taker_or_maker(matchRole), 'side': self.parse_trade_side(direction), 'price': self.safe_string(trade, 'P'), 'amount': self.safe_string(trade, 'V'), 'cost': self.safe_string(trade, 'T'), 'fee': fee, }, market) def parse_trade_side(self, direction: Str) -> Str: sides = { '0': 'buy', '1': 'sell', } return self.safe_string(sides, direction, direction) def handle_taker_or_maker(self, matchRole: Str) -> Str: roles = { '0': 'maker', '1': 'taker', } return self.safe_string(roles, matchRole, matchRole) async def watch_ohlcv(self, symbol: str, timeframe: str = '1m', since: Int = None, limit: Int = None, params={}) -> List[list]: """ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market https://www.deepcoin.com/docs/publicWS/KLines :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() market = self.market(symbol) symbol = market['symbol'] timeframes = self.safe_dict(self.options, 'timeframes', {}) interval = self.safe_string(timeframes, timeframe, timeframe) messageHash = 'ohlcv' + '::' + symbol + '::' + timeframe suffix = '_' + interval ohlcv = await self.watch_public(market, messageHash, '11', params, suffix) if self.newUpdates: limit = ohlcv.getLimit(symbol, limit) return self.filter_by_since_limit(ohlcv, since, limit, 0, True) async def un_watch_ohlcv(self, symbol: str, timeframe: str = '1m', params={}) -> Any: """ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market https://docs.backpack.exchange/#tag/Streams/Public/K-Line :param str symbol: unified symbol of the market to fetch OHLCV data for :param str [timeframe]: the length of time each candle represents :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() market = self.market(symbol) symbol = market['symbol'] timeframes = self.safe_dict(self.options, 'timeframes', {}) interval = self.safe_string(timeframes, timeframe, timeframe) messageHash = 'ohlcv' + '::' + symbol + '::' + timeframe suffix = '_' + interval subscription = { 'topic': 'ohlcv', 'symbolsAndTimeframes': [[symbol, timeframe]], } return await self.un_watch_public(market, messageHash, '11', params, subscription, suffix) def handle_ohlcv(self, client: Client, message): # # { # "a": "PK", # "tt": 1760972831580, # "mt": 1760972831580, # "r": [ # { # "d": { # "I": "BTC/USDT", # "P": "1m", # "B": 1760972820, # "O": 111373, # "C": 111382.9, # "H": 111382.9, # "L": 111373, # "V": 0.2414172, # "M": 26888.19693324 # }, # "t": "LK" # } # ] # } # response = self.safe_list(message, 'r', []) first = self.safe_dict(response, 0, {}) data = self.safe_dict(first, 'd', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) interval = self.safe_string(data, 'P') timeframe = self.find_timeframe(interval) if not (symbol in self.ohlcvs): self.ohlcvs[symbol] = {} if not (timeframe in self.ohlcvs[symbol]): limit = self.safe_integer(self.options, 'OHLCVLimit', 1000) self.ohlcvs[symbol][timeframe] = ArrayCacheByTimestamp(limit) stored = self.ohlcvs[symbol][timeframe] if data is not None: ohlcv = self.parse_ws_ohlcv(data, market) stored.append(ohlcv) messageHash = 'ohlcv' + '::' + symbol + '::' + timeframe client.resolve(stored, messageHash) def parse_ws_ohlcv(self, ohlcv, market: Market = None) -> list: # # { # "I": "BTC/USDT", # "P": "1m", # "B": 1760972820, # "O": 111373, # "C": 111382.9, # "H": 111382.9, # "L": 111373, # "V": 0.2414172, # "M": 26888.19693324 # } # return [ self.safe_timestamp(ohlcv, 'B'), self.safe_number(ohlcv, 'O'), self.safe_number(ohlcv, 'H'), self.safe_number(ohlcv, 'L'), self.safe_number(ohlcv, 'C'), self.safe_number(ohlcv, 'V'), ] 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 https://www.deepcoin.com/docs/publicWS/25LevelIncrementalMarketData :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 ` indexed by market symbols """ await self.load_markets() market = self.market(symbol) messageHash = 'orderbook' + '::' + market['symbol'] suffix = '_0.1' orderbook = await self.watch_public(market, messageHash, '25', params, suffix) return orderbook.limit() async def un_watch_order_book(self, symbol: str, params={}) -> Any: """ unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data https://www.deepcoin.com/docs/publicWS/25LevelIncrementalMarketData :param str symbol: unified array of symbols :param dict [params]: extra parameters specific to the exchange API endpoint :returns dict: A dictionary of `order book structures ` indexed by market symbols """ await self.load_markets() market = self.market(symbol) messageHash = 'orderbook' + '::' + market['symbol'] suffix = '_0.1' subscription = { 'topic': 'orderbook', } return await self.un_watch_public(market, messageHash, '25', params, subscription, suffix) def handle_order_book(self, client: Client, message): # # { # "a": "PMO", # "t": "i", # i - update, f - snapshot # "r": [ # { # "d": {"I": "ETH/USDT", "D": "1", "P": 4021, "V": 54.39979} # }, # { # "d": {"I": "ETH/USDT", "D": "0", "P": 4021.1, "V": 49.56724} # } # ], # "tt": 1760975816446, # "mt": 1760975816446 # } # response = self.safe_list(message, 'r', []) first = self.safe_dict(response, 0, {}) data = self.safe_dict(first, 'd', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) if not (symbol in self.orderbooks): self.orderbooks[symbol] = self.order_book() orderbook = self.orderbooks[symbol] type = self.safe_string(message, 't') if orderbook['timestamp'] is None: if type == 'f': # snapshot self.handle_order_book_snapshot(client, message) else: # cache the updates until the snapshot is received orderbook.cache.append(message) else: self.handle_order_book_message(client, message, orderbook) messageHash = 'orderbook' + '::' + symbol client.resolve(orderbook, messageHash) def handle_order_book_snapshot(self, client: Client, message): entries = self.safe_list(message, 'r', []) first = self.safe_dict(entries, 0, {}) data = self.safe_dict(first, 'd', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) orderbook = self.orderbooks[symbol] orderedEntries: dict = { 'bids': [], 'asks': [], } for i in range(0, len(entries)): entry = entries[i] entryData = self.safe_dict(entry, 'd', {}) side = self.safe_string(entryData, 'D') price = self.safe_number(entryData, 'P') volume = self.safe_number(entryData, 'V') if side == '0': # bid orderedEntries['bids'].append([price, volume]) elif side == '1': # ask orderedEntries['asks'].append([price, volume]) timestamp = self.safe_integer(message, 'mt') snapshot = self.parse_order_book(orderedEntries, symbol, timestamp) orderbook.reset(snapshot) cachedMessages = orderbook.cache for j in range(0, len(cachedMessages)): cachedMessage = cachedMessages[j] self.handle_order_book_message(client, cachedMessage, orderbook) orderbook.cache = [] messageHash = 'orderbook' + '::' + symbol client.resolve(orderbook, messageHash) def handle_order_book_message(self, client: Client, message, orderbook): # { # "a": "PMO", # "t": "i", # i - update, f - snapshot # "r": [ # { # "d": {"I": "ETH/USDT", "D": "1", "P": 4021, "V": 54.39979} # }, # { # "d": {"I": "ETH/USDT", "D": "0", "P": 4021.1, "V": 49.56724} # } # ], # "tt": 1760975816446, # "mt": 1760975816446 # } # timestamp = self.safe_integer(message, 'mt') if timestamp > orderbook['timestamp']: response = self.safe_list(message, 'r', []) self.handle_deltas(orderbook, response) orderbook['timestamp'] = timestamp orderbook['datetime'] = self.iso8601(timestamp) def handle_delta(self, orderbook, entry): data = self.safe_dict(entry, 'd', {}) bids = orderbook['bids'] asks = orderbook['asks'] side = self.safe_string(data, 'D') price = self.safe_number(data, 'P') volume = self.safe_number(data, 'V') if side == '0': # bid bids.store(price, volume) elif side == '1': # ask asks.store(price, volume) 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 https://www.deepcoin.com/docs/privateWS/Trade :param str symbol: unified market symbol of the market orders were made in :param int [since]: the earliest time in ms to fetch orders for :param int [limit]: the maximum number of order structures to retrieve :param dict [params]: extra parameters specific to the exchange API endpoint :returns dict[]: a list of `order structures ` """ messageHash = 'myTrades' await self.load_markets() if symbol is not None: symbol = self.symbol(symbol) messageHash += '::' + symbol trades = await self.watch_private(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): # # { # "action": "PushTrade", # "result": [ # { # "table": "Trade", # "data": { # "A": "9256245", # "CC": "USDT", # "CP": 0, # "D": "0", # "F": 0.152, # "I": "DOGE/USDT", # "IT": 1761048103, # "M": "9256245", # "OS": "1001437462198486", # "P": 0.19443, # "T": 14.77668, # "TI": "1001056459096708", # "TT": 1761048103, # "V": 76, # "f": "DOGE", # "l": 1, # "m": "1", # "o": "0" # } # } # ] # } # result = self.safe_list(message, 'result', []) first = self.safe_dict(result, 0, {}) data = self.safe_dict(first, 'data', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) messageHash = 'myTrades' symbolMessageHash = messageHash + '::' + symbol if (messageHash in client.futures) or (symbolMessageHash in client.futures): if self.myTrades is None: limit = self.safe_integer(self.options, 'tradesLimit', 1000) self.myTrades = ArrayCacheBySymbolById(limit) stored = self.myTrades parsed = self.parse_ws_trade(data, market) stored.append(parsed) client.resolve(stored, messageHash) client.resolve(stored, symbolMessageHash) async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]: """ watches information on multiple orders made by the user https://www.deepcoin.com/docs/privateWS/order :param str symbol: unified market symbol of the market orders were made in :param int [since]: the earliest time in ms to fetch orders for :param int [limit]: the maximum number of order structures to retrieve :param dict [params]: extra parameters specific to the exchange API endpoint :returns dict[]: a list of `order structures ` """ messageHash = 'orders' await self.load_markets() if symbol is not None: symbol = self.symbol(symbol) messageHash += '::' + symbol orders = await self.watch_private(messageHash, params) if self.newUpdates: limit = orders.getLimit(symbol, limit) return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True) def handle_order(self, client: Client, message): # # { # "action": "PushOrder", # "result": [ # { # "table": "Order", # "data": { # "D": "0", # "I": "DOGE/USDT", # "IT": 1761051006, # "L": "1001437480817468", # "OPT": "4", # "OS": "1001437480817468", # "OT": "0", # "Or": "1", # "P": 0.19537, # "T": 14.84128, # "U": 1761051006, # "V": 76, # "VT": 76, # "i": 1, # "l": 1, # "o": "0", # "p": "0", # "t": 0.19528 # } # } # ] # } # result = self.safe_list(message, 'result', []) first = self.safe_dict(result, 0, {}) data = self.safe_dict(first, 'data', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) messageHash = 'orders' symbolMessageHash = messageHash + '::' + symbol if (messageHash in client.futures) or (symbolMessageHash in client.futures): if self.orders is None: limit = self.safe_integer(self.options, 'ordersLimit', 1000) self.orders = ArrayCacheBySymbolById(limit) parsed = self.parse_ws_order(data, market) self.orders.append(parsed) client.resolve(self.orders, messageHash) client.resolve(self.orders, symbolMessageHash) def parse_ws_order(self, order, market: Market = None) -> Order: # # { # "D": "0", # "I": "DOGE/USDT", # "IT": 1761051006, # "L": "1001437480817468", # "OPT": "4", # "OS": "1001437480817468", # "OT": "0", # "Or": "1", # "P": 0.19537, # "T": 14.84128, # "U": 1761051006, # "V": 76, # "VT": 76, # "i": 1, # "l": 1, # "o": "0", # "p": "0", # "t": 0.19528 # } # state = self.safe_string(order, 'Or') timestamp = self.safe_timestamp(order, 'IT') direction = self.safe_string(order, 'D') return self.safe_order({ 'id': self.safe_string(order, 'OS'), 'clientOrderId': None, 'datetime': self.iso8601(timestamp), 'timestamp': timestamp, 'lastTradeTimestamp': None, 'lastUpdateTimestamp': self.safe_timestamp(order, 'U'), 'status': self.parse_ws_order_status(state), 'symbol': market['symbol'], 'type': None, 'timeInForce': None, 'side': self.parse_trade_side(direction), 'price': self.safe_string(order, 'P'), 'average': self.safe_string(order, 't'), 'amount': self.safe_string(order, 'V'), 'filled': self.safe_string(order, 'VT'), 'remaining': None, 'triggerPrice': None, 'takeProfitPrice': self.safe_string(order, 'TPT'), 'stopLossPrice': self.safe_string(order, 'SLT'), 'cost': self.safe_string(order, 'T'), 'trades': None, 'fee': None, 'reduceOnly': None, 'postOnly': None, 'info': order, }, market) def parse_ws_order_status(self, status: Str) -> Str: statuses = { '1': 'closed', '4': 'open', '6': 'canceled', } return self.safe_string(statuses, status, status) async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]: """ watch all open positions https://www.deepcoin.com/docs/privateWS/Position :param str[] [symbols]: list of unified market symbols to watch positions for :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 :returns dict[]: a list of `position structure ` """ await self.load_markets() listenKey = await self.authenticate() symbols = self.market_symbols(symbols) messageHash = 'positions' messageHashes = [] if symbols is not None: for i in range(0, len(symbols)): symbol = symbols[i] symbolMessageHash = messageHash + '::' + symbol messageHashes.append(symbolMessageHash) else: messageHashes.append(messageHash) url = self.urls['api']['ws']['private'] + '?listenKey=' + listenKey positions = await self.watch_multiple(url, messageHashes, params, ['private']) if self.newUpdates: return positions return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit, True) def handle_position(self, client: Client, message): # # { # "action": "PushPosition", # "result": [ # { # "table": "Position", # "data": { # "A": "9256245", # "CP": 0, # "I": "DOGE/USDT", # "M": "9256245", # "OP": 0.198845, # "Po": 151.696, # "U": 1761058213, # "i": 1, # "l": 1, # "p": "0", # "u": 0 # } # } # ] # } # result = self.safe_list(message, 'result', []) first = self.safe_dict(result, 0, {}) data = self.safe_dict(first, 'data', {}) marketId = self.safe_string(data, 'I') market = self.safe_market(marketId, None, '/') symbol = self.safe_symbol(marketId, market) messageHash = 'positions' symbolMessageHash = messageHash + '::' + symbol if (messageHash in client.futures) or (symbolMessageHash in client.futures): if self.positions is None: self.positions = ArrayCacheBySymbolBySide() parsed = self.parse_ws_position(data, market) self.positions.append(parsed) client.resolve(self.positions, messageHash) client.resolve(self.positions, symbolMessageHash) def parse_ws_position(self, position, market: Market = None) -> Position: # # { # "A": "9256245", # "CP": 0, # "I": "DOGE/USDT", # "M": "9256245", # "OP": 0.198845, # "Po": 151.696, # "U": 1761058213, # "i": 1, # "l": 1, # "p": "0", # "u": 0 # } # timestamp = self.safe_integer(position, 'U') direction = self.safe_string(position, 'p') marginMode = self.safe_string(position, 'i') return self.safe_position({ 'symbol': market['symbol'], 'id': None, 'timestamp': timestamp, 'datetime': self.iso8601(timestamp), 'contracts': self.safe_string(position, 'Po'), 'contractSize': None, 'side': self.parse_position_side(direction), 'notional': None, 'leverage': self.omit_zero(self.safe_string(position, 'l')), 'unrealizedPnl': None, 'realizedPnl': None, 'collateral': None, 'entryPrice': self.safe_string(position, 'OP'), 'markPrice': None, 'liquidationPrice': None, 'marginMode': self.parse_ws_margin_mode(marginMode), 'hedged': True, 'maintenanceMargin': self.safe_string(position, 'u'), 'maintenanceMarginPercentage': None, 'initialMargin': None, 'initialMarginPercentage': None, 'marginRatio': None, 'lastUpdateTimestamp': None, 'lastPrice': None, 'stopLossPrice': None, 'takeProfitPrice': None, 'percentage': None, 'info': position, }) def parse_position_side(self, direction: Str) -> Str: if direction is None: return direction directions = { '0': 'long', '1': 'short', } return self.safe_string(directions, direction, direction) def parse_ws_margin_mode(self, marginMode: Str) -> Str: if marginMode is None: return marginMode modes = { '0': 'isolated', '1': 'cross', } return self.safe_string(modes, marginMode, marginMode) def handle_message(self, client: Client, message): if message == 'pong': self.handle_pong(client, message) else: m = self.safe_string(message, 'm') if (m is not None) and (m != 'Success'): self.handle_error_message(client, message) action = self.safe_string_2(message, 'a', 'action') if action == 'RecvTopicAction': self.handle_subscription_status(client, message) elif action == 'PO': self.handle_ticker(client, message) elif action == 'PMT': self.handle_trades(client, message) elif action == 'PK': self.handle_ohlcv(client, message) elif action == 'PMO': self.handle_order_book(client, message) elif action == 'PushTrade': self.handle_my_trade(client, message) elif action == 'PushOrder': self.handle_order(client, message) elif action == 'PushPosition': self.handle_position(client, message) def handle_subscription_status(self, client: Client, message): # # { # "a": "RecvTopicAction", # "m": "Success", # "r": [ # { # "d": { # "A": "0", # "L": 1, # "T": "7", # "F": "DeepCoin_BTC/USDT", # "R": -1 # } # } # ] # } # response = self.safe_list(message, 'r', []) first = self.safe_dict(response, 0, {}) data = self.safe_dict(first, 'd', {}) action = self.safe_string(data, 'A') # 1 = subscribe, 0 = unsubscribe if action == '0': subscriptionsById = self.index_by(client.subscriptions, 'id') subId = self.safe_integer(data, 'L') subscription = self.safe_dict(subscriptionsById, subId, {}) # original watch subscription subHash = self.safe_string(subscription, 'subHash') unsubHash = 'unsubscribe::' + subHash unsubsciption = self.safe_dict(client.subscriptions, unsubHash, {}) # unWatch subscription self.handle_un_subscription(client, unsubsciption) def handle_un_subscription(self, client: Client, subscription: dict): subHash = self.safe_string(subscription, 'subHash') unsubHash = self.safe_string(subscription, 'unsubHash') self.clean_unsubscription(client, subHash, unsubHash) self.clean_cache(subscription) def handle_error_message(self, client: Client, message): # # { # "a": "RecvTopicAction", # "m": "subscription cluster does not "exist": BTC/USD", # "r": [ # { # "d": { # "A": "1", # "L": 1, # "T": "7", # "F": "DeepCoin_BTC/USD", # "R": -1 # } # } # ] # } # messageText = self.safe_string(message, 'm', '') response = self.safe_list(message, 'r', []) first = self.safe_dict(response, 0, {}) data = self.safe_dict(first, 'd', {}) requestId = self.safe_integer(data, 'L') subscriptionsById = self.index_by(client.subscriptions, 'id') subscription = self.safe_dict(subscriptionsById, requestId, {}) messageHash = self.safe_string(subscription, 'subHash') feedback = self.id + ' ' + self.json(message) try: self.throw_exactly_matched_exception(self.exceptions['exact'], messageText, feedback) self.throw_broadly_matched_exception(self.exceptions['broad'], messageText, feedback) raise ExchangeError(feedback) except Exception as e: client.reject(e, messageHash)