Add get_option to expose ft_has via method
This commit is contained in:
parent
87a3115073
commit
f6d832c6d9
@ -81,7 +81,7 @@ def start_download_data(args: Dict[str, Any]) -> None:
|
||||
data_format_trades=config['dataformat_trades'],
|
||||
)
|
||||
else:
|
||||
if not exchange._ft_has.get('ohlcv_has_history', True):
|
||||
if not exchange.get_option('ohlcv_has_history', True):
|
||||
raise OperationalException(
|
||||
f"Historic klines not available for {exchange.name}. "
|
||||
"Please use `--dl-trades` instead for this exchange "
|
||||
|
@ -302,8 +302,8 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes
|
||||
if trading_mode == 'futures':
|
||||
# Predefined candletype (and timeframe) depending on exchange
|
||||
# Downloads what is necessary to backtest based on futures data.
|
||||
tf_mark = exchange._ft_has['mark_ohlcv_timeframe']
|
||||
fr_candle_type = CandleType.from_string(exchange._ft_has['mark_ohlcv_price'])
|
||||
tf_mark = exchange.get_option('mark_ohlcv_timeframe')
|
||||
fr_candle_type = CandleType.from_string(exchange.get_option('mark_ohlcv_price'))
|
||||
# All exchanges need FundingRate for futures trading.
|
||||
# The timeframe is aligned to the mark-price timeframe.
|
||||
for funding_candle_type in (CandleType.FUNDING_RATE, fr_candle_type):
|
||||
|
@ -674,6 +674,12 @@ class Exchange:
|
||||
f"Freqtrade does not support {mm_value} {trading_mode.value} on {self.name}"
|
||||
)
|
||||
|
||||
def get_option(self, param: str, default: Any = None) -> Any:
|
||||
"""
|
||||
Get parameter value from _ft_has
|
||||
"""
|
||||
return self._ft_has.get(param, default)
|
||||
|
||||
def exchange_has(self, endpoint: str) -> bool:
|
||||
"""
|
||||
Checks if exchange implements a specific API endpoint.
|
||||
|
@ -267,7 +267,7 @@ class Backtesting:
|
||||
funding_rates_dict = history.load_data(
|
||||
datadir=self.config['datadir'],
|
||||
pairs=self.pairlists.whitelist,
|
||||
timeframe=self.exchange._ft_has['mark_ohlcv_timeframe'],
|
||||
timeframe=self.exchange.get_option('mark_ohlcv_timeframe'),
|
||||
timerange=self.timerange,
|
||||
startup_candles=0,
|
||||
fail_without_data=True,
|
||||
@ -279,12 +279,12 @@ class Backtesting:
|
||||
mark_rates_dict = history.load_data(
|
||||
datadir=self.config['datadir'],
|
||||
pairs=self.pairlists.whitelist,
|
||||
timeframe=self.exchange._ft_has['mark_ohlcv_timeframe'],
|
||||
timeframe=self.exchange.get_option('mark_ohlcv_timeframe'),
|
||||
timerange=self.timerange,
|
||||
startup_candles=0,
|
||||
fail_without_data=True,
|
||||
data_format=self.config.get('dataformat_ohlcv', 'json'),
|
||||
candle_type=CandleType.from_string(self.exchange._ft_has["mark_ohlcv_price"])
|
||||
candle_type=CandleType.from_string(self.exchange.get_option("mark_ohlcv_price"))
|
||||
)
|
||||
# Combine data to avoid combining the data per trade.
|
||||
unavailable_pairs = []
|
||||
|
@ -73,7 +73,7 @@ class VolumePairList(IPairList):
|
||||
|
||||
if (not self._use_range and not (
|
||||
self._exchange.exchange_has('fetchTickers')
|
||||
and self._exchange._ft_has["tickers_have_quoteVolume"])):
|
||||
and self._exchange.get_option("tickers_have_quoteVolume"))):
|
||||
raise OperationalException(
|
||||
"Exchange does not support dynamic whitelist in this configuration. "
|
||||
"Please edit your config and either remove Volumepairlist, "
|
||||
@ -193,7 +193,7 @@ class VolumePairList(IPairList):
|
||||
) in candles else None
|
||||
# in case of candle data calculate typical price and quoteVolume for candle
|
||||
if pair_candles is not None and not pair_candles.empty:
|
||||
if self._exchange._ft_has["ohlcv_volume_currency"] == "base":
|
||||
if self._exchange.get_option("ohlcv_volume_currency") == "base":
|
||||
pair_candles['typical_price'] = (pair_candles['high'] + pair_candles['low']
|
||||
+ pair_candles['close']) / 3
|
||||
|
||||
|
@ -2352,10 +2352,10 @@ def test_fetch_l2_order_book(default_conf, mocker, order_book_l2, exchange_name)
|
||||
order_book = exchange.fetch_l2_order_book(pair='ETH/BTC', limit=val)
|
||||
assert api_mock.fetch_l2_order_book.call_args_list[0][0][0] == 'ETH/BTC'
|
||||
# Not all exchanges support all limits for orderbook
|
||||
if not exchange._ft_has['l2_limit_range'] or val in exchange._ft_has['l2_limit_range']:
|
||||
if not exchange.get_option('l2_limit_range') or val in exchange.get_option('l2_limit_range'):
|
||||
assert api_mock.fetch_l2_order_book.call_args_list[0][0][1] == val
|
||||
else:
|
||||
next_limit = exchange.get_next_limit_in_list(val, exchange._ft_has['l2_limit_range'])
|
||||
next_limit = exchange.get_next_limit_in_list(val, exchange.get_option('l2_limit_range'))
|
||||
assert api_mock.fetch_l2_order_book.call_args_list[0][0][1] == next_limit
|
||||
|
||||
|
||||
@ -3311,16 +3311,16 @@ def test_merge_ft_has_dict(default_conf, mocker):
|
||||
|
||||
ex = Kraken(default_conf)
|
||||
assert ex._ft_has != Exchange._ft_has_default
|
||||
assert ex._ft_has['trades_pagination'] == 'id'
|
||||
assert ex._ft_has['trades_pagination_arg'] == 'since'
|
||||
assert ex.get_option('trades_pagination') == 'id'
|
||||
assert ex.get_option('trades_pagination_arg') == 'since'
|
||||
|
||||
# Binance defines different values
|
||||
ex = Binance(default_conf)
|
||||
assert ex._ft_has != Exchange._ft_has_default
|
||||
assert ex._ft_has['stoploss_on_exchange']
|
||||
assert ex._ft_has['order_time_in_force'] == ['gtc', 'fok', 'ioc']
|
||||
assert ex._ft_has['trades_pagination'] == 'id'
|
||||
assert ex._ft_has['trades_pagination_arg'] == 'fromId'
|
||||
assert ex.get_option('stoploss_on_exchange')
|
||||
assert ex.get_option('order_time_in_force') == ['gtc', 'fok', 'ioc']
|
||||
assert ex.get_option('trades_pagination') == 'id'
|
||||
assert ex.get_option('trades_pagination_arg') == 'fromId'
|
||||
|
||||
conf = copy.deepcopy(default_conf)
|
||||
conf['exchange']['_ft_has_params'] = {"DeadBeef": 20,
|
||||
|
Loading…
Reference in New Issue
Block a user