Skip to content

Commit

Permalink
Merge branch 'freqtrade:develop' into freqtrade-develop
Browse files Browse the repository at this point in the history
  • Loading branch information
stash86 authored Dec 13, 2024
2 parents 44ddb05 + abbfe04 commit aa001a4
Show file tree
Hide file tree
Showing 60 changed files with 3,960 additions and 1,553 deletions.
11 changes: 8 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ repos:
- types-cachetools==5.5.0.20240820
- types-filelock==3.2.7
- types-requests==2.32.0.20241016
- types-tabulate==0.9.0.20240106
- types-python-dateutil==2.9.0.20241003
- types-tabulate==0.9.0.20241207
- types-python-dateutil==2.9.0.20241206
- SQLAlchemy==2.0.36
# stages: [push]

Expand All @@ -31,7 +31,7 @@ repos:

- repo: https://github.com/charliermarsh/ruff-pre-commit
# Ruff version.
rev: 'v0.8.0'
rev: 'v0.8.2'
hooks:
- id: ruff
- id: ruff-format
Expand All @@ -56,6 +56,11 @@ repos:
.*\.md
)$
- repo: https://github.com/stefmolin/exif-stripper
rev: 0.6.1
hooks:
- id: strip-exif

- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
Expand Down
13 changes: 11 additions & 2 deletions build_helpers/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,17 @@
},
"dry_run_wallet": {
"description": "Initial wallet balance for dry run mode.",
"type": "number",
"default": 1000
"type": [
"number",
"object"
],
"default": 1000,
"patternProperties": {
"^[a-zA-Z0-9]+$": {
"type": "number"
}
},
"additionalProperties": false
},
"cancel_open_orders_on_exit": {
"description": "Cancel open orders when exiting.",
Expand Down
2 changes: 2 additions & 0 deletions docs/advanced-hyperopt.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class SuperDuperHyperOptLoss(IHyperOptLoss):
config: Config,
processed: dict[str, DataFrame],
backtest_stats: dict[str, Any],
starting_balance: float,
**kwargs,
) -> float:
"""
Expand Down Expand Up @@ -70,6 +71,7 @@ Currently, the arguments are:
* `config`: Config object used (Note: Not all strategy-related parameters will be updated here if they are part of a hyperopt space).
* `processed`: Dict of Dataframes with the pair as keys containing the data used for backtesting.
* `backtest_stats`: Backtesting statistics using the same format as the backtesting file "strategy" substructure. Available fields can be seen in `generate_strategy_stats()` in `optimize_reports.py`.
* `starting_balance`: Starting balance used for backtesting.

This function needs to return a floating point number (`float`). Smaller numbers will be interpreted as better results. The parameters and balancing for this is up to you.

Expand Down
Binary file modified docs/assets/frequi-login-CORS-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/telegram_forcebuy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 28 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,19 @@ Please note that Environment variables will overwrite corresponding settings in

Common example:

```
``` bash
FREQTRADE__TELEGRAM__CHAT_ID=<telegramchatid>
FREQTRADE__TELEGRAM__TOKEN=<telegramToken>
FREQTRADE__EXCHANGE__KEY=<yourExchangeKey>
FREQTRADE__EXCHANGE__SECRET=<yourExchangeSecret>
```

Json lists are parsed as json - so you can use the following to set a list of pairs:

``` bash
export FREQTRADE__EXCHANGE__PAIR_WHITELIST='["BTC/USDT", "ETH/USDT"]'
```

!!! Note
Environment variables detected are logged at startup - so if you can't find why a value is not what you think it should be based on the configuration, make sure it's not loaded from an environment variable.

Expand All @@ -54,7 +60,7 @@ FREQTRADE__EXCHANGE__SECRET=<yourExchangeSecret>

??? Warning "Loading sequence"
Environment variables are loaded after the initial configuration. As such, you cannot provide the path to the configuration through environment variables. Please use `--config path/to/config.json` for that.
This also applies to user_dir to some degree. while the user directory can be set through environment variables - the configuration will **not** be loaded from that location.
This also applies to `user_dir` to some degree. while the user directory can be set through environment variables - the configuration will **not** be loaded from that location.

### Multiple configuration files

Expand Down Expand Up @@ -168,7 +174,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `timeframe` | The timeframe to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). Usually missing in configuration, and specified in the strategy. [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** String
| `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency). <br> **Datatype:** String
| `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode. <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in Dry Run mode.<br>*Defaults to `1000`.* <br> **Datatype:** Float
| `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in Dry Run mode. [More information below](#dry-run-wallet)<br>*Defaults to `1000`.* <br> **Datatype:** Float or Dict
| `cancel_open_orders_on_exit` | Cancel open orders when the `/stop` RPC command is issued, `Ctrl+C` is pressed or the bot dies unexpectedly. When set to `true`, this allows you to use `/stop` to cancel unfilled and partially filled orders in the event of a market crash. It does not impact open positions. <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `minimal_roi` | **Required.** Set the threshold as ratio the bot will use to exit a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
Expand Down Expand Up @@ -324,6 +330,25 @@ To limit this calculation in case of large stoploss values, the calculated minim
!!! Warning
Since the limits on exchanges are usually stable and are not updated often, some pairs can show pretty high minimum limits, simply because the price increased a lot since the last limit adjustment by the exchange. Freqtrade adjusts the stake-amount to this value, unless it's > 30% more than the calculated/desired stake-amount - in which case the trade is rejected.

#### Dry-run wallet

When running in dry-run mode, the bot will use a simulated wallet to execute trades. The starting balance of this wallet is defined by `dry_run_wallet` (defaults to 1000).
For more complex scenarios, you can also assign a dictionary to `dry_run_wallet` to define the starting balance for each currency.

```json
"dry_run_wallet": {
"BTC": 0.01,
"ETH": 2,
"USDT": 1000
}
```

Command line options (`--dry-run-wallet`) can be used to override the configuration value, but only for the float value, not for the dictionary. If you'd like to use the dictionary, please adjust the configuration file.

!!! Note
Balances not in stake-currency will not be used for trading, but are shown as part of the wallet balance.
On Cross-margin exchanges, the wallet balance may be used to calculate the available collateral for trading.

#### Tradable balance

By default, the bot assumes that the `complete amount - 1%` is at it's disposal, and when using [dynamic stake amount](#dynamic-stake-amount), it will split the complete balance into `max_open_trades` buckets per trade.
Expand Down
4 changes: 4 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ This could be caused by the following reasons:
* The installation did not complete successfully.
* Please check the [Installation documentation](installation.md).

### The bot starts, but in STOPPED mode

Make sure you set the `initial_state` config option to `"running"` in your config.json

### I have waited 5 minutes, why hasn't the bot made any trades yet?

* Depending on the buy strategy, the amount of whitelisted coins, the
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements-docs.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
markdown==3.7
mkdocs==1.6.1
mkdocs-material==9.5.47
mkdocs-material==9.5.48
mdx_truly_sane_lists==1.3
pymdown-extensions==10.12
jinja2==3.1.4
Expand Down
6 changes: 6 additions & 0 deletions docs/strategy-callbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,12 @@ The strategy is expected to return a negative stake_amount (in stake currency) f
Returning the full owned stake at that point (`-trade.stake_amount`) results in a full exit.
Returning a value more than the above (so remaining stake_amount would become negative) will result in the bot ignoring the signal.

For a partial exit, it's important to know that the formula used to calculate the amount of the coin for the partial exit order is `amount to be exited partially = negative_stake_amount * trade.amount / trade.stake_amount`, where `negative_stake_amount` is the value returned from the `adjust_trade_position` function. As seen in the formula, the formula don't care about current profit/loss of the position. It only care about `trade.amount` and `trade.stake_amount` which aren't affected by the price movement at all.

For example, let's say you buy 2 SHITCOIN/USDT at open rate of 50, which means the trade's stake amount is 100 USDT. Now the price has rose to 200 and you want to sell half of it. In that case, you have to return -50% of trade.stake_amount (0.5 * 100 USDT) which equals to -50. The bot will calculate the amount it needed to sell, which is `50 * 2 / 100` which equals 1 SHITCOIN/USDT. If you return -200 (50% of 2 * 200), the bot will ignore it since trade.stake_amount is only 100 USDT but you asked it to sell 200 USDT which means you are asking it to sell 4 SHITCOIN/USDT.

Back to the example above, since current rate is 200, the current USDT value of your trade is now 400 USDT. Let's say you want to partially sell 100 USDT to take out the initial investment and leave the profit in the trade in hope of the price keep rising. In that case, you have to do different approach. First, you need to calculate the exact amount you needed to sell. In this case, since you want to sell 100 USDT worth based of current rate, the exact amount you need to partially sell is `100 * 2 / 400` which equals 0.5 SHITCOIN/USDT. Since we know now the exact amount we want to sell (0.5), the value you need to return in the `adjust_trade_position` function is `-amount to be exited partially * trade.stake_amount / trade.amount`, which equals -25. The bot will sell 0.5 SHITCOIN/USDT, keeping 1.5 in trade. You will receive 100 USDT from the partial exit.

!!! Note "About stake size"
Using fixed stake size means it will be the amount used for the first order, just like without position adjustment.
If you wish to buy additional orders with DCA, then make sure to leave enough funds in the wallet for that.
Expand Down
4 changes: 2 additions & 2 deletions freqtrade/commands/optimize_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def setup_optimize_configuration(args: dict[str, Any], method: RunMode) -> dict[
:return: Configuration
"""
from freqtrade.configuration import setup_utils_configuration
from freqtrade.util import fmt_coin
from freqtrade.util import fmt_coin, get_dry_run_wallet

config = setup_utils_configuration(args, method)

Expand All @@ -26,7 +26,7 @@ def setup_optimize_configuration(args: dict[str, Any], method: RunMode) -> dict[
RunMode.HYPEROPT: "hyperoptimization",
}
if method in no_unlimited_runmodes.keys():
wallet_size = config["dry_run_wallet"] * config["tradable_balance_ratio"]
wallet_size = get_dry_run_wallet(config) * config["tradable_balance_ratio"]
# tradable_balance_ratio
if (
config["stake_amount"] != constants.UNLIMITED_STAKE_AMOUNT
Expand Down
4 changes: 3 additions & 1 deletion freqtrade/configuration/config_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@
},
"dry_run_wallet": {
"description": "Initial wallet balance for dry run mode.",
"type": "number",
"type": ["number", "object"],
"default": DRY_RUN_WALLET,
"patternProperties": {r"^[a-zA-Z0-9]+$": {"type": "number"}},
"additionalProperties": False,
},
"cancel_open_orders_on_exit": {
"description": "Cancel open orders when exiting.",
Expand Down
10 changes: 10 additions & 0 deletions freqtrade/configuration/environment_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import os
from typing import Any

import rapidjson

from freqtrade.constants import ENV_VAR_PREFIX
from freqtrade.misc import deep_merge_dicts

Expand All @@ -20,6 +22,14 @@ def _get_var_typed(val):
return True
elif val.lower() in ("f", "false"):
return False
# try to convert from json
try:
value = rapidjson.loads(val)
# Limited to lists for now
if isinstance(value, list):
return value
except rapidjson.JSONDecodeError:
pass
# keep as string
return val

Expand Down
Loading

0 comments on commit aa001a4

Please sign in to comment.