Merge branch 'freqtrade:develop' into bt-metrics

This commit is contained in:
Stefano Ariestasia
2023-11-27 10:46:21 +09:00
committed by GitHub
32 changed files with 215 additions and 121 deletions
+6 -6
View File
@@ -90,7 +90,7 @@ jobs:
- name: Backtesting (multi) - name: Backtesting (multi)
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade new-strategy -s AwesomeStrategy freqtrade new-strategy -s AwesomeStrategy
freqtrade new-strategy -s AwesomeStrategyMin --template minimal freqtrade new-strategy -s AwesomeStrategyMin --template minimal
@@ -98,7 +98,7 @@ jobs:
- name: Hyperopt - name: Hyperopt
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 6 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all freqtrade hyperopt --datadir tests/testdata -e 6 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
@@ -200,14 +200,14 @@ jobs:
- name: Backtesting - name: Backtesting
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade new-strategy -s AwesomeStrategyAdv --template advanced freqtrade new-strategy -s AwesomeStrategyAdv --template advanced
freqtrade backtesting --datadir tests/testdata --strategy AwesomeStrategyAdv freqtrade backtesting --datadir tests/testdata --strategy AwesomeStrategyAdv
- name: Hyperopt - name: Hyperopt
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
@@ -275,13 +275,13 @@ jobs:
- name: Backtesting - name: Backtesting
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt - name: Hyperopt
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
+1 -1
View File
@@ -1,4 +1,4 @@
FROM python:3.11.6-slim-bullseye as base FROM python:3.11.6-slim-bookworm as base
# Setup env # Setup env
ENV LANG C.UTF-8 ENV LANG C.UTF-8
-1
View File
@@ -28,7 +28,6 @@ hesitate to read the source code and understand the mechanism of this bot.
Please read the [exchange specific notes](docs/exchanges.md) to learn about eventual, special configurations needed for each exchange. Please read the [exchange specific notes](docs/exchanges.md) to learn about eventual, special configurations needed for each exchange.
- [X] [Binance](https://www.binance.com/) - [X] [Binance](https://www.binance.com/)
- [X] [Bittrex](https://bittrex.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Huobi](http://huobi.com/) - [X] [Huobi](http://huobi.com/)
- [X] [Kraken](https://kraken.com/) - [X] [Kraken](https://kraken.com/)
+1 -1
View File
@@ -54,7 +54,7 @@ docker tag freqtrade:$TAG_FREQAI_ARM ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker tag freqtrade:$TAG_FREQAI_RL_ARM ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM docker tag freqtrade:$TAG_FREQAI_RL_ARM ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM
# Run backtest # Run backtest
docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG_ARM} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3 docker run --rm -v $(pwd)/tests/testdata/config.tests.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG_ARM} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "failed running backtest" echo "failed running backtest"
+1 -1
View File
@@ -67,7 +67,7 @@ docker tag freqtrade:$TAG_FREQAI ${CACHE_IMAGE}:$TAG_FREQAI
docker tag freqtrade:$TAG_FREQAI_RL ${CACHE_IMAGE}:$TAG_FREQAI_RL docker tag freqtrade:$TAG_FREQAI_RL ${CACHE_IMAGE}:$TAG_FREQAI_RL
# Run backtest # Run backtest
docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3 docker run --rm -v $(pwd)/tests/testdata/config.tests.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "failed running backtest" echo "failed running backtest"
+16 -16
View File
@@ -1,6 +1,6 @@
{ {
"max_open_trades": 3, "max_open_trades": 3,
"stake_currency": "BTC", "stake_currency": "USDT",
"stake_amount": 0.05, "stake_amount": 0.05,
"tradable_balance_ratio": 0.99, "tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD", "fiat_display_currency": "USD",
@@ -36,21 +36,21 @@
"ccxt_async_config": { "ccxt_async_config": {
}, },
"pair_whitelist": [ "pair_whitelist": [
"ALGO/BTC", "ALGO/USDT",
"ATOM/BTC", "ATOM/USDT",
"BAT/BTC", "BAT/USDT",
"BCH/BTC", "BCH/USDT",
"BRD/BTC", "BRD/USDT",
"EOS/BTC", "EOS/USDT",
"ETH/BTC", "ETH/USDT",
"IOTA/BTC", "IOTA/USDT",
"LINK/BTC", "LINK/USDT",
"LTC/BTC", "LTC/USDT",
"NEO/BTC", "NEO/USDT",
"NXS/BTC", "NXS/USDT",
"XMR/BTC", "XMR/USDT",
"XRP/BTC", "XRP/USDT",
"XTZ/BTC" "XTZ/USDT"
], ],
"pair_blacklist": [ "pair_blacklist": [
"BNB/.*" "BNB/.*"
+3 -3
View File
@@ -1,4 +1,4 @@
FROM python:3.9.16-slim-bullseye as base FROM python:3.11.6-slim-bookworm as base
# Setup env # Setup env
ENV LANG C.UTF-8 ENV LANG C.UTF-8
@@ -11,7 +11,7 @@ ENV FT_APP_ENV="docker"
# Prepare environment # Prepare environment
RUN mkdir /freqtrade \ RUN mkdir /freqtrade \
&& apt-get update \ && apt-get update \
&& apt-get -y install sudo libatlas3-base libopenblas-base curl sqlite3 libhdf5-dev libutf8proc-dev libsnappy-dev \ && apt-get -y install sudo libatlas3-base libopenblas-dev curl sqlite3 libhdf5-dev libutf8proc-dev libsnappy-dev \
&& apt-get clean \ && apt-get clean \
&& useradd -u 1000 -G sudo -U -m ftuser \ && useradd -u 1000 -G sudo -U -m ftuser \
&& chown ftuser:ftuser /freqtrade \ && chown ftuser:ftuser /freqtrade \
@@ -24,7 +24,7 @@ WORKDIR /freqtrade
# Install dependencies # Install dependencies
FROM base as python-deps FROM base as python-deps
RUN apt-get update \ RUN apt-get update \
&& apt-get -y install build-essential libssl-dev libffi-dev libopenblas-dev libgfortran5 pkg-config cmake gcc \ && apt-get -y install build-essential libssl-dev libffi-dev libgfortran5 pkg-config cmake gcc \
&& apt-get clean \ && apt-get clean \
&& echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > /etc/pip.conf && echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > /etc/pip.conf
+2 -2
View File
@@ -170,11 +170,11 @@ freqtrade backtesting --strategy AwesomeStrategy --dry-run-wallet 1000
Using a different on-disk historical candle (OHLCV) data source Using a different on-disk historical candle (OHLCV) data source
Assume you downloaded the history data from the Bittrex exchange and kept it in the `user_data/data/bittrex-20180101` directory. Assume you downloaded the history data from the Binance exchange and kept it in the `user_data/data/binance-20180101` directory.
You can then use this data for backtesting as follows: You can then use this data for backtesting as follows:
```bash ```bash
freqtrade backtesting --strategy AwesomeStrategy --datadir user_data/data/bittrex-20180101 freqtrade backtesting --strategy AwesomeStrategy --datadir user_data/data/binance-20180101
``` ```
--- ---
+2 -2
View File
@@ -594,7 +594,7 @@ creating trades on the exchange.
```json ```json
"exchange": { "exchange": {
"name": "bittrex", "name": "binance",
"key": "key", "key": "key",
"secret": "secret", "secret": "secret",
... ...
@@ -644,7 +644,7 @@ API Keys are usually only required for live trading (trading for real money, bot
```json ```json
{ {
"exchange": { "exchange": {
"name": "bittrex", "name": "binance",
"key": "af8ddd35195e9dc500b9a6f799f6f5c93d89193b", "key": "af8ddd35195e9dc500b9a6f799f6f5c93d89193b",
"secret": "08a9dc6db3d7b53e1acebd9275677f4b0a04f1a5", "secret": "08a9dc6db3d7b53e1acebd9275677f4b0a04f1a5",
//"password": "", // Optional, not needed by all exchanges) //"password": "", // Optional, not needed by all exchanges)
-1
View File
@@ -74,7 +74,6 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| | **Reinforcement Learning Parameters within the `freqai.rl_config` sub dictionary** | | **Reinforcement Learning Parameters within the `freqai.rl_config` sub dictionary**
| `rl_config` | A dictionary containing the control parameters for a Reinforcement Learning model. <br> **Datatype:** Dictionary. | `rl_config` | A dictionary containing the control parameters for a Reinforcement Learning model. <br> **Datatype:** Dictionary.
| `train_cycles` | Training time steps will be set based on the `train_cycles * number of training data points. <br> **Datatype:** Integer. | `train_cycles` | Training time steps will be set based on the `train_cycles * number of training data points. <br> **Datatype:** Integer.
| `cpu_count` | Number of processors to dedicate to the Reinforcement Learning training process. <br> **Datatype:** int.
| `max_trade_duration_candles`| Guides the agent training to keep trades below desired length. Example usage shown in `prediction_models/ReinforcementLearner.py` within the customizable `calculate_reward()` function. <br> **Datatype:** int. | `max_trade_duration_candles`| Guides the agent training to keep trades below desired length. Example usage shown in `prediction_models/ReinforcementLearner.py` within the customizable `calculate_reward()` function. <br> **Datatype:** int.
| `model_type` | Model string from stable_baselines3 or SBcontrib. Available strings include: `'TRPO', 'ARS', 'RecurrentPPO', 'MaskablePPO', 'PPO', 'A2C', 'DQN'`. User should ensure that `model_training_parameters` match those available to the corresponding stable_baselines3 model by visiting their documentaiton. [PPO doc](https://stable-baselines3.readthedocs.io/en/master/modules/ppo.html) (external website) <br> **Datatype:** string. | `model_type` | Model string from stable_baselines3 or SBcontrib. Available strings include: `'TRPO', 'ARS', 'RecurrentPPO', 'MaskablePPO', 'PPO', 'A2C', 'DQN'`. User should ensure that `model_training_parameters` match those available to the corresponding stable_baselines3 model by visiting their documentaiton. [PPO doc](https://stable-baselines3.readthedocs.io/en/master/modules/ppo.html) (external website) <br> **Datatype:** string.
| `policy_type` | One of the available policy types from stable_baselines3 <br> **Datatype:** string. | `policy_type` | One of the available policy types from stable_baselines3 <br> **Datatype:** string.
-1
View File
@@ -40,7 +40,6 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is
Please read the [exchange specific notes](exchanges.md) to learn about eventual, special configurations needed for each exchange. Please read the [exchange specific notes](exchanges.md) to learn about eventual, special configurations needed for each exchange.
- [X] [Binance](https://www.binance.com/) - [X] [Binance](https://www.binance.com/)
- [X] [Bittrex](https://bittrex.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Huobi](http://huobi.com/) - [X] [Huobi](http://huobi.com/)
- [X] [Kraken](https://kraken.com/) - [X] [Kraken](https://kraken.com/)
+1 -1
View File
@@ -1,6 +1,6 @@
markdown==3.5.1 markdown==3.5.1
mkdocs==1.5.3 mkdocs==1.5.3
mkdocs-material==9.4.8 mkdocs-material==9.4.10
mdx_truly_sane_lists==1.3 mdx_truly_sane_lists==1.3
pymdown-extensions==10.4 pymdown-extensions==10.4
jinja2==3.1.2 jinja2==3.1.2
+30 -24
View File
@@ -427,25 +427,33 @@ zb True missing opt: fetchMyTrades
Use the `list-timeframes` subcommand to see the list of timeframes available for the exchange. Use the `list-timeframes` subcommand to see the list of timeframes available for the exchange.
``` ```
usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-1] usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[--exchange EXCHANGE] [-1]
optional arguments: options:
-h, --help show this help message and exit -h, --help show this help message and exit
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided. --exchange EXCHANGE Exchange name. Only valid if no config is provided.
-1, --one-column Print output in one column. -1, --one-column Print output in one column.
Common arguments: Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages). -v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. --logfile FILE, --log-file FILE
Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit -V, --version show program's version number and exit
-c PATH, --config PATH -c PATH, --config PATH
Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-` Specify configuration file (default:
to read config from stdin. `userdir/config.json` or `config.json` whichever
-d PATH, --datadir PATH exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH, --data-dir PATH
Path to directory with historical backtesting data. Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH --userdir PATH, --user-data-dir PATH
Path to userdata directory. Path to userdata directory.
``` ```
* Example: see the timeframes for the 'binance' exchange, set in the configuration file: * Example: see the timeframes for the 'binance' exchange, set in the configuration file:
@@ -479,20 +487,17 @@ usage: freqtrade list-markets [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv] [--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]] [--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
[--trading-mode {spot,margin,futures}] [-a] [--trading-mode {spot,margin,futures}]
usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH] usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv] [--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]] [--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a]
[--trading-mode {spot,margin,futures}] [--trading-mode {spot,margin,futures}]
options:
optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no --exchange EXCHANGE Exchange name. Only valid if no config is provided.
config is provided.
--print-list Print list of pairs or market symbols. By default data --print-list Print list of pairs or market symbols. By default data
is printed in the tabular format. is printed in the tabular format.
--print-json Print list of pairs or market symbols in JSON format. --print-json Print list of pairs or market symbols in JSON format.
@@ -504,20 +509,22 @@ optional arguments:
Specify quote currency(-ies). Space-separated list. Specify quote currency(-ies). Space-separated list.
-a, --all Print all pairs or market symbols. By default only -a, --all Print all pairs or market symbols. By default only
active ones are shown. active ones are shown.
--trading-mode {spot,margin,futures} --trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
Select Trading mode Select Trading mode
Common arguments: Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages). -v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are: --logfile FILE, --log-file FILE
Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more 'syslog', 'journald'. See the documentation for more
details. details.
-V, --version show program's version number and exit -V, --version show program's version number and exit
-c PATH, --config PATH -c PATH, --config PATH
Specify configuration file (default: `config.json`). Specify configuration file (default:
Multiple --config options may be used. Can be set to `userdir/config.json` or `config.json` whichever
`-` to read config from stdin. exists). Multiple --config options may be used. Can be
-d PATH, --datadir PATH set to `-` to read config from stdin.
-d PATH, --datadir PATH, --data-dir PATH
Path to directory with historical backtesting data. Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH --userdir PATH, --user-data-dir PATH
Path to userdata directory. Path to userdata directory.
@@ -532,7 +539,7 @@ Pairs/markets are sorted by its symbol string in the printed output.
### Examples ### Examples
* Print the list of active pairs with quote currency USD on exchange, specified in the default * Print the list of active pairs with quote currency USD on exchange, specified in the default
configuration file (i.e. pairs on the "Bittrex" exchange) in JSON format: configuration file (i.e. pairs on the "Binance" exchange) in JSON format:
``` ```
$ freqtrade list-pairs --quote USD --print-json $ freqtrade list-pairs --quote USD --print-json
@@ -564,7 +571,7 @@ usage: freqtrade test-pairlist [-h] [--userdir PATH] [-v] [-c PATH]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
[-1] [--print-json] [--exchange EXCHANGE] [-1] [--print-json] [--exchange EXCHANGE]
optional arguments: options:
-h, --help show this help message and exit -h, --help show this help message and exit
--userdir PATH, --user-data-dir PATH --userdir PATH, --user-data-dir PATH
Path to userdata directory. Path to userdata directory.
@@ -578,8 +585,7 @@ optional arguments:
Specify quote currency(-ies). Space-separated list. Specify quote currency(-ies). Space-separated list.
-1, --one-column Print output in one column. -1, --one-column Print output in one column.
--print-json Print list of pairs or market symbols in JSON format. --print-json Print list of pairs or market symbols in JSON format.
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no --exchange EXCHANGE Exchange name. Only valid if no config is provided.
config is provided.
``` ```
@@ -108,7 +108,6 @@ def ask_user_config() -> Dict[str, Any]:
"choices": [ "choices": [
"binance", "binance",
"binanceus", "binanceus",
"bittrex",
"gate", "gate",
"huobi", "huobi",
"kraken", "kraken",
-1
View File
@@ -52,7 +52,6 @@ MAP_EXCHANGE_CHILDCLASS = {
SUPPORTED_EXCHANGES = [ SUPPORTED_EXCHANGES = [
'binance', 'binance',
'bittrex',
'gate', 'gate',
'huobi', 'huobi',
'kraken', 'kraken',
+21 -11
View File
@@ -486,11 +486,14 @@ class Exchange:
except ccxt.BaseError: except ccxt.BaseError:
logger.exception('Unable to initialize markets.') logger.exception('Unable to initialize markets.')
def reload_markets(self) -> None: def reload_markets(self, force: bool = False) -> None:
"""Reload markets both sync and async if refresh interval has passed """ """Reload markets both sync and async if refresh interval has passed """
# Check whether markets have to be reloaded # Check whether markets have to be reloaded
if (self._last_markets_refresh > 0) and ( if (
self._last_markets_refresh + self.markets_refresh_interval > dt_ts()): not force
and self._last_markets_refresh > 0
and (self._last_markets_refresh + self.markets_refresh_interval > dt_ts())
):
return None return None
logger.debug("Performing scheduled market reload..") logger.debug("Performing scheduled market reload..")
try: try:
@@ -1228,16 +1231,16 @@ class Exchange:
return order return order
except ccxt.InsufficientFunds as e: except ccxt.InsufficientFunds as e:
raise InsufficientFundsError( raise InsufficientFundsError(
f'Insufficient funds to create {ordertype} sell order on market {pair}. ' f'Insufficient funds to create {ordertype} {side} order on market {pair}. '
f'Tried to sell amount {amount} at rate {limit_rate}. ' f'Tried to {side} amount {amount} at rate {limit_rate} with '
f'Message: {e}') from e f'stop-price {stop_price_norm}. Message: {e}') from e
except ccxt.InvalidOrder as e: except (ccxt.InvalidOrder, ccxt.BadRequest) as e:
# Errors: # Errors:
# `Order would trigger immediately.` # `Order would trigger immediately.`
raise InvalidOrderException( raise InvalidOrderException(
f'Could not create {ordertype} sell order on market {pair}. ' f'Could not create {ordertype} {side} order on market {pair}. '
f'Tried to sell amount {amount} at rate {limit_rate}. ' f'Tried to {side} amount {amount} at rate {limit_rate} with '
f'Message: {e}') from e f'stop-price {stop_price_norm}. Message: {e}') from e
except ccxt.DDoSProtection as e: except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e: except (ccxt.NetworkError, ccxt.ExchangeError) as e:
@@ -1496,8 +1499,9 @@ class Exchange:
@retrier @retrier
def fetch_bids_asks(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict: def fetch_bids_asks(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict:
""" """
:param symbols: List of symbols to fetch
:param cached: Allow cached result :param cached: Allow cached result
:return: fetch_tickers result :return: fetch_bids_asks result
""" """
if not self.exchange_has('fetchBidsAsks'): if not self.exchange_has('fetchBidsAsks'):
return {} return {}
@@ -1546,6 +1550,12 @@ class Exchange:
raise OperationalException( raise OperationalException(
f'Exchange {self._api.name} does not support fetching tickers in batch. ' f'Exchange {self._api.name} does not support fetching tickers in batch. '
f'Message: {e}') from e f'Message: {e}') from e
except ccxt.BadSymbol as e:
logger.warning(f"Could not load tickers due to {e.__class__.__name__}. Message: {e} ."
"Reloading markets.")
self.reload_markets(True)
# Re-raise exception to repeat the call.
raise TemporaryError from e
except ccxt.DDoSProtection as e: except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e: except (ccxt.NetworkError, ccxt.ExchangeError) as e:
@@ -3,7 +3,6 @@ from typing import Any, Dict, Type, Union
from stable_baselines3.common.callbacks import BaseCallback from stable_baselines3.common.callbacks import BaseCallback
from stable_baselines3.common.logger import HParam from stable_baselines3.common.logger import HParam
from stable_baselines3.common.vec_env import VecEnv
from freqtrade.freqai.RL.BaseEnvironment import BaseActions from freqtrade.freqai.RL.BaseEnvironment import BaseActions
@@ -13,13 +12,9 @@ class TensorboardCallback(BaseCallback):
Custom callback for plotting additional values in tensorboard and Custom callback for plotting additional values in tensorboard and
episodic summary reports. episodic summary reports.
""" """
# Override training_env type to fix type errors
training_env: Union[VecEnv, None] = None
def __init__(self, verbose=1, actions: Type[Enum] = BaseActions): def __init__(self, verbose=1, actions: Type[Enum] = BaseActions):
super().__init__(verbose) super().__init__(verbose)
self.model: Any = None self.model: Any = None
self.logger: Any = None
self.actions: Type[Enum] = actions self.actions: Type[Enum] = actions
def _on_training_start(self) -> None: def _on_training_start(self) -> None:
@@ -47,8 +42,6 @@ class TensorboardCallback(BaseCallback):
def _on_step(self) -> bool: def _on_step(self) -> bool:
local_info = self.locals["infos"][0] local_info = self.locals["infos"][0]
if self.training_env is None:
return True
if hasattr(self.training_env, 'envs'): if hasattr(self.training_env, 'envs'):
tensorboard_metrics = self.training_env.envs[0].unwrapped.tensorboard_metrics tensorboard_metrics = self.training_env.envs[0].unwrapped.tensorboard_metrics
+1 -1
View File
@@ -21,7 +21,7 @@ logger = logging.getLogger(__name__)
def _format_exception_message(space: str, ignore_missing_space: bool) -> None: def _format_exception_message(space: str, ignore_missing_space: bool) -> None:
msg = (f"The '{space}' space is included into the hyperoptimization " msg = (f"The '{space}' space is included into the hyperoptimization "
f"but no parameter for this space was not found in your Strategy. " f"but no parameter for this space was found in your Strategy. "
) )
if ignore_missing_space: if ignore_missing_space:
logger.warning(msg + "This space will be ignored.") logger.warning(msg + "This space will be ignored.")
+4 -1
View File
@@ -1066,7 +1066,10 @@ class LocalTrade:
exit_amount = o.safe_amount_after_fee exit_amount = o.safe_amount_after_fee
prof = self.calculate_profit(exit_rate, exit_amount, float(avg_price)) prof = self.calculate_profit(exit_rate, exit_amount, float(avg_price))
close_profit_abs += prof.profit_abs close_profit_abs += prof.profit_abs
close_profit = prof.profit_ratio if total_stake > 0:
# This needs to be calculated based on the last occuring exit to be aligned
# with realized_profit.
close_profit = (close_profit_abs / total_stake) * self.leverage
else: else:
total_stake = total_stake + self._calc_open_trade_value(tmp_amount, price) total_stake = total_stake + self._calc_open_trade_value(tmp_amount, price)
max_stake_amount += (tmp_amount * price) max_stake_amount += (tmp_amount * price)
+2 -1
View File
@@ -21,6 +21,7 @@ from freqtrade.misc import pair_to_filename
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.strategy import IStrategy from freqtrade.strategy import IStrategy
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -636,7 +637,7 @@ def load_and_plot_trades(config: Config):
exchange = ExchangeResolver.load_exchange(config) exchange = ExchangeResolver.load_exchange(config)
IStrategy.dp = DataProvider(config, exchange) IStrategy.dp = DataProvider(config, exchange)
strategy.ft_bot_start() strategy.ft_bot_start()
strategy.bot_loop_start(datetime.now(timezone.utc)) strategy_safe_wrapper(strategy.bot_loop_start)(current_time=datetime.now(timezone.utc))
plot_elements = init_plotscript(config, list(exchange.markets), strategy.startup_candle_count) plot_elements = init_plotscript(config, list(exchange.markets), strategy.startup_candle_count)
timerange = plot_elements['timerange'] timerange = plot_elements['timerange']
trades = plot_elements['trades'] trades = plot_elements['trades']
@@ -290,9 +290,6 @@ class FreqaiExampleStrategy(IStrategy):
return df return df
def get_ticker_indicator(self):
return int(self.config["timeframe"][:-1])
def confirm_trade_entry( def confirm_trade_entry(
self, self,
pair: str, pair: str,
+1 -1
View File
@@ -7,7 +7,7 @@
-r docs/requirements-docs.txt -r docs/requirements-docs.txt
coveralls==3.3.1 coveralls==3.3.1
ruff==0.1.5 ruff==0.1.6
mypy==1.7.0 mypy==1.7.0
pre-commit==3.5.0 pre-commit==3.5.0
pytest==7.4.3 pytest==7.4.3
+1 -1
View File
@@ -5,7 +5,7 @@
torch==2.0.1 torch==2.0.1
#until these branches will be released we can use this #until these branches will be released we can use this
gymnasium==0.29.1 gymnasium==0.29.1
stable_baselines3==2.1.0 stable_baselines3==2.2.1
sb3_contrib>=2.0.0a9 sb3_contrib>=2.0.0a9
# Progress bar for stable-baselines3 and sb3-contrib # Progress bar for stable-baselines3 and sb3-contrib
tqdm==4.66.1 tqdm==4.66.1
+1 -1
View File
@@ -2,7 +2,7 @@
-r requirements.txt -r requirements.txt
# Required for hyperopt # Required for hyperopt
scipy==1.11.3 scipy==1.11.4
scikit-learn==1.1.3 scikit-learn==1.1.3
scikit-optimize==0.9.0 scikit-optimize==0.9.0
filelock==3.13.1 filelock==3.13.1
+6 -7
View File
@@ -2,9 +2,9 @@ numpy==1.26.2
pandas==2.1.3 pandas==2.1.3
pandas-ta==0.3.14b pandas-ta==0.3.14b
ccxt==4.1.52 ccxt==4.1.57
cryptography==41.0.5 cryptography==41.0.5
aiohttp==3.8.6 aiohttp==3.9.0
SQLAlchemy==2.0.23 SQLAlchemy==2.0.23
python-telegram-bot==20.6 python-telegram-bot==20.6
# can't be hard-pinned due to telegram-bot pinning httpx with ~ # can't be hard-pinned due to telegram-bot pinning httpx with ~
@@ -12,17 +12,16 @@ httpx>=0.24.1
arrow==1.3.0 arrow==1.3.0
cachetools==5.3.2 cachetools==5.3.2
requests==2.31.0 requests==2.31.0
urllib3==2.0.7 urllib3==2.1.0
jsonschema==4.19.2 jsonschema==4.20.0
TA-Lib==0.4.28 TA-Lib==0.4.28
technical==1.4.0 technical==1.4.0
tabulate==0.9.0 tabulate==0.9.0
pycoingecko==3.1.0 pycoingecko==3.1.0
jinja2==3.1.2 jinja2==3.1.2
tables==3.9.1 tables==3.9.1
blosc==1.11.1
joblib==1.3.2 joblib==1.3.2
rich==13.6.0 rich==13.7.0
pyarrow==14.0.1; platform_machine != 'armv7l' pyarrow==14.0.1; platform_machine != 'armv7l'
# find first, C search in arrays # find first, C search in arrays
@@ -38,7 +37,7 @@ sdnotify==0.3.2
# API Server # API Server
fastapi==0.104.1 fastapi==0.104.1
pydantic==2.4.2 pydantic==2.5.1
uvicorn==0.24.0.post1 uvicorn==0.24.0.post1
pyjwt==2.8.0 pyjwt==2.8.0
aiofiles==23.2.1 aiofiles==23.2.1
+9 -1
View File
@@ -1851,7 +1851,7 @@ def test_fetch_bids_asks(default_conf, mocker):
@pytest.mark.parametrize("exchange_name", EXCHANGES) @pytest.mark.parametrize("exchange_name", EXCHANGES)
def test_get_tickers(default_conf, mocker, exchange_name): def test_get_tickers(default_conf, mocker, exchange_name, caplog):
api_mock = MagicMock() api_mock = MagicMock()
tick = {'ETH/BTC': { tick = {'ETH/BTC': {
'symbol': 'ETH/BTC', 'symbol': 'ETH/BTC',
@@ -1900,6 +1900,14 @@ def test_get_tickers(default_conf, mocker, exchange_name):
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
exchange.get_tickers() exchange.get_tickers()
caplog.clear()
api_mock.fetch_tickers = MagicMock(side_effect=[ccxt.BadSymbol("SomeSymbol"), []])
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
x = exchange.get_tickers()
assert x == []
assert log_has_re(r'Could not load tickers due to BadSymbol\..*SomeSymbol', caplog)
caplog.clear()
api_mock.fetch_tickers = MagicMock(return_value={}) api_mock.fetch_tickers = MagicMock(return_value={})
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
exchange.get_tickers() exchange.get_tickers()
+1 -1
View File
@@ -18,7 +18,7 @@ from tests.conftest import log_has_re
def test_check_exchange(default_conf, caplog) -> None: def test_check_exchange(default_conf, caplog) -> None:
# Test an officially supported by Freqtrade team exchange # Test an officially supported by Freqtrade team exchange
default_conf['runmode'] = RunMode.DRY_RUN default_conf['runmode'] = RunMode.DRY_RUN
default_conf.get('exchange').update({'name': 'BITTREX'}) default_conf.get('exchange').update({'name': 'BINANCE'})
assert check_exchange(default_conf) assert check_exchange(default_conf)
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.", assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
caplog) caplog)
+6
View File
@@ -310,6 +310,8 @@ def test_start_calls_optimizer(mocker, hyperopt_conf, capsys) -> None:
'freqtrade.optimize.hyperopt.get_timerange', 'freqtrade.optimize.hyperopt.get_timerange',
MagicMock(return_value=(datetime(2017, 12, 10), datetime(2017, 12, 13))) MagicMock(return_value=(datetime(2017, 12, 10), datetime(2017, 12, 13)))
) )
# Dummy-reduce points to ensure scikit-learn is forced to generate new values
mocker.patch('freqtrade.optimize.hyperopt.INITIAL_POINTS', 2)
parallel = mocker.patch( parallel = mocker.patch(
'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel', 'freqtrade.optimize.hyperopt.Hyperopt.run_optimizer_parallel',
@@ -860,6 +862,8 @@ def test_simplified_interface_failed(mocker, hyperopt_conf, space) -> None:
def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmp_path, fee) -> None: def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmp_path, fee) -> None:
patch_exchange(mocker) patch_exchange(mocker)
mocker.patch(f'{EXMS}.get_fee', fee) mocker.patch(f'{EXMS}.get_fee', fee)
# Dummy-reduce points to ensure scikit-learn is forced to generate new values
mocker.patch('freqtrade.optimize.hyperopt.INITIAL_POINTS', 2)
(tmp_path / 'hyperopt_results').mkdir(parents=True) (tmp_path / 'hyperopt_results').mkdir(parents=True)
# No hyperopt needed # No hyperopt needed
hyperopt_conf.update({ hyperopt_conf.update({
@@ -904,6 +908,8 @@ def test_in_strategy_auto_hyperopt_with_parallel(mocker, hyperopt_conf, tmp_path
mocker.patch(f'{EXMS}.markets', mocker.patch(f'{EXMS}.markets',
PropertyMock(return_value=get_markets())) PropertyMock(return_value=get_markets()))
(tmp_path / 'hyperopt_results').mkdir(parents=True) (tmp_path / 'hyperopt_results').mkdir(parents=True)
# Dummy-reduce points to ensure scikit-learn is forced to generate new values
mocker.patch('freqtrade.optimize.hyperopt.INITIAL_POINTS', 2)
# No hyperopt needed # No hyperopt needed
hyperopt_conf.update({ hyperopt_conf.update({
'strategy': 'HyperoptableStrategy', 'strategy': 'HyperoptableStrategy',
+18 -18
View File
@@ -2676,9 +2676,9 @@ def test_order_to_ccxt(limit_buy_order_open, limit_sell_order_usdt_open):
'orders': [ 'orders': [
(('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None, None)), (('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None, None)),
(('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None, None)), (('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None, None)),
(('sell', 50, 12), (150.0, 12.5, 1875.0, -25.0, -25.0, -0.04)), (('sell', 50, 12), (150.0, 12.5, 1875.0, -25.0, -25.0, -0.01)),
(('sell', 100, 20), (50.0, 12.5, 625.0, 725.0, 750.0, 0.60)), (('sell', 100, 20), (50.0, 12.5, 625.0, 725.0, 750.0, 0.29)),
(('sell', 50, 5), (50.0, 12.5, 625.0, 350.0, -375.0, -0.60)), (('sell', 50, 5), (50.0, 12.5, 625.0, 350.0, -375.0, 0.14)),
], ],
'end_profit': 350.0, 'end_profit': 350.0,
'end_profit_ratio': 0.14, 'end_profit_ratio': 0.14,
@@ -2688,9 +2688,9 @@ def test_order_to_ccxt(limit_buy_order_open, limit_sell_order_usdt_open):
'orders': [ 'orders': [
(('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None, None)), (('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None, None)),
(('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None, None)), (('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None, None)),
(('sell', 50, 12), (150.0, 12.5, 1875.0, -28.0625, -28.0625, -0.044788)), (('sell', 50, 12), (150.0, 12.5, 1875.0, -28.0625, -28.0625, -0.011197)),
(('sell', 100, 20), (50.0, 12.5, 625.0, 713.8125, 741.875, 0.59201995)), (('sell', 100, 20), (50.0, 12.5, 625.0, 713.8125, 741.875, 0.2848129)),
(('sell', 50, 5), (50.0, 12.5, 625.0, 336.625, -377.1875, -0.60199501)), (('sell', 50, 5), (50.0, 12.5, 625.0, 336.625, -377.1875, 0.1343142)),
], ],
'end_profit': 336.625, 'end_profit': 336.625,
'end_profit_ratio': 0.1343142, 'end_profit_ratio': 0.1343142,
@@ -2700,10 +2700,10 @@ def test_order_to_ccxt(limit_buy_order_open, limit_sell_order_usdt_open):
'orders': [ 'orders': [
(('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None, None)), (('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None, None)),
(('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None, None)), (('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None, None)),
(('sell', 100, 11), (100.0, 5.0, 500.0, 596.0, 596.0, 1.189027)), (('sell', 100, 11), (100.0, 5.0, 500.0, 596.0, 596.0, 0.5945137)),
(('buy', 150, 15), (250.0, 11.0, 2750.0, 596.0, 596.0, 1.189027)), (('buy', 150, 15), (250.0, 11.0, 2750.0, 596.0, 596.0, 0.5945137)),
(('sell', 100, 19), (150.0, 11.0, 1650.0, 1388.5, 792.5, 0.7186579)), (('sell', 100, 19), (150.0, 11.0, 1650.0, 1388.5, 792.5, 0.4261653)),
(('sell', 150, 23), (150.0, 11.0, 1650.0, 3175.75, 1787.25, 1.08048062)), (('sell', 150, 23), (150.0, 11.0, 1650.0, 3175.75, 1787.25, 0.9747170)),
], ],
'end_profit': 3175.75, 'end_profit': 3175.75,
'end_profit_ratio': 0.9747170, 'end_profit_ratio': 0.9747170,
@@ -2714,10 +2714,10 @@ def test_order_to_ccxt(limit_buy_order_open, limit_sell_order_usdt_open):
'orders': [ 'orders': [
(('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None, None)), (('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None, None)),
(('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None, None)), (('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None, None)),
(('sell', 100, 11), (100.0, 5.0, 500.0, 600.0, 600.0, 1.2)), (('sell', 100, 11), (100.0, 5.0, 500.0, 600.0, 600.0, 0.6)),
(('buy', 150, 15), (250.0, 11.0, 2750.0, 600.0, 600.0, 1.2)), (('buy', 150, 15), (250.0, 11.0, 2750.0, 600.0, 600.0, 0.6)),
(('sell', 100, 19), (150.0, 11.0, 1650.0, 1400.0, 800.0, 0.72727273)), (('sell', 100, 19), (150.0, 11.0, 1650.0, 1400.0, 800.0, 0.43076923)),
(('sell', 150, 23), (150.0, 11.0, 1650.0, 3200.0, 1800.0, 1.09090909)), (('sell', 150, 23), (150.0, 11.0, 1650.0, 3200.0, 1800.0, 0.98461538)),
], ],
'end_profit': 3200.0, 'end_profit': 3200.0,
'end_profit_ratio': 0.98461538, 'end_profit_ratio': 0.98461538,
@@ -2727,10 +2727,10 @@ def test_order_to_ccxt(limit_buy_order_open, limit_sell_order_usdt_open):
'orders': [ 'orders': [
(('buy', 100, 8), (100.0, 8.0, 800.0, 0.0, None, None)), (('buy', 100, 8), (100.0, 8.0, 800.0, 0.0, None, None)),
(('buy', 100, 9), (200.0, 8.5, 1700.0, 0.0, None, None)), (('buy', 100, 9), (200.0, 8.5, 1700.0, 0.0, None, None)),
(('sell', 100, 10), (100.0, 8.5, 850.0, 150.0, 150.0, 0.17647059)), (('sell', 100, 10), (100.0, 8.5, 850.0, 150.0, 150.0, 0.08823529)),
(('buy', 150, 11), (250.0, 10, 2500.0, 150.0, 150.0, 0.17647059)), (('buy', 150, 11), (250.0, 10, 2500.0, 150.0, 150.0, 0.08823529)),
(('sell', 100, 12), (150.0, 10.0, 1500.0, 350.0, 200.0, 0.2)), (('sell', 100, 12), (150.0, 10.0, 1500.0, 350.0, 200.0, 0.1044776)),
(('sell', 150, 14), (150.0, 10.0, 1500.0, 950.0, 600.0, 0.40)), (('sell', 150, 14), (150.0, 10.0, 1500.0, 950.0, 600.0, 0.283582)),
], ],
'end_profit': 950.0, 'end_profit': 950.0,
'end_profit_ratio': 0.283582, 'end_profit_ratio': 0.283582,
+5 -5
View File
@@ -6569,16 +6569,16 @@ def test_position_adjust2(mocker, default_conf_usdt, fee) -> None:
# tuple 2 - amount, open_rate, stake_amount, cumulative_profit, realized_profit, rel_profit # tuple 2 - amount, open_rate, stake_amount, cumulative_profit, realized_profit, rel_profit
(('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None, None)), (('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None, None)),
(('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None, None)), (('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None, None)),
(('sell', 50, 12), (150.0, 12.5, 1875.0, -28.0625, -28.0625, -0.044788)), (('sell', 50, 12), (150.0, 12.5, 1875.0, -28.0625, -28.0625, -0.011197)),
(('sell', 100, 20), (50.0, 12.5, 625.0, 713.8125, 741.875, 0.59201995)), (('sell', 100, 20), (50.0, 12.5, 625.0, 713.8125, 741.875, 0.2848129)),
(('sell', 50, 5), (50.0, 12.5, 625.0, 336.625, 336.625, 0.1343142)), # final profit (sum) (('sell', 50, 5), (50.0, 12.5, 625.0, 336.625, 336.625, 0.1343142)), # final profit (sum)
), ),
( (
(('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None, None)), (('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None, None)),
(('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None, None)), (('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None, None)),
(('sell', 100, 11), (100.0, 5.0, 500.0, 596.0, 596.0, 1.189027)), (('sell', 100, 11), (100.0, 5.0, 500.0, 596.0, 596.0, 0.5945137)),
(('buy', 150, 15), (250.0, 11.0, 2750.0, 596.0, 596.0, 1.189027)), (('buy', 150, 15), (250.0, 11.0, 2750.0, 596.0, 596.0, 0.5945137)),
(('sell', 100, 19), (150.0, 11.0, 1650.0, 1388.5, 792.5, 0.7186579)), (('sell', 100, 19), (150.0, 11.0, 1650.0, 1388.5, 792.5, 0.4261653)),
(('sell', 150, 23), (150.0, 11.0, 1650.0, 3175.75, 3175.75, 0.9747170)), # final profit (('sell', 150, 23), (150.0, 11.0, 1650.0, 3175.75, 3175.75, 0.9747170)), # final profit
) )
]) ])
+2
View File
@@ -1,3 +1,4 @@
import time
from unittest.mock import MagicMock from unittest.mock import MagicMock
import pytest import pytest
@@ -440,6 +441,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
assert trade.open_rate == 1.99 assert trade.open_rate == 1.99
assert trade.orders[-1].price == 1.96 assert trade.orders[-1].price == 1.96
assert trade.orders[-1].cost == 120 * leverage assert trade.orders[-1].cost == 120 * leverage
time.sleep(0.1)
# Replace new order with diff. order at a lower price # Replace new order with diff. order at a lower price
freqtrade.strategy.adjust_entry_price = MagicMock(return_value=1.95) freqtrade.strategy.adjust_entry_price = MagicMock(return_value=1.95)
+74
View File
@@ -0,0 +1,74 @@
{
"max_open_trades": 3,
"stake_currency": "BTC",
"stake_amount": 0.05,
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD",
"timeframe": "5m",
"dry_run": true,
"cancel_open_orders_on_exit": false,
"unfilledtimeout": {
"entry": 5,
"exit": 5,
"exit_timeout_count": 0,
"unit": "minutes"
},
"entry_pricing": {
"price_side": "same",
"use_order_book": true,
"order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"exit_pricing":{
"price_side": "same",
"use_order_book": true,
"order_book_top": 1
},
"exchange": {
"name": "gate",
"key": "your_exchange_key",
"secret": "your_exchange_secret",
"ccxt_config": {},
"ccxt_async_config": {},
"pair_whitelist": [
"ETH/BTC",
"LTC/BTC",
"ETC/BTC",
"XLM/BTC",
"XRP/BTC",
"ADA/BTC",
"DOT/BTC"
],
"pair_blacklist": [
"DOGE/BTC"
]
},
"pairlists": [
{"method": "StaticPairList"}
],
"telegram": {
"enabled": false,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id"
},
"api_server": {
"enabled": false,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"verbosity": "error",
"jwt_secret_key": "somethingrandom",
"CORS_origins": [],
"username": "freqtrader",
"password": "SuperSecurePassword"
},
"bot_name": "freqtrade",
"initial_state": "running",
"force_entry_enable": false,
"internals": {
"process_throttle_secs": 5
}
}