def fetch_market(self, market_id): """ Fetch and cache it. It rarely changes. """ instrument = self._instruments.get(market_id) market = None if instrument: market = Market(market_id, instrument['altname']) market.is_open = True market.expiry = '-' # "wsname":"XBT\/USD" # wsname = WebSocket pair name (if available) # pair_decimals = scaling decimal places for pair # lot_decimals = scaling decimal places for volume # lot_multiplier = amount to multiply lot volume by to get currency volume # "aclass_base":"currency" base_asset = instrument['base'] # XXBT market.set_base(base_asset, base_asset, instrument['pair_decimals']) # "aclass_quote":"currency" quote_asset = instrument['quote'] # ZUSD market.set_quote(quote_asset, quote_asset, instrument['lot_decimals']) # 8 # tick size at the base asset precision market.one_pip_means = math.pow(10.0, -instrument['pair_decimals']) # 1 market.value_per_pip = 1.0 market.contract_size = 1.0 market.lot_size = 1.0 # "lot":"unit", "lot_multiplier":1 # "margin_call":80, "margin_stop":40 # margin_call = margin call level # margin_stop = stop-out/liquidation margin level leverages = set(instrument.get('leverage_buy', [])) leverages.intersection(set(instrument.get('leverage_sell', []))) market.margin_factor = 1.0 / max(leverages) if len( leverages) > 0 else 1.0 market.set_leverages(leverages) size_limit = self._size_limits.get(instrument['altname'], {}) min_size = size_limit.get('min-size', 1.0) size_limits = [str(min_size), "0.0", str(min_size)] notional_limits = ["0.0", "0.0", "0.0"] price_limits = ["0.0", "0.0", "0.0"] market.set_size_limits(float(size_limits[0]), float(size_limits[1]), float(size_limits[2])) market.set_price_limits(float(price_limits[0]), float(price_limits[1]), float(price_limits[2])) market.set_notional_limits(float(notional_limits[0]), 0.0, 0.0) # "lot":"unit" market.unit_type = Market.UNIT_AMOUNT market.market_type = Market.TYPE_CRYPTO market.contract_type = Market.CONTRACT_SPOT market.trade = Market.TRADE_ASSET if leverages: market.trade |= Market.TRADE_MARGIN market.trade |= Market.TRADE_FIFO # orders capacities market.orders = Order.ORDER_LIMIT | Order.ORDER_MARKET | Order.ORDER_STOP | Order.ORDER_TAKE_PROFIT # @todo take the first but it might depends of the traded volume per 30 days, then request volume window to got it # "fees":[[0,0.26],[50000,0.24],[100000,0.22],[250000,0.2],[500000,0.18],[1000000,0.16],[2500000,0.14],[5000000,0.12],[10000000,0.1]], # "fees_maker":[[0,0.16],[50000,0.14],[100000,0.12],[250000,0.1],[500000,0.08],[1000000,0.06],[2500000,0.04],[5000000,0.02],[10000000,0]], fees = instrument.get('fees', []) fees_maker = instrument.get('fees_maker', []) if fees: market.taker_fee = round(fees[0][1] * 0.01, 6) if fees_maker: market.maker_fee = round(fees_maker[0][1] * 0.01, 6) if instrument.get('fee_volume_currency'): market.fee_currency = instrument['fee_volume_currency'] if quote_asset != self.BASE_QUOTE: # from XXBTZUSD / XXBTZEUR ... # @todo pass # if self._tickers_data.get(quote_asset+self.BASE_QUOTE): # market.base_exchange_rate = float(self._tickers_data.get(quote_asset+self.BASE_QUOTE, {'price', '1.0'})['price']) # elif self._tickers_data.get(self.BASE_QUOTE+quote_asset): # market.base_exchange_rate = 1.0 / float(self._tickers_data.get(self.BASE_QUOTE+quote_asset, {'price', '1.0'})['price']) # else: # market.base_exchange_rate = 1.0 else: market.base_exchange_rate = 1.0 # @todo contract_size # market.contract_size = 1.0 / mid_price # market.value_per_pip = market.contract_size / mid_price # volume 24h : not have here # notify for strategy self.service.notify(Signal.SIGNAL_MARKET_INFO_DATA, self.name, (market_id, market)) # store the last market info to be used for backtesting if not self._read_only: Database.inst().store_market_info(( self.name, market.market_id, market.symbol, market.market_type, market.unit_type, market.contract_type, # type market.trade, market.orders, # type market.base, market.base_display, market.base_precision, # base market.quote, market.quote_display, market.quote_precision, # quote market.expiry, int(market.last_update_time * 1000.0), # expiry, timestamp str(market.lot_size), str(market.contract_size), str(market.base_exchange_rate), str(market.value_per_pip), str(market.one_pip_means), '-', *size_limits, *notional_limits, *price_limits, str(market.maker_fee), str(market.taker_fee), str(market.maker_commission), str(market.taker_commission))) return market
def fetch_market(self, market_id): """ Fetch and cache it. It rarely changes. """ instrument = self._instruments.get(market_id) market = None if instrument: market = Market(market_id, instrument['altname']) market.is_open = True market.expiry = '-' # "wsname":"XBT\/USD" # wsname = WebSocket pair name (if available) # pair_decimals = scaling decimal places for pair # lot_decimals = scaling decimal places for volume # lot_multiplier = amount to multiply lot volume by to get currency volume # "aclass_base":"currency" base_asset = instrument['base'] # XXBT market.set_base(base_asset, base_asset, instrument['pair_decimals']) # "aclass_quote":"currency" quote_asset = instrument['quote'] # ZUSD market.set_quote(quote_asset, quote_asset, instrument['lot_decimals']) # 8 # tick size at the base asset precision market.one_pip_means = math.pow(10.0, -instrument['pair_decimals']) # 1 market.value_per_pip = 1.0 market.contract_size = 1.0 market.lot_size = 1.0 # "lot":"unit", "lot_multiplier":1 # "margin_call":80, "margin_stop":40 # margin_call = margin call level # margin_stop = stop-out/liquidation margin level leverages = set(instrument.get('leverage_buy', [])) leverages.intersection(set(instrument.get('leverage_sell', []))) market.margin_factor = 1.0 / max(leverages) market.set_leverages(leverages) size_limits = ["1.0", "0.0", "1.0"] notional_limits = ["1.0", "0.0", "0.0"] price_limits = ["0.0", "0.0", "0.0"] # size min/max/step @todo using lot_decimals / pair_decimals # for afilter in instrument["filters"]: # if afilter['filterType'] == "LOT_SIZE": # size_limits = [afilter['minQty'], afilter['maxQty'], afilter['stepSize']] # elif afilter['filterType'] == "MIN_NOTIONAL": # notional_limits[0] = afilter['minNotional'] # elif afilter['filterType'] == "PRICE_FILTER": # price_limits = [afilter['minPrice'], afilter['maxPrice'], afilter['tickSize']] # if float(size_limits[2]) < 1: # size_limits[2] = str(float(size_limits[2])) # * 10) market.set_size_limits(float(size_limits[0]), float(size_limits[1]), float(size_limits[2])) market.set_price_limits(float(price_limits[0]), float(price_limits[1]), float(price_limits[2])) market.set_notional_limits(float(notional_limits[0]), 0.0, 0.0) # "lot":"unit" market.unit_type = Market.UNIT_AMOUNT market.market_type = Market.TYPE_CRYPTO market.trade = Market.TRADE_ASSET market.contract_type = Market.CONTRACT_SPOT # @todo add a copy with market.trade = Market.TRADE_MARGIN market.contract_type = Market.CONTRACT_FUTUR # orders capacities market.orders = Order.ORDER_LIMIT | Order.ORDER_MARKET | Order.ORDER_STOP | Order.ORDER_TAKE_PROFIT # "fees":[[0,0.26],[50000,0.24],[100000,0.22],[250000,0.2],[500000,0.18],[1000000,0.16],[2500000,0.14],[5000000,0.12],[10000000,0.1]], # "fees_maker":[[0,0.16],[50000,0.14],[100000,0.12],[250000,0.1],[500000,0.08],[1000000,0.06],[2500000,0.04],[5000000,0.02],[10000000,0]], # market.maker_fee = account['makerCommission'] * 0.0001 # market.taker_fee = account['takerCommission'] * 0.0001 # 'fee_volume_currency': 'ZUSD' # fee_volume_currency = volume discount currency # if quote_asset != self.BASE_QUOTE: # if self._tickers_data.get(quote_asset+self.BASE_QUOTE): # market.base_exchange_rate = float(self._tickers_data.get(quote_asset+self.BASE_QUOTE, {'price', '1.0'})['price']) # elif self._tickers_data.get(self.BASE_QUOTE+quote_asset): # market.base_exchange_rate = 1.0 / float(self._tickers_data.get(self.BASE_QUOTE+quote_asset, {'price', '1.0'})['price']) # else: # market.base_exchange_rate = 1.0 # else: # market.base_exchange_rate = 1.0 # market.contract_size = 1.0 / mid_price # market.value_per_pip = market.contract_size / mid_price # volume 24h : not have here # store the last market info to be used for backtesting if not self._read_only: Database.inst().store_market_info(( self.name, market.market_id, market.symbol, market.market_type, market.unit_type, market.contract_type, # type market.trade, market.orders, # type market.base, market.base_display, market.base_precision, # base market.quote, market.quote_display, market.quote_precision, # quote market.expiry, int(market.last_update_time * 1000.0), # expiry, timestamp str(market.lot_size), str(market.contract_size), str(market.base_exchange_rate), str(market.value_per_pip), str(market.one_pip_means), '-', *size_limits, *notional_limits, *price_limits, str(market.maker_fee), str(market.taker_fee), str(market.maker_commission), str(market.taker_commission))) # notify for strategy self.service.notify(Signal.SIGNAL_MARKET_INFO_DATA, self.name, (market_id, market)) return market