def parse_order(self, order, market=None): # # { # "id":11, # "datetime":"2014-10-21 10:47:20", # "type":"sell", # "price":42000, # "amount_original":1.2, # "amount_outstanding":1.2, # "status":"closed", # "trades":[] # no clarification of trade value structure of order endpoint # } # id = self.safe_string(order, 'id') datetimeString = self.safe_string(order, 'datetime') timestamp = None if datetimeString is not None: timestamp = self.parse8601(order['datetime'] + '+09:00') # Tokyo time amount = self.safe_string(order, 'amount_original') remaining = self.safe_string(order, 'amount_outstanding') price = self.safe_string(order, 'price') # status is set by fetchOrder method only status = self.parse_order_status(self.safe_string(order, 'status')) # fetchOrders do not return status, use heuristic if status is None: if Precise.string_equals(remaining, '0'): status = 'closed' trades = None # todo: self.parse_trades(order['trades']) symbol = None if market is not None: symbol = market['symbol'] side = self.safe_string(order, 'type') return self.safe_order( { 'id': id, 'clientOrderId': None, 'timestamp': timestamp, 'datetime': self.iso8601(timestamp), 'lastTradeTimestamp': None, 'amount': amount, 'remaining': remaining, 'filled': None, 'side': side, 'type': None, 'timeInForce': None, 'postOnly': None, 'status': status, 'symbol': symbol, 'price': price, 'stopPrice': None, 'cost': None, 'trades': trades, 'fee': None, 'info': order, 'average': None, }, market)
def parse_order(self, order, market=None): # # # fetchOrder # # { # "transaction_date": "1572497603668315", # "type": "bid", # "order_status": "Completed", # "order_currency": "BTC", # "payment_currency": "KRW", # "order_price": "8601000", # "order_qty": "0.007", # "cancel_date": "", # "cancel_type": "", # "contract": [ # { # "transaction_date": "1572497603902030", # "price": "8601000", # "units": "0.005", # "fee_currency": "KRW", # "fee": "107.51", # "total": "43005" # }, # ] # } # # { # order_date: '1603161798539254', # type: 'ask', # order_status: 'Cancel', # order_currency: 'BTC', # payment_currency: 'KRW', # watch_price: '0', # order_price: '13344000', # order_qty: '0.0125', # cancel_date: '1603161803809993', # cancel_type: '사용자취소', # contract: [ # { # transaction_date: '1603161799976383', # price: '13344000', # units: '0.0015', # fee_currency: 'KRW', # fee: '0', # total: '20016' # } # ], # } # # fetchOpenOrders # # { # "order_currency": "BTC", # "payment_currency": "KRW", # "order_id": "C0101000007408440032", # "order_date": "1571728739360570", # "type": "bid", # "units": "5.0", # "units_remaining": "5.0", # "price": "501000", # } # timestamp = self.safe_integer_product(order, 'order_date', 0.001) sideProperty = self.safe_value_2(order, 'type', 'side') side = 'buy' if (sideProperty == 'bid') else 'sell' status = self.parse_order_status( self.safe_string(order, 'order_status')) price = self.safe_string_2(order, 'order_price', 'price') type = 'limit' if Precise.string_equals(price, '0'): type = 'market' amount = self.safe_string_2(order, 'order_qty', 'units') remaining = self.safe_string(order, 'units_remaining') if remaining is None: if status == 'closed': remaining = '0' elif status != 'canceled': remaining = amount symbol = None baseId = self.safe_string(order, 'order_currency') quoteId = self.safe_string(order, 'payment_currency') base = self.safe_currency_code(baseId) quote = self.safe_currency_code(quoteId) if (base is not None) and (quote is not None): symbol = base + '/' + quote if (symbol is None) and (market is not None): symbol = market['symbol'] id = self.safe_string(order, 'order_id') rawTrades = self.safe_value(order, 'contract', []) return self.safe_order( { 'info': order, 'id': id, 'clientOrderId': None, 'timestamp': timestamp, 'datetime': self.iso8601(timestamp), 'lastTradeTimestamp': None, 'symbol': symbol, 'type': type, 'timeInForce': None, 'postOnly': None, 'side': side, 'price': price, 'stopPrice': None, 'amount': amount, 'cost': None, 'average': None, 'filled': None, 'remaining': remaining, 'status': status, 'fee': None, 'trades': rawTrades, }, market)
async def fetch_markets(self, params={}): markets = await self.publicGetSymbols(params) # # [ # { # "symbol": "122406567911", # "name": "BTC/USDT", # "base": "32", # "quote": "57", # "marketStatus": 0, # "baseName": "BTC", # "quoteName": "USDT", # "active": True, # "maker": "0.0008", # "taker": "0.0008", # "precision": { # "amount": 6, # "price": 2, # "minPrice":1 # }, # "limits": { # "amount": { # "min": "0.000001", # "max": "-1" # }, # "price": { # "min": "0.01", # "max": "-1" # } # } # } # ] # result = [] for i in range(0, len(markets)): market = markets[i] id = self.safe_string(market, 'symbol') base = self.safe_string(market, 'baseName') quote = self.safe_string(market, 'quoteName') baseId = self.safe_string(market, 'base') quoteId = self.safe_string(market, 'quote') normalBase = base.split('@' + baseId)[0] normalQuote = quote.split('@' + quoteId)[0] if quoteId == '126': normalQuote = 'ZAR' # The id 126 coin is a special coin whose name on the chain is actually ZAR, but it is changed to ZCN after creation, so it must be changed to ZAR when placing the transaction in the chain normalSymbol = normalBase + '/' + normalQuote if baseId in self.commonCurrencies: base = self.commonCurrencies[baseId] if quoteId in self.commonCurrencies: quote = self.commonCurrencies[quoteId] symbol = base + '/' + quote limits = self.safe_value(market, 'limits', {}) amount = self.safe_value(limits, 'amount', {}) price = self.safe_value(limits, 'price', {}) precision = self.safe_value(market, 'precision', {}) active = self.safe_string(market, 'active') maxAmount = self.safe_string(amount, 'max') if Precise.string_equals(maxAmount, '-1'): maxAmount = None maxPrice = self.safe_string(price, 'max') if Precise.string_equals(maxPrice, '-1'): maxPrice = None entry = { 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'baseId': baseId, 'quoteId': quoteId, 'info': market, 'type': 'spot', 'spot': True, 'active': active, 'precision': { 'amount': self.safe_integer(precision, 'amount'), 'price': self.safe_integer(precision, 'price'), }, 'normalSymbol': normalSymbol, 'limits': { 'amount': { 'min': self.safe_number(amount, 'min'), 'max': self.parse_number(maxAmount), }, 'price': { 'min': self.safe_number(price, 'min'), 'max': self.parse_number(maxPrice), }, 'cost': { 'min': None, 'max': None, }, }, } result.append(entry) return result
async def fetch_currencies(self, params={}): currencies = await self.publicGetCurrencies(params) result = {} for i in range(0, len(currencies)): currency = currencies[i] id = self.safe_string(currency, 'code') code = None if id in self.commonCurrencies: code = self.commonCurrencies[id] else: code = self.safe_string(currency, 'name') name = self.safe_string(currency, 'fullname') # in byte-trade.com DEX, request https://api-v2.byte-trade.com/currencies will return currencies, # the api doc is https://github.com/Bytetrade/bytetrade-official-api-docs/wiki/rest-api#get-currencies-get-currencys-supported-in-bytetradecom # we can see the coin name is none-unique in the result, the coin which code is 18 is the CyberMiles ERC20, and the coin which code is 35 is the CyberMiles main chain, but their name is same. # that is because bytetrade is a DEX, supports people create coin with the same name, but the id(code) of coin is unique, so we should use the id or name and id as the identity of coin. # For coin name and symbol is same with CCXT, I use name@id as the key of commonCurrencies dict. # [{ # "name": "CMT", # currency name, non-unique # "code": "18", # currency id, unique # "type": "crypto", # "fullname": "CyberMiles", # "active": True, # "chainType": "ethereum", # "basePrecision": 18, # "transferPrecision": 10, # "externalPrecision": 18, # "chainContractAddress": "0xf85feea2fdd81d51177f6b8f35f0e6734ce45f5f", # "limits": { # "deposit": { # "min": "0", # "max": "-1" # }, # "withdraw": { # "min": "0", # "max": "-1" # } # } # }, # { # "name": "CMT", # "code": "35", # "type": "crypto", # "fullname": "CyberMiles", # "active": True, # "chainType": "cmt", # "basePrecision": 18, # "transferPrecision": 10, # "externalPrecision": 18, # "chainContractAddress": "0x0000000000000000000000000000000000000000", # "limits": { # "deposit": { # "min": "1", # "max": "-1" # }, # "withdraw": { # "min": "10", # "max": "-1" # } # } # } # ] active = self.safe_value(currency, 'active') limits = self.safe_value(currency, 'limits') deposit = self.safe_value(limits, 'deposit') amountPrecision = self.safe_integer(currency, 'basePrecision') maxDeposit = self.safe_string(deposit, 'max') if Precise.string_equals(maxDeposit, '-1'): maxDeposit = None withdraw = self.safe_value(limits, 'withdraw') maxWithdraw = self.safe_string(withdraw, 'max') if Precise.string_equals(maxWithdraw, '-1'): maxWithdraw = None result[code] = { 'id': id, 'code': code, 'name': name, 'active': active, 'deposit': None, 'withdraw': None, 'precision': amountPrecision, 'fee': None, 'limits': { 'amount': { 'min': None, 'max': None }, 'deposit': { 'min': self.safe_number(deposit, 'min'), 'max': self.parse_number(maxDeposit), }, 'withdraw': { 'min': self.safe_number(withdraw, 'min'), 'max': self.parse_number(maxWithdraw), }, }, 'info': currency, } return result
def parse_trade(self, trade, market): # # fetchTrades(public) # # { # "sequence":276989, # "timestamp":1648651276949, # "price":"35773.20000000", # "volume":"0.00300000", # "is_buy":false # } # # fetchMyTrades(private) # # { # "pair":"LTCXBT", # "sequence":3256813, # "order_id":"BXEX6XHHDT5EGW2", # "type":"ASK", # "timestamp":1648652135235, # "price":"0.002786", # "volume":"0.10", # "base":"0.10", # "counter":"0.0002786", # "fee_base":"0.0001", # "fee_counter":"0.00", # "is_buy":false, # "client_order_id":"" # } # # For public trade data(is_buy is True) indicates 'buy' side but for private trade data # is_buy indicates maker or taker. The value of "type"(ASK/BID) indicate sell/buy side. # Private trade data includes ID field which public trade data does not. orderId = self.safe_string(trade, 'order_id') id = self.safe_string(trade, 'sequence') takerOrMaker = None side = None if orderId is not None: type = self.safe_string(trade, 'type') if (type == 'ASK') or (type == 'SELL'): side = 'sell' elif (type == 'BID') or (type == 'BUY'): side = 'buy' if side == 'sell' and trade['is_buy']: takerOrMaker = 'maker' elif side == 'buy' and not trade['is_buy']: takerOrMaker = 'maker' else: takerOrMaker = 'taker' else: side = 'buy' if trade['is_buy'] else 'sell' feeBaseString = self.safe_string(trade, 'fee_base') feeCounterString = self.safe_string(trade, 'fee_counter') feeCurrency = None feeCost = None if feeBaseString is not None: if not Precise.string_equals(feeBaseString, '0.0'): feeCurrency = market['base'] feeCost = feeBaseString elif feeCounterString is not None: if not Precise.string_equals(feeCounterString, '0.0'): feeCurrency = market['quote'] feeCost = feeCounterString timestamp = self.safe_integer(trade, 'timestamp') return self.safe_trade( { 'info': trade, 'id': id, 'timestamp': timestamp, 'datetime': self.iso8601(timestamp), 'symbol': market['symbol'], 'order': orderId, 'type': None, 'side': side, 'takerOrMaker': takerOrMaker, 'price': self.safe_string(trade, 'price'), 'amount': self.safe_string(trade, 'volume'), # Does not include potential fee costs 'cost': self.safe_string(trade, 'counter'), 'fee': { 'cost': feeCost, 'currency': feeCurrency, }, }, market)
assert Precise.string_mul(x, a) == '2' assert Precise.string_mul(a, x) == '2' assert Precise.string_mul(y, a) == '6969690000000000000' assert Precise.string_mul(a, y) == '6969690000000000000' assert Precise.string_div(y, a) == '696.969' assert Precise.string_div(y, a, -1) == '690' assert Precise.string_div(y, a, 0) == '696' assert Precise.string_div(y, a, 1) == '696.9' assert Precise.string_div(y, a, 2) == '696.96' assert Precise.string_div(a, y) == '0.001434784043479695' assert Precise.string_abs('0') == '0' assert Precise.string_abs('-0') == '0' assert Precise.string_abs('-500.1') == '500.1' assert Precise.string_abs('213') == '213' assert Precise.string_neg('0') == '0' assert Precise.string_neg('-0') == '0' assert Precise.string_neg('-500.1') == '500.1' assert Precise.string_neg('213') == '-213' assert Precise.string_mod('57.123', '10') == '7.123' assert Precise.string_mod('18', '6') == '0' assert Precise.string_mod('10.1', '0.5') == '0.1' assert Precise.string_mod('10000000', '5555') == '1000' assert Precise.string_mod('5550', '120') == '30' assert Precise.string_equals('1.0000', '1') assert Precise.string_equals('-0.0', '0') assert Precise.string_equals('5.534000', '5.5340')
def parse_order(self, order, market=None): # # fetchOrder, createOrder, cancelOrder, cancelOrders, fetchOpenOrders, fetchClosedOrders # # { # "cancelledQuantity": "0.3", # "clientOrderId": "my-order-1", # "createdAt": "1970-01-01T00:00:00", # "cursorId": 50, # "expireTime": "1970-01-01T00:00:00", # "filledQuantity": "0.3", # "id": "string", # "price": "0.017", # "quantity": "0.3", # "side": "BUY", # "symbol": "TIMEETH", # "type": "LIMIT", # "updatedAt": "1970-01-01T00:00:00" # "trades": [], # injected from the outside # } # id = self.safe_string(order, 'id') type = self.safe_string_lower(order, 'type') side = self.safe_string_lower(order, 'side') marketId = self.safe_string(order, 'symbol') symbol = self.safe_symbol(marketId, market) timestamp = self.parse8601(self.safe_string(order, 'createdAt')) price = self.safe_string(order, 'price') amount = self.safe_string(order, 'quantity') filled = self.safe_string(order, 'filledQuantity') canceledQuantity = self.omit_zero(self.safe_string(order, 'cancelledQuantity')) status = None if Precise.string_equals(filled, amount): status = 'closed' elif canceledQuantity is not None: status = 'canceled' else: status = 'open' rawTrades = self.safe_value(order, 'trades', []) clientOrderId = self.safe_string(order, 'clientOrderId') return self.safe_order({ 'info': order, 'id': id, 'clientOrderId': clientOrderId, 'timestamp': timestamp, 'datetime': self.iso8601(timestamp), 'lastTradeTimestamp': None, 'symbol': symbol, 'type': type, 'timeInForce': None, 'postOnly': None, 'side': side, 'price': price, 'stopPrice': None, 'amount': amount, 'cost': None, 'average': None, 'filled': filled, 'remaining': None, 'status': status, 'fee': None, 'trades': rawTrades, }, market)