Skip to content

Commit

Permalink
Merge pull request #10163 from freqtrade/new_release
Browse files Browse the repository at this point in the history
New release 2024.4
  • Loading branch information
xmatthias committed Apr 30, 2024
2 parents 569a87c + 39eda1b commit 2152a95
Show file tree
Hide file tree
Showing 148 changed files with 4,296 additions and 1,260 deletions.
22 changes: 0 additions & 22 deletions .devcontainer/Dockerfile

This file was deleted.

47 changes: 21 additions & 26 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,42 +1,37 @@
{
"name": "freqtrade Develop",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"image": "ghcr.io/freqtrade/freqtrade-devcontainer:latest",
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
8080
],
"mounts": [
"source=freqtrade-bashhistory,target=/home/ftuser/commandhistory,type=volume"
],
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/freqtrade,type=bind,consistency=cached",
// Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "ftuser",

"onCreateCommand": "pip install --user -e .",
"postCreateCommand": "freqtrade create-userdir --userdir user_data/",

"workspaceFolder": "/workspaces/freqtrade",
"customizations": {
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"editor.insertSpaces": true,
"files.trimTrailingWhitespace": true,
"[markdown]": {
"files.trimTrailingWhitespace": false,
"vscode": {
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"editor.insertSpaces": true,
"files.trimTrailingWhitespace": true,
"[markdown]": {
"files.trimTrailingWhitespace": false,
},
"python.pythonPath": "/usr/local/bin/python",
},
"python.pythonPath": "/usr/local/bin/python",
},

// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker",
"vscode-icons-team.vscode-icons",
],
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.isort",
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker",
"vscode-icons-team.vscode-icons",
"github.vscode-github-actions",
],
}
}
}
21 changes: 21 additions & 0 deletions .github/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM freqtradeorg/freqtrade:develop_freqairl

USER root
# Install dependencies
COPY requirements-dev.txt /freqtrade/

ARG USERNAME=ftuser

RUN apt-get update \
&& apt-get -y install --no-install-recommends apt-utils dialog git ssh vim build-essential zsh \
&& apt-get clean \
&& mkdir -p /home/${USERNAME}/.vscode-server /home/${USERNAME}/.vscode-server-insiders /home/${USERNAME}/commandhistory \
&& chown ${USERNAME}:${USERNAME} -R /home/${USERNAME}/.local/ \
&& chown ${USERNAME}: -R /home/${USERNAME}/

USER ftuser

RUN pip install --user autopep8 -r docs/requirements-docs.txt -r requirements-dev.txt --no-cache-dir

# Empty the ENTRYPOINT to allow all commands
ENTRYPOINT []
12 changes: 12 additions & 0 deletions .github/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "freqtrade Dev container image builder",
"build": {
"dockerfile": "Dockerfile",
"context": "../../"
},
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
},
"ghcr.io/stuartleeks/dev-container-features/shell-history:0.0.3": {}
}
}
3 changes: 3 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ updates:
pytest:
patterns:
- "pytest*"
mkdocs:
patterns:
- "mkdocs*"

- package-ecosystem: "github-actions"
directory: "/"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ "macos-latest", "macos-13", "macos-14" ]
os: [ "macos-12", "macos-13", "macos-14" ]
python-version: ["3.9", "3.10", "3.11", "3.12"]
exclude:
- os: "macos-14"
Expand Down Expand Up @@ -414,7 +414,7 @@ jobs:
pytest --random-order --longrun --durations 20 -n auto
# Notify only once - when CI completes (and after deploy) in case it's successfull
# Notify only once - when CI completes (and after deploy) in case it's successful
notify-complete:
needs: [
build-linux,
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/devcontainer-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Devcontainer Pre-Build

on:
workflow_dispatch:
# push:
# branches:
# - "master"
# tags:
# - "v*.*.*"
# pull_requests:
# branches:
# - "master"

concurrency:
group: "${{ github.workflow }}"
cancel-in-progress: true

permissions:
packages: write

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
-
name: Checkout
id: checkout
uses: actions/checkout@v4
-
name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Pre-build dev container image
uses: devcontainers/ci@v0.3
with:
subFolder: .github
imageName: ghcr.io/${{ github.repository }}-devcontainer
cacheFrom: ghcr.io/${{ github.repository }}-devcontainer
push: always
15 changes: 11 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ repos:
# stages: [push]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.9.0"
rev: "v1.10.0"
hooks:
- id: mypy
exclude: build_helpers
additional_dependencies:
- types-cachetools==5.3.0.7
- types-filelock==3.2.7
- types-requests==2.31.0.20240311
- types-requests==2.31.0.20240406
- types-tabulate==0.9.0.20240106
- types-python-dateutil==2.9.0.20240316
- SQLAlchemy==2.0.29
Expand All @@ -31,12 +31,12 @@ repos:

- repo: https://github.com/charliermarsh/ruff-pre-commit
# Ruff version.
rev: 'v0.3.4'
rev: 'v0.4.2'
hooks:
- id: ruff

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: end-of-file-fixer
exclude: |
Expand All @@ -54,3 +54,10 @@ repos:
(?x)^(
.*\.md
)$
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
- id: codespell
additional_dependencies:
- tomli
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.12.2-slim-bookworm as base
FROM python:3.12.3-slim-bookworm as base

# Setup env
ENV LANG C.UTF-8
Expand Down
4 changes: 2 additions & 2 deletions build_helpers/pre_commit_update.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File used in CI to ensure pre-commit dependencies are kept uptodate.
# File used in CI to ensure pre-commit dependencies are kept up-to-date.

import sys
from pathlib import Path
Expand All @@ -21,7 +21,7 @@
'types-') or r.startswith('SQLAlchemy')]

with pre_commit_file.open('r') as file:
f = yaml.load(file, Loader=yaml.FullLoader)
f = yaml.load(file, Loader=yaml.SafeLoader)


mypy_repo = [repo for repo in f['repos'] if repo['repo']
Expand Down
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/advanced-backtesting.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 1 2 3 4 5
```

This command will read from the last backtesting results. The `--analysis-groups` option is
used to specify the various tabular outputs showing the profit fo each group or trade,
used to specify the various tabular outputs showing the profit of each group or trade,
ranging from the simplest (0) to the most detailed per pair, per buy and per sell tag (4):

* 0: overall winrate and profit summary by enter_tag
Expand Down
13 changes: 7 additions & 6 deletions docs/backtesting.md
Original file line number Diff line number Diff line change
Expand Up @@ -522,21 +522,22 @@ To save time, by default backtest will reuse a cached result from within the las

### Further backtest-result analysis

To further analyze your backtest results, you can [export the trades](#exporting-trades-to-file).
You can then load the trades to perform further analysis as shown in the [data analysis](data-analysis.md#backtesting) backtesting section.
To further analyze your backtest results, freqtrade will export the trades to file by default.
You can then load the trades to perform further analysis as shown in the [data analysis](strategy_analysis_example.md#load-backtest-results-to-pandas-dataframe) backtesting section.

## Assumptions made by backtesting

Since backtesting lacks some detailed information about what happens within a candle, it needs to take a few assumptions:

- Exchange [trading limits](#trading-limits-in-backtesting) are respected
- Entries happen at open-price
- All orders are filled at the requested price (no slippage, no unfilled orders)
- All orders are filled at the requested price (no slippage) as long as the price is within the candle's high/low range
- Exit-signal exits happen at open-price of the consecutive candle
- Exits don't free their trade slot for a new trade until the next candle
- Exit-signal is favored over Stoploss, because exit-signals are assumed to trigger on candle's open
- ROI
- exits are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the exit will be at 2%)
- exits are never "below the candle", so a ROI of 2% may result in a exit at 2.4% if low was at 2.4% profit
- Exits are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the exit will be at 2%)
- Exits are never "below the candle", so a ROI of 2% may result in a exit at 2.4% if low was at 2.4% profit
- ROI entries which came into effect on the triggering candle (e.g. `120: 0.02` for 1h candles, from `60: 0.05`) will use the candle's open as exit rate
- Force-exits caused by `<N>=-1` ROI entries use low as exit value, unless N falls on the candle open (e.g. `120: -1` for 1h candles)
- Stoploss exits happen exactly at stoploss price, even if low was lower, but the loss will be `2 * fees` higher than the stoploss price
Expand Down Expand Up @@ -587,7 +588,7 @@ These precision values are based on current exchange limits (as described in the

## Improved backtest accuracy

One big limitation of backtesting is it's inability to know how prices moved intra-candle (was high before close, or viceversa?).
One big limitation of backtesting is it's inability to know how prices moved intra-candle (was high before close, or vice-versa?).
So assuming you run backtesting with a 1h timeframe, there will be 4 prices for that candle (Open, High, Low, Close).

While backtesting does take some assumptions (read above) about this - this can never be perfect, and will always be biased in one way or the other.
Expand Down
8 changes: 4 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `position_adjustment_enable` | Enables the strategy to use position adjustments (additional buys or sells). [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.*<br> **Datatype:** Boolean
| `max_entry_position_adjustment` | Maximum additional order(s) for each open trade on top of the first entry Order. Set it to `-1` for unlimited additional orders. [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `-1`.*<br> **Datatype:** Positive Integer or -1
| | **Exchange**
| `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename). <br> **Datatype:** String
| `exchange.name` | **Required.** Name of the exchange class to use. <br> **Datatype:** String
| `exchange.key` | API key to use for the exchange. Only required when you are in production mode.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
Expand Down Expand Up @@ -252,7 +252,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `disable_dataframe_checks` | Disable checking the OHLCV dataframe returned from the strategy methods for correctness. Only use when intentionally changing the dataframe and understand what you are doing. [Strategy Override](#parameters-in-the-strategy).<br> *Defaults to `False`*. <br> **Datatype:** Boolean
| `internals.process_throttle_secs` | Set the process throttle, or minimum loop duration for one bot iteration loop. Value in second. <br>*Defaults to `5` seconds.* <br> **Datatype:** Positive Integer
| `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages. <br>*Defaults to `60` seconds.* <br> **Datatype:** Positive Integer or 0
| `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details. <br> **Datatype:** Boolean
| `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](advanced-setup.md#configure-the-bot-running-as-a-systemd-service) for more details. <br> **Datatype:** Boolean
| `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`. <br> **Datatype:** ClassName
| `strategy_path` | Adds an additional strategy lookup path (must be a directory). <br> **Datatype:** String
| `recursive_strategy_search` | Set to `true` to recursively search sub-directories inside `user_data/strategies` for a strategy. <br> **Datatype:** Boolean
Expand Down Expand Up @@ -370,7 +370,7 @@ This setting works in combination with `max_open_trades`. The maximum capital en
For example, the bot will at most use (0.05 BTC x 3) = 0.15 BTC, assuming a configuration of `max_open_trades=3` and `stake_amount=0.05`.

!!! Note
This setting respects the [available balance configuration](#available-balance).
This setting respects the [available balance configuration](#tradable-balance).

#### Dynamic stake amount

Expand Down Expand Up @@ -547,7 +547,7 @@ is automatically cancelled by the exchange.
**PO (Post only):**

Post only order. The order is either placed as a maker order, or it is canceled.
This means the order must be placed on orderbook for at at least time in an unfilled state.
This means the order must be placed on orderbook for at least time in an unfilled state.

#### time_in_force config

Expand Down
6 changes: 3 additions & 3 deletions docs/developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Details will obviously vary between setups - but this should work to get you sta
``` json
{
"name": "freqtrade trade",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "freqtrade",
"console": "integratedTerminal",
Expand Down Expand Up @@ -261,7 +261,7 @@ For that reason, they must implement the following methods:

The `until` portion should be calculated using the provided `calculate_lock_end()` method.

All Protections should use `"stop_duration"` / `"stop_duration_candles"` to define how long a a pair (or all pairs) should be locked.
All Protections should use `"stop_duration"` / `"stop_duration_candles"` to define how long a pair (or all pairs) should be locked.
The content of this is made available as `self._stop_duration` to the each Protection.

If your protection requires a look-back period, please use `"lookback_period"` / `"lockback_period_candles"` to keep all protections aligned.
Expand Down Expand Up @@ -305,7 +305,7 @@ The `IProtection` parent class provides a helper method for this in `calculate_l

Most exchanges supported by CCXT should work out of the box.

To quickly test the public endpoints of an exchange, add a configuration for your exchange to `test_ccxt_compat.py` and run these tests with `pytest --longrun tests/exchange/test_ccxt_compat.py`.
To quickly test the public endpoints of an exchange, add a configuration for your exchange to `tests/exchange_online/conftest.py` and run these tests with `pytest --longrun tests/exchange_online/test_ccxt_compat.py`.
Completing these tests successfully a good basis point (it's a requirement, actually), however these won't guarantee correct exchange functioning, as this only tests public endpoints, but no private endpoint (like generate order or similar).

Also try to use `freqtrade download-data` for an extended timerange (multiple months) and verify that the data downloaded correctly (no holes, the specified timerange was actually downloaded).
Expand Down
2 changes: 1 addition & 1 deletion docs/edge.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ $$ R = \frac{\text{average_profit}}{\text{average_loss}} = \frac{\mu_{win}}{\mu_

### Expectancy

By combining the Win Rate $W$ and and the Risk Reward ratio $R$ to create an expectancy ratio $E$. A expectance ratio is the expected return of the investment made in a trade. We can compute the value of $E$ as follows:
By combining the Win Rate $W$ and the Risk Reward ratio $R$ to create an expectancy ratio $E$. A expectance ratio is the expected return of the investment made in a trade. We can compute the value of $E$ as follows:

$$E = R * W - L$$

Expand Down
2 changes: 1 addition & 1 deletion docs/exchanges.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ $ pip3 install web3
Most exchanges return current incomplete candle via their OHLCV/klines API interface.
By default, Freqtrade assumes that incomplete candle is fetched from the exchange and removes the last candle assuming it's the incomplete candle.

Whether your exchange returns incomplete candles or not can be checked using [the helper script](developer.md#Incomplete-candles) from the Contributor documentation.
Whether your exchange returns incomplete candles or not can be checked using [the helper script](developer.md#incomplete-candles) from the Contributor documentation.

Due to the danger of repainting, Freqtrade does not allow you to use this incomplete candle.

Expand Down

0 comments on commit 2152a95

Please sign in to comment.