Skip to content

Commit a99e584

Browse files
committed
[Hollaex] make fee tier configurable
1 parent 2d06100 commit a99e584

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

Trading/Exchange/hollaex/hollaex_exchange.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ async def _refresh_exchange_fee_tiers(self, all_markets: list[dict]):
148148
fee_pairs = list(fees_by_tier[next(iter(fees_by_tier))]) if fees_by_tier else []
149149
self.logger.info(
150150
f"Refreshed {exchange_name} fee tiers. Sample: {sample}. {len(sample)} tiers: {list(sample)} "
151-
f"over {len(fee_pairs)} pairs: {fee_pairs}."
151+
f"over {len(fee_pairs)} pairs: {fee_pairs}. Using fee tiers "
152+
f"{self._get_fee_tiers(self.exchange_manager.exchange, not self.exchange_manager.is_backtesting).value}."
152153
)
153154

154155
@classmethod
@@ -177,7 +178,7 @@ def register_simulator_connector_fee_methods(
177178
):
178179
# only called in backtesting
179180
# overrides exchange simulator connector calculate_fees and get_fees to use fetched fees instead
180-
fee_tiers = cls._get_fee_tiers(False)
181+
fee_tiers = cls._get_fee_tiers(None, False)
181182
simulator_connector.calculate_fees = cls.simulator_connector_calculate_fees_factory(exchange_name, fee_tiers)
182183
simulator_connector.get_fees = cls.simulator_connector_get_fees_factory(exchange_name, fee_tiers)
183184

@@ -188,8 +189,9 @@ def calculate_fees(
188189
# only called in live trading
189190
is_real_trading = not self.exchange_manager.is_backtesting # consider live trading as real to use basic tier
190191
try:
192+
fee_tiers = self._get_fee_tiers(self.exchange_manager.exchange, is_real_trading)
191193
return self._calculate_fetched_fees(
192-
self.exchange_manager.exchange_name, self._get_fee_tiers(is_real_trading),
194+
self.exchange_manager.exchange_name, fee_tiers,
193195
symbol, order_type, quantity, price, taker_or_maker
194196
)
195197
except errors.MissingFeeDetailsError as err:
@@ -201,7 +203,8 @@ def get_fees(self, symbol):
201203
# only called in live trading
202204
try:
203205
is_real_trading = not self.exchange_manager.is_backtesting # consider live trading as real to use basic tier
204-
return self._get_fees(self.exchange_manager.exchange_name, self._get_fee_tiers(is_real_trading), symbol)
206+
fee_tiers = self._get_fee_tiers(self.exchange_manager.exchange, is_real_trading)
207+
return self._get_fees(self.exchange_manager.exchange_name, fee_tiers, symbol)
205208
except errors.MissingFeeDetailsError:
206209
self.logger.error(f"Missing fee details, using default value")
207210
market = self.get_market_status(symbol, with_fixer=False)
@@ -258,7 +261,14 @@ def _calculate_fetched_fees(
258261
}
259262

260263
@classmethod
261-
def _get_fee_tiers(cls, is_real_trading: bool):
264+
def _get_fee_tiers(cls, rest_exchange: typing.Optional[exchanges.RestExchange], is_real_trading: bool):
265+
if (
266+
rest_exchange
267+
and isinstance(rest_exchange, hollaex)
268+
and (fee_tiers := rest_exchange.get_configured_fee_tiers())
269+
):
270+
return fee_tiers
271+
# default to basic tier
262272
return FeeTiers.BASIC if is_real_trading else FeeTiers.VIP
263273

264274
@classmethod
@@ -320,6 +330,7 @@ class hollaex(exchanges.RestExchange):
320330

321331
BASE_REST_API = "api.hollaex.com"
322332
REST_KEY = "rest"
333+
FEE_TIERS_KEY = "fee_tiers"
323334
HAS_WEBSOCKETS_KEY = "has_websockets"
324335
REQUIRE_ORDER_FEES_FROM_TRADES = True # set True when get_order is not giving fees on closed orders and fees
325336
SUPPORT_FETCHING_CANCELLED_ORDERS = False
@@ -398,16 +409,29 @@ def init_user_inputs_from_class(cls, inputs: dict) -> None:
398409
cls.REST_KEY, commons_enums.UserInputTypes.TEXT, f"https://{cls.BASE_REST_API}", inputs,
399410
title=f"Address of the Hollaex based exchange API (similar to https://{cls.BASE_REST_API})"
400411
)
412+
cls.CLASS_UI.user_input(
413+
cls.FEE_TIERS_KEY, commons_enums.UserInputTypes.OPTIONS, FeeTiers.BASIC.value, inputs,
414+
title=f"Fee tiers to use for the exchange. Used to predict fees.",
415+
options=[tier.value for tier in FeeTiers]
416+
)
401417
cls.CLASS_UI.user_input(
402418
cls.HAS_WEBSOCKETS_KEY, commons_enums.UserInputTypes.BOOLEAN, True, inputs,
403419
title=f"Use websockets feed. To enable only when websockets are supported by the exchange."
404420
)
405421

406422
def get_additional_connector_config(self):
407423
return {
408-
ccxt_enums.ExchangeColumns.URLS.value: self.get_patched_urls(self.tentacle_config[self.REST_KEY])
424+
ccxt_enums.ExchangeColumns.URLS.value: self.get_patched_urls(self.get_api_url())
409425
}
410426

427+
def get_api_url(self):
428+
return self.tentacle_config[self.REST_KEY]
429+
430+
def get_configured_fee_tiers(self) -> typing.Optional[FeeTiers]:
431+
if tiers := self.tentacle_config.get(self.FEE_TIERS_KEY):
432+
return FeeTiers(tiers)
433+
return None
434+
411435
@classmethod
412436
def get_custom_url_config(cls, tentacle_config: dict, exchange_name: str) -> dict:
413437
if details := cls.get_exchange_details(tentacle_config, exchange_name):

0 commit comments

Comments
 (0)