diff --git a/docs/configuration.md b/docs/configuration.md
index 7a304ec9e..e3b15f4f6 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -204,9 +204,9 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `exchange.uid` | API uid to use for the exchange. Only required when you are in production mode and for exchanges that use uid for API requests.
**Keep it in secret, do not disclose publicly.**
**Datatype:** String
| `exchange.pair_whitelist` | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Supports regex pairs as `.*/BTC`. Not used by VolumePairList. [More information](plugins.md#pairlists-and-pairlist-handlers).
**Datatype:** List
| `exchange.pair_blacklist` | List of pairs the bot must absolutely avoid for trading and backtesting. [More information](plugins.md#pairlists-and-pairlist-handlers).
**Datatype:** List
-| `exchange.ccxt_config` | Additional CCXT parameters passed to both ccxt instances (sync and async). This is usually the correct place for additional ccxt configurations. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation). Please avoid adding exchange secrets here (use the dedicated fields instead), as they may be contained in logs.
**Datatype:** Dict
-| `exchange.ccxt_sync_config` | Additional CCXT parameters passed to the regular (sync) ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
**Datatype:** Dict
-| `exchange.ccxt_async_config` | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
**Datatype:** Dict
+| `exchange.ccxt_config` | Additional CCXT parameters passed to both ccxt instances (sync and async). This is usually the correct place for additional ccxt configurations. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://docs.ccxt.com/#/README?id=overriding-exchange-properties-upon-instantiation). Please avoid adding exchange secrets here (use the dedicated fields instead), as they may be contained in logs.
**Datatype:** Dict
+| `exchange.ccxt_sync_config` | Additional CCXT parameters passed to the regular (sync) ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://docs.ccxt.com/#/README?id=overriding-exchange-properties-upon-instantiation)
**Datatype:** Dict
+| `exchange.ccxt_async_config` | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://docs.ccxt.com/#/README?id=overriding-exchange-properties-upon-instantiation)
**Datatype:** Dict
| `exchange.enable_ws` | Enable the usage of Websockets for the exchange.
*Defaults to `true`.*
**Datatype:** Boolean
| `exchange.markets_refresh_interval` | The interval in minutes in which markets are reloaded.
*Defaults to `60` minutes.*
**Datatype:** Positive Integer
| `exchange.skip_pair_validation` | Skip pairlist validation on startup.
*Defaults to `false`*
**Datatype:** Boolean
diff --git a/docs/freqai-running.md b/docs/freqai-running.md
index 553a8b698..1b721b658 100644
--- a/docs/freqai-running.md
+++ b/docs/freqai-running.md
@@ -73,11 +73,11 @@ Backtesting mode requires [downloading the necessary data](#downloading-data-to-
---
-### Saving prediction data
+### Saving backtesting prediction data
To allow for tweaking your strategy (**not** the features!), FreqAI will automatically save the predictions during backtesting so that they can be reused for future backtests and live runs using the same `identifier` model. This provides a performance enhancement geared towards enabling **high-level hyperopting** of entry/exit criteria.
-An additional directory called `backtesting_predictions`, which contains all the predictions stored in `hdf` format, will be created in the `unique-id` folder.
+An additional directory called `backtesting_predictions`, which contains all the predictions stored in `feather` format, will be created in the `unique-id` folder.
To change your **features**, you **must** set a new `identifier` in the config to signal to FreqAI to train new models.
@@ -89,7 +89,6 @@ FreqAI allow you to reuse live historic predictions through the backtest paramet
The `--timerange` parameter must not be informed, as it will be automatically calculated through the data in the historic predictions file.
-
### Downloading data to cover the full backtest period
For live/dry deployments, FreqAI will download the necessary data automatically. However, to use backtesting functionality, you need to download the necessary data using `download-data` (details [here](data-download.md#data-downloading)). You need to pay careful attention to understanding how much *additional* data needs to be downloaded to ensure that there is a sufficient amount of training data *before* the start of the backtesting time range. The amount of additional data can be roughly estimated by moving the start date of the time range backwards by `train_period_days` and the `startup_candle_count` (see the [parameter table](freqai-parameter-table.md) for detailed descriptions of these parameters) from the beginning of the desired backtesting time range.
diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py
index 257166f9c..3a542226c 100644
--- a/freqtrade/commands/list_commands.py
+++ b/freqtrade/commands/list_commands.py
@@ -45,7 +45,8 @@ def start_list_exchanges(args: Dict[str, Any]) -> None:
"name": exchange["name"],
**valid_entry,
"supported": "Official" if exchange["supported"] else "",
- "trade_modes": ", ".join(
+ "trade_modes": ("DEX: " if exchange["dex"] else "")
+ + ", ".join(
(f"{a['margin_mode']} " if a["margin_mode"] else "") + a["trading_mode"]
for a in exchange["trade_modes"]
),
diff --git a/freqtrade/exchange/binance_leverage_tiers.json b/freqtrade/exchange/binance_leverage_tiers.json
index be9f68d98..ae797c9e5 100644
--- a/freqtrade/exchange/binance_leverage_tiers.json
+++ b/freqtrade/exchange/binance_leverage_tiers.json
@@ -8437,7 +8437,7 @@
}
}
],
- "BTC/USDT:USDT-240628": [
+ "BTC/USDT:USDT-240927": [
{
"tier": 1.0,
"currency": "USDT",
@@ -8567,7 +8567,7 @@
}
}
],
- "BTC/USDT:USDT-240927": [
+ "BTC/USDT:USDT-241227": [
{
"tier": 1.0,
"currency": "USDT",
@@ -13805,7 +13805,7 @@
}
}
],
- "ETH/USDT:USDT-240628": [
+ "ETH/USDT:USDT-240927": [
{
"tier": 1.0,
"currency": "USDT",
@@ -13935,7 +13935,7 @@
}
}
],
- "ETH/USDT:USDT-240927": [
+ "ETH/USDT:USDT-241227": [
{
"tier": 1.0,
"currency": "USDT",
diff --git a/freqtrade/exchange/check_exchange.py b/freqtrade/exchange/check_exchange.py
index 73b1c8a97..6d82bae04 100644
--- a/freqtrade/exchange/check_exchange.py
+++ b/freqtrade/exchange/check_exchange.py
@@ -47,7 +47,7 @@ def check_exchange(config: Config, check_for_bad: bool = True) -> bool:
f'{", ".join(available_exchanges())}'
)
- valid, reason = validate_exchange(exchange)
+ valid, reason, _ = validate_exchange(exchange)
if not valid:
if check_for_bad:
raise OperationalException(
diff --git a/freqtrade/exchange/exchange_utils.py b/freqtrade/exchange/exchange_utils.py
index 89b378c08..9c2514f92 100644
--- a/freqtrade/exchange/exchange_utils.py
+++ b/freqtrade/exchange/exchange_utils.py
@@ -53,7 +53,7 @@ def available_exchanges(ccxt_module: Optional[CcxtModuleType] = None) -> List[st
return [x for x in exchanges if validate_exchange(x)[0]]
-def validate_exchange(exchange: str) -> Tuple[bool, str]:
+def validate_exchange(exchange: str) -> Tuple[bool, str, bool]:
"""
returns: can_use, reason
with Reason including both missing and missing_opt
@@ -62,10 +62,13 @@ def validate_exchange(exchange: str) -> Tuple[bool, str]:
ex_mod = getattr(ccxt.pro, exchange.lower())()
except AttributeError:
ex_mod = getattr(ccxt.async_support, exchange.lower())()
+
+ if not ex_mod or not ex_mod.has:
+ return False, "", False
+
result = True
reason = ""
- if not ex_mod or not ex_mod.has:
- return False, ""
+ is_dex = getattr(ex_mod, "dex", False)
missing = [
k
for k, v in EXCHANGE_HAS_REQUIRED.items()
@@ -84,18 +87,19 @@ def validate_exchange(exchange: str) -> Tuple[bool, str]:
if missing_opt:
reason += f"{'. ' if reason else ''}missing opt: {', '.join(missing_opt)}. "
- return result, reason
+ return result, reason, is_dex
def _build_exchange_list_entry(
exchange_name: str, exchangeClasses: Dict[str, Any]
) -> ValidExchangesType:
- valid, comment = validate_exchange(exchange_name)
+ valid, comment, is_dex = validate_exchange(exchange_name)
result: ValidExchangesType = {
"name": exchange_name,
"valid": valid,
"supported": exchange_name.lower() in SUPPORTED_EXCHANGES,
"comment": comment,
+ "dex": is_dex,
"trade_modes": [{"trading_mode": "spot", "margin_mode": ""}],
}
if resolved := exchangeClasses.get(exchange_name.lower()):
diff --git a/freqtrade/types/valid_exchanges_type.py b/freqtrade/types/valid_exchanges_type.py
index c01149455..9de05b964 100644
--- a/freqtrade/types/valid_exchanges_type.py
+++ b/freqtrade/types/valid_exchanges_type.py
@@ -14,4 +14,5 @@ class ValidExchangesType(TypedDict):
valid: bool
supported: bool
comment: str
+ dex: bool
trade_modes: List[TradeModeType]
diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py
index ffb2408f1..673f98e05 100644
--- a/tests/rpc/test_rpc_apiserver.py
+++ b/tests/rpc/test_rpc_apiserver.py
@@ -2154,6 +2154,7 @@ def test_api_exchanges(botclient):
"valid": True,
"supported": True,
"comment": "",
+ "dex": False,
"trade_modes": [
{"trading_mode": "spot", "margin_mode": ""},
{"trading_mode": "futures", "margin_mode": "isolated"},
@@ -2165,6 +2166,16 @@ def test_api_exchanges(botclient):
"name": "mexc",
"valid": True,
"supported": False,
+ "dex": False,
+ "comment": "",
+ "trade_modes": [{"trading_mode": "spot", "margin_mode": ""}],
+ }
+ waves = [x for x in response["exchanges"] if x["name"] == "wavesexchange"][0]
+ assert waves == {
+ "name": "wavesexchange",
+ "valid": True,
+ "supported": False,
+ "dex": True,
"comment": "",
"trade_modes": [{"trading_mode": "spot", "margin_mode": ""}],
}