Compare commits

...

593 Commits

Author SHA1 Message Date
Matthias 4f1e249574 Merge pull request #12452 from freqtrade/new_release
New release 2025.10
2025-10-31 16:53:02 +01:00
Matthias e23a211503 chore: bump version to 2025.10 2025-10-31 07:05:04 +01:00
Matthias 2e78440ef1 Merge branch 'stable' into new_release 2025-10-31 07:04:49 +01:00
Matthias cbaba293b5 fix: more complete fix for #12451 2025-10-31 07:02:53 +01:00
Matthias cdd9968831 test: use realistic arguments for tests 2025-10-31 07:02:53 +01:00
Matthias 6b4318a801 fix: trade.id must be checked as int
fixes problem with psycopg3

closes #12451
2025-10-31 07:02:53 +01:00
Matthias 95f2cc0f88 Merge pull request #12449 from stash86/develop-copy
throw error on recursive analysis on 0 startup candle
2025-10-31 06:28:56 +01:00
Stefano 1d652d1284 throw error on recursive analysis on 0 startup candle 2025-10-31 08:51:56 +09:00
Matthias 758f1eea93 test: consistent use of "spaces" in tests 2025-10-30 06:38:43 +01:00
Matthias f952502af5 Merge pull request #12447 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-10-30 06:37:31 +01:00
Freqtrade Bot b17a274ee8 chore: update pre-commit hooks 2025-10-30 03:21:28 +00:00
Matthias 4adab37b2a test: update test for removal of --hyperopt argument 2025-10-29 17:58:00 +01:00
Matthias ff7b1e0edc chore: remove long-deprecated "--hyperopt" argument 2025-10-29 17:57:51 +01:00
Matthias b2aa392a98 fix: log level setup 2025-10-28 20:00:39 +01:00
Matthias 0c1b892713 chore: add parameter descriptions to load_object 2025-10-28 19:41:35 +01:00
Matthias ee0952a848 chore: simplify iResolver 2025-10-28 19:35:18 +01:00
Matthias a166f452cb chore: move comment to right place 2025-10-28 19:32:57 +01:00
Matthias a458264bc5 fix: improve resilience in strategy wrapper 2025-10-28 19:09:09 +01:00
Matthias 13919054ac Merge pull request #12439 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-10-28 06:20:17 +01:00
Freqtrade Bot 8e4aeb62d3 chore: update pre-commit hooks 2025-10-28 03:19:47 +00:00
Matthias 609ac560fb Merge pull request #12434 from freqtrade/dependabot/pip/develop/ccxt-4.5.12
chore(deps): bump ccxt from 4.5.11 to 4.5.12
2025-10-27 20:06:12 +01:00
Matthias 5ae0328722 chore: fix redundant import 2025-10-27 19:49:49 +01:00
Matthias 89802da1c7 test: update tests for new okx limits 2025-10-27 19:45:21 +01:00
Matthias 43be6eef67 chore: re-align okx limits with ccxt 2025-10-27 19:45:15 +01:00
Matthias dc736da971 Merge pull request #12423 from freqtrade/dependabot/pip/develop/scipy-8c88e3b5d9
chore(deps-dev): bump scipy-stubs from 1.16.2.3 to 1.16.2.4 in the scipy group
2025-10-27 13:35:54 +01:00
Matthias aae1731e3b chore: bump scipy-stubs in pre-commit config 2025-10-27 13:20:37 +01:00
dependabot[bot] f39acd5585 chore(deps-dev): bump scipy-stubs in the scipy group
Bumps the scipy group with 1 update: [scipy-stubs](https://github.com/scipy/scipy-stubs).


Updates `scipy-stubs` from 1.16.2.3 to 1.16.2.4
- [Release notes](https://github.com/scipy/scipy-stubs/releases)
- [Commits](https://github.com/scipy/scipy-stubs/compare/v1.16.2.3...v1.16.2.4)

---
updated-dependencies:
- dependency-name: scipy-stubs
  dependency-version: 1.16.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: scipy
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 08:05:24 +00:00
Matthias 50f32ee56a Merge pull request #12435 from samgermain/cross-docs
cross leverage docs fix
2025-10-27 09:04:07 +01:00
Matthias 7d62e97024 Merge pull request #12425 from freqtrade/dependabot/pip/develop/types-c656cdcffe
chore(deps-dev): bump types-cachetools from 6.2.0.20250827 to 6.2.0.20251022 in the types group
2025-10-27 09:02:44 +01:00
Matthias 15eb454103 Merge pull request #12433 from freqtrade/dependabot/pip/develop/pydantic-2.12.3
chore(deps): bump pydantic from 2.12.2 to 2.12.3
2025-10-27 08:37:21 +01:00
Sam 179cefa89f cross leverage docs fix 2025-10-27 00:33:33 -06:00
dependabot[bot] c251877aba chore(deps): bump ccxt from 4.5.11 to 4.5.12
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.11 to 4.5.12.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/v4.5.11...v4.5.12)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-version: 4.5.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 06:25:41 +00:00
Matthias 8352b0fe07 Merge pull request #12426 from freqtrade/dependabot/pip/develop/aiohttp-3.13.1
chore(deps): bump aiohttp from 3.13.0 to 3.13.1
2025-10-27 07:23:46 +01:00
Matthias 2a7859b3df Merge pull request #12431 from freqtrade/dependabot/pip/develop/ta-lib-0.6.8
chore(deps): bump ta-lib from 0.6.7 to 0.6.8
2025-10-27 07:18:43 +01:00
dependabot[bot] 4064586d18 chore(deps): bump pydantic from 2.12.2 to 2.12.3
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.12.2 to 2.12.3.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.12.2...v2.12.3)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.12.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 05:46:12 +00:00
Matthias 7ddb6d3554 Merge pull request #12429 from freqtrade/dependabot/pip/develop/xgboost-3.1.1
chore(deps): bump xgboost from 3.0.5 to 3.1.1
2025-10-27 06:45:15 +01:00
Matthias 9206c0086f chore: add ta-lib armhf wheels 2025-10-27 06:43:22 +01:00
Matthias 0c6e5ace59 chore: bump types-cachetools in pre-commit config 2025-10-27 06:42:10 +01:00
Matthias 47f5b25265 Merge pull request #12430 from freqtrade/dependabot/pip/develop/uvicorn-0.38.0
chore(deps): bump uvicorn from 0.37.0 to 0.38.0
2025-10-27 06:41:13 +01:00
Matthias e3c8ef19c3 Merge pull request #12424 from freqtrade/dependabot/pip/develop/ruff-0.14.1
chore(deps-dev): bump ruff from 0.14.0 to 0.14.1
2025-10-27 06:40:42 +01:00
Matthias 803ef41a75 Merge pull request #12427 from freqtrade/dependabot/pip/develop/psutil-7.1.1
chore(deps): bump psutil from 7.1.0 to 7.1.1
2025-10-27 06:40:30 +01:00
Matthias 984f505fa6 Merge pull request #12428 from freqtrade/dependabot/pip/develop/fastapi-0.119.1
chore(deps): bump fastapi from 0.119.0 to 0.119.1
2025-10-27 06:40:15 +01:00
Matthias b89266225d Merge pull request #12432 from freqtrade/dependabot/pip/develop/python-rapidjson-1.22
chore(deps): bump python-rapidjson from 1.21 to 1.22
2025-10-27 06:39:58 +01:00
dependabot[bot] a45930a5cf chore(deps): bump python-rapidjson from 1.21 to 1.22
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 1.21 to 1.22.
- [Changelog](https://github.com/python-rapidjson/python-rapidjson/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-rapidjson/python-rapidjson/compare/v1.21...v1.22)

---
updated-dependencies:
- dependency-name: python-rapidjson
  dependency-version: '1.22'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:04:33 +00:00
dependabot[bot] fe06a87aa2 chore(deps): bump ta-lib from 0.6.7 to 0.6.8
Bumps [ta-lib](https://github.com/ta-lib/ta-lib-python) from 0.6.7 to 0.6.8.
- [Release notes](https://github.com/ta-lib/ta-lib-python/releases)
- [Changelog](https://github.com/TA-Lib/ta-lib-python/blob/master/CHANGELOG)
- [Commits](https://github.com/ta-lib/ta-lib-python/compare/v0.6.7...v0.6.8)

---
updated-dependencies:
- dependency-name: ta-lib
  dependency-version: 0.6.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:04:32 +00:00
dependabot[bot] f9940c4f1f chore(deps): bump uvicorn from 0.37.0 to 0.38.0
Bumps [uvicorn](https://github.com/Kludex/uvicorn) from 0.37.0 to 0.38.0.
- [Release notes](https://github.com/Kludex/uvicorn/releases)
- [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md)
- [Commits](https://github.com/Kludex/uvicorn/compare/0.37.0...0.38.0)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-version: 0.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:04:11 +00:00
dependabot[bot] 5c3ebd3761 chore(deps): bump xgboost from 3.0.5 to 3.1.1
Bumps [xgboost](https://github.com/dmlc/xgboost) from 3.0.5 to 3.1.1.
- [Release notes](https://github.com/dmlc/xgboost/releases)
- [Changelog](https://github.com/dmlc/xgboost/blob/master/NEWS.md)
- [Commits](https://github.com/dmlc/xgboost/compare/v3.0.5...v3.1.1)

---
updated-dependencies:
- dependency-name: xgboost
  dependency-version: 3.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:03:53 +00:00
dependabot[bot] 9050325fda chore(deps): bump fastapi from 0.119.0 to 0.119.1
Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.119.0 to 0.119.1.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](https://github.com/fastapi/fastapi/compare/0.119.0...0.119.1)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.119.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:03:03 +00:00
dependabot[bot] 9ca2342a0b chore(deps): bump psutil from 7.1.0 to 7.1.1
Bumps [psutil](https://github.com/giampaolo/psutil) from 7.1.0 to 7.1.1.
- [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst)
- [Commits](https://github.com/giampaolo/psutil/compare/release-7.1.0...release-7.1.1)

---
updated-dependencies:
- dependency-name: psutil
  dependency-version: 7.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:02:56 +00:00
dependabot[bot] ad9bb75fd5 chore(deps): bump aiohttp from 3.13.0 to 3.13.1
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:02:51 +00:00
dependabot[bot] f96dfd04f7 chore(deps-dev): bump types-cachetools in the types group
Bumps the types group with 1 update: [types-cachetools](https://github.com/typeshed-internal/stub_uploader).


Updates `types-cachetools` from 6.2.0.20250827 to 6.2.0.20251022
- [Commits](https://github.com/typeshed-internal/stub_uploader/commits)

---
updated-dependencies:
- dependency-name: types-cachetools
  dependency-version: 6.2.0.20251022
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: types
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:02:40 +00:00
dependabot[bot] d63982c32c chore(deps-dev): bump ruff from 0.14.0 to 0.14.1
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.14.0 to 0.14.1.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.14.0...0.14.1)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.14.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 03:02:36 +00:00
Matthias 14b5392d5f Merge pull request #12420 from qinhanlei/uv-pip
Add support for uv in setup.sh
2025-10-26 09:47:48 +01:00
Matthias 16dd4073ff docs: update setup script docs for uv support 2025-10-26 09:32:36 +01:00
Matthias 9595936d73 chore: fix uv only install 2025-10-26 09:04:30 +01:00
Matthias c18a52fd2d test: update tests for new error formatting 2025-10-25 13:15:41 +02:00
Matthias 75c39d3617 feat: improve strategy error warning
closes #12418
2025-10-25 13:15:24 +02:00
Matthias 911a803a56 fix: improve error-handling for odd configurations 2025-10-25 09:49:55 +02:00
Matthias f04315fa8f fix: gracefully handle custom stake returning string
closes #12421
2025-10-25 09:42:45 +02:00
Matthias 89e68d7d4d test: add test case for string custom stake amount 2025-10-25 09:42:45 +02:00
Hanlei Qin 4fc5f33fa1 fix an omission 2025-10-25 15:16:20 +08:00
Matthias c2056085c9 Merge pull request #12419 from stash86/main-stash
Fix typo
2025-10-25 08:49:17 +02:00
Hanlei Qin 9f7b7ef889 Use uv instead of pip if available 2025-10-25 12:33:14 +08:00
Stefano cdb194a363 fix typo 2025-10-25 13:13:40 +09:00
Stefano 0986350f05 fix typo 2025-10-25 13:11:11 +09:00
Hanlei Qin 119cadcb2b Replace pip with uv for package installations in setup.sh 2025-10-24 19:55:57 +08:00
Matthias 803db3b55b Merge pull request #12413 from hippocritical/develop
add np.NAN to strategy updater conversion (which worked in 1.x but not in 2.x anymore)
2025-10-24 08:41:51 +02:00
hippocritical c2fd6e3237 NAN is sometimes used by some programmers when numpy was 1.x but now on 2.x the caps version is disallowed.
Added the caps conversion to lower case nan to fix that automatically.

Source:
https://numpy.org/doc/2.0/reference/constants.html?utm_source=chatgpt.com
NaN and NAN are aliases of nan.
2025-10-24 08:11:44 +02:00
Matthias bf7fc79519 Merge pull request #12412 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-10-23 19:46:01 +02:00
Freqtrade Bot cded5bcb4c chore: update pre-commit hooks 2025-10-23 17:29:57 +00:00
Matthias f8d3373e13 docs: update documentation to refer to psycopg3
It's the newer version with broader support for new packages (e.g. numpy2).

closes #12409
2025-10-23 19:11:43 +02:00
Matthias f1d48c8189 test: explicitly test for psycopg3 2025-10-23 07:11:15 +02:00
Matthias 866bda8606 test: update test string for psycopg3 2025-10-23 07:06:36 +02:00
Matthias 78a00ef249 Merge pull request #12398 from freqtrade/fix/remove_deprecation_warning
Work around os.fork deprecation
2025-10-21 06:34:28 +02:00
Matthias b6bc3042b4 Merge pull request #12408 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-10-21 06:25:23 +02:00
Freqtrade Bot 4ee699d27b chore: update pre-commit hooks 2025-10-21 03:19:09 +00:00
Matthias 2effa7a31b Merge branch 'develop' into fix/remove_deprecation_warning 2025-10-20 20:23:08 +02:00
Matthias c50b77303d Merge pull request #12400 from qinhanlei/patch-1
Update sb3_contrib dependency condition
2025-10-20 20:20:55 +02:00
Matthias 40bfaa6245 chore: align pyproject.toml platform limitations 2025-10-20 19:41:50 +02:00
Matthias f4656a0c6e test: ensure mp_start runs on startup 2025-10-20 19:30:32 +02:00
Matthias 161e5e3dfa refactor: switch mp-method to forkserver globally 2025-10-20 19:28:17 +02:00
Robert Caulk 023da4fc29 Merge pull request #12299 from freqtrade/dependabot/pip/develop/gymnasium-1.2.1
chore(deps): bump gymnasium from 0.29.1 to 1.2.1
2025-10-20 17:07:49 +02:00
dependabot[bot] 5c8261f8d1 chore(deps): bump gymnasium from 0.29.1 to 1.2.1
Bumps [gymnasium](https://github.com/Farama-Foundation/Gymnasium) from 0.29.1 to 1.2.1.
- [Release notes](https://github.com/Farama-Foundation/Gymnasium/releases)
- [Commits](https://github.com/Farama-Foundation/Gymnasium/compare/v0.29.1...v1.2.1)

---
updated-dependencies:
- dependency-name: gymnasium
  dependency-version: 1.2.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 04:30:27 +00:00
Matthias 080aafa1da Merge pull request #12406 from freqtrade/dependabot/pip/develop/torch-2.9.0
chore(deps): bump torch from 2.8.0 to 2.9.0
2025-10-20 06:26:48 +02:00
Matthias 43d6a6782a Merge pull request #12402 from freqtrade/dependabot/pip/develop/cryptography-46.0.3
chore(deps): bump cryptography from 46.0.2 to 46.0.3
2025-10-20 06:25:52 +02:00
Matthias f0028a6b6e Merge pull request #12407 from freqtrade/dependabot/pip/develop/humanize-4.14.0
chore(deps): bump humanize from 4.13.0 to 4.14.0
2025-10-20 06:25:09 +02:00
Matthias 98439f4e48 Merge pull request #12405 from freqtrade/dependabot/pip/develop/numpy-2.3.4
chore(deps): bump numpy from 2.3.3 to 2.3.4
2025-10-20 06:24:54 +02:00
Matthias 78802ae9aa Merge pull request #12404 from freqtrade/dependabot/pip/develop/numexpr-2.14.1
chore(deps): bump numexpr from 2.13.1 to 2.14.1
2025-10-20 06:24:24 +02:00
Matthias 99b4e5382e Merge pull request #12401 from freqtrade/dependabot/pip/develop/pydantic-2.12.2
chore(deps): bump pydantic from 2.12.0 to 2.12.2
2025-10-20 06:24:08 +02:00
Matthias 2b24f939da Merge pull request #12403 from freqtrade/dependabot/pip/develop/mkdocs-3c1a69b1c7
chore(deps): bump mkdocs-material from 9.6.21 to 9.6.22 in the mkdocs group
2025-10-20 06:23:24 +02:00
dependabot[bot] 3271e5cd43 chore(deps): bump humanize from 4.13.0 to 4.14.0
Bumps [humanize](https://github.com/python-humanize/humanize) from 4.13.0 to 4.14.0.
- [Release notes](https://github.com/python-humanize/humanize/releases)
- [Commits](https://github.com/python-humanize/humanize/compare/4.13.0...4.14.0)

---
updated-dependencies:
- dependency-name: humanize
  dependency-version: 4.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 03:02:42 +00:00
dependabot[bot] 94bd6b7142 chore(deps): bump torch from 2.8.0 to 2.9.0
Bumps [torch](https://github.com/pytorch/pytorch) from 2.8.0 to 2.9.0.
- [Release notes](https://github.com/pytorch/pytorch/releases)
- [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md)
- [Commits](https://github.com/pytorch/pytorch/compare/v2.8.0...v2.9.0)

---
updated-dependencies:
- dependency-name: torch
  dependency-version: 2.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 03:02:37 +00:00
dependabot[bot] b59c4caf81 chore(deps): bump numpy from 2.3.3 to 2.3.4
Bumps [numpy](https://github.com/numpy/numpy) from 2.3.3 to 2.3.4.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v2.3.3...v2.3.4)

---
updated-dependencies:
- dependency-name: numpy
  dependency-version: 2.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 03:02:21 +00:00
dependabot[bot] 8bfa3a5d11 chore(deps): bump numexpr from 2.13.1 to 2.14.1
Bumps [numexpr](https://github.com/pydata/numexpr) from 2.13.1 to 2.14.1.
- [Release notes](https://github.com/pydata/numexpr/releases)
- [Changelog](https://github.com/pydata/numexpr/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/pydata/numexpr/compare/v2.13.1...v2.14.1)

---
updated-dependencies:
- dependency-name: numexpr
  dependency-version: 2.14.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 03:02:14 +00:00
dependabot[bot] b161924941 chore(deps): bump mkdocs-material in the mkdocs group
Bumps the mkdocs group with 1 update: [mkdocs-material](https://github.com/squidfunk/mkdocs-material).


Updates `mkdocs-material` from 9.6.21 to 9.6.22
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.21...9.6.22)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.6.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: mkdocs
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 03:02:09 +00:00
dependabot[bot] aad125211e chore(deps): bump cryptography from 46.0.2 to 46.0.3
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.2 to 46.0.3.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/46.0.2...46.0.3)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 46.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 03:02:03 +00:00
dependabot[bot] 39f8149e27 chore(deps): bump pydantic from 2.12.0 to 2.12.2
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.12.0 to 2.12.2.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.12.0...v2.12.2)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.12.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 03:02:00 +00:00
WingStone d6541d81c3 Update sb3_contrib dependency condition
Install dependencies for development on macOS with Intel x86_64 Chip.
2025-10-20 10:49:35 +08:00
Matthias 763f08a08e test: test catboost on aarch64 runners 2025-10-19 16:46:33 +02:00
Matthias 886d5d1db6 chore: update catboost install 2025-10-19 16:45:13 +02:00
Matthias 9b1fc7a6d4 Merge pull request #12394 from freqtrade/feat/bitget_futures
Add support for bitget futures
2025-10-19 16:32:39 +02:00
Matthias 8d95ca3506 chore: disable deprecationWarning
Very targeted at  'CatBoostClassifier' object has no attribute '__sklearn_tags__'
2025-10-19 16:32:25 +02:00
Matthias 44ec500744 test: add Test-case to ensure hyperopt logging 2025-10-19 12:59:08 +02:00
Matthias 8526733b36 chore: update hyperopt test strategy to new interface 2025-10-19 12:55:00 +02:00
Matthias 9041000bc4 fix: attempt to work around deprecation message 2025-10-19 12:05:52 +02:00
Matthias be16ffea23 fix: move logging setup to hyperopter
restores hyperopt logging functionality
2025-10-19 09:09:59 +02:00
Matthias a0c4b520fc fix: okxus doesn't support futures trading 2025-10-19 08:24:06 +02:00
Matthias dcd9e2ef14 feat: bitget stop orders don't block assets 2025-10-18 13:02:33 +02:00
Matthias 46dc378472 test: add bitget leverage prep test 2025-10-18 09:53:42 +02:00
Matthias d1e73c1916 test: add test for cross liquidation price not supported 2025-10-18 09:48:48 +02:00
Matthias 0f60ee8763 feat: add bitget as supported exchange 2025-10-18 08:53:18 +02:00
Matthias 5b45f1bbc8 docs: add bitget as supported exchange 2025-10-18 08:52:52 +02:00
Matthias d283252ac7 fix: bitget only provides 100 funding rate candles per call 2025-10-18 08:47:55 +02:00
Matthias 02a0ce8c49 test: enable online bitget tests 2025-10-18 08:47:55 +02:00
Matthias f82d8f3b52 test: refactor _get_params test for simpler reading 2025-10-18 08:47:55 +02:00
Matthias 1f620257f9 test: test for get_params 2025-10-18 08:47:55 +02:00
Matthias 16e9109e96 test: add test for bitget exchange init 2025-10-18 08:47:55 +02:00
Matthias 0c65c915a4 feat: more settings for bitget futures 2025-10-18 08:47:55 +02:00
Matthias 7aca82b590 docs: clarify exchange warning 2025-10-18 08:47:55 +02:00
Matthias 99566b4d9b docs: slight refactor to exchanges structure 2025-10-18 08:47:55 +02:00
Matthias eb31581c7b docs(bitget): Add futures notes for bitget 2025-10-18 08:47:55 +02:00
Matthias d46af09c10 docs: add bitget to support matrix 2025-10-18 08:47:55 +02:00
Matthias badc7ed18c feat(bitget): fix liquidation formula 2025-10-18 08:47:55 +02:00
Matthias 3da36eae31 feat: bitget futures order parameters 2025-10-18 08:47:55 +02:00
Matthias fcbe58e971 feat: Add bitget exchange init 2025-10-18 08:47:55 +02:00
Matthias 572ce0b739 feat: bitget liquidation price calc 2025-10-18 08:47:55 +02:00
Matthias 0f31607617 feat: Enable bitget futures trading 2025-10-18 08:47:55 +02:00
Matthias 6a15f0c271 chore: update exchange docstrings 2025-10-18 08:45:56 +02:00
Matthias d77bcf0e18 chore: update web proxy url 2025-10-16 20:51:57 +02:00
Matthias 5df0530223 Merge pull request #12389 from mrpabloyeah/add-day-of-week-to-backtest-breakdowns
Add day of week to backtest breakdowns
2025-10-16 20:16:02 +02:00
Matthias 522fa092ba test: add explicit weekday test 2025-10-16 19:23:53 +02:00
Matthias 8f6f2ab872 test: add explicit test for weekday change 2025-10-16 19:21:31 +02:00
Matthias 7185026378 chore: revert unnecessary period name customization 2025-10-16 19:17:10 +02:00
Matthias db11844661 Merge pull request #12392 from freqtrade/dependabot/pip/develop/ccxt-4.5.11
chore(deps): bump ccxt from 4.5.10 to 4.5.11
2025-10-16 07:03:08 +02:00
Matthias 163d8a0e10 Merge pull request #12391 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-10-16 06:45:34 +02:00
dependabot[bot] 7a38423c1e chore(deps): bump ccxt from 4.5.10 to 4.5.11
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.10 to 4.5.11.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/v4.5.10...v4.5.11)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-version: 4.5.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-16 04:43:09 +00:00
Matthias 46e0219040 chore: add devcontainer update to dependabot 2025-10-16 06:38:08 +02:00
Freqtrade Bot 1ff49aa614 chore: update pre-commit hooks 2025-10-16 03:17:22 +00:00
Matthias c878c673ab fix: improve datetime for trade_list_to_dataframe
closes #12388
2025-10-15 19:36:06 +02:00
Matthias 642f24eba5 chore: fix odd debug message wording 2025-10-15 19:31:10 +02:00
Matthias bdd60ecbbd fix: Set use_db for historic analysis
closes #12390
2025-10-15 18:27:20 +02:00
Matthias 4cf736911d fix: cleanup backtest after it ran 2025-10-15 18:19:02 +02:00
Matthias 0bf83f8744 chore: improved reset_backtest function 2025-10-15 18:17:55 +02:00
Matthias 6bd7fdb8ac chore: improved naming for method 2025-10-15 18:17:30 +02:00
Matthias a745136190 chore: fix action version missmatch 2025-10-15 06:59:37 +02:00
Matthias a672c32d6a chore: add dependabot cooldown configs 2025-10-15 06:58:31 +02:00
mrpabloyeah 1294724ee8 Add day of week to backtest breakdowns 2025-10-14 21:13:48 +02:00
Matthias b13af0e88b Merge pull request #12385 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-10-14 06:50:12 +02:00
Matthias 0041bf5e4e test: use ft_additional_exchange_init in tests 2025-10-14 06:30:05 +02:00
Matthias d7c027fc7a test: add ft_additional_exchange_init to simplify test setups 2025-10-14 06:29:59 +02:00
Matthias b3ceaa87d7 chore: remove redundant comment 2025-10-14 06:29:44 +02:00
Freqtrade Bot d237974ebe chore: update pre-commit hooks 2025-10-14 03:16:08 +00:00
Matthias a82c852675 Merge pull request #12370 from freqtrade/dependabot/pip/develop/scipy-78fb2d86bd
chore(deps-dev): bump scipy-stubs from 1.16.2.0 to 1.16.2.3 in the scipy group
2025-10-13 08:45:48 +02:00
Matthias bb76099b5a Merge pull request #12381 from freqtrade/dependabot/pip/develop/aiohttp-3.13.0
chore(deps): bump aiohttp from 3.12.15 to 3.13.0
2025-10-13 08:18:11 +02:00
Matthias 01ca34ebee chore: bump scipy-stubs in pre-commit config 2025-10-13 08:17:53 +02:00
dependabot[bot] 4af18a3471 chore(deps): bump aiohttp from 3.12.15 to 3.13.0
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 05:32:12 +00:00
dependabot[bot] 5d8500ff7f chore(deps-dev): bump scipy-stubs in the scipy group
Bumps the scipy group with 1 update: [scipy-stubs](https://github.com/scipy/scipy-stubs).


Updates `scipy-stubs` from 1.16.2.0 to 1.16.2.3
- [Release notes](https://github.com/scipy/scipy-stubs/releases)
- [Commits](https://github.com/scipy/scipy-stubs/compare/v1.16.2.0...v1.16.2.3)

---
updated-dependencies:
- dependency-name: scipy-stubs
  dependency-version: 1.16.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: scipy
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 05:25:30 +00:00
Matthias 8a59dfd495 Merge pull request #12380 from freqtrade/dependabot/pip/develop/pydantic-2.12.0
chore(deps): bump pydantic from 2.11.10 to 2.12.0
2025-10-13 07:24:30 +02:00
Matthias f4da8edb90 Merge pull request #12376 from freqtrade/dependabot/pip/develop/sqlalchemy-2.0.44
chore(deps): bump sqlalchemy from 2.0.43 to 2.0.44
2025-10-13 07:20:41 +02:00
Matthias f1824f6f2e Merge pull request #12368 from freqtrade/dependabot/pip/develop/types-42ec8c0646
chore(deps-dev): bump types-python-dateutil from 2.9.0.20250822 to 2.9.0.20251008 in the types group
2025-10-13 07:09:57 +02:00
dependabot[bot] 54b01bd44d chore(deps): bump pydantic from 2.11.10 to 2.12.0
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.10 to 2.12.0.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.11.10...v2.12.0)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 04:48:24 +00:00
Matthias 634be642f2 Merge pull request #12377 from freqtrade/dependabot/pip/develop/aiofiles-25.1.0
chore(deps): bump aiofiles from 24.1.0 to 25.1.0
2025-10-13 06:47:28 +02:00
Matthias 2e5000a016 chore: bump sqlalchemy in pre-commit config 2025-10-13 06:47:14 +02:00
dependabot[bot] b51ed49dbf chore(deps): bump sqlalchemy from 2.0.43 to 2.0.44
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.43 to 2.0.44.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-version: 2.0.44
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 04:43:22 +00:00
Matthias 92d2bde559 chore: bump pre-commit python-dateutil stubs 2025-10-13 06:39:38 +02:00
Matthias 92ae444026 Merge pull request #12375 from freqtrade/dependabot/pip/develop/ccxt-4.5.10
chore(deps): bump ccxt from 4.5.7 to 4.5.10
2025-10-13 06:36:23 +02:00
Matthias 51795474d7 Merge pull request #12373 from freqtrade/dependabot/pip/develop/isort-7.0.0
chore(deps-dev): bump isort from 6.1.0 to 7.0.0
2025-10-13 06:35:04 +02:00
Matthias 63a37fc2d3 Merge pull request #12374 from freqtrade/dependabot/pip/develop/rich-14.2.0
chore(deps): bump rich from 14.1.0 to 14.2.0
2025-10-13 06:34:42 +02:00
Matthias 7d79ac1e56 Merge pull request #12378 from freqtrade/dependabot/pip/develop/ruff-0.14.0
chore(deps-dev): bump ruff from 0.13.3 to 0.14.0
2025-10-13 06:34:25 +02:00
Matthias acf6d94ee1 Merge pull request #12371 from freqtrade/dependabot/pip/develop/cachetools-6.2.1
chore(deps): bump cachetools from 6.2.0 to 6.2.1
2025-10-13 06:34:05 +02:00
Matthias a03e726aad Merge pull request #12372 from freqtrade/dependabot/pip/develop/filelock-3.20.0
chore(deps): bump filelock from 3.19.1 to 3.20.0
2025-10-13 06:33:45 +02:00
Matthias 6ce27e50f0 Merge pull request #12379 from freqtrade/dependabot/pip/develop/fastapi-0.119.0
chore(deps): bump fastapi from 0.118.0 to 0.119.0
2025-10-13 06:33:33 +02:00
Matthias d3bdf1ab96 Merge pull request #12369 from freqtrade/dependabot/github_actions/develop/astral-sh/setup-uv-7.1.0
chore(deps): bump astral-sh/setup-uv from 6.8.0 to 7.1.0
2025-10-13 06:33:18 +02:00
dependabot[bot] a0ec5f6fe2 chore(deps): bump fastapi from 0.118.0 to 0.119.0
Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.118.0 to 0.119.0.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](https://github.com/fastapi/fastapi/compare/0.118.0...0.119.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.119.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:03:46 +00:00
dependabot[bot] d512ae6c86 chore(deps-dev): bump ruff from 0.13.3 to 0.14.0
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.13.3 to 0.14.0.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.13.3...0.14.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.14.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:03:33 +00:00
dependabot[bot] 612790c730 chore(deps): bump aiofiles from 24.1.0 to 25.1.0
Bumps [aiofiles](https://github.com/Tinche/aiofiles) from 24.1.0 to 25.1.0.
- [Release notes](https://github.com/Tinche/aiofiles/releases)
- [Changelog](https://github.com/Tinche/aiofiles/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Tinche/aiofiles/compare/v24.1.0...v25.1.0)

---
updated-dependencies:
- dependency-name: aiofiles
  dependency-version: 25.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:03:25 +00:00
dependabot[bot] 0e84c203e6 chore(deps): bump ccxt from 4.5.7 to 4.5.10
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.7 to 4.5.10.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/v4.5.7...v4.5.10)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-version: 4.5.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:02:24 +00:00
dependabot[bot] 61119d60b9 chore(deps): bump rich from 14.1.0 to 14.2.0
Bumps [rich](https://github.com/Textualize/rich) from 14.1.0 to 14.2.0.
- [Release notes](https://github.com/Textualize/rich/releases)
- [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Textualize/rich/compare/v14.1.0...v14.2.0)

---
updated-dependencies:
- dependency-name: rich
  dependency-version: 14.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:02:10 +00:00
dependabot[bot] 3870758ab8 chore(deps-dev): bump isort from 6.1.0 to 7.0.0
Bumps [isort](https://github.com/PyCQA/isort) from 6.1.0 to 7.0.0.
- [Release notes](https://github.com/PyCQA/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PyCQA/isort/compare/6.1.0...7.0.0)

---
updated-dependencies:
- dependency-name: isort
  dependency-version: 7.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:02:06 +00:00
dependabot[bot] 1b76900b9e chore(deps): bump filelock from 3.19.1 to 3.20.0
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.19.1 to 3.20.0.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.19.1...3.20.0)

---
updated-dependencies:
- dependency-name: filelock
  dependency-version: 3.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:02:00 +00:00
dependabot[bot] b63d61f2b2 chore(deps): bump cachetools from 6.2.0 to 6.2.1
Bumps [cachetools](https://github.com/tkem/cachetools) from 6.2.0 to 6.2.1.
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v6.2.0...v6.2.1)

---
updated-dependencies:
- dependency-name: cachetools
  dependency-version: 6.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:01:54 +00:00
dependabot[bot] 90e36700c3 chore(deps): bump astral-sh/setup-uv from 6.8.0 to 7.1.0
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.8.0 to 7.1.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/d0cc045d04ccac9d8b7881df0226f9e82c39688e...3259c6206f993105e3a61b142c2d97bf4b9ef83d)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:01:30 +00:00
dependabot[bot] d79b82d24e chore(deps-dev): bump types-python-dateutil in the types group
Bumps the types group with 1 update: [types-python-dateutil](https://github.com/typeshed-internal/stub_uploader).


Updates `types-python-dateutil` from 2.9.0.20250822 to 2.9.0.20251008
- [Commits](https://github.com/typeshed-internal/stub_uploader/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-version: 2.9.0.20251008
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: types
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 03:01:15 +00:00
Matthias b8e288e613 Merge pull request #12282 from mrpabloyeah/update-documentation-for-trade-and-order-objects
Update documentation for Trade and Order objects
2025-10-12 15:36:58 +02:00
Matthias ca76ccb6af docs: improve some documentation wording 2025-10-12 15:22:36 +02:00
Matthias bb6e33c8c4 docs: remove methods that are not considered as public interface 2025-10-12 10:29:07 +02:00
Matthias f529b7b526 docs: Update trade-object documentation
partially reverts c1cd14 - includes a few enhancements to it
2025-10-12 10:25:56 +02:00
Matthias ea0c51c498 Merge pull request #12201 from mihalt/fix_merge_informative_pair
Fix the truncation of values by merge_ordered in merge_informative_pair
2025-10-12 10:15:47 +02:00
Matthias a9447e7edf Merge branch 'develop' into fix_merge_informative_pair 2025-10-12 09:51:43 +02:00
Matthias 93b87696c6 fix: handle case where informative does not overlap with the main data 2025-10-12 09:51:31 +02:00
Matthias 876875cff2 test: add test-case for no overlap merges 2025-10-12 09:51:15 +02:00
Matthias 2649ba0916 docs (freqAI): align docs with actual model name 2025-10-11 16:04:04 +02:00
Matthias 923f687a33 Merge pull request #12354 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-10-09 06:31:22 +02:00
Freqtrade Bot 613fdad671 chore: update pre-commit hooks 2025-10-09 03:15:03 +00:00
Matthias d8a89a3a42 chore: re-add type requirement 2025-10-08 07:08:48 +02:00
Matthias 34cba1480e test: improved line-annotation test-case 2025-10-08 07:07:39 +02:00
Matthias 9ea249180a test: add annotation line test 2025-10-08 06:42:53 +02:00
Matthias 4ba13a4254 fic: Improve type safety for annotationType 2025-10-08 06:42:38 +02:00
Matthias e6371f38fd chore: bump docker image to 3.13.8 2025-10-08 06:36:15 +02:00
Matthias e55a196e8f docs: update docs for line annotations
closes #12307
2025-10-07 19:29:52 +02:00
Matthias f9696d557c feat: Add line chart type 2025-10-07 19:29:52 +02:00
Matthias 0715f46a4a docs: fix broken doc example 2025-10-07 19:29:52 +02:00
Matthias a5450672b1 feat: add line annotations 2025-10-07 19:29:52 +02:00
Matthias 39bf71680c test: Update test case description wording 2025-10-07 07:12:58 +02:00
Matthias 372cfeee33 fix: timeout exit count should consider remaining amount
closes #12343
2025-10-07 06:50:54 +02:00
Matthias ca4e4efeb8 test: Add test scenario for partially filled exit
* followed by exit_timeout_count
* shouldn't place order for the full amount

part of #12343
2025-10-07 06:48:35 +02:00
Matthias 4c9e608a1a chore: bump version to 2025.9.1 2025-10-07 06:33:59 +02:00
Matthias 90665731c1 fix: bitvavo is now using tick-size for pricing and amount rounding 2025-10-07 06:33:35 +02:00
Matthias 7a9ea40d72 chore: bump ccxt to 4.5.7 2025-10-07 06:33:27 +02:00
Matthias 96c65dacdd Merge pull request #12345 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-10-07 06:27:24 +02:00
Freqtrade Bot c46080f0b2 chore: update pre-commit hooks 2025-10-07 03:13:29 +00:00
Matthias cfd7d0a38b test: add ccxt parse test for kraken
part of #12326
2025-10-06 19:13:20 +02:00
Matthias 0df1650f2d Merge pull request #12338 from freqtrade/dependabot/pip/develop/pydantic-2.11.10
chore(deps): bump pydantic from 2.11.9 to 2.11.10
2025-10-06 08:17:06 +02:00
Matthias 8bba3081ab Merge pull request #12330 from freqtrade/dependabot/pip/develop/mkdocs-d51531eb39
chore(deps): bump mkdocs-material from 9.6.20 to 9.6.21 in the mkdocs group
2025-10-06 07:06:38 +02:00
Matthias d5f23bb5a8 Merge pull request #12336 from freqtrade/dependabot/pip/develop/certifi-2025.10.5
chore(deps): bump certifi from 2025.8.3 to 2025.10.5
2025-10-06 06:57:46 +02:00
Matthias b81df43132 Merge pull request #12332 from freqtrade/dependabot/github_actions/develop/peter-evans/dockerhub-description-5.0.0
chore(deps): bump peter-evans/dockerhub-description from 4.0.2 to 5.0.0
2025-10-06 06:52:28 +02:00
Matthias c5f303f0c4 Merge pull request #12339 from freqtrade/dependabot/pip/develop/pandas-2.3.3
chore(deps): bump pandas from 2.3.2 to 2.3.3
2025-10-06 06:51:51 +02:00
Matthias 3a51db79c9 docs: update open-source spelling to open source
based on https://opensource.org/blog/is-open-source-ever-hyphenated
2025-10-06 06:38:18 +02:00
dependabot[bot] bda9606ae3 chore(deps): bump pydantic from 2.11.9 to 2.11.10
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.9 to 2.11.10.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v2.11.10/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.11.9...v2.11.10)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.11.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 04:34:03 +00:00
Matthias b59e208468 Merge pull request #12341 from freqtrade/dependabot/pip/develop/isort-6.1.0
chore(deps-dev): bump isort from 6.0.1 to 6.1.0
2025-10-06 06:30:41 +02:00
dependabot[bot] 6b6f0a1d87 chore(deps): bump pandas from 2.3.2 to 2.3.3
Bumps [pandas](https://github.com/pandas-dev/pandas) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Commits](https://github.com/pandas-dev/pandas/compare/v2.3.2...v2.3.3)

---
updated-dependencies:
- dependency-name: pandas
  dependency-version: 2.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 04:30:26 +00:00
Matthias 5676dd89af Merge pull request #12337 from freqtrade/dependabot/pip/develop/cryptography-46.0.2
chore(deps): bump cryptography from 46.0.1 to 46.0.2
2025-10-06 06:30:25 +02:00
Matthias 3ec26e169e Merge pull request #12340 from freqtrade/dependabot/pip/develop/ruff-0.13.3
chore(deps-dev): bump ruff from 0.13.2 to 0.13.3
2025-10-06 06:29:25 +02:00
Matthias 2115af3857 Merge pull request #12342 from freqtrade/dependabot/pip/develop/plotly-6.3.1
chore(deps): bump plotly from 6.3.0 to 6.3.1
2025-10-06 06:29:07 +02:00
Matthias ed3f619db6 Merge pull request #12335 from freqtrade/dependabot/pip/develop/numexpr-2.13.1
chore(deps): bump numexpr from 2.13.0 to 2.13.1
2025-10-06 06:28:52 +02:00
Matthias e58f42de21 Merge pull request #12334 from freqtrade/dependabot/pip/develop/fastapi-0.118.0
chore(deps): bump fastapi from 0.117.1 to 0.118.0
2025-10-06 06:28:35 +02:00
Matthias 0f26fe4bc9 Merge pull request #12333 from freqtrade/dependabot/github_actions/develop/docker/login-action-3.6.0
chore(deps): bump docker/login-action from 3.5.0 to 3.6.0
2025-10-06 06:27:53 +02:00
Matthias 69a715dff1 Merge pull request #12331 from freqtrade/dependabot/github_actions/develop/astral-sh/setup-uv-6.8.0
chore(deps): bump astral-sh/setup-uv from 6.7.0 to 6.8.0
2025-10-06 06:27:36 +02:00
dependabot[bot] dba758b5e4 chore(deps): bump plotly from 6.3.0 to 6.3.1
Bumps [plotly](https://github.com/plotly/plotly.py) from 6.3.0 to 6.3.1.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/main/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v6.3.0...v6.3.1)

---
updated-dependencies:
- dependency-name: plotly
  dependency-version: 6.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:03:03 +00:00
dependabot[bot] d6218892bf chore(deps-dev): bump isort from 6.0.1 to 6.1.0
Bumps [isort](https://github.com/PyCQA/isort) from 6.0.1 to 6.1.0.
- [Release notes](https://github.com/PyCQA/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PyCQA/isort/compare/6.0.1...6.1.0)

---
updated-dependencies:
- dependency-name: isort
  dependency-version: 6.1.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:02:55 +00:00
dependabot[bot] 4608279305 chore(deps-dev): bump ruff from 0.13.2 to 0.13.3
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.13.2 to 0.13.3.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.13.2...0.13.3)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.13.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:02:49 +00:00
dependabot[bot] bbd7a19ef9 chore(deps): bump cryptography from 46.0.1 to 46.0.2
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.1 to 46.0.2.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/46.0.1...46.0.2)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 46.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:02:24 +00:00
dependabot[bot] 9a95ad1435 chore(deps): bump certifi from 2025.8.3 to 2025.10.5
Bumps [certifi](https://github.com/certifi/python-certifi) from 2025.8.3 to 2025.10.5.
- [Commits](https://github.com/certifi/python-certifi/compare/2025.08.03...2025.10.05)

---
updated-dependencies:
- dependency-name: certifi
  dependency-version: 2025.10.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:02:19 +00:00
dependabot[bot] 5bd42d5625 chore(deps): bump numexpr from 2.13.0 to 2.13.1
Bumps [numexpr](https://github.com/pydata/numexpr) from 2.13.0 to 2.13.1.
- [Release notes](https://github.com/pydata/numexpr/releases)
- [Changelog](https://github.com/pydata/numexpr/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/pydata/numexpr/compare/v2.13.0...v2.13.1)

---
updated-dependencies:
- dependency-name: numexpr
  dependency-version: 2.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:02:07 +00:00
dependabot[bot] 0c446d45df chore(deps): bump fastapi from 0.117.1 to 0.118.0
Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.117.1 to 0.118.0.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](https://github.com/fastapi/fastapi/compare/0.117.1...0.118.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.118.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:02:01 +00:00
dependabot[bot] 2bfc8d86a9 chore(deps): bump docker/login-action from 3.5.0 to 3.6.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/184bdaa0721073962dff0199f1fb9940f07167d1...5e57cd118135c172c3672efd75eb46360885c0ef)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:01:53 +00:00
dependabot[bot] 98ab14f67e chore(deps): bump peter-evans/dockerhub-description from 4.0.2 to 5.0.0
Bumps [peter-evans/dockerhub-description](https://github.com/peter-evans/dockerhub-description) from 4.0.2 to 5.0.0.
- [Release notes](https://github.com/peter-evans/dockerhub-description/releases)
- [Commits](https://github.com/peter-evans/dockerhub-description/compare/432a30c9e07499fd01da9f8a49f0faf9e0ca5b77...1b9a80c056b620d92cedb9d9b5a223409c68ddfa)

---
updated-dependencies:
- dependency-name: peter-evans/dockerhub-description
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:01:48 +00:00
dependabot[bot] 845e96f12e chore(deps): bump astral-sh/setup-uv from 6.7.0 to 6.8.0
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.7.0 to 6.8.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/b75a909f75acd358c2196fb9a5f1299a9a8868a4...d0cc045d04ccac9d8b7881df0226f9e82c39688e)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 6.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:01:45 +00:00
dependabot[bot] 1ad75f5ec5 chore(deps): bump mkdocs-material in the mkdocs group
Bumps the mkdocs group with 1 update: [mkdocs-material](https://github.com/squidfunk/mkdocs-material).


Updates `mkdocs-material` from 9.6.20 to 9.6.21
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.20...9.6.21)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.6.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: mkdocs
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 03:01:44 +00:00
Matthias 89b6e69340 Merge pull request #12311 from freqtrade/fix/allow-override
fix: Allow users to override the exchange check for FreqAI incase the…
2025-10-05 08:09:28 +02:00
Matthias 2d40807b66 chore: fix description typo 2025-10-05 07:56:42 +02:00
Matthias 8e44bc48b8 docs: update IOC documentation
related: #12322
2025-10-04 11:45:09 +02:00
Matthias 082fd0fd8b fix: "taker" may not always be filled for futures pairs
Gate fee removal:  https://github.com/ccxt/ccxt/pull/14271
2025-10-03 18:25:13 +02:00
Matthias 9e4af4f8ad Merge pull request #12321 from stash86/main-stash
fix typo
2025-10-03 18:02:05 +02:00
Stefano 0740f87a32 fix typo 2025-10-03 15:38:19 +09:00
Matthias 5542febef6 Merge pull request #12309 from freqtrade/feat/hyperliquid_cross
hyperliquid cross futures support
2025-10-02 18:06:47 +02:00
Matthias 4eba2c6a24 fix: bitvavo is now using tick-size for pricing and amount rounding 2025-10-02 07:20:30 +02:00
Matthias e654c29c82 chore: bump ccxt to 4.5.7 2025-10-02 07:20:30 +02:00
Matthias 0bcd6e078b Merge pull request #12316 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-10-02 06:39:42 +02:00
Freqtrade Bot 4698c0a066 chore: update pre-commit hooks 2025-10-02 03:12:18 +00:00
Robert Caulk 70fa12f1b2 chore: log a warning that the user is in territory that might not work. 2025-10-01 16:36:55 +02:00
Robert Caulk 8d86cc1173 fix: Allow users to override the exchange check for FreqAI incase they know that they dont need historic data for their system 2025-10-01 16:34:10 +02:00
Matthias c7aaa77e44 test: test cross margin calc for hyperliquid 2025-09-30 20:39:40 +02:00
Matthias 1e8252ffcc test: simplify hyperliquid test 2025-09-30 20:33:13 +02:00
Matthias 361b34641c chore: simplify hyperliquid dry-run calc 2025-09-30 20:33:03 +02:00
Matthias 88c0c3503f docs: Add cross margin warning note 2025-09-30 19:50:50 +02:00
Matthias 102fc3e184 test: add basic online tests for coinex exchange 2025-09-30 19:23:02 +02:00
Matthias abd02979dd feat: add coinex subclass
closes #12306
2025-09-30 19:22:52 +02:00
Matthias f6c4227ca6 feat: Add documentation to hyperliquid liquidation calc 2025-09-30 07:05:32 +02:00
Matthias d6bc8f4a24 docs: enable hyperliquid cross 2025-09-30 06:47:09 +02:00
Matthias a9c3799547 feat: enable hyperliquid cross futures 2025-09-30 06:34:05 +02:00
Matthias 3ea4603d1c Merge pull request #12305 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-09-30 06:26:21 +02:00
Freqtrade Bot 84dfb035b1 chore: update pre-commit hooks 2025-09-30 03:14:01 +00:00
Matthias aacd8f49f4 chore: bump develop version to 2025.10-dev 2025-09-29 19:36:39 +02:00
Matthias c66e221012 Merge pull request #12304 from freqtrade/new_release
New release 2025.9
2025-09-29 19:33:25 +02:00
Matthias f38d2466df chore: bump version to 2025.9 2025-09-29 18:18:46 +02:00
Matthias 1cc92c645a Merge branch 'stable' into new_release 2025-09-29 18:18:35 +02:00
Matthias ab764df411 chore(deps): bump ft-pandas-ta from 0.3.15 to 0.3.16 2025-09-29 18:16:35 +02:00
Matthias 5363ee7198 chore(deps): bump ft-pandas-ta from 0.3.15 to 0.3.16 2025-09-29 18:16:03 +02:00
Matthias 4b78ba42b1 Merge pull request #12302 from freqtrade/dependabot/pip/develop/ccxt-4.5.6
chore(deps): bump ccxt from 4.5.5 to 4.5.6
2025-09-29 06:32:55 +02:00
dependabot[bot] 567f118ce1 chore(deps): bump ccxt from 4.5.5 to 4.5.6
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.5 to 4.5.6.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/v4.5.5...v4.5.6)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-version: 4.5.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 04:32:53 +00:00
Matthias 230e892482 Merge pull request #12298 from freqtrade/dependabot/pip/develop/uvicorn-0.37.0
chore(deps): bump uvicorn from 0.36.0 to 0.37.0
2025-09-29 06:32:02 +02:00
Matthias 9e616e81ad Merge pull request #12303 from freqtrade/dependabot/pip/develop/python-telegram-bot-22.5
chore(deps): bump python-telegram-bot from 22.4 to 22.5
2025-09-29 06:31:39 +02:00
Matthias d1e055c015 Merge pull request #12301 from freqtrade/dependabot/pip/develop/ruff-0.13.2
chore(deps-dev): bump ruff from 0.13.1 to 0.13.2
2025-09-29 06:30:26 +02:00
Matthias 3bcd6694b7 Merge pull request #12300 from freqtrade/dependabot/pip/develop/numexpr-2.13.0
chore(deps): bump numexpr from 2.12.1 to 2.13.0
2025-09-29 06:30:18 +02:00
dependabot[bot] 86d8fc5ee3 chore(deps): bump python-telegram-bot from 22.4 to 22.5
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 22.4 to 22.5.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v22.4...v22.5)

---
updated-dependencies:
- dependency-name: python-telegram-bot
  dependency-version: '22.5'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 03:17:24 +00:00
dependabot[bot] 78f291264e chore(deps-dev): bump ruff from 0.13.1 to 0.13.2
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.13.1 to 0.13.2.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.13.1...0.13.2)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.13.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 03:13:53 +00:00
dependabot[bot] fdc3c7ba09 chore(deps): bump numexpr from 2.12.1 to 2.13.0
Bumps [numexpr](https://github.com/pydata/numexpr) from 2.12.1 to 2.13.0.
- [Release notes](https://github.com/pydata/numexpr/releases)
- [Changelog](https://github.com/pydata/numexpr/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/pydata/numexpr/compare/v2.12.1...v2.13.0)

---
updated-dependencies:
- dependency-name: numexpr
  dependency-version: 2.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 03:12:41 +00:00
dependabot[bot] f8621e850f chore(deps): bump uvicorn from 0.36.0 to 0.37.0
Bumps [uvicorn](https://github.com/Kludex/uvicorn) from 0.36.0 to 0.37.0.
- [Release notes](https://github.com/Kludex/uvicorn/releases)
- [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md)
- [Commits](https://github.com/Kludex/uvicorn/compare/0.36.0...0.37.0)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 03:11:27 +00:00
Matthias 87c5f89b6c fix: ensure exportFilename is a path object 2025-09-28 11:36:46 +02:00
Matthias 780c794ef0 Merge pull request #12292 from freqtrade/maint/combine_ci
Combine CI definition
2025-09-27 18:23:39 +02:00
Matthias 8b4070dbcf chore(ci): parallel tests 2025-09-27 18:04:43 +02:00
Matthias 4e089fd17e chore(ci): split check between windows and linux 2025-09-27 17:23:16 +02:00
Matthias f454006ec3 chore(ci): combine windows ci into generic test runner 2025-09-27 16:51:10 +02:00
Matthias f5002929ee chore(ci): name some jobs properly 2025-09-27 16:03:00 +02:00
Matthias 4e1d75a3e1 chore(ci): improved job naming 2025-09-27 16:01:04 +02:00
Matthias d4462ba5d8 chore(ci): remove useless alias 2025-09-27 15:55:23 +02:00
Matthias 6dc71269a2 chore(ci): simplify actions by combining linux and macOS runs 2025-09-27 15:54:27 +02:00
Matthias 730ccba535 chore: fix return type 2025-09-27 15:28:14 +02:00
Matthias 1175721579 docs: use exchange features include 2025-09-27 13:11:04 +02:00
Matthias e5157d5471 docs: enhance exchange-features table 2025-09-27 13:10:18 +02:00
Matthias 7fcb23e0c7 docs: add exchange overview 2025-09-27 13:02:04 +02:00
Matthias f075d90d99 chore: slight refactor in ft_has initialization 2025-09-27 12:14:34 +02:00
Matthias bf94748058 docs: update showcase, update outdated link 2025-09-27 08:58:36 +02:00
Matthias 2890d13d92 feat: Improve styling of list-exchanges table 2025-09-27 08:54:25 +02:00
Matthias 9232778732 docs: add support policy to FAQ 2025-09-27 08:48:56 +02:00
Matthias 70a25f9837 Merge pull request #12259 from stash86/delist
Implement delisting check on futures market
2025-09-26 07:14:01 +02:00
Matthias 4434df1999 docs: improve doc wording 2025-09-26 06:59:22 +02:00
Matthias b9e9f6f040 refactor: indicate private methods by convention 2025-09-26 06:47:36 +02:00
Matthias f92caf0f1f chore: add response sample to private endpoint 2025-09-26 06:44:10 +02:00
Matthias 55b90917e4 docs: Improve documentation clarity 2025-09-26 06:38:02 +02:00
Matthias d0546e998a chore: further restructuring to contributing guide 2025-09-25 19:21:13 +02:00
Matthias e9f414b29c chore: improve contributing wording 2025-09-25 19:17:48 +02:00
Matthias 7638261e8f chore: update contributing documentation 2025-09-25 19:10:41 +02:00
Matthias a049d6eab1 feat: add magin_mode to show_config response 2025-09-25 07:20:27 +02:00
Matthias 61f46b959e Merge pull request #12286 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-09-25 06:42:43 +02:00
Stefano ccb1e4af02 Merge branch 'freqtrade:develop' into delist 2025-09-25 12:27:21 +09:00
Freqtrade Bot 06424cae28 chore: update pre-commit hooks 2025-09-25 03:15:49 +00:00
Matthias 9aeb2eaabd feat: add z-level to annotations 2025-09-24 18:13:42 +02:00
Matthias c6061daec4 test: rename tests to match scheme 2025-09-23 20:17:36 +02:00
Matthias 5be0352705 test: add binance spot-delist test 2025-09-23 20:17:30 +02:00
Matthias 06995f26fd chore: improve reliability of binance spot delisting 2025-09-23 20:16:49 +02:00
Matthias 7b45844670 test: ensure non-unified ccxt method ain't going away. 2025-09-23 19:57:43 +02:00
Matthias 0a0c2adf7d chore: capture missing exception 2025-09-23 19:55:18 +02:00
Matthias 7aab3b34d6 test: add more tests for delist exchange code 2025-09-23 19:55:11 +02:00
Matthias c4aa221c9b Merge pull request #12276 from freqtrade/dependabot/pip/develop/mypy-1.18.2
chore(deps-dev): bump mypy from 1.18.1 to 1.18.2
2025-09-23 06:36:42 +02:00
dependabot[bot] da12071d8f chore(deps-dev): bump mypy from 1.18.1 to 1.18.2
Bumps [mypy](https://github.com/python/mypy) from 1.18.1 to 1.18.2.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.18.1...v1.18.2)

---
updated-dependencies:
- dependency-name: mypy
  dependency-version: 1.18.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-23 06:16:26 +02:00
Matthias 581a9bb1c9 Merge pull request #12274 from freqtrade/dependabot/pip/develop/cryptography-46.0.1
chore(deps): bump cryptography from 45.0.7 to 46.0.1
2025-09-23 06:15:46 +02:00
Matthias f5258510cc Merge pull request #12283 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-09-23 06:14:51 +02:00
Freqtrade Bot 99401f9d69 chore: update pre-commit hooks 2025-09-23 03:13:37 +00:00
mrpabloyeah c1cd14cad2 Remove internal or useless attributes and unnecessary text 2025-09-23 01:01:36 +02:00
dependabot[bot] 729bea2d8e chore(deps): bump cryptography from 45.0.7 to 46.0.1
Bumps [cryptography](https://github.com/pyca/cryptography) from 45.0.7 to 46.0.1.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/45.0.7...46.0.1)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 46.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 20:21:39 +02:00
Matthias 8b72e4f23e chore: fix line-lengths 2025-09-22 20:16:46 +02:00
Matthias 17202c6d29 test: add test for DelistFilter 2025-09-22 19:59:12 +02:00
Matthias 567d4331fd test: initial delistFilter tests 2025-09-22 19:44:03 +02:00
mrpabloyeah 565b343dee Update documentation for Trade and Order objects 2025-09-22 19:38:49 +02:00
Matthias 92c9f443e8 test: add test for dp.check_delisting 2025-09-22 19:30:19 +02:00
Matthias dd2d7bb863 docs: slightly restructure documentation 2025-09-22 19:22:22 +02:00
Stefano 9c0d612729 add example, make sure to raise error on unsupported exchanges and/or trading mode 2025-09-22 15:55:36 +09:00
Stefano 07d5636d1e Merge branch 'freqtrade:develop' into delist 2025-09-22 13:38:03 +09:00
Matthias 977cabb580 Merge pull request #12272 from freqtrade/dependabot/pip/develop/fastapi-0.117.1
chore(deps): bump fastapi from 0.116.1 to 0.117.1
2025-09-22 06:30:46 +02:00
Matthias 15a7e1d9d1 Merge pull request #12278 from freqtrade/dependabot/pip/develop/psutil-7.1.0
chore(deps): bump psutil from 7.0.0 to 7.1.0
2025-09-22 06:29:54 +02:00
Matthias 953ffcf204 Merge pull request #12277 from freqtrade/dependabot/pip/develop/uvicorn-0.36.0
chore(deps): bump uvicorn from 0.35.0 to 0.36.0
2025-09-22 06:29:31 +02:00
Matthias b24e6e72c7 Merge pull request #12273 from freqtrade/dependabot/pip/develop/ccxt-4.5.5
chore(deps): bump ccxt from 4.5.4 to 4.5.5
2025-09-22 06:28:45 +02:00
Matthias 82b05f6b5a Merge pull request #12271 from freqtrade/dependabot/pip/develop/mkdocs-aa22fc2ea5
chore(deps): bump mkdocs-material from 9.6.19 to 9.6.20 in the mkdocs group
2025-09-22 06:28:33 +02:00
Matthias a662802011 Merge pull request #12275 from freqtrade/dependabot/pip/develop/ruff-0.13.1
chore(deps-dev): bump ruff from 0.13.0 to 0.13.1
2025-09-22 06:28:14 +02:00
Matthias 5483ade786 Merge pull request #12270 from freqtrade/dependabot/pip/develop/pytest-8796ca11bd
chore(deps-dev): bump pytest-mock from 3.15.0 to 3.15.1 in the pytest group
2025-09-22 06:27:53 +02:00
dependabot[bot] ae02a7007b chore(deps): bump psutil from 7.0.0 to 7.1.0
Bumps [psutil](https://github.com/giampaolo/psutil) from 7.0.0 to 7.1.0.
- [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst)
- [Commits](https://github.com/giampaolo/psutil/compare/release-7.0.0...release-7.1.0)

---
updated-dependencies:
- dependency-name: psutil
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 03:02:47 +00:00
dependabot[bot] 3c6e058b00 chore(deps): bump uvicorn from 0.35.0 to 0.36.0
Bumps [uvicorn](https://github.com/Kludex/uvicorn) from 0.35.0 to 0.36.0.
- [Release notes](https://github.com/Kludex/uvicorn/releases)
- [Changelog](https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md)
- [Commits](https://github.com/Kludex/uvicorn/compare/0.35.0...0.36.0)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 03:02:44 +00:00
dependabot[bot] ad3ddcaadb chore(deps-dev): bump ruff from 0.13.0 to 0.13.1
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.13.0 to 0.13.1.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.13.0...0.13.1)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.13.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 03:02:23 +00:00
dependabot[bot] be56052417 chore(deps): bump ccxt from 4.5.4 to 4.5.5
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.4 to 4.5.5.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/v4.5.4...v4.5.5)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-version: 4.5.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 03:02:06 +00:00
dependabot[bot] 9a888d9896 chore(deps): bump fastapi from 0.116.1 to 0.117.1
Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.116.1 to 0.117.1.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](https://github.com/fastapi/fastapi/compare/0.116.1...0.117.1)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.117.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 03:01:51 +00:00
dependabot[bot] 24a7e585e4 chore(deps): bump mkdocs-material in the mkdocs group
Bumps the mkdocs group with 1 update: [mkdocs-material](https://github.com/squidfunk/mkdocs-material).


Updates `mkdocs-material` from 9.6.19 to 9.6.20
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.19...9.6.20)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.6.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: mkdocs
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 03:01:42 +00:00
dependabot[bot] 2120f1ed5b chore(deps-dev): bump pytest-mock in the pytest group
Bumps the pytest group with 1 update: [pytest-mock](https://github.com/pytest-dev/pytest-mock).


Updates `pytest-mock` from 3.15.0 to 3.15.1
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.15.0...v3.15.1)

---
updated-dependencies:
- dependency-name: pytest-mock
  dependency-version: 3.15.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 03:01:33 +00:00
Matthias 3a2bb22cb3 Merge pull request #12268 from freqtrade/maint/cache
changes to CI caching
2025-09-21 17:40:32 +02:00
Matthias a7c4ec6eaf chore: try without brew python fixes
Should work now since we're using UV...
2025-09-21 16:51:13 +02:00
Matthias f7b934b306 chore(ci): try to not prune uv cache 2025-09-21 16:21:32 +02:00
Matthias d34e7a1e8e chore: don't retry bootstrap indefinitely
better behavior is to stop after a couple  of attempts
2025-09-21 15:02:34 +02:00
Matthias 4804ec986a chore: cleanup unused (and now unsupported) comments 2025-09-21 15:02:24 +02:00
Matthias 16117e5b6c chore: remove obsolete todo 2025-09-20 20:23:43 +02:00
Matthias 985805e0d5 test: add test for order_book_to_dataframe 2025-09-20 20:23:23 +02:00
Matthias 78acaf8f4c Merge pull request #12214 from mrpabloyeah/fix-shufflefilter-behavior-in-backtesting
Fix ShuffleFilter behavior in backtesting
2025-09-19 20:36:37 +02:00
Matthias a1dad065b2 docs: enhance doc wording around pairlists 2025-09-19 20:32:01 +02:00
Matthias 3b03d4346c docs: enhance freqUI documentation page structure 2025-09-19 20:31:03 +02:00
Matthias c6551819cd chore: re-word help string 2025-09-19 20:23:36 +02:00
Matthias e58635a881 test: minor adjustments to new tests 2025-09-19 20:23:07 +02:00
Matthias 8e3331d0db chore: rename variable for clarity 2025-09-19 20:16:44 +02:00
Matthias 8391a0612d chore: use ccxt's "set_markets_from_exchange" instead of manual logic 2025-09-18 07:11:55 +02:00
Matthias 68c00d1c4d chore: bump ccxt min-version requirement
this will allow us to use new features
e.g. `.set_markets_from_exchange()`
2025-09-18 07:11:55 +02:00
Matthias f48f24ce2e Merge pull request #12263 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-09-18 06:29:06 +02:00
Freqtrade Bot 9d5a88416a chore: update pre-commit hooks 2025-09-18 03:12:21 +00:00
Stefano a314786056 Merge branch 'delist' of https://github.com/stash86/freqtrade into delist 2025-09-17 13:38:14 +09:00
Stefano aee9b2c749 remove lock 2025-09-17 13:38:09 +09:00
Stefano 3fffee3b05 Merge branch 'freqtrade:develop' into delist 2025-09-17 11:55:26 +09:00
Stefano 72abae7b94 disable delisting check on non-trading mode 2025-09-17 11:38:28 +09:00
Stefano a300df7ff3 fix precommit 2025-09-17 09:22:21 +09:00
Stefano 8e500d4601 add DelistFilter 2025-09-17 09:16:05 +09:00
Matthias f6e1442fdf Merge pull request #12257 from stash86/main-stash
Update API docs
2025-09-16 21:26:44 +02:00
Stefano d8d8260d76 remove logger 2025-09-16 16:11:23 +09:00
Stefano 72dd0d062b add spot check for binance 2025-09-16 15:52:19 +09:00
Stefano 03c67d6a3b switch to use dataprovider to give flexibility to users 2025-09-16 14:59:44 +09:00
Matthias 314cd10e27 Merge pull request #12260 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-09-16 06:28:36 +02:00
Freqtrade Bot 6e6a929fac chore: update pre-commit hooks 2025-09-16 03:12:05 +00:00
Stefano d069f5477e add delisted pair to blacklist 2025-09-16 11:06:34 +09:00
Stefano a4a5fbe4a8 add column name for bybit and okx 2025-09-16 10:53:00 +09:00
Stefano 01e288297a fix precommit 2025-09-16 09:33:48 +09:00
Stefano 7564b1e6df remove extra log, fix delivery time check for binance 2025-09-16 09:23:20 +09:00
Stefano cf010c3f17 initial concept 2025-09-16 08:54:47 +09:00
Stefano 5ff95db9e1 move the example of blacklist to Programmatic Use card 2025-09-16 08:17:35 +09:00
Matthias ada72d2264 Merge pull request #12247 from freqtrade/dependabot/pip/develop/ruff-0.13.0
chore(deps-dev): bump ruff from 0.12.12 to 0.13.0
2025-09-15 20:21:40 +02:00
Matthias 9f436dcd1e chore: fix RUF043 violations 2025-09-15 19:20:20 +02:00
Matthias 95a710d4a8 chore: fix RUF059 violations 2025-09-15 19:15:43 +02:00
Matthias bf5d300a54 Merge pull request #12248 from freqtrade/dependabot/pip/develop/pydantic-2.11.9
chore(deps): bump pydantic from 2.11.7 to 2.11.9
2025-09-15 11:45:52 +02:00
Matthias f7a1325339 Merge pull request #12246 from freqtrade/dependabot/pip/develop/scipy-26573e6263
chore(deps): bump the scipy group with 2 updates
2025-09-15 11:29:03 +02:00
Stefano e13152715c Merge branch 'freqtrade:develop' into main-stash 2025-09-15 17:32:04 +09:00
Stefano 19a35ed111 add examples on API docs. Fix some params name 2025-09-15 17:29:33 +09:00
Matthias e62ba8ed1e chore: update scipy-stubs in pre-commit 2025-09-15 08:52:49 +02:00
Matthias f62ded94bb Merge pull request #12251 from freqtrade/dependabot/pip/develop/numpy-2.3.3
chore(deps): bump numpy from 2.3.2 to 2.3.3
2025-09-15 08:27:25 +02:00
dependabot[bot] 74f459d7ed chore(deps): bump numpy from 2.3.2 to 2.3.3
Bumps [numpy](https://github.com/numpy/numpy) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v2.3.2...v2.3.3)

---
updated-dependencies:
- dependency-name: numpy
  dependency-version: 2.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 05:59:20 +00:00
dependabot[bot] 815a351435 chore(deps): bump the scipy group with 2 updates
Bumps the scipy group with 2 updates: [scipy](https://github.com/scipy/scipy) and [scipy-stubs](https://github.com/scipy/scipy-stubs).


Updates `scipy` from 1.16.1 to 1.16.2
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.16.1...v1.16.2)

Updates `scipy-stubs` from 1.16.1.1 to 1.16.2.0
- [Release notes](https://github.com/scipy/scipy-stubs/releases)
- [Commits](https://github.com/scipy/scipy-stubs/compare/v1.16.1.1...v1.16.2.0)

---
updated-dependencies:
- dependency-name: scipy
  dependency-version: 1.16.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: scipy
- dependency-name: scipy-stubs
  dependency-version: 1.16.2.0
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: scipy
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 05:59:02 +00:00
Matthias 9857f30703 Merge pull request #12252 from freqtrade/dependabot/pip/develop/numexpr-2.12.1
chore(deps): bump numexpr from 2.11.0 to 2.12.1
2025-09-15 07:58:08 +02:00
Matthias a7de2cf682 Merge pull request #12242 from freqtrade/dependabot/pip/develop/types-91b7a93ceb
chore(deps-dev): bump types-requests from 2.32.4.20250809 to 2.32.4.20250913 in the types group
2025-09-15 07:57:40 +02:00
dependabot[bot] 5e2f4924d6 chore(deps-dev): bump ruff from 0.12.12 to 0.13.0
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.12.12 to 0.13.0.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.12.12...0.13.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.13.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 05:48:27 +00:00
Matthias b74a334f25 Merge pull request #12250 from freqtrade/dependabot/pip/develop/mypy-1.18.1
chore(deps-dev): bump mypy from 1.17.1 to 1.18.1
2025-09-15 07:43:37 +02:00
Matthias 58c9a61cf0 Merge pull request #12253 from freqtrade/dependabot/pip/develop/scikit-learn-1.7.2
chore(deps): bump scikit-learn from 1.7.1 to 1.7.2
2025-09-15 07:18:23 +02:00
Matthias d5620cf8b5 chore: bump types-requests in pre-commit config 2025-09-15 07:12:06 +02:00
Matthias 2e50c100f9 Merge pull request #12254 from freqtrade/dependabot/pip/develop/python-telegram-bot-22.4
chore(deps): bump python-telegram-bot from 22.3 to 22.4
2025-09-15 07:00:27 +02:00
dependabot[bot] 776d9ac5e0 chore(deps): bump numexpr from 2.11.0 to 2.12.1
Bumps [numexpr](https://github.com/pydata/numexpr) from 2.11.0 to 2.12.1.
- [Release notes](https://github.com/pydata/numexpr/releases)
- [Changelog](https://github.com/pydata/numexpr/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/pydata/numexpr/compare/v2.11.0...v2.12.1)

---
updated-dependencies:
- dependency-name: numexpr
  dependency-version: 2.12.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 05:00:16 +00:00
Matthias 301e348789 Merge pull request #12243 from freqtrade/dependabot/github_actions/develop/astral-sh/setup-uv-6.7.0
chore(deps): bump astral-sh/setup-uv from 6.6.1 to 6.7.0
2025-09-15 06:59:54 +02:00
Matthias 6467d85059 Merge pull request #12244 from freqtrade/dependabot/github_actions/develop/zizmorcore/zizmor-action-0.2.0
chore(deps): bump zizmorcore/zizmor-action from 0.1.2 to 0.2.0
2025-09-15 06:59:15 +02:00
dependabot[bot] 4b4d090d39 chore(deps-dev): bump mypy from 1.17.1 to 1.18.1
Bumps [mypy](https://github.com/python/mypy) from 1.17.1 to 1.18.1.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.17.1...v1.18.1)

---
updated-dependencies:
- dependency-name: mypy
  dependency-version: 1.18.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 04:56:25 +00:00
Matthias 2ddafa28f2 Merge pull request #12249 from freqtrade/dependabot/pip/develop/bottleneck-1.6.0
chore(deps): bump bottleneck from 1.5.0 to 1.6.0
2025-09-15 06:56:10 +02:00
Matthias d6bb47816c Merge pull request #12256 from freqtrade/dependabot/pip/develop/ccxt-4.5.4
chore(deps): bump ccxt from 4.5.3 to 4.5.4
2025-09-15 06:55:30 +02:00
Matthias f40d90cf08 Merge pull request #12245 from freqtrade/dependabot/pip/develop/pytest-b85b31bc10
chore(deps-dev): bump the pytest group with 2 updates
2025-09-15 06:54:51 +02:00
dependabot[bot] ab7c1ec24f chore(deps): bump ccxt from 4.5.3 to 4.5.4
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/v4.5.3...v4.5.4)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-version: 4.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:54:21 +00:00
dependabot[bot] be5969a1e1 chore(deps): bump python-telegram-bot from 22.3 to 22.4
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 22.3 to 22.4.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v22.3...v22.4)

---
updated-dependencies:
- dependency-name: python-telegram-bot
  dependency-version: '22.4'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:03:48 +00:00
dependabot[bot] 992d173adc chore(deps): bump scikit-learn from 1.7.1 to 1.7.2
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 1.7.1 to 1.7.2.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/1.7.1...1.7.2)

---
updated-dependencies:
- dependency-name: scikit-learn
  dependency-version: 1.7.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:03:41 +00:00
dependabot[bot] 5396519b20 chore(deps): bump bottleneck from 1.5.0 to 1.6.0
Bumps [bottleneck](https://github.com/pydata/bottleneck) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/pydata/bottleneck/releases)
- [Changelog](https://github.com/pydata/bottleneck/blob/master/RELEASE.rst)
- [Commits](https://github.com/pydata/bottleneck/compare/v1.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: bottleneck
  dependency-version: 1.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:02:30 +00:00
dependabot[bot] d8122f5d33 chore(deps): bump pydantic from 2.11.7 to 2.11.9
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.7 to 2.11.9.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v2.11.9/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.11.7...v2.11.9)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.11.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:02:26 +00:00
dependabot[bot] 92f8b2dd02 chore(deps-dev): bump the pytest group with 2 updates
Bumps the pytest group with 2 updates: [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) and [pytest-cov](https://github.com/pytest-dev/pytest-cov).


Updates `pytest-asyncio` from 1.1.0 to 1.2.0
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v1.1.0...v1.2.0)

Updates `pytest-cov` from 6.3.0 to 7.0.0
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v6.3.0...v7.0.0)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-version: 1.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: pytest
- dependency-name: pytest-cov
  dependency-version: 7.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:01:47 +00:00
dependabot[bot] 29e35cf824 chore(deps): bump zizmorcore/zizmor-action from 0.1.2 to 0.2.0
Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.1.2 to 0.2.0.
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](https://github.com/zizmorcore/zizmor-action/compare/5ca5fc7a4779c5263a3ffa0e1f693009994446d1...e673c3917a1aef3c65c972347ed84ccd013ecda4)

---
updated-dependencies:
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:01:45 +00:00
dependabot[bot] 26ff88c71a chore(deps): bump astral-sh/setup-uv from 6.6.1 to 6.7.0
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.6.1 to 6.7.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/557e51de59eb14aaaba2ed9621916900a91d50c6...b75a909f75acd358c2196fb9a5f1299a9a8868a4)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 6.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:01:42 +00:00
dependabot[bot] 7b3951f1e5 chore(deps-dev): bump types-requests in the types group
Bumps the types group with 1 update: [types-requests](https://github.com/typeshed-internal/stub_uploader).


Updates `types-requests` from 2.32.4.20250809 to 2.32.4.20250913
- [Commits](https://github.com/typeshed-internal/stub_uploader/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-version: 2.32.4.20250913
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: types
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 03:01:24 +00:00
mrpabloyeah 5dbfc92c5a Add --enable-dynamic-pairlist option in backtesting 2025-09-14 13:58:53 +02:00
Matthias 0ca846b2c5 test: update test comment 2025-09-14 10:34:11 +02:00
Matthias 747eac0417 chore: update code to use at
which has better performance than chaining iloc and column selection
2025-09-14 10:33:43 +02:00
Matthias 88cc24c5b9 chore: fix odd code comment 2025-09-14 10:33:28 +02:00
Matthias 0111e97856 test: update test 2025-09-14 10:33:09 +02:00
Matthias a14281722a chore: remove no longer necessary TODO comments 2025-09-14 10:12:59 +02:00
Matthias a80f3ae919 fix: re-add candle_type_def to configuration
Temporary fix for now ...
closes #12239
2025-09-13 13:59:25 +02:00
mrpabloyeah 5f558137d3 Add cache for expanded_blacklist() in PairListManager in backtest mode 2025-09-12 13:01:50 +02:00
Matthias ecd66f8a64 fix: backtesting through UI not working consecutive times
closes #12239
2025-09-11 20:14:12 +02:00
Matthias 8d965d4833 docs: Add link to storing custom data from order_filled
part of #12238
2025-09-11 19:29:23 +02:00
Matthias 25a3de653c Merge pull request #12237 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-09-11 06:31:23 +02:00
Freqtrade Bot ac519a273b chore: update pre-commit hooks 2025-09-11 03:14:58 +00:00
Matthias 68429f9c37 fix: improve wording for config overriding strategy values
closes #12212
2025-09-10 20:17:53 +02:00
Matthias 5cb41badc1 chore: don't log timeframe from cli twice
part of #12212
2025-09-10 20:16:21 +02:00
Matthias 54bebeabb7 Merge pull request #12229 from freqtrade/lookahead_analysis_12168
Lookahead analysis - fix false positives
2025-09-10 19:46:29 +02:00
Matthias 3a17c2b55c Merge pull request #12232 from stash86/main-stash
correctly handle pairlist that use wildcard
2025-09-10 06:51:22 +02:00
Stefano 7b7b8b8f8b correctly handle pairlist that use wildcard 2025-09-10 09:09:24 +09:00
mrpabloyeah 55201b6224 Fix: Hyperopt breaks when self.dynamic_pairlist is set to True 2025-09-09 20:17:14 +02:00
Matthias 49b9296cd9 test: Add futures to test matrix 2025-09-09 19:43:00 +02:00
Matthias 09fabd911e test: simplify and improve fetch_ohlcv test
Also adress okx mark oddity - which didn't show up before due to odd
test setup (using "" instead of "spot").
2025-09-09 19:42:17 +02:00
mrpabloyeah 43be752847 Do not verify the backlist if it is empty 2025-09-09 19:24:32 +02:00
Matthias 6cfd31c705 fix: "price" shouldn't be sent for regular futures candles 2025-09-09 19:18:28 +02:00
mrpabloyeah 3bce9278bd Add cache for gen_pairlist() in StaticPairList in backtest mode 2025-09-09 14:37:08 +02:00
Matthias 068caf159d test: update test for new okx candle limits 2025-09-09 07:12:03 +02:00
Matthias eb8875b64b feat: adjust okx ohlcv candle limits 2025-09-09 07:11:42 +02:00
Matthias 97578c0831 Merge pull request #12231 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-09-09 06:31:08 +02:00
Freqtrade Bot 7219f71bc1 chore: update pre-commit hooks 2025-09-09 03:15:50 +00:00
mrpabloyeah eea9133b3f test_time_pair_generator_open_trades_first() 2025-09-09 03:03:07 +02:00
mrpabloyeah a8f543ce62 Add test_time_pair_generator_refresh_pairlist() 2025-09-09 03:01:46 +02:00
Matthias b35172a3b8 chore: export lookahead command partial 2025-09-08 20:43:58 +02:00
Matthias 7b8f0583a4 test: add test for order_type force behavior 2025-09-08 20:02:09 +02:00
Matthias 7ae89711dd docs: update docs for lookahead analysis override 2025-09-08 19:52:38 +02:00
Matthias a2c3729254 feat: Override order types for lookahead analysis
this avoids false positives - but could cause false-negatives
if the problem is in a pricing callback.
`--allow-limit-orders` can re-allow limit orders to test for this scenario.

part of #12168
2025-09-08 19:52:15 +02:00
Matthias 14c9f783d5 refactor: Improve clarity of method name 2025-09-08 19:40:20 +02:00
Matthias 6c9c709c65 chore: use fstring in strategy helper 2025-09-08 19:37:46 +02:00
Matthias 1c2ffc6aaa chore: improve log message 2025-09-08 19:32:20 +02:00
Matthias a6d2bc5238 chore: fix docker armhf build 2025-09-08 19:12:27 +02:00
mrpabloyeah 737d2804d2 Fix spelling mistake 2025-09-08 17:47:33 +02:00
Matthias 3e14c2664e Merge pull request #12218 from freqtrade/dependabot/pip/develop/pytest-85bdb35c79
chore(deps-dev): bump the pytest group with 3 updates
2025-09-08 07:40:23 +02:00
Matthias 78bd8554aa Merge pull request #12221 from freqtrade/dependabot/pip/develop/ta-lib-0.6.7
chore(deps): bump ta-lib from 0.6.6 to 0.6.7
2025-09-08 07:39:43 +02:00
Matthias f1d5679fba Merge pull request #12223 from freqtrade/dependabot/pip/develop/cryptography-45.0.7
chore(deps): bump cryptography from 45.0.6 to 45.0.7
2025-09-08 07:30:47 +02:00
dependabot[bot] a9e82b7fc2 chore(deps-dev): bump the pytest group with 3 updates
Bumps the pytest group with 3 updates: [pytest](https://github.com/pytest-dev/pytest), [pytest-cov](https://github.com/pytest-dev/pytest-cov) and [pytest-mock](https://github.com/pytest-dev/pytest-mock).


Updates `pytest` from 8.4.1 to 8.4.2
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.4.1...8.4.2)

Updates `pytest-cov` from 6.2.1 to 6.3.0
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v6.2.1...v6.3.0)

Updates `pytest-mock` from 3.14.1 to 3.15.0
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.14.1...v3.15.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 8.4.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: pytest
- dependency-name: pytest-cov
  dependency-version: 6.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: pytest
- dependency-name: pytest-mock
  dependency-version: 3.15.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: pytest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 05:09:00 +00:00
dependabot[bot] 21f77f9c5d chore(deps): bump cryptography from 45.0.6 to 45.0.7
Bumps [cryptography](https://github.com/pyca/cryptography) from 45.0.6 to 45.0.7.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/45.0.6...45.0.7)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 45.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 05:05:45 +00:00
Matthias c4c0198d20 chore: Update ta-lib armhf wheel 2025-09-08 07:04:19 +02:00
dependabot[bot] d72d13ed58 chore(deps): bump ta-lib from 0.6.6 to 0.6.7
Bumps [ta-lib](https://github.com/ta-lib/ta-lib-python) from 0.6.6 to 0.6.7.
- [Release notes](https://github.com/ta-lib/ta-lib-python/releases)
- [Changelog](https://github.com/TA-Lib/ta-lib-python/blob/master/CHANGELOG)
- [Commits](https://github.com/ta-lib/ta-lib-python/compare/v0.6.6...v0.6.7)

---
updated-dependencies:
- dependency-name: ta-lib
  dependency-version: 0.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 05:01:16 +00:00
Matthias 5ea0705547 Merge pull request #12225 from freqtrade/dependabot/pip/develop/ruff-0.12.12
chore(deps-dev): bump ruff from 0.12.11 to 0.12.12
2025-09-08 06:55:33 +02:00
Matthias 575b50deda Merge pull request #12224 from freqtrade/dependabot/pip/develop/xgboost-3.0.5
chore(deps): bump xgboost from 3.0.4 to 3.0.5
2025-09-08 06:51:35 +02:00
Matthias a0d1a04605 Merge pull request #12219 from freqtrade/dependabot/pip/develop/mkdocs-9523af169b
chore(deps): bump mkdocs-material from 9.6.18 to 9.6.19 in the mkdocs group
2025-09-08 06:51:14 +02:00
Matthias aa4704e37d Merge pull request #12220 from freqtrade/dependabot/pip/develop/markdown-3.9
chore(deps): bump markdown from 3.8.2 to 3.9
2025-09-08 06:51:00 +02:00
Matthias 4143a2559a Merge pull request #12215 from freqtrade/dependabot/github_actions/develop/astral-sh/setup-uv-6.6.1
chore(deps): bump astral-sh/setup-uv from 6.6.0 to 6.6.1
2025-09-08 06:50:35 +02:00
Matthias 693a8fa979 Merge pull request #12217 from freqtrade/dependabot/github_actions/develop/actions/setup-python-6
chore(deps): bump actions/setup-python from 5 to 6
2025-09-08 06:50:12 +02:00
Matthias 6ec639d347 Merge pull request #12216 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.13.0
chore(deps): bump pypa/gh-action-pypi-publish from 1.12.4 to 1.13.0
2025-09-08 06:49:56 +02:00
Matthias 52d5d35afb Merge pull request #12222 from freqtrade/dependabot/pip/develop/ccxt-4.5.3
chore(deps): bump ccxt from 4.5.2 to 4.5.3
2025-09-08 06:47:36 +02:00
dependabot[bot] 8a21cc6d18 chore(deps-dev): bump ruff from 0.12.11 to 0.12.12
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.12.11 to 0.12.12.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.12.11...0.12.12)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.12.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:02:47 +00:00
dependabot[bot] b6bedf20ce chore(deps): bump xgboost from 3.0.4 to 3.0.5
Bumps [xgboost](https://github.com/dmlc/xgboost) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/dmlc/xgboost/releases)
- [Changelog](https://github.com/dmlc/xgboost/blob/master/NEWS.md)
- [Commits](https://github.com/dmlc/xgboost/compare/v3.0.4...v3.0.5)

---
updated-dependencies:
- dependency-name: xgboost
  dependency-version: 3.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:02:37 +00:00
dependabot[bot] 9f02279d5a chore(deps): bump ccxt from 4.5.2 to 4.5.3
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.5.2 to 4.5.3.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/v4.5.2...v4.5.3)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-version: 4.5.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:02:26 +00:00
dependabot[bot] 6f9906e935 chore(deps): bump markdown from 3.8.2 to 3.9
Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.8.2 to 3.9.
- [Release notes](https://github.com/Python-Markdown/markdown/releases)
- [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md)
- [Commits](https://github.com/Python-Markdown/markdown/compare/3.8.2...3.9.0)

---
updated-dependencies:
- dependency-name: markdown
  dependency-version: '3.9'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:02:10 +00:00
dependabot[bot] e934c3934d chore(deps): bump mkdocs-material in the mkdocs group
Bumps the mkdocs group with 1 update: [mkdocs-material](https://github.com/squidfunk/mkdocs-material).


Updates `mkdocs-material` from 9.6.18 to 9.6.19
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.18...9.6.19)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-version: 9.6.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: mkdocs
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:01:58 +00:00
dependabot[bot] d6f78e4cc8 chore(deps): bump actions/setup-python from 5 to 6
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:01:46 +00:00
dependabot[bot] f9cc05b202 chore(deps): bump pypa/gh-action-pypi-publish from 1.12.4 to 1.13.0
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.12.4 to 1.13.0.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/76f52bc884231f62b9a034ebfe128415bbaabdfc...ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-version: 1.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:01:42 +00:00
dependabot[bot] 76eb92b821 chore(deps): bump astral-sh/setup-uv from 6.6.0 to 6.6.1
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.6.0 to 6.6.1.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/4959332f0f014c5280e7eac8b70c90cb574c9f9b...557e51de59eb14aaaba2ed9621916900a91d50c6)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 6.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:01:38 +00:00
mrpabloyeah e749051dbc Fix ShuffleFilter behavior in backtesting 2025-09-07 23:28:33 +02:00
Matthias 6de7c70e7e Merge pull request #11625 from alisalama/develop
Parallelisation of iterative data downloads for speed improvement
2025-09-07 19:31:52 +02:00
Matthias 74f52b14cd chore(ci): disable package cleanup on pull requests 2025-09-07 19:31:12 +02:00
Matthias e33363bf6c feat: allow disabling parallel data-download per exchange 2025-09-07 18:18:34 +02:00
Matthias 7d77e63b81 chore: simplify comment 2025-09-07 15:54:16 +02:00
Matthias cfa855dec8 test: remove missleading comment 2025-09-07 15:53:56 +02:00
Matthias 34a72a0555 feat: doin't drop last candle for funding fees 2025-09-07 15:52:44 +02:00
Matthias a9db7d0286 chore: improve log wording 2025-09-07 15:35:00 +02:00
Matthias 19140e9cfa doc: fix funding fee doc sample 2025-09-07 12:01:32 +02:00
Matthias b0c3f2ff7f chore(ci): fix actions permission 2025-09-07 09:21:22 +02:00
Matthias 8686b56b9e chore(ci): automatically cleanup untagged images 2025-09-07 09:16:58 +02:00
Matthias 6ab731acdb chore(ci): Try simpler syntax 2025-09-07 09:10:44 +02:00
Matthias 8ca63cf0ee chore(ci): Improved workflow syntax 2025-09-07 09:04:27 +02:00
Matthias 5774c08b4a chore(ci): use proper input syntax 2025-09-07 09:01:22 +02:00
Matthias b731cdef56 chore(ci): use proper input syntax 2025-09-07 08:59:57 +02:00
Matthias b51c93fbc1 chore(ci): attempt at package-cleanup 2025-09-07 08:57:06 +02:00
Matthias e948839fb5 feat: have timerange have a default display way 2025-09-06 19:18:12 +02:00
Matthias 587ec513db fix: Odd error downloading wrong timerange when using --days via UI 2025-09-06 19:17:01 +02:00
Matthias efed5700be fix: handle RuntimeError on trades download
asyncio raises RuntimeError if the handler is not set on
the main thread.

closes #12211
2025-09-06 18:09:26 +02:00
Matthias 5ddaea7efc chore: improve log message 2025-09-06 18:01:35 +02:00
Matthias 66577b741f doc: improve orderbook wording 2025-09-06 17:52:20 +02:00
Matthias 09017980b6 docs: add live funding rate documentation 2025-09-06 17:52:20 +02:00
Matthias 3a7721ebe8 test: add test for fetch_funding_rate
part of #12206
2025-09-06 17:52:14 +02:00
Matthias 35cc3efd5a feat: improve docstring and error handling
part of #12206
2025-09-06 17:52:09 +02:00
Matthias 95ad756909 feat: add "current funding fee" endpoint
part of #12206
2025-09-06 17:51:50 +02:00
Matthias 816ca2ea15 feat: add error in case of non-available informative dataframe 2025-09-06 09:38:23 +02:00
Matthias 246891a8f6 feat: limit downloadable funding rates to funding rate interval
Limit using wrong funding-rate timeframes, which can cause wrong
information and assumptions in the strategy

Part of #12206
2025-09-06 09:21:28 +02:00
Matthias 25fd63c6d0 chore: make internal attribute really private 2025-09-06 09:10:44 +02:00
Matthias cadbbd0e2e chore: improve variable naming for clarity 2025-09-06 09:08:01 +02:00
Matthias 65b83c46fb Merge pull request #12208 from freqtrade/test_flat_dockerbuild
Restructure docker builds
2025-09-05 11:44:32 +02:00
Matthias 31204a37a5 chore(ci): set missed env 2025-09-05 07:09:22 +02:00
Matthias 67774c71e5 chore(ci): set composite action outputs 2025-09-04 20:01:29 +02:00
Matthias 44b65daf1c chore(ci): Switch to use outputs instead of global environments 2025-09-04 19:51:30 +02:00
Matthias 48ff0c5744 chore(ci): Use buildx imagetools only 2025-09-04 07:06:28 +02:00
Matthias 3934aa118f chore(ci): use docker buildx imagetool create 2025-09-04 07:06:27 +02:00
Matthias d40efb883c chore(ci): use proper manifest command 2025-09-04 07:06:27 +02:00
Matthias 84ec09565a chore(ci): Fix docker github login 2025-09-04 07:06:27 +02:00
Matthias 387431e4df chore(ci): use docker manifest to copy to ghcr 2025-09-04 07:06:27 +02:00
Matthias 662747c06c chore(ci): enable aliases 2025-09-04 07:06:27 +02:00
Matthias 89272e9ddb chore(ci): don't cache qemu image 2025-09-04 07:06:27 +02:00
Matthias 23d4d25e39 chore(ci): move everything to docker build action 2025-09-04 07:06:27 +02:00
Matthias 488a608c90 chore(ci): simplify build steps 2025-09-04 07:06:27 +02:00
Matthias a94d18a10b chore(ci): use composite action to extract docker variables 2025-09-04 07:06:27 +02:00
Matthias 94aba0f9ac chore(ci) fix step naming 2025-09-04 07:06:27 +02:00
Matthias 35c3ca91eb chore(ci): fix small typo 2025-09-04 07:06:27 +02:00
Matthias 53328bc595 chore(ci): allow failure on pull 2025-09-04 07:06:27 +02:00
Matthias bb7a4c4739 chore(ci): move CI build to action
* Reduce the need for a helper script
* increase visibility into individual build times
2025-09-04 07:06:27 +02:00
Matthias 7d38963c61 chore(ci): extract environment parts to ci file 2025-09-04 07:06:27 +02:00
Matthias a7e7c17134 Merge pull request #12207 from freqtrade/update/binance-leverage-tiers
Update Binance Leverage Tiers
2025-09-04 06:51:27 +02:00
Freqtrade Bot 0544af1f68 chore: update pre-commit hooks 2025-09-04 03:10:44 +00:00
Mihail 70d7dcd189 Made test_merge_informative_pair_monthly asserts data dependent. 2025-09-03 19:55:37 +00:00
Mihail d36fdc1d69 Added exact dates to test_merge_informative_pair_monthly. 2025-09-03 12:20:38 +00:00
Mihail b9482f420d Changed test_merge_informative_pair_monthly test to contain the data from previous informative candle on start too. 2025-09-02 19:25:08 +00:00
Matthias ba87f3e7d7 chore: exclude .venv and userdata from dockerfiles 2025-09-02 20:59:23 +02:00
Mihail 3fe721a772 Fix for merge_informative_pair fix. 2025-09-02 18:33:23 +00:00
Matthias b60a3802e7 feat: remove numpy and pandas downgrade for armhf 2025-09-02 19:21:01 +02:00
Matthias 4beb6a8049 Merge pull request #12198 from hustrust/develop
chore: remove redundant word in docs/freq-ui.md
2025-09-02 18:18:20 +02:00
Mihail a53c4a3ed1 Fix the truncation of values by merge_ordered in the merge_informative_pair helper. 2025-09-02 15:35:20 +03:00
Robert Caulk bd10afc796 Merge pull request #12195 from Kritoooo/fix-skip-empty-test-labels
feat: warn user with clear message when test labels empty
2025-09-02 12:19:56 +02:00
hustrust 2868efa779 chore: remove redundant word in docs/freq-ui.md
Signed-off-by: hustrust <hustrust@outlook.com>
2025-09-02 16:28:51 +08:00
Matthias fe466e2e86 chore(ci): set environment variables directly 2025-09-02 07:23:10 +02:00
Matthias 6c5771b40c chore(ci): remove some redundant environment variables 2025-09-02 07:16:10 +02:00
Matthias 5c81d31bd1 chore(ci): Updated docker hub login 2025-09-02 07:13:18 +02:00
Matthias b1b3b42489 Merge pull request #12196 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2025-09-02 06:58:52 +02:00
Freqtrade Bot 5b03fc1a89 chore: update pre-commit hooks 2025-09-02 03:18:44 +00:00
Matthias dd73c724c4 Merge pull request #12183 from freqtrade/dependabot/pip/develop/ta-lib-0.6.6
chore(deps): bump ta-lib from 0.6.5 to 0.6.6
2025-09-01 20:01:50 +02:00
Matthias 5cbcd68446 chore: update armhf binary 2025-09-01 19:47:45 +02:00
Kritoooo 3bc1afd149 feat: warn user with clear message when test labels empty 2025-09-01 21:21:24 +08:00
Matthias 877761ecd3 Merge pull request #12185 from freqtrade/dependabot/pip/develop/cachetools-6.2.0
chore(deps): bump cachetools from 6.1.0 to 6.2.0
2025-09-01 11:00:55 +02:00
Matthias 9ef464e002 Merge pull request #12188 from freqtrade/dependabot/pip/develop/questionary-2.1.1
chore(deps): bump questionary from 2.1.0 to 2.1.1
2025-09-01 10:49:48 +02:00
dependabot[bot] 3deb089d64 chore(deps): bump cachetools from 6.1.0 to 6.2.0
Bumps [cachetools](https://github.com/tkem/cachetools) from 6.1.0 to 6.2.0.
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v6.1.0...v6.2.0)

---
updated-dependencies:
- dependency-name: cachetools
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 08:40:20 +00:00
Matthias f4f2249447 Merge pull request #12187 from freqtrade/dependabot/pip/develop/types-562fd16d2b
chore(deps-dev): bump types-cachetools from 6.1.0.20250717 to 6.2.0.20250827 in the types group
2025-09-01 10:36:57 +02:00
dependabot[bot] 1c5a4f4f39 chore(deps): bump questionary from 2.1.0 to 2.1.1
Bumps [questionary](https://github.com/tmbo/questionary) from 2.1.0 to 2.1.1.
- [Commits](https://github.com/tmbo/questionary/compare/2.1.0...2.1.1)

---
updated-dependencies:
- dependency-name: questionary
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 08:10:19 +00:00
Matthias 1909fc3139 chore: update pre-commit cachetools 2025-09-01 10:05:43 +02:00
Matthias 2de831f1b2 Merge pull request #12189 from freqtrade/dependabot/pip/develop/orjson-3.11.3
chore(deps): bump orjson from 3.11.2 to 3.11.3
2025-09-01 10:03:51 +02:00
Matthias 1739200ee4 Merge pull request #12191 from freqtrade/dependabot/pip/develop/humanize-4.13.0
chore(deps): bump humanize from 4.12.3 to 4.13.0
2025-09-01 10:03:38 +02:00
Matthias 31a44178a4 Merge pull request #12193 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.52
chore(deps): bump prompt-toolkit from 3.0.51 to 3.0.52
2025-09-01 10:02:22 +02:00
Matthias eb9f233a78 Merge pull request #12192 from freqtrade/dependabot/pip/develop/ruff-0.12.11
chore(deps-dev): bump ruff from 0.12.10 to 0.12.11
2025-09-01 10:01:05 +02:00
dependabot[bot] 3986dc2617 chore(deps): bump prompt-toolkit from 3.0.51 to 3.0.52
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.51 to 3.0.52.
- [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases)
- [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/main/CHANGELOG)
- [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.51...3.0.52)

---
updated-dependencies:
- dependency-name: prompt-toolkit
  dependency-version: 3.0.52
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 06:24:42 +00:00
dependabot[bot] 1f7f2ee3dd chore(deps-dev): bump ruff from 0.12.10 to 0.12.11
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.12.10 to 0.12.11.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.12.10...0.12.11)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.12.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 06:22:56 +00:00
dependabot[bot] 6e0da1aa3a chore(deps): bump humanize from 4.12.3 to 4.13.0
Bumps [humanize](https://github.com/python-humanize/humanize) from 4.12.3 to 4.13.0.
- [Release notes](https://github.com/python-humanize/humanize/releases)
- [Commits](https://github.com/python-humanize/humanize/compare/4.12.3...4.13.0)

---
updated-dependencies:
- dependency-name: humanize
  dependency-version: 4.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 06:22:50 +00:00
dependabot[bot] af3b0ed39f chore(deps): bump orjson from 3.11.2 to 3.11.3
Bumps [orjson](https://github.com/ijl/orjson) from 3.11.2 to 3.11.3.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.11.2...3.11.3)

---
updated-dependencies:
- dependency-name: orjson
  dependency-version: 3.11.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 06:21:23 +00:00
dependabot[bot] 1302b67772 chore(deps-dev): bump types-cachetools in the types group
Bumps the types group with 1 update: [types-cachetools](https://github.com/typeshed-internal/stub_uploader).


Updates `types-cachetools` from 6.1.0.20250717 to 6.2.0.20250827
- [Commits](https://github.com/typeshed-internal/stub_uploader/commits)

---
updated-dependencies:
- dependency-name: types-cachetools
  dependency-version: 6.2.0.20250827
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: types
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 06:20:24 +00:00
dependabot[bot] 6d44248607 chore(deps): bump ta-lib from 0.6.5 to 0.6.6
Bumps [ta-lib](https://github.com/ta-lib/ta-lib-python) from 0.6.5 to 0.6.6.
- [Release notes](https://github.com/ta-lib/ta-lib-python/releases)
- [Changelog](https://github.com/TA-Lib/ta-lib-python/blob/master/CHANGELOG)
- [Commits](https://github.com/ta-lib/ta-lib-python/compare/v0.6.5...v0.6.6)

---
updated-dependencies:
- dependency-name: ta-lib
  dependency-version: 0.6.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 06:18:21 +00:00
Matthias 5f1d9cbab1 Merge pull request #12151 from mpagnoulle/feat/trades-timerange-filtering
Trades TimeRange filtering for FeatherDataHandler and _if_enabled_populate_trades
2025-08-31 10:00:23 +02:00
Matthias aad21195df docs: document nested webhook functionality 2025-08-31 08:41:30 +02:00
Matthias 739a67fdcb test: add test for new webhook functionality 2025-08-31 08:41:12 +02:00
Matthias 48bd5cb2c0 feat: add nested webhook message support 2025-08-31 08:41:05 +02:00
Matthias 2542102280 test: Test telegram init exception handling 2025-08-30 20:02:03 +02:00
Matthias 81a5d49687 fix: list-data --trades no longer working when used with --pairs filter 2025-08-30 19:58:24 +02:00
Matthias 321b44b779 chore: fix 2025-08-30 19:57:47 +02:00
Matthias 61a1ed897f chore: bump pyright minimum version 2025-08-30 18:10:21 +02:00
Matthias 5bb4cffa21 chore: clarify deprecation message 2025-08-30 18:02:26 +02:00
Matthias 5c314b6f1c chore: bump dev version to 2025.9-dev 2025-08-30 17:56:49 +02:00
Maxime Pagnoulle 9d5295fdb4 feat: Support for unbounded start and/or end in timerange filtering, added associated tests 2025-08-30 17:38:23 +02:00
Matthias eaf3fc8833 test: add negative test for parallel download 2025-08-29 20:06:03 +02:00
Matthias 94c5ddc13d test: add test covering parallel pair merging 2025-08-29 07:26:05 +02:00
Matthias a3fedbaba7 docs: update outdated comments 2025-08-29 07:11:19 +02:00
Matthias 564634be45 docs: update exported help messages 2025-08-28 07:08:36 +02:00
Matthias ab3ae3dc62 chore: Update cli help 2025-08-28 07:08:25 +02:00
Matthias d037f67f74 test: add parallel download test 2025-08-28 07:07:27 +02:00
Matthias b1b6341a6e test: improve parallel test to capture caching 2025-08-28 06:50:17 +02:00
Matthias 8c92f9407d chore: use candle_type as argument for parallel-download 2025-08-28 06:50:08 +02:00
Matthias e0aa660b56 chore: improve docstring wording 2025-08-28 06:46:45 +02:00
Matthias 59ab51c06c test: Update basic test for calls to parallel-download 2025-08-27 20:19:47 +02:00
Matthias 2eb2617b6f chore: make condition more logical 2025-08-27 20:19:31 +02:00
Matthias b284572ea7 chore: update docstring 2025-08-27 19:44:39 +02:00
Matthias 1e5d9ecfa3 chore: improved logstring 2025-08-27 10:22:40 +02:00
Matthias e8bda298e3 Merge branch 'develop' into pr/alisalama/11625 2025-08-27 10:15:07 +02:00
Matthias 489cd008d6 chore: invert "parallel download" option 2025-08-27 10:15:04 +02:00
Matthias 3ff1e31a81 test: don't use fixture if it's only used once 2025-08-27 08:31:14 +02:00
Maxime Pagnoulle f21c5ea88a feat: Remove redundant filtering, add tests for pyarrow trade filtering, use date utils for date to ts conversion 2025-08-24 11:59:56 +02:00
Maxime Pagnoulle 82903cc567 feat: Filter trades based on timerange 2025-08-23 20:25:26 +02:00
Maxime Pagnoulle 0233c38711 feat: Only load trades needed for specified timerange 2025-08-23 20:24:10 +02:00
Ali Salama 4e2ccfc091 Added use_parallel_download command line option 2025-04-25 15:50:56 +01:00
Ali Salama e4b1e1118b Changed filter to pop 2025-04-25 10:33:39 +01:00
Ali Salama ba2e798f7d Added data.empty / new pair check 2025-04-12 11:35:23 +01:00
Ali Salama 85edef8394 Changed to use refresh_latest_ohlcv 2025-04-12 10:15:31 +01:00
Ali Salama 559f6e2791 Parallelisation of iterative data downloads 2025-04-11 16:16:07 +01:00
162 changed files with 18857 additions and 8058 deletions
+2 -1
View File
@@ -14,10 +14,11 @@ MANIFEST.in
README.md
freqtrade.service
freqtrade.egg-info
.venv/
config.json*
*.sqlite
user_data
user_data/
*.log
.vscode
+92
View File
@@ -0,0 +1,92 @@
name: 'docker-tags'
description: 'Set Docker default Tag environment variables'
# inputs:
outputs:
BRANCH_NAME:
description: 'The branch name'
value: ${{ steps.tags.outputs.BRANCH_NAME }}
TAG:
description: 'The Docker tag'
value: ${{ steps.tags.outputs.TAG }}
TAG_PLOT:
description: 'The Docker tag for the plot'
value: ${{ steps.tags.outputs.TAG_PLOT }}
TAG_FREQAI:
description: 'The Docker tag for the freqai'
value: ${{ steps.tags.outputs.TAG_FREQAI }}
TAG_FREQAI_RL:
description: 'The Docker tag for the freqai_rl'
value: ${{ steps.tags.outputs.TAG_FREQAI_RL }}
TAG_FREQAI_TORCH:
description: 'The Docker tag for the freqai_torch'
value: ${{ steps.tags.outputs.TAG_FREQAI_TORCH }}
TAG_ARM:
description: 'The Docker tag for the arm'
value: ${{ steps.tags.outputs.TAG_ARM }}
TAG_PLOT_ARM:
description: 'The Docker tag for the plot arm'
value: ${{ steps.tags.outputs.TAG_PLOT_ARM }}
TAG_FREQAI_ARM:
description: 'The Docker tag for the freqai arm'
value: ${{ steps.tags.outputs.TAG_FREQAI_ARM }}
TAG_FREQAI_RL_ARM:
description: 'The Docker tag for the freqai_rl arm'
value: ${{ steps.tags.outputs.TAG_FREQAI_RL_ARM }}
TAG_PI:
description: 'The Docker tag for the pi'
value: ${{ steps.tags.outputs.TAG_PI }}
CACHE_TAG_PI:
description: 'The Docker cache tag for the pi'
value: ${{ steps.tags.outputs.CACHE_TAG_PI }}
runs:
using: "composite"
steps:
- name: Extract branch name
shell: bash
id: tags
env:
BRANCH_NAME_INPUT: ${{ github.event.inputs.branch_name }}
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
BRANCH_NAME="${BRANCH_NAME_INPUT}"
else
BRANCH_NAME="${GITHUB_REF##*/}"
fi
# Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot
TAG_FREQAI=${TAG}_freqai
TAG_FREQAI_RL=${TAG_FREQAI}rl
TAG_FREQAI_TORCH=${TAG_FREQAI}torch
TAG_ARM=${TAG}_arm
TAG_PLOT_ARM=${TAG_PLOT}_arm
TAG_FREQAI_ARM=${TAG_FREQAI}_arm
TAG_FREQAI_RL_ARM=${TAG_FREQAI_RL}_arm
TAG_PI="${TAG}_pi"
CACHE_TAG_PI=${CACHE_IMAGE}:${TAG_PI}_cache
echo "BRANCH_NAME=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
echo "TAG=${TAG}" >> "$GITHUB_OUTPUT"
echo "TAG_PLOT=${TAG_PLOT}" >> "$GITHUB_OUTPUT"
echo "TAG_FREQAI=${TAG_FREQAI}" >> "$GITHUB_OUTPUT"
echo "TAG_FREQAI_RL=${TAG_FREQAI_RL}" >> "$GITHUB_OUTPUT"
echo "TAG_FREQAI_TORCH=${TAG_FREQAI_TORCH}" >> "$GITHUB_OUTPUT"
echo "TAG_ARM=${TAG_ARM}" >> "$GITHUB_OUTPUT"
echo "TAG_PLOT_ARM=${TAG_PLOT_ARM}" >> "$GITHUB_OUTPUT"
echo "TAG_FREQAI_ARM=${TAG_FREQAI_ARM}" >> "$GITHUB_OUTPUT"
echo "TAG_FREQAI_RL_ARM=${TAG_FREQAI_RL_ARM}" >> "$GITHUB_OUTPUT"
echo "TAG_PI=${TAG_PI}" >> "$GITHUB_OUTPUT"
echo "CACHE_TAG_PI=${CACHE_TAG_PI}" >> "$GITHUB_OUTPUT"
cat "$GITHUB_OUTPUT"
- name: Save commit SHA to file
shell: bash
# Add commit to docker container
run: |
echo "${GITHUB_SHA}" > freqtrade_commit
+16
View File
@@ -1,6 +1,8 @@
version: 2
updates:
- package-ecosystem: docker
cooldown:
default-days: 4
directories:
- "/"
- "/docker"
@@ -11,8 +13,20 @@ updates:
update-types: ["version-update:semver-major"]
open-pull-requests-limit: 10
- package-ecosystem: devcontainers
directory: "/"
cooldown:
default-days: 4
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: pip
directory: "/"
cooldown:
default-days: 4
exclude:
- ccxt
schedule:
interval: weekly
time: "03:00"
@@ -36,6 +50,8 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
cooldown:
default-days: 4
schedule:
interval: "weekly"
open-pull-requests-limit: 10
@@ -19,7 +19,7 @@ jobs:
with:
persist-credentials: false
- uses: actions/setup-python@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
+70 -230
View File
@@ -19,12 +19,12 @@ concurrency:
permissions:
repository-projects: read
jobs:
build-linux:
tests:
name: "Tests and Linting"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ "ubuntu-22.04", "ubuntu-24.04" ]
os: [ "ubuntu-22.04", "ubuntu-24.04", "macos-14", "macos-15" , "windows-2022", "windows-2025" ]
python-version: ["3.11", "3.12", "3.13"]
steps:
@@ -33,21 +33,27 @@ jobs:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v6.6.0
uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d # v7.1.0
with:
activate-environment: true
enable-cache: true
python-version: ${{ matrix.python-version }}
cache-dependency-glob: "requirements**.txt"
cache-suffix: "${{ matrix.python-version }}"
prune-cache: false
- name: Installation - *nix
- name: Installation - macOS (Brew)
if: ${{ runner.os == 'macOS' }}
run: |
# brew update
# TODO: Should be the brew upgrade
brew install libomp
- name: Installation (python)
run: |
uv pip install --upgrade wheel
uv pip install -r requirements-dev.txt
@@ -61,7 +67,7 @@ jobs:
- name: Tests
if: (!(runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-24.04'))
run: |
pytest --random-order
pytest --random-order --durations 20 -n auto
- name: Tests with Coveralls
if: (runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-24.04')
@@ -88,9 +94,9 @@ jobs:
run: |
python build_helpers/create_command_partials.py
- name: Check for repository changes
- name: Check for repository changes - *nix
# TODO: python 3.13 slightly changed the output of argparse.
if: (matrix.python-version != '3.13')
if: ${{ (matrix.python-version != '3.13') && (runner.os != 'Windows') }}
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "Repository is dirty, changes detected:"
@@ -101,13 +107,27 @@ jobs:
echo "Repository is clean, no changes detected."
fi
- name: Check for repository changes - Windows
if: ${{ runner.os == 'Windows' && (matrix.python-version != '3.13') }}
run: |
if (git status --porcelain) {
Write-Host "Repository is dirty, changes detected:"
git status
git diff
exit 1
}
else {
Write-Host "Repository is clean, no changes detected."
}
- name: Backtesting (multi)
run: |
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
cp tests/testdata/config.tests.json user_data/config.json
freqtrade new-strategy -s AwesomeStrategy
freqtrade new-strategy -s AwesomeStrategyMin --template minimal
freqtrade backtesting --datadir tests/testdata --strategy-list AwesomeStrategy AwesomeStrategyMin -i 5m
freqtrade new-strategy -s AwesomeStrategyAdv --template advanced
freqtrade backtesting --datadir tests/testdata --strategy-list AwesomeStrategy AwesomeStrategyMin AwesomeStrategyAdv -i 5m
- name: Hyperopt
run: |
@@ -128,208 +148,13 @@ jobs:
ruff format --check
- name: Mypy
if: matrix.os == 'ubuntu-24.04'
run: |
mypy freqtrade scripts tests
- name: Discord notification
uses: rjstone/discord-webhook-notify@c2597273488aeda841dd1e891321952b51f7996f #v2.2.1
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
severity: error
details: Freqtrade CI failed on ${{ matrix.os }}
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
build-macos:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ "macos-14", "macos-15" ]
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Install uv
uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v6.6.0
with:
activate-environment: true
enable-cache: true
python-version: ${{ matrix.python-version }}
cache-dependency-glob: "requirements**.txt"
cache-suffix: "${{ matrix.python-version }}"
prune-cache: false
- name: Installation - macOS (Brew)
run: |
# brew update
# TODO: Should be the brew upgrade
# homebrew fails to update python due to unlinking failures
# https://github.com/actions/runner-images/issues/6817
rm /usr/local/bin/2to3 || true
rm /usr/local/bin/2to3-3.11 || true
rm /usr/local/bin/2to3-3.12 || true
rm /usr/local/bin/idle3 || true
rm /usr/local/bin/idle3.11 || true
rm /usr/local/bin/idle3.12 || true
rm /usr/local/bin/pydoc3 || true
rm /usr/local/bin/pydoc3.11 || true
rm /usr/local/bin/pydoc3.12 || true
rm /usr/local/bin/python3 || true
rm /usr/local/bin/python3.11 || true
rm /usr/local/bin/python3.12 || true
rm /usr/local/bin/python3-config || true
rm /usr/local/bin/python3.11-config || true
rm /usr/local/bin/python3.12-config || true
brew install libomp
- name: Installation (python)
run: |
uv pip install wheel
uv pip install -r requirements-dev.txt
uv pip install -e ft_client/
uv pip install -e .
- name: Tests
run: |
pytest --random-order
- name: Check for repository changes
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "Repository is dirty, changes detected:"
git status
git diff
exit 1
else
echo "Repository is clean, no changes detected."
fi
- name: Backtesting
run: |
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade new-strategy -s AwesomeStrategyAdv --template advanced
freqtrade backtesting --datadir tests/testdata --strategy AwesomeStrategyAdv
- name: Hyperopt
run: |
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Sort imports (isort)
run: |
isort --check .
- name: Run Ruff
run: |
ruff check --output-format=github
- name: Run Ruff format check
run: |
ruff format --check
- name: Mypy
if: matrix.os == 'macos-15'
run: |
mypy freqtrade scripts
- name: Discord notification
uses: rjstone/discord-webhook-notify@c2597273488aeda841dd1e891321952b51f7996f #v2.2.1
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
severity: info
details: Test Succeeded!
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
build-windows:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ "windows-2022", "windows-2025" ]
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v6.6.0
with:
activate-environment: true
enable-cache: true
python-version: ${{ matrix.python-version }}
cache-dependency-glob: "requirements**.txt"
cache-suffix: "${{ matrix.python-version }}"
prune-cache: false
- name: Installation
run: |
function uvpipFunction { uv pip $args }
Set-Alias -name pip -value uvpipFunction
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
pip install -e .
- name: Tests
run: |
pytest --random-order --durations 20 -n auto
- name: Check for repository changes
run: |
if (git status --porcelain) {
Write-Host "Repository is dirty, changes detected:"
git status
git diff
exit 1
}
else {
Write-Host "Repository is clean, no changes detected."
}
- name: Backtesting
run: |
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt
run: |
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Run Ruff
run: |
ruff check --output-format=github
- name: Run Ruff format check
run: |
ruff format --check
- name: Mypy
if: ${{ matrix.os == 'ubuntu-24.04' || matrix.os == 'macos-15' }}
run: |
mypy freqtrade scripts tests
- name: Run Pester tests (PowerShell)
if: ${{ runner.os == 'Windows' }}
shell: powershell
run: |
$PSVersionTable
Set-PSRepository psgallery -InstallationPolicy trusted
@@ -338,25 +163,24 @@ jobs:
Invoke-Pester -Path "tests" -CI
if ($Error.Length -gt 0) {exit 1}
shell: powershell
- name: Discord notification
uses: rjstone/discord-webhook-notify@c2597273488aeda841dd1e891321952b51f7996f #v2.2.1
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
if: ${{ failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) }}
with:
severity: error
details: Test Failed
details: Freqtrade CI failed on ${{ matrix.os }} with Python ${{ matrix.python-version }}!
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
mypy-version-check:
runs-on: ubuntu-22.04
name: "Mypy Version Check"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.12"
@@ -366,18 +190,20 @@ jobs:
python build_helpers/pre_commit_update.py
pre-commit:
name: "Pre-commit checks"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: actions/setup-python@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
docs-check:
name: "Documentation build"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
@@ -389,7 +215,7 @@ jobs:
./tests/test_docs.sh
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.12"
@@ -409,6 +235,7 @@ jobs:
build-linux-online:
# Run pytest with "live" checks
name: "Tests and Linting - Online tests"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
@@ -416,19 +243,18 @@ jobs:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b # v6.6.0
uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d # v7.1.0
with:
activate-environment: true
enable-cache: true
python-version: "3.12"
cache-dependency-glob: "requirements**.txt"
cache-suffix: "3.12"
prune-cache: false
- name: Installation - *nix
run: |
@@ -439,7 +265,7 @@ jobs:
- name: Tests incl. ccxt compatibility tests
env:
CI_WEB_PROXY: http://152.67.78.211:13128
CI_WEB_PROXY: http://152.67.66.8:13128
run: |
pytest --random-order --longrun --durations 20 -n auto
@@ -447,9 +273,7 @@ jobs:
# Notify only once - when CI completes (and after deploy) in case it's successful
notify-complete:
needs: [
build-linux,
build-macos,
build-windows,
tests,
docs-check,
mypy-version-check,
pre-commit,
@@ -481,7 +305,7 @@ jobs:
build:
name: "Build"
needs: [ build-linux, build-macos, build-windows, docs-check, mypy-version-check, pre-commit ]
needs: [ tests, docs-check, mypy-version-check, pre-commit ]
runs-on: ubuntu-22.04
steps:
@@ -490,7 +314,7 @@ jobs:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.12"
@@ -544,7 +368,7 @@ jobs:
merge-multiple: true
- name: Publish to PyPI (Test)
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
with:
repository-url: https://test.pypi.org/legacy/
@@ -573,12 +397,17 @@ jobs:
merge-multiple: true
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
docker-build:
name: "Docker Build and Deploy"
needs: [ build-linux, build-macos, build-windows, docs-check, mypy-version-check, pre-commit ]
needs: [
tests,
docs-check,
mypy-version-check,
pre-commit
]
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade'
uses: ./.github/workflows/docker-build.yml
permissions:
@@ -588,3 +417,14 @@ jobs:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
packages-cleanup:
name: "Docker Package Cleanup"
uses: ./.github/workflows/packages-cleanup.yml
# Only run on push, schedule, or release events
if: (github.event_name == 'push' || github.event_name == 'schedule') && github.repository == 'freqtrade/freqtrade'
permissions:
packages: write
with:
package_name: 'freqtrade'
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
persist-credentials: true
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
with:
persist-credentials: false
- name: Login to GitHub Container Registry
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
+219 -49
View File
@@ -20,6 +20,12 @@ on:
permissions:
contents: read
env:
IMAGE_NAME: "freqtradeorg/freqtrade"
CACHE_IMAGE: "freqtradeorg/freqtrade_cache"
GHCR_IMAGE_NAME: "ghcr.io/freqtrade/freqtrade"
PI_PLATFORM: "linux/arm/v7"
jobs:
deploy-docker:
name: "Deploy Docker x64 and armv7l"
@@ -31,33 +37,20 @@ jobs:
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
- name: Set docker tag names
id: tags
uses: ./.github/actions/docker-tags
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
python-version: "3.12"
- name: Extract branch name
id: extract-branch
env:
BRANCH_NAME_INPUT: ${{ github.event.inputs.branch_name }}
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
BRANCH_NAME="${BRANCH_NAME_INPUT}"
else
BRANCH_NAME="${GITHUB_REF##*/}"
fi
echo "GITHUB_REF='${GITHUB_REF}'"
echo "branch=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
- name: Dockerhub login
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: |
echo "${DOCKER_PASSWORD}" | docker login --username ${DOCKER_USERNAME} --password-stdin
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
with:
cache-image: false
- name: Set up Docker Buildx
id: buildx
@@ -68,11 +61,86 @@ jobs:
env:
PLATFORMS: ${{ steps.buildx.outputs.platforms }}
- name: Build and test and push docker images
- name: Build image without cache
if: github.event_name == 'schedule'
env:
BRANCH_NAME: ${{ steps.extract-branch.outputs.branch }}
TAG: ${{ steps.tags.outputs.TAG }}
run: |
build_helpers/publish_docker_multi.sh
docker build -t ${CACHE_IMAGE}:${TAG} .
- name: Build ARMHF image without cache
if: github.event_name == 'schedule'
env:
TAG_PI: ${{ steps.tags.outputs.TAG_PI }}
CACHE_TAG_PI: ${{ steps.tags.outputs.CACHE_TAG_PI }}
run: |
docker buildx build \
--cache-to=type=registry,ref=${CACHE_TAG_PI} \
-f docker/Dockerfile.armhf \
--platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG_PI} \
--push \
--provenance=false \
.
- name: Build image with cache
if: github.event_name != 'schedule'
env:
TAG: ${{ steps.tags.outputs.TAG }}
run: |
docker pull ${IMAGE_NAME}:${TAG} || true
docker build --cache-from ${IMAGE_NAME}:${TAG} -t ${CACHE_IMAGE}:${TAG} .
- name: Build ARMHF image with cache
if: github.event_name != 'schedule'
# disable provenance due to https://github.com/docker/buildx/issues/1509
env:
TAG_PI: ${{ steps.tags.outputs.TAG_PI }}
CACHE_TAG_PI: ${{ steps.tags.outputs.CACHE_TAG_PI }}
run: |
docker buildx build \
--cache-from=type=registry,ref=${CACHE_TAG_PI} \
--cache-to=type=registry,ref=${CACHE_TAG_PI} \
-f docker/Dockerfile.armhf \
--platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG_PI} \
--push \
--provenance=false \
.
- name: Run build for AI images
env:
TAG: ${{ steps.tags.outputs.TAG }}
TAG_PLOT: ${{ steps.tags.outputs.TAG_PLOT }}
TAG_FREQAI: ${{ steps.tags.outputs.TAG_FREQAI }}
TAG_FREQAI_RL: ${{ steps.tags.outputs.TAG_FREQAI_RL }}
run: |
docker build --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG} -t ${CACHE_IMAGE}:${TAG_PLOT} -f docker/Dockerfile.plot .
docker build --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG} -t ${CACHE_IMAGE}:${TAG_FREQAI} -f docker/Dockerfile.freqai .
docker build --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_FREQAI} -t ${CACHE_IMAGE}:${TAG_FREQAI_RL} -f docker/Dockerfile.freqai_rl .
- name: Run backtest in Docker
env:
TAG: ${{ steps.tags.outputs.TAG }}
run: |
docker run --rm -v $(pwd)/tests/testdata/config.tests.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests ${CACHE_IMAGE}:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
- name: Push cache images
env:
TAG: ${{ steps.tags.outputs.TAG }}
TAG_PLOT: ${{ steps.tags.outputs.TAG_PLOT }}
TAG_FREQAI: ${{ steps.tags.outputs.TAG_FREQAI }}
TAG_FREQAI_RL: ${{ steps.tags.outputs.TAG_FREQAI_RL }}
run: |
docker push ${CACHE_IMAGE}:$TAG
docker push ${CACHE_IMAGE}:$TAG_PLOT
docker push ${CACHE_IMAGE}:$TAG_FREQAI
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL
- name: list Images
run: |
docker images
deploy-arm:
name: "Deploy Docker ARM64"
@@ -88,33 +156,135 @@ jobs:
with:
persist-credentials: false
- name: Extract branch name
id: extract-branch
env:
BRANCH_NAME_INPUT: ${{ github.event.inputs.branch_name }}
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
BRANCH_NAME="${BRANCH_NAME_INPUT}"
else
BRANCH_NAME="${GITHUB_REF##*/}"
fi
echo "GITHUB_REF='${GITHUB_REF}'"
echo "branch=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
- name: Set docker tag names
id: tags
uses: ./.github/actions/docker-tags
- name: Dockerhub login
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: |
echo "${DOCKER_PASSWORD}" | docker login --username ${DOCKER_USERNAME} --password-stdin
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and test and push docker images
- name: Login to github
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image without cache
if: github.event_name == 'schedule'
env:
BRANCH_NAME: ${{ steps.extract-branch.outputs.branch }}
GHCR_USERNAME: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_ARM: ${{ steps.tags.outputs.TAG_ARM }}
run: |
build_helpers/publish_docker_arm64.sh
docker build -t ${IMAGE_NAME}:${TAG_ARM} .
- name: Build image with cache
if: github.event_name != 'schedule'
env:
TAG_ARM: ${{ steps.tags.outputs.TAG_ARM }}
run: |
docker pull ${IMAGE_NAME}:${TAG_ARM} || true
docker build --cache-from ${IMAGE_NAME}:${TAG_ARM} -t ${CACHE_IMAGE}:${TAG_ARM} .
- name: Run build for AI images
env:
TAG_ARM: ${{ steps.tags.outputs.TAG_ARM }}
TAG_PLOT_ARM: ${{ steps.tags.outputs.TAG_PLOT_ARM }}
TAG_FREQAI_ARM: ${{ steps.tags.outputs.TAG_FREQAI_ARM }}
TAG_FREQAI_RL_ARM: ${{ steps.tags.outputs.TAG_FREQAI_RL_ARM }}
run: |
docker build --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t ${CACHE_IMAGE}:${TAG_PLOT_ARM} -f docker/Dockerfile.plot .
docker build --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t ${CACHE_IMAGE}:${TAG_FREQAI_ARM} -f docker/Dockerfile.freqai .
docker build --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_FREQAI_ARM} -t ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM} -f docker/Dockerfile.freqai_rl .
- name: Run backtest in Docker
env:
TAG_ARM: ${{ steps.tags.outputs.TAG_ARM }}
run: |
docker run --rm -v $(pwd)/tests/testdata/config.tests.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests ${CACHE_IMAGE}:${TAG_ARM} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
- name: Docker images
run: |
docker images
- name: Push cache images
env:
TAG_ARM: ${{ steps.tags.outputs.TAG_ARM }}
TAG_PLOT_ARM: ${{ steps.tags.outputs.TAG_PLOT_ARM }}
TAG_FREQAI_ARM: ${{ steps.tags.outputs.TAG_FREQAI_ARM }}
TAG_FREQAI_RL_ARM: ${{ steps.tags.outputs.TAG_FREQAI_RL_ARM }}
run: |
docker push ${CACHE_IMAGE}:$TAG_PLOT_ARM
docker push ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM
docker push ${CACHE_IMAGE}:$TAG_ARM
- name: Create manifests
env:
TAG_ARM: ${{ steps.tags.outputs.TAG_ARM }}
TAG: ${{ steps.tags.outputs.TAG }}
TAG_PI: ${{ steps.tags.outputs.TAG_PI }}
run: |
docker buildx imagetools create \
--tag ${IMAGE_NAME}:${TAG} \
--tag ${GHCR_IMAGE_NAME}:${TAG} \
${CACHE_IMAGE}:${TAG} ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI}
- name: Create multiarch image - Plot
env:
TAG_PLOT: ${{ steps.tags.outputs.TAG_PLOT }}
TAG_PLOT_ARM: ${{ steps.tags.outputs.TAG_PLOT_ARM }}
run: |
docker buildx imagetools create \
--tag ${IMAGE_NAME}:${TAG_PLOT} \
--tag ${GHCR_IMAGE_NAME}:${TAG_PLOT} \
${CACHE_IMAGE}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM}
- name: Create multiarch image - FreqAI
env:
TAG_FREQAI: ${{ steps.tags.outputs.TAG_FREQAI }}
TAG_FREQAI_ARM: ${{ steps.tags.outputs.TAG_FREQAI_ARM }}
run: |
docker buildx imagetools create \
--tag ${IMAGE_NAME}:${TAG_FREQAI} \
--tag ${GHCR_IMAGE_NAME}:${TAG_FREQAI} \
${CACHE_IMAGE}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI_ARM}
- name: Create multiarch image - FreqAI RL
env:
TAG_FREQAI_RL: ${{ steps.tags.outputs.TAG_FREQAI_RL }}
TAG_FREQAI_RL_ARM: ${{ steps.tags.outputs.TAG_FREQAI_RL_ARM }}
TAG_FREQAI_TORCH: ${{ steps.tags.outputs.TAG_FREQAI_TORCH }}
run: |
# Create special Torch tag - which is identical to the RL tag.
docker buildx imagetools create \
--tag ${IMAGE_NAME}:${TAG_FREQAI_RL} \
--tag ${GHCR_IMAGE_NAME}:${TAG_FREQAI_RL} \
--tag ${IMAGE_NAME}:${TAG_FREQAI_TORCH} \
--tag ${GHCR_IMAGE_NAME}:${TAG_FREQAI_TORCH} \
${CACHE_IMAGE}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM}
- name: Tag latest
if: env.TAG == 'develop'
env:
TAG: ${{ steps.tags.outputs.TAG }}
run: |
# Tag image as latest
docker buildx imagetools create \
--tag ${GHCR_IMAGE_NAME}:${TAG} \
--tag ${GHCR_IMAGE_NAME}:latest \
${IMAGE_NAME}:${TAG}
- name: Docker images
run: |
docker images
- name: Image cleanup
run: |
docker image prune -a --force --filter "until=24h"
- name: Discord notification
uses: rjstone/discord-webhook-notify@c2597273488aeda841dd1e891321952b51f7996f #v2.2.1
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
persist-credentials: false
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4.0.2
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
+46
View File
@@ -0,0 +1,46 @@
name: Cleanup Packages
on:
workflow_call:
inputs:
package_name:
description: 'Package name to clean up'
required: false
default: 'freqtrade'
type: string
workflow_dispatch:
inputs:
package_name:
description: 'Package name to clean up'
required: false
default: 'freqtrade'
type: choice
options:
- 'freqtrade'
- 'freqtrade-devcontainer'
delete-untagged:
description: 'Whether to delete only untagged images'
required: false
default: true
type: boolean
env:
PACKAGE_NAME: "freqtrade"
jobs:
deploy-docker:
name: "Delete Packages"
runs-on: ubuntu-24.04
if: github.repository == 'freqtrade/freqtrade'
permissions:
packages: write
steps:
- name: "Delete untagged Package Versions"
uses: actions/delete-package-versions@v5
with:
package-name: ${{ inputs.package_name || env.PACKAGE_NAME }}
package-type: 'container'
min-versions-to-keep: 10
delete-only-untagged-versions: ${{ inputs.delete-untagged || 'true' }}
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
with:
persist-credentials: false
- uses: actions/setup-python@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"
+2 -2
View File
@@ -21,9 +21,9 @@ jobs:
# actions: read # only needed for private repos
steps:
- name: Checkout repository
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4.2.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Run zizmor 🌈
uses: zizmorcore/zizmor-action@5ca5fc7a4779c5263a3ffa0e1f693009994446d1 # v0.1.2
uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0
+10 -10
View File
@@ -21,22 +21,22 @@ repos:
# stages: [push]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.17.1"
rev: "v1.18.2"
hooks:
- id: mypy
exclude: build_helpers
additional_dependencies:
- types-cachetools==6.1.0.20250717
- types-cachetools==6.2.0.20251022
- types-filelock==3.2.7
- types-requests==2.32.4.20250809
- types-requests==2.32.4.20250913
- types-tabulate==0.9.0.20241207
- types-python-dateutil==2.9.0.20250822
- scipy-stubs==1.16.1.1
- SQLAlchemy==2.0.43
- types-python-dateutil==2.9.0.20251008
- scipy-stubs==1.16.2.4
- SQLAlchemy==2.0.44
# stages: [push]
- repo: https://github.com/pycqa/isort
rev: "6.0.1"
rev: "7.0.0"
hooks:
- id: isort
name: isort (python)
@@ -44,7 +44,7 @@ repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
# Ruff version.
rev: 'v0.12.10'
rev: 'v0.14.2'
hooks:
- id: ruff
- id: ruff-format
@@ -70,7 +70,7 @@ repos:
)$
- repo: https://github.com/stefmolin/exif-stripper
rev: 1.1.0
rev: 1.2.0
hooks:
- id: strip-exif
@@ -83,6 +83,6 @@ repos:
# Ensure github actions remain safe
- repo: https://github.com/woodruffw/zizmor-pre-commit
rev: v1.12.1
rev: v1.16.0
hooks:
- id: zizmor
+32 -30
View File
@@ -9,8 +9,10 @@ Issues labeled [good first issue](https://github.com/freqtrade/freqtrade/labels/
Few pointers for contributions:
- Create your PR against the `develop` branch, not `stable`.
- New features need to contain unit tests, must conform to PEP8 (max-line-length = 100) and should be documented with the introduction PR.
- PR's can be declared as `[WIP]` - which signify Work in Progress Pull Requests (which are not finished).
- Stick to english in both commit messages, PR descriptions and code comments and variable names.
- New features need to contain unit tests, must pass CI (run pre-commit and pytest to get an early feedback) and should be documented with the introduction PR.
- PR's can be declared as draft - signaling Work in Progress for Pull Requests (which are not finished). We'll still aim to provide feedback on draft PR's in a timely manner.
- If you're using AI for your PR, please both mention it in the PR description and do a thorough review of the generated code. The final responsibility for the code with the PR author, not with the AI.
If you are unsure, discuss the feature on our [discord server](https://discord.gg/p7nuUNVfP7) or in a [issue](https://github.com/freqtrade/freqtrade/issues) before a Pull Request.
@@ -43,43 +45,43 @@ pytest tests/test_<file_name>.py
pytest tests/test_<file_name>.py::test_<method_name>
```
### 2. Test if your code is PEP8 compliant
### 2. Test if your code corresponds to our style guide
#### Run Ruff
We receive a lot of code that fails preliminary CI checks.
To help with that, we encourage contributors to install the git pre-commit hook that will let you know immediately when you try to commit code that fails these checks.
You can manually run pre-commit with `pre-commit run -a` - or install the git hook with `pre-commit install` to have it run automatically on each commit.
Running `pre-commit run -a` will run all checks, including `ruff`, `mypy` and `codespell` (among others).
#### Additional styles applied
- Have docstrings on all public methods
- Use double-quotes for docstrings
- Multiline docstrings should be indented to the level of the first quote
- Doc-strings should follow the reST format (`:param xxx: ...`, `:return: ...`, `:raises KeyError: ...`)
#### Manually run the individual checks
The following sections describe how to run the individual checks that are running as part of the pre-commit hook.
##### Run ruff
Check your code with ruff to ensure that it follows the style guide.
```bash
ruff check .
ruff format .
```
We receive a lot of code that fails the `ruff` checks.
To help with that, we encourage you to install the git pre-commit
hook that will warn you when you try to commit code that fails these checks.
##### Run mypy
you can manually run pre-commit with `pre-commit run -a`.
##### Additional styles applied
* Have docstrings on all public methods
* Use double-quotes for docstrings
* Multiline docstrings should be indented to the level of the first quote
* Doc-strings should follow the reST format (`:param xxx: ...`, `:return: ...`, `:raises KeyError: ... `)
### 3. Test if all type-hints are correct
#### Run mypy
Check your code with mypy to ensure that it follows the type-hinting rules.
``` bash
mypy freqtrade
```
### 4. Ensure formatting is correct
#### Run ruff
``` bash
ruff format .
```
## (Core)-Committer Guide
### Process: Pull Requests
@@ -118,18 +120,18 @@ Exceptions:
- Ensure cross-platform compatibility for every change that's accepted. Windows, Mac & Linux.
- Ensure no malicious code is introduced into the core code.
- Create issues for any major changes and enhancements that you wish to make. Discuss things transparently and get community feedback.
- Keep feature versions as small as possible, preferably one new feature per version.
- Keep feature PR's as small as possible, preferably one new feature per PR.
- Be welcoming to newcomers and encourage diverse new contributors from all backgrounds. See the Python Community Code of Conduct (https://www.python.org/psf/codeofconduct/).
### Becoming a Committer
Contributors may be given commit privileges. Preference will be given to those with:
1. Past contributions to Freqtrade and other related open-source projects. Contributions to Freqtrade include both code (both accepted and pending) and friendly participation in the issue tracker and Pull request reviews. Both quantity and quality are considered.
1. Past contributions to Freqtrade and other related open source projects. Contributions to Freqtrade include both code (both accepted and pending) and friendly participation in the issue tracker and Pull request reviews. Both quantity and quality are considered.
1. A coding style that the other core committers find simple, minimal, and clean.
1. Access to resources for cross-platform development and testing.
1. Time to devote to the project regularly.
Being a Committer does not grant write permission on `develop` or `stable` for security reasons (Users trust Freqtrade with their Exchange API keys).
Being a Committer does not automatically grant write permission on `develop` or `stable` for security reasons (Users trust Freqtrade with their Exchange API keys).
After being Committer for some time, a Committer may be named Core Committer and given full repository access.
+1 -1
View File
@@ -1,4 +1,4 @@
FROM python:3.13.7-slim-bookworm AS base
FROM python:3.13.8-slim-bookworm AS base
# Setup env
ENV LANG=C.UTF-8
+3 -1
View File
@@ -27,8 +27,9 @@ 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.
- [X] [Binance](https://www.binance.com/)
- [X] [Bitmart](https://bitmart.com/)
- [X] [BingX](https://bingx.com/invite/0EM9RX)
- [X] [Bitget](https://www.bitget.com/)
- [X] [Bitmart](https://bitmart.com/)
- [X] [Bybit](https://bybit.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [HTX](https://www.htx.com/)
@@ -41,6 +42,7 @@ Please read the [exchange specific notes](docs/exchanges.md) to learn about even
### Supported Futures Exchanges (experimental)
- [X] [Binance](https://www.binance.com/)
- [X] [Bitget](https://www.bitget.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Hyperliquid](https://hyperliquid.xyz/) (A decentralized exchange, or DEX)
- [X] [OKX](https://okx.com/)
-119
View File
@@ -1,119 +0,0 @@
#!/bin/sh
# Use BuildKit, otherwise building on ARM fails
export DOCKER_BUILDKIT=1
IMAGE_NAME=freqtradeorg/freqtrade
CACHE_IMAGE=freqtradeorg/freqtrade_cache
GHCR_IMAGE_NAME=ghcr.io/freqtrade/freqtrade
# Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot
TAG_FREQAI=${TAG}_freqai
TAG_FREQAI_RL=${TAG_FREQAI}rl
TAG_FREQAI_TORCH=${TAG_FREQAI}torch
TAG_PI="${TAG}_pi"
TAG_ARM=${TAG}_arm
TAG_PLOT_ARM=${TAG_PLOT}_arm
TAG_FREQAI_ARM=${TAG_FREQAI}_arm
TAG_FREQAI_RL_ARM=${TAG_FREQAI_RL}_arm
echo "Running for ${TAG}"
# Add commit and commit_message to docker container
echo "${GITHUB_SHA}" > freqtrade_commit
if [ "${GITHUB_EVENT_NAME}" = "schedule" ]; then
echo "event ${GITHUB_EVENT_NAME}: full rebuild - skipping cache"
# Build regular image
docker build -t freqtrade:${TAG_ARM} .
else
echo "event ${GITHUB_EVENT_NAME}: building with cache"
# Build regular image
docker pull ${IMAGE_NAME}:${TAG_ARM}
docker build --cache-from ${IMAGE_NAME}:${TAG_ARM} -t freqtrade:${TAG_ARM} .
fi
if [ $? -ne 0 ]; then
echo "failed building multiarch images"
return 1
fi
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_PLOT_ARM} -f docker/Dockerfile.plot .
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_FREQAI_ARM} -f docker/Dockerfile.freqai .
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_FREQAI_ARM} -t freqtrade:${TAG_FREQAI_RL_ARM} -f docker/Dockerfile.freqai_rl .
# Tag image for upload and next build step
docker tag freqtrade:$TAG_ARM ${CACHE_IMAGE}:$TAG_ARM
docker tag freqtrade:$TAG_PLOT_ARM ${CACHE_IMAGE}:$TAG_PLOT_ARM
docker tag freqtrade:$TAG_FREQAI_ARM ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker tag freqtrade:$TAG_FREQAI_RL_ARM ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM
# Run backtest
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
echo "failed running backtest"
return 1
fi
docker images
docker push ${CACHE_IMAGE}:$TAG_PLOT_ARM
docker push ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM
docker push ${CACHE_IMAGE}:$TAG_ARM
# Create multi-arch image
# Make sure that all images contained here are pushed to github first.
# Otherwise installation might fail.
echo "create manifests"
docker manifest create ${IMAGE_NAME}:${TAG} ${CACHE_IMAGE}:${TAG} ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI}
docker manifest push -p ${IMAGE_NAME}:${TAG}
docker manifest create ${IMAGE_NAME}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_PLOT}
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI}
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI_RL}
# Create special Torch tag - which is identical to the RL tag.
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI_TORCH} ${CACHE_IMAGE}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI_TORCH}
# copy images to ghcr.io
alias crane="docker run --rm -i -v $(pwd)/.crane:/home/nonroot/.docker/ gcr.io/go-containerregistry/crane"
mkdir .crane
chmod a+rwx .crane
echo "${GHCR_TOKEN}" | crane auth login ghcr.io -u "${GHCR_USERNAME}" --password-stdin
crane copy ${IMAGE_NAME}:${TAG_FREQAI_RL} ${GHCR_IMAGE_NAME}:${TAG_FREQAI_RL}
crane copy ${IMAGE_NAME}:${TAG_FREQAI_RL} ${GHCR_IMAGE_NAME}:${TAG_FREQAI_TORCH}
crane copy ${IMAGE_NAME}:${TAG_FREQAI} ${GHCR_IMAGE_NAME}:${TAG_FREQAI}
crane copy ${IMAGE_NAME}:${TAG_PLOT} ${GHCR_IMAGE_NAME}:${TAG_PLOT}
crane copy ${IMAGE_NAME}:${TAG} ${GHCR_IMAGE_NAME}:${TAG}
# Tag as latest for develop builds
if [ "${TAG}" = "develop" ]; then
echo 'Tagging image as latest'
docker manifest create ${IMAGE_NAME}:latest ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG}
docker manifest push -p ${IMAGE_NAME}:latest
crane copy ${IMAGE_NAME}:latest ${GHCR_IMAGE_NAME}:latest
fi
docker images
rm -rf .crane
# Cleanup old images from arm64 node.
docker image prune -a --force --filter "until=24h"
-89
View File
@@ -1,89 +0,0 @@
#!/bin/sh
# The below assumes a correctly setup docker buildx environment
IMAGE_NAME=freqtradeorg/freqtrade
CACHE_IMAGE=freqtradeorg/freqtrade_cache
# Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot
TAG_FREQAI=${TAG}_freqai
TAG_FREQAI_RL=${TAG_FREQAI}rl
TAG_PI="${TAG}_pi"
PI_PLATFORM="linux/arm/v7"
echo "Running for ${TAG}"
CACHE_TAG=${CACHE_IMAGE}:${TAG_PI}_cache
# Add commit and commit_message to docker container
echo "${GITHUB_SHA}" > freqtrade_commit
if [ "${GITHUB_EVENT_NAME}" = "schedule" ]; then
echo "event ${GITHUB_EVENT_NAME}: full rebuild - skipping cache"
# Build regular image
docker build -t freqtrade:${TAG} .
# Build PI image
docker buildx build \
--cache-to=type=registry,ref=${CACHE_TAG} \
-f docker/Dockerfile.armhf \
--platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG_PI} \
--push \
--provenance=false \
.
else
echo "event ${GITHUB_EVENT_NAME}: building with cache"
# Build regular image
docker pull ${IMAGE_NAME}:${TAG}
docker build --cache-from ${IMAGE_NAME}:${TAG} -t freqtrade:${TAG} .
# Pull last build to avoid rebuilding the whole image
# docker pull --platform ${PI_PLATFORM} ${IMAGE_NAME}:${TAG}
# disable provenance due to https://github.com/docker/buildx/issues/1509
docker buildx build \
--cache-from=type=registry,ref=${CACHE_TAG} \
--cache-to=type=registry,ref=${CACHE_TAG} \
-f docker/Dockerfile.armhf \
--platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG_PI} \
--push \
--provenance=false \
.
fi
if [ $? -ne 0 ]; then
echo "failed building multiarch images"
return 1
fi
# Tag image for upload and next build step
docker tag freqtrade:$TAG ${CACHE_IMAGE}:$TAG
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG} -t freqtrade:${TAG_PLOT} -f docker/Dockerfile.plot .
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG} -t freqtrade:${TAG_FREQAI} -f docker/Dockerfile.freqai .
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_FREQAI} -t freqtrade:${TAG_FREQAI_RL} -f docker/Dockerfile.freqai_rl .
docker tag freqtrade:$TAG_PLOT ${CACHE_IMAGE}:$TAG_PLOT
docker tag freqtrade:$TAG_FREQAI ${CACHE_IMAGE}:$TAG_FREQAI
docker tag freqtrade:$TAG_FREQAI_RL ${CACHE_IMAGE}:$TAG_FREQAI_RL
# Run backtest
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
echo "failed running backtest"
return 1
fi
docker images
docker push ${CACHE_IMAGE}:$TAG
docker push ${CACHE_IMAGE}:$TAG_PLOT
docker push ${CACHE_IMAGE}:$TAG_FREQAI
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL
docker images
if [ $? -ne 0 ]; then
echo "failed building image"
return 1
fi
+8 -1
View File
@@ -268,7 +268,8 @@
"day",
"week",
"month",
"year"
"year",
"weekday"
]
}
},
@@ -587,6 +588,7 @@
"RemotePairList",
"MarketCapPairList",
"AgeFilter",
"DelistFilter",
"FullTradesFilter",
"OffsetFilter",
"PerformanceFilter",
@@ -1460,6 +1462,11 @@
"type": "boolean",
"default": false
},
"override_exchange_check": {
"description": "Override the exchange check to force FreqAI to use exchanges that may not have enough historic data. Turn this to True if you know your FreqAI model and strategy do not require historical data.",
"type": "boolean",
"default": false
},
"feature_parameters": {
"description": "The parameters used to engineer the feature set",
"type": "object",
+38 -18
View File
@@ -25,10 +25,10 @@
"trading_mode": "spot",
"margin_mode": "",
"minimal_roi": {
"40": 0.0,
"30": 0.01,
"20": 0.02,
"0": 0.04
"40": 0.0,
"30": 0.01,
"20": 0.02,
"0": 0.04
},
"stoploss": -0.10,
"unfilledtimeout": {
@@ -47,7 +47,7 @@
"bids_to_ask_delta": 1
}
},
"exit_pricing":{
"exit_pricing": {
"price_side": "same",
"use_order_book": true,
"order_book_top": 1,
@@ -70,18 +70,38 @@
"exit": "GTC"
},
"pairlists": [
{"method": "StaticPairList"},
{"method": "FullTradesFilter"},
{
"method": "StaticPairList"
},
{
"method": "DelistFilter",
"max_days_from_now": 0,
},
{
"method": "FullTradesFilter"
},
{
"method": "VolumePairList",
"number_assets": 20,
"sort_key": "quoteVolume",
"refresh_period": 1800
},
{"method": "AgeFilter", "min_days_listed": 10},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01, "min_price": 0.00000010},
{"method": "SpreadFilter", "max_spread_ratio": 0.005},
{
"method": "AgeFilter",
"min_days_listed": 10
},
{
"method": "PrecisionFilter"
},
{
"method": "PriceFilter",
"low_price_ratio": 0.01,
"min_price": 0.00000010
},
{
"method": "SpreadFilter",
"max_spread_ratio": 0.005
},
{
"method": "RangeStabilityFilter",
"lookback_days": 10,
@@ -166,12 +186,12 @@
"external_message_consumer": {
"enabled": false,
"producers": [
{
"name": "default",
"host": "127.0.0.2",
"port": 8080,
"ws_token": "secret_ws_t0ken."
}
{
"name": "default",
"host": "127.0.0.2",
"port": 8080,
"ws_token": "secret_ws_t0ken."
}
],
"wait_timeout": 300,
"ping_timeout": 10,
@@ -195,4 +215,4 @@
"reduce_df_footprint": false,
"dataformat_ohlcv": "feather",
"dataformat_trades": "feather"
}
}
+1 -2
View File
@@ -34,8 +34,7 @@ COPY build_helpers/* /tmp/
# Install dependencies
COPY --chown=ftuser:ftuser requirements.txt /freqtrade/
USER ftuser
RUN pip install --user --prefer-binary --no-cache-dir "numpy<3.0" build \
&& pip install --user --no-index --find-links /tmp/ pyarrow TA-Lib \
RUN pip install --user --only-binary=:all: --find-links /tmp/ pyarrow TA-Lib \
&& pip install --user --no-cache-dir -r requirements.txt
# Copy dependencies to runtime-image
+2 -2
View File
@@ -134,10 +134,10 @@ The following systems have been tested and are known to work with freqtrade:
### PostgreSQL
Installation:
`pip install psycopg2-binary`
`pip install "psycopg[binary]"`
Usage:
`... --db-url postgresql+psycopg2://<username>:<password>@localhost:5432/<database>`
`... --db-url postgresql+psycopg://<username>:<password>@localhost:5432/<database>`
Freqtrade will automatically create the tables necessary upon startup.
+3 -3
View File
@@ -4,7 +4,7 @@ usage: freqtrade backtesting-show [-h] [-v] [--no-color] [--logfile FILE] [-V]
[--backtest-filename PATH]
[--backtest-directory PATH]
[--show-pair-list]
[--breakdown {day,week,month,year} [{day,week,month,year} ...]]
[--breakdown {day,week,month,year,weekday} [{day,week,month,year,weekday} ...]]
options:
-h, --help show this help message and exit
@@ -18,9 +18,9 @@ options:
Directory to use for backtest results. Example:
`--export-directory=user_data/backtest_results/`.
--show-pair-list Show backtesting pairlist sorted by profit.
--breakdown {day,week,month,year} [{day,week,month,year} ...]
--breakdown {day,week,month,year,weekday} [{day,week,month,year,weekday} ...]
Show backtesting breakdown per [day, week, month,
year].
year, weekday].
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
+10 -4
View File
@@ -10,13 +10,14 @@ usage: freqtrade backtesting [-h] [-v] [--no-color] [--logfile FILE] [-V]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[-p PAIRS [PAIRS ...]] [--eps]
[--enable-protections]
[--enable-dynamic-pairlist]
[--dry-run-wallet DRY_RUN_WALLET]
[--timeframe-detail TIMEFRAME_DETAIL]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
[--export {none,trades,signals}]
[--backtest-filename PATH]
[--backtest-directory PATH]
[--breakdown {day,week,month,year} [{day,week,month,year} ...]]
[--breakdown {day,week,month,year,weekday} [{day,week,month,year,weekday} ...]]
[--cache {none,day,week,month}]
[--freqai-backtest-live-models] [--notes TEXT]
@@ -44,9 +45,14 @@ options:
Allow buying the same pair multiple times (position
stacking).
--enable-protections, --enableprotections
Enable protections for backtesting.Will slow
Enable protections for backtesting. Will slow
backtesting down by a considerable amount, but will
include configured protections
--enable-dynamic-pairlist
Enables dynamic pairlist refreshes in backtesting. The
pairlist will be generated for each new candle if
you're using a pairlist handler that supports this
feature, for example, ShuffleFilter.
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
Starting balance, used for backtesting / hyperopt and
dry-runs.
@@ -71,9 +77,9 @@ options:
--backtest-directory PATH, --export-directory PATH
Directory to use for backtest results. Example:
`--export-directory=user_data/backtest_results/`.
--breakdown {day,week,month,year} [{day,week,month,year} ...]
--breakdown {day,week,month,year,weekday} [{day,week,month,year,weekday} ...]
Show backtesting breakdown per [day, week, month,
year].
year, weekday].
--cache {none,day,week,month}
Load a cached backtest result no older than specified
age (default: day).
+4
View File
@@ -4,6 +4,7 @@ usage: freqtrade download-data [-h] [-v] [--no-color] [--logfile FILE] [-V]
[-p PAIRS [PAIRS ...]] [--pairs-file FILE]
[--days INT] [--new-pairs-days INT]
[--include-inactive-pairs]
[--no-parallel-download]
[--timerange TIMERANGE] [--dl-trades]
[--convert] [--exchange EXCHANGE]
[-t TIMEFRAMES [TIMEFRAMES ...]] [--erase]
@@ -24,6 +25,9 @@ options:
Default: `None`.
--include-inactive-pairs
Also download data from inactive pairs.
--no-parallel-download
Disable parallel startup download. Only use this if
you experience issues.
--timerange TIMERANGE
Specify what timerange of data to use.
--dl-trades Download trades instead of OHLCV data.
+3 -3
View File
@@ -4,7 +4,7 @@ usage: freqtrade hyperopt-show [-h] [-v] [--no-color] [--logfile FILE] [-V]
[--profitable] [-n INT] [--print-json]
[--hyperopt-filename FILENAME] [--no-header]
[--disable-param-export]
[--breakdown {day,week,month,year} [{day,week,month,year} ...]]
[--breakdown {day,week,month,year,weekday} [{day,week,month,year,weekday} ...]]
options:
-h, --help show this help message and exit
@@ -18,9 +18,9 @@ options:
--no-header Do not print epoch details header.
--disable-param-export
Disable automatic hyperopt parameter export.
--breakdown {day,week,month,year} [{day,week,month,year} ...]
--breakdown {day,week,month,year,weekday} [{day,week,month,year,weekday} ...]
Show backtesting breakdown per [day, week, month,
year].
year, weekday].
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
+1 -1
View File
@@ -44,7 +44,7 @@ options:
Allow buying the same pair multiple times (position
stacking).
--enable-protections, --enableprotections
Enable protections for backtesting.Will slow
Enable protections for backtesting. Will slow
backtesting down by a considerable amount, but will
include configured protections
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
+10 -1
View File
@@ -11,6 +11,7 @@ usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE]
[--stake-amount STAKE_AMOUNT]
[--fee FLOAT] [-p PAIRS [PAIRS ...]]
[--enable-protections]
[--enable-dynamic-pairlist]
[--dry-run-wallet DRY_RUN_WALLET]
[--timeframe-detail TIMEFRAME_DETAIL]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
@@ -21,6 +22,7 @@ usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE]
[--minimum-trade-amount INT]
[--targeted-trade-amount INT]
[--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME]
[--allow-limit-orders]
options:
-h, --help show this help message and exit
@@ -43,9 +45,14 @@ options:
Limit command to these pairs. Pairs are space-
separated.
--enable-protections, --enableprotections
Enable protections for backtesting.Will slow
Enable protections for backtesting. Will slow
backtesting down by a considerable amount, but will
include configured protections
--enable-dynamic-pairlist
Enables dynamic pairlist refreshes in backtesting. The
pairlist will be generated for each new candle if
you're using a pairlist handler that supports this
feature, for example, ShuffleFilter.
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
Starting balance, used for backtesting / hyperopt and
dry-runs.
@@ -79,6 +86,8 @@ options:
--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME
Use this csv-filename to store lookahead-analysis-
results
--allow-limit-orders Allow limit orders in lookahead analysis (could cause
false positives in lookahead analysis results).
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
+4 -5
View File
@@ -571,9 +571,7 @@ Commonly used time in force are:
**GTC (Good Till Canceled):**
This is most of the time the default time in force. It means the order will remain
on exchange till it is cancelled by the user. It can be fully or partially fulfilled.
If partially fulfilled, the remaining will stay on the exchange till cancelled.
This is most of the time the default time in force. It means the order will remain on exchange till it is cancelled by the user. It can be fully or partially fulfilled. If partially fulfilled, the remaining will stay on the exchange till cancelled.
**FOK (Fill Or Kill):**
@@ -581,8 +579,9 @@ It means if the order is not executed immediately AND fully then it is cancelled
**IOC (Immediate Or Canceled):**
It is the same as FOK (above) except it can be partially fulfilled. The remaining part
is automatically cancelled by the exchange.
It is the same as FOK (above) except it can be partially fulfilled. The remaining part is automatically cancelled by the exchange.
Not necessarily recommended, as this can lead to partial fills below the minimum trade size.
**PO (Post only):**
+20 -5
View File
@@ -2,6 +2,10 @@
This page combines common gotchas and Information which are exchange-specific and most likely don't apply to other exchanges.
## Quick overview of supported exchange features
--8<-- "includes/exchange-features.md"
## Exchange configuration
Freqtrade is based on [CCXT library](https://github.com/ccxt/ccxt) that supports over 100 cryptocurrency
@@ -294,7 +298,14 @@ Without these permissions, the bot will not start correctly and show errors like
Bybit supports [time_in_force](configuration.md#understand-order_time_in_force) with settings "GTC" (good till cancelled), "FOK" (full-or-cancel), "IOC" (immediate-or-cancel) and "PO" (Post only) settings.
Futures trading on bybit is currently supported for isolated futures mode.
!!! Warning "Unified accounts"
Freqtrade assumes accounts to be dedicated to the bot.
We therefore recommend the usage of one subaccount per bot. This is especially important when using unified accounts.
Other configurations (multiple bots on one account, manual non-bot trades on the bot account) are not supported and may lead to unexpected behavior.
### Bybit Futures
Futures trading on bybit is supported for isolated futures mode.
On startup, freqtrade will set the position mode to "One-way Mode" for the whole (sub)account. This avoids making this call over and over again (slowing down bot operations), but means that manual changes to this setting may result in exceptions and errors.
@@ -308,10 +319,6 @@ API Keys for live futures trading must have the following permissions:
We do strongly recommend to limit all API keys to the IP you're going to use it from.
!!! Warning "Unified accounts"
Freqtrade assumes accounts to be dedicated to the bot.
We therefore recommend the usage of one subaccount per bot. This is especially important when using unified accounts.
Other configurations (multiple bots on one account, manual non-bot trades on the bot account) are not supported and may lead to unexpected behavior.
## Bitmart
@@ -351,6 +358,12 @@ Bitget supports [time_in_force](configuration.md#understand-order_time_in_force)
Bitget supports `stoploss_on_exchange` and can use both stop-loss-market and stop-loss-limit orders. It provides great advantages, so we recommend to benefit from it.
You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide which type of stoploss shall be used.
### Bitget Futures
Futures trading on bitget is supported for isolated futures mode.
On startup, freqtrade will set the position mode to "One-way Mode" for the whole (sub)account. This avoids making this call over and over again (slowing down bot operations), but means that manual changes to this setting may result in exceptions and errors.
## Hyperliquid
!!! Tip "Stoploss on Exchange"
@@ -474,3 +487,5 @@ For example, to test the order type `FOK` with Kraken, and modify candle limit t
!!! Warning
Please make sure to fully understand the impacts of these settings before modifying them.
Using `_ft_has_params` overrides may lead to unexpected behavior, and may even break your bot.
We will not be able to provide support for issues caused by custom settings in `_ft_has_params`.
+7
View File
@@ -297,6 +297,13 @@ Should you be asked to expose your exchange keys or send funds to some random wa
Failing to follow these guidelines will not be responsibility of freqtrade.
## Support policy
We provide free support for Freqtrade on our [Discord server](https://discord.gg/p7nuUNVfP7) and via GitHub issues.
We only support the most recent release (e.g. 2025.8) and the current development branch (e.g. 2025.9-dev).
If you're on an older version, please follow the [upgrade instructions](updating.md) and see if your problem has already been addressed.
## "Freqtrade token"
Freqtrade does not have a Crypto token offering.
+11 -2
View File
@@ -4,7 +4,7 @@ Freqtrade provides a builtin webserver, which can serve [FreqUI](https://github.
By default, the UI is automatically installed as part of the installation (script, docker).
freqUI can also be manually installed by using the `freqtrade install-ui` command.
This same command can also be used to update freqUI to new new releases.
This same command can also be used to update freqUI to new releases.
Once the bot is started in trade / dry-run mode (with `freqtrade trade`) - the UI will be available under the configured API port (by default `http://127.0.0.1:8080`).
@@ -70,7 +70,16 @@ Things you can change (among others):
![FreqUI - Settings view](assets/frequi-settings-dark.png#only-dark)
![FreqUI - Settings view](assets/frequi-settings-light.png#only-light)
## Backtesting
## Webserver mode
when freqtrade is started in [webserver mode](utils.md#webserver-mode) (freqtrade started with `freqtrade webserver`), the webserver will start in a special mode allowing for additional features, for example:
* Downloading data
* Testing pairlists
* [Backtesting strategies](#backtesting)
* ... to be expanded
### Backtesting
When freqtrade is started in [webserver mode](utils.md#webserver-mode) (freqtrade started with `freqtrade webserver`), the backtesting view becomes available.
This view allows you to backtest strategies and visualize the results.
+1 -1
View File
@@ -79,7 +79,7 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| `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 documentation. [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.
| `max_training_drawdown_pct` | The maximum drawdown that the agent is allowed to experience during training. <br> **Datatype:** float. <br> Default: 0.8
| `cpu_count` | Number of threads/cpus to dedicate to the Reinforcement Learning training process (depending on if `ReinforcementLearning_multiproc` is selected or not). Recommended to leave this untouched, by default, this value is set to the total number of physical cores minus 1. <br> **Datatype:** int.
| `cpu_count` | Number of threads/cpus to dedicate to the Reinforcement Learning training process (depending on if `ReinforcementLearner_multiproc` is selected or not). Recommended to leave this untouched, by default, this value is set to the total number of physical cores minus 1. <br> **Datatype:** int.
| `model_reward_parameters` | Parameters used inside the customizable `calculate_reward()` function in `ReinforcementLearner.py` <br> **Datatype:** int.
| `add_state_info` | Tell FreqAI to include state information in the feature set for training and inferencing. The current state variables include trade duration, current profit, trade position. This is only available in dry/live runs, and is automatically switched to false for backtesting. <br> **Datatype:** bool. <br> Default: `False`.
| `net_arch` | Network architecture which is well described in [`stable_baselines3` doc](https://stable-baselines3.readthedocs.io/en/master/guide/custom_policy.html#examples). In summary: `[<shared layers>, dict(vf=[<non-shared value network layers>], pi=[<non-shared policy network layers>])]`. By default this is set to `[128, 128]`, which defines 2 shared hidden layers with 128 units each.
+3 -3
View File
@@ -7,7 +7,7 @@
FreqAI is a software designed to automate a variety of tasks associated with training a predictive machine learning model to generate market forecasts given a set of input signals. In general, FreqAI aims to be a sandbox for easily deploying robust machine learning libraries on real-time data ([details](#freqai-position-in-open-source-machine-learning-landscape)).
!!! Note
FreqAI is, and always will be, a not-for-profit, open-source project. FreqAI does *not* have a crypto token, FreqAI does *not* sell signals, and FreqAI does not have a domain besides the present [freqtrade documentation](https://www.freqtrade.io/en/latest/freqai/).
FreqAI is, and always will be, a not-for-profit, open source project. FreqAI does *not* have a crypto token, FreqAI does *not* sell signals, and FreqAI does not have a domain besides the present [freqtrade documentation](https://www.freqtrade.io/en/latest/freqai/).
Features include:
@@ -81,9 +81,9 @@ If you are using docker, a dedicated tag with FreqAI dependencies is available a
!!! note "docker-compose-freqai.yml"
We do provide an explicit docker-compose file for this in `docker/docker-compose-freqai.yml` - which can be used via `docker compose -f docker/docker-compose-freqai.yml run ...` - or can be copied to replace the original docker file. This docker-compose file also contains a (disabled) section to enable GPU resources within docker containers. This obviously assumes the system has GPU resources available.
### FreqAI position in open-source machine learning landscape
### FreqAI position in open source machine learning landscape
Forecasting chaotic time-series based systems, such as equity/cryptocurrency markets, requires a broad set of tools geared toward testing a wide range of hypotheses. Fortunately, a recent maturation of robust machine learning libraries (e.g. `scikit-learn`) has opened up a wide range of research possibilities. Scientists from a diverse range of fields can now easily prototype their studies on an abundance of established machine learning algorithms. Similarly, these user-friendly libraries enable "citizen scientists" to use their basic Python skills for data exploration. However, leveraging these machine learning libraries on historical and live chaotic data sources can be logistically difficult and expensive. Additionally, robust data collection, storage, and handling presents a disparate challenge. [`FreqAI`](#freqai) aims to provide a generalized and extensible open-sourced framework geared toward live deployments of adaptive modeling for market forecasting. The `FreqAI` framework is effectively a sandbox for the rich world of open-source machine learning libraries. Inside the `FreqAI` sandbox, users find they can combine a wide variety of third-party libraries to test creative hypotheses on a free live 24/7 chaotic data source - cryptocurrency exchange data.
Forecasting chaotic time-series based systems, such as equity/cryptocurrency markets, requires a broad set of tools geared toward testing a wide range of hypotheses. Fortunately, a recent maturation of robust machine learning libraries (e.g. `scikit-learn`) has opened up a wide range of research possibilities. Scientists from a diverse range of fields can now easily prototype their studies on an abundance of established machine learning algorithms. Similarly, these user-friendly libraries enable "citizen scientists" to use their basic Python skills for data exploration. However, leveraging these machine learning libraries on historical and live chaotic data sources can be logistically difficult and expensive. Additionally, robust data collection, storage, and handling presents a disparate challenge. [`FreqAI`](#freqai) aims to provide a generalized and extensible open-sourced framework geared toward live deployments of adaptive modeling for market forecasting. The `FreqAI` framework is effectively a sandbox for the rich world of open source machine learning libraries. Inside the `FreqAI` sandbox, users find they can combine a wide variety of third-party libraries to test creative hypotheses on a free live 24/7 chaotic data source - cryptocurrency exchange data.
### Citing FreqAI
+21
View File
@@ -0,0 +1,21 @@
| Exchange | Mode | Margin mode | Stoploss type |
|---------|---------|------|------------------|
| [Binance](exchanges.md#binance) | spot | | limit |
| [Binance](exchanges.md#binance) | futures | isolated, cross | market, limit |
| [Bingx](exchanges.md#bingx) | spot | | market, limit |
| [Bitmart](exchanges.md#bitmart) | spot | | ❌ (not supported) |
| [Bitget](exchanges.md#bitget) | spot | | market, limit |
| [Bitget](exchanges.md#bitget) | futures | isolated | market, limit |
| [Bybit](exchanges.md#bybit) | spot | | ❌ (not supported) |
| [Bybit](exchanges.md#bybit) | futures | isolated | market, limit |
| [Gate.io](exchanges.md#gateio) | spot | | limit |
| [Gate.io](exchanges.md#gateio) | futures | isolated | limit |
| [HTX](exchanges.md#htx) | spot | | limit |
| [Hyperliquid](exchanges.md#hyperliquid) | spot | | ❌ (not supported) |
| [Hyperliquid](exchanges.md#hyperliquid) | futures | isolated, cross | limit |
| [Kraken](exchanges.md#kraken) | spot | | market, limit |
| [OKX](exchanges.md#okx) | spot | | limit |
| [OKX](exchanges.md#okx) | futures | isolated | limit |
| [Bitvavo](exchanges.md#bitvavo) | spot | | ❌ (not supported) |
| [Kucoin](exchanges.md#kucoin) | spot | | market, limit |
+21 -7
View File
@@ -4,7 +4,7 @@ Pairlist Handlers define the list of pairs (pairlist) that the bot should trade.
In your configuration, you can use Static Pairlist (defined by the [`StaticPairList`](#static-pair-list) Pairlist Handler) and Dynamic Pairlist (defined by the [`VolumePairList`](#volume-pair-list) and [`PercentChangePairList`](#percent-change-pair-list) Pairlist Handlers).
Additionally, [`AgeFilter`](#agefilter), [`PrecisionFilter`](#precisionfilter), [`PriceFilter`](#pricefilter), [`ShuffleFilter`](#shufflefilter), [`SpreadFilter`](#spreadfilter) and [`VolatilityFilter`](#volatilityfilter) act as Pairlist Filters, removing certain pairs and/or moving their positions in the pairlist.
Additionally, [`AgeFilter`](#agefilter), [`DelistFilter`](#delistfilter), [`PrecisionFilter`](#precisionfilter), [`PriceFilter`](#pricefilter), [`ShuffleFilter`](#shufflefilter), [`SpreadFilter`](#spreadfilter) and [`VolatilityFilter`](#volatilityfilter) act as Pairlist Filters, removing certain pairs and/or moving their positions in the pairlist.
If multiple Pairlist Handlers are used, they are chained and a combination of all Pairlist Handlers forms the resulting pairlist the bot uses for trading and backtesting. Pairlist Handlers are executed in the sequence they are configured. You can define either `StaticPairList`, `VolumePairList`, `ProducerPairList`, `RemotePairList`, `MarketCapPairList` or `PercentChangePairList` as the starting Pairlist Handler.
@@ -27,6 +27,7 @@ You may also use something like `.*DOWN/BTC` or `.*UP/BTC` to exclude leveraged
* [`RemotePairList`](#remotepairlist)
* [`MarketCapPairList`](#marketcappairlist)
* [`AgeFilter`](#agefilter)
* [`DelistFilter`](#delistfilter)
* [`FullTradesFilter`](#fulltradesfilter)
* [`OffsetFilter`](#offsetfilter)
* [`PerformanceFilter`](#performancefilter)
@@ -38,7 +39,7 @@ You may also use something like `.*DOWN/BTC` or `.*UP/BTC` to exclude leveraged
* [`VolatilityFilter`](#volatilityfilter)
!!! Tip "Testing pairlists"
Pairlist configurations can be quite tricky to get right. Best use the [`test-pairlist`](utils.md#test-pairlist) utility sub-command to test your configuration quickly.
Pairlist configurations can be quite tricky to get right. Best use freqUI in [webserver mode](freq-ui.md#webserver-mode) or the [`test-pairlist`](utils.md#test-pairlist) utility sub-command to test your Pairlist configuration quickly.
#### Static Pair List
@@ -180,7 +181,7 @@ More sophisticated approach can be used, by using `lookback_timeframe` for candl
* `refresh_period`: Defines the interval (in seconds) at which the pairlist will be refreshed. The default is 1800 seconds (30 minutes).
* `lookback_days`: Number of days to look back. When `lookback_days` is selected, the `lookback_timeframe` is defaulted to 1 day.
* `lookback_timeframe`: Timeframe to use for the lookback period.
* `lookback_period`: Number of periods to look back at.
* `lookback_period`: Number of periods to look back at.
When PercentChangePairList is used after other Pairlist Handlers, it will operate on the outputs of those handlers. If it is the leading Pairlist Handler, it will select pairs from all available markets with the specified stake currency.
@@ -270,7 +271,6 @@ You can limit the length of the pairlist with the optional parameter `number_ass
],
```
!!! Tip "Combining pairlists"
This pairlist can be combined with all other pairlists and filters for further pairlist reduction, and can also act as an "additional" pairlist, on top of already defined pairs.
`ProducerPairList` can also be used multiple times in sequence, combining the pairs from multiple producers.
@@ -312,7 +312,7 @@ The `pairlist_url` option specifies the URL of the remote server where the pairl
The `save_to_file` option, when provided with a valid filename, saves the processed pairlist to that file in JSON format. This option is optional, and by default, the pairlist is not saved to a file.
??? Example "Multi bot with shared pairlist example"
`save_to_file` can be used to save the pairlist to a file with Bot1:
```json
@@ -407,6 +407,16 @@ be caught out buying before the pair has finished dropping in price.
This filter allows freqtrade to ignore pairs until they have been listed for at least `min_days_listed` days and listed before `max_days_listed`.
#### DelistFilter
Removes pairs that will be delisted on the exchange maximum `max_days_from_now` days from now (defaults to `0` which remove all future delisted pairs no matter how far from now). Currently this filter only supports following exchanges:
!!! Note "Available exchanges"
Delist filter is only available on Binance, where Binance Futures will work for both dry and live modes, while Binance Spot is limited to live mode (for technical reasons).
!!! Warning "Backtesting"
`DelistFilter` does not support backtesting mode.
#### FullTradesFilter
Shrink whitelist to consist only in-trade pairs when the trade slots are full (when `max_open_trades` isn't being set to `-1` in the config).
@@ -438,7 +448,7 @@ Example to remove the first 10 pairs from the pairlist, and takes the next 20 (t
```
!!! Warning
When `OffsetFilter` is used to split a larger pairlist among multiple bots in combination with `VolumeFilter`
When `OffsetFilter` is used to split a larger pairlist among multiple bots in combination with `VolumeFilter`
it can not be guaranteed that pairs won't overlap due to slightly different refresh intervals for the
`VolumeFilter`.
@@ -601,7 +611,7 @@ Adding `"sort_direction": "asc"` or `"sort_direction": "desc"` enables sorting m
### Full example of Pairlist Handlers
The below example blacklists `BNB/BTC`, uses `VolumePairList` with `20` assets, sorting pairs by `quoteVolume` and applies [`PrecisionFilter`](#precisionfilter) and [`PriceFilter`](#pricefilter), filtering all assets where 1 price unit is > 1%. Then the [`SpreadFilter`](#spreadfilter) and [`VolatilityFilter`](#volatilityfilter) is applied and pairs are finally shuffled with the random seed set to some predefined value.
The below example blacklists `BNB/BTC`, uses `VolumePairList` with `20` assets, sorting pairs by `quoteVolume`, then filter future delisted pairs using [`DelistFilter`](#delistfilter) and [`AgeFilter`](#agefilter) to remove pairs that are listed less than 10 days ago. After that [`PrecisionFilter`](#precisionfilter) and [`PriceFilter`](#pricefilter) are applied, filtering all assets where 1 price unit is > 1%. Then the [`SpreadFilter`](#spreadfilter) and [`VolatilityFilter`](#volatilityfilter) are applied and pairs are finally shuffled with the random seed set to some predefined value.
```json
"exchange": {
@@ -614,6 +624,10 @@ The below example blacklists `BNB/BTC`, uses `VolumePairList` with `20` assets,
"number_assets": 20,
"sort_key": "quoteVolume"
},
{
"method": "DelistFilter",
"max_days_from_now": 0,
},
{"method": "AgeFilter", "min_days_listed": 10},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01},
+2 -2
View File
@@ -1,11 +1,11 @@
This section will highlight a few projects from members of the community.
!!! Note
The projects below are for the most part not maintained by the freqtrade , therefore use your own caution before using them.
The projects below are for the most part not maintained by the freqtrade team, therefore use your own caution before using them.
- [Example freqtrade strategies](https://github.com/freqtrade/freqtrade-strategies/)
- [FrequentHippo - Statistics of dry/live runs and backtests](http://frequenthippo.ddns.net) (by hippocritical).
- [Online pairlist generator](https://remotepairlist.com/) (by Blood4rc).
- [Freqtrade Backtesting Project](https://strat.ninja/) (by Blood4rc).
- [Freqtrade analysis notebook](https://github.com/froggleston/freqtrade_analysis_notebook) (by Froggleston).
- [TUI for freqtrade](https://github.com/froggleston/freqtrade-frogtrade9000) (by Froggleston).
- [FTUI - Terminal UI for freqtrade](https://github.com/freqtrade/ftui) (by Froggleston).
- [Bot Academy](https://botacademy.ddns.net/) (by stash86) - Blog about crypto bot projects.
+2
View File
@@ -39,6 +39,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual,
- [X] [Binance](https://www.binance.com/)
- [X] [BingX](https://bingx.com/invite/0EM9RX)
- [X] [Bitget](https://www.bitget.com/)
- [X] [Bitmart](https://bitmart.com/)
- [X] [Bybit](https://bybit.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
@@ -52,6 +53,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual,
### Supported Futures Exchanges (experimental)
- [X] [Binance](https://www.binance.com/)
- [X] [Bitget](https://www.bitget.com/)
- [X] [Bybit](https://bybit.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Hyperliquid](https://hyperliquid.xyz/) (A decentralized exchange, or DEX)
+1 -1
View File
@@ -24,7 +24,7 @@ The easiest way to install and run Freqtrade is to clone the bot Github reposito
The `stable` branch contains the code of the last release (done usually once per month on an approximately one week old snapshot of the `develop` branch to prevent packaging bugs, so potentially it's more stable).
!!! Note
Python3.11 or higher and the corresponding `pip` are assumed to be available. The install-script will warn you and stop if that's not the case. `git` is also needed to clone the Freqtrade repository.
Either [uv](https://docs.astral.sh/uv/), or Python3.11 or higher and the corresponding `pip` are assumed to be available. The install-script will warn you and stop if that's not the case. `git` is also needed to clone the Freqtrade repository.
Also, python headers (`python<yourversion>-dev` / `python<yourversion>-devel`) must be available for the installation to complete successfully.
!!! Warning "Up-to-date clock"
+7 -2
View File
@@ -17,7 +17,7 @@ If you already have an existing strategy, please read the [strategy migration gu
## Shorting
Shorting is not possible when trading with [`trading_mode`](#leverage-trading-modes) set to `spot`. To short trade, `trading_mode` must be set to `margin`(currently unavailable) or [`futures`](#futures), with [`margin_mode`](#margin-mode) set to `cross`(currently unavailable) or [`isolated`](#isolated-margin-mode)
Shorting is not possible when trading with [`trading_mode`](#leverage-trading-modes) set to `spot`. To short trade, `trading_mode` must be set to `margin`(currently unavailable) or [`futures`](#futures), with [`margin_mode`](#margin-mode) set to [`cross`](#cross-margin-mode) or [`isolated`](#isolated-margin-mode)
For a strategy to short, the strategy class must set the class variable `can_short = True`
@@ -72,7 +72,7 @@ A futures pair will therefore have the naming of `base/quote:settle` (e.g. `ETH/
On top of `trading_mode` - you will also have to configure your `margin_mode`.
While freqtrade currently only supports one margin mode, this will change, and by configuring it now you're all set for future updates.
The possible values are: `isolated`, or `cross`(*currently unavailable*).
The possible values are: `isolated`, or `cross`.
#### Isolated margin mode
@@ -92,6 +92,11 @@ One account is used to share collateral between markets (trading pairs). Margin
Please read the [exchange specific notes](exchanges.md) for exchanges that support this mode and how they differ.
!!! Warning "Increased risk of liquidation"
Cross margin mode increases the risk of full account liquidation, as all trades share the same collateral.
A loss on one trade can affect the liquidation price of other trades.
Also, cross-position influence may not be fully simulated in dry-run or backtesting mode.
## Set leverage to use
Different strategies and risk profiles will require different levels of leverage.
+4
View File
@@ -22,6 +22,7 @@ This is done by not looking at the strategy code itself, but at changed indicato
- `--dry-run-wallet` is forced to be basically infinite (1 billion).
- `--stake-amount` is forced to be a static 10000 (10k).
- `--enable-protections` is forced to be off.
- `order_types` are forced to be "market" (late entries) unless `--lookahead-allow-limit-orders` is set.
These are set to avoid users accidentally generating false positives.
@@ -99,6 +100,9 @@ This would lead to a false-negative, i.e. the strategy will be reported as non-b
Please don't use any options like enabling position stacking as this will distort the number of checked signals.
If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` slots,
and that you have enough capital in the backtest wallet configuration.
- limit orders in combination with `custom_entry_price()` and `custom_exit_price()` callbacks can cause late / delayed entries and exists, causing false positives.
To avoid this - market orders are forced for this command. This implicitly means that `custom_entry_price()` and `custom_exit_price()` callbacks are not called.
Using `--lookahead-allow-limit-orders` will skip the override and use your configured order types - however has shown to eventually produce false positives.
- In the results table, the `biased_indicators` column
will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased.
**These are not biased and can safely be ignored.**
+2 -2
View File
@@ -1,6 +1,6 @@
markdown==3.8.2
markdown==3.9
mkdocs==1.6.1
mkdocs-material==9.6.18
mkdocs-material==9.6.22
mdx_truly_sane_lists==1.3
pymdown-extensions==10.16.1
jinja2==3.1.6
+54 -49
View File
@@ -140,6 +140,11 @@ This method will work for all arguments - check the "show" command for a list of
# Get the status of the bot
ping = client.ping()
print(ping)
# Add pairs to blacklist
client.blacklist("BTC/USDT", "ETH/USDT")
# Add pairs to blacklist by supplying a list
client.blacklist(*listPairs)
# ...
```
@@ -155,63 +160,63 @@ freqtrade-client help
Possible commands:
available_pairs
Return available pair (backtest data) based on timeframe / stake_currency selection
Return available pair (backtest data) based on timeframe / stake_currency selection
:param timeframe: Only pairs with this timeframe available.
:param stake_currency: Only pairs that include this timeframe
balance
Get the account balance.
Get the account balance.
blacklist
Show the current blacklist.
Show the current blacklist.
:param add: List of coins to add (example: "BNB/BTC")
cancel_open_order
Cancel open order for trade.
Cancel open order for trade.
:param trade_id: Cancels open orders for this trade.
count
Return the amount of open trades.
Return the amount of open trades.
daily
Return the profits for each day, and amount of trades.
Return the profits for each day, and amount of trades.
delete_lock
Delete (disable) lock from the database.
Delete (disable) lock from the database.
:param lock_id: ID for the lock to delete
delete_trade
Delete trade from the database.
Delete trade from the database.
Tries to close open orders. Requires manual handling of this asset on the exchange.
:param trade_id: Deletes the trade with this ID from the database.
forcebuy
Buy an asset.
Buy an asset.
:param pair: Pair to buy (ETH/BTC)
:param price: Optional - price to buy
forceenter
Force entering a trade
Force entering a trade
:param pair: Pair to buy (ETH/BTC)
:param side: 'long' or 'short'
:param price: Optional - price to buy
forceexit
Force-exit a trade.
Force-exit a trade.
:param tradeid: Id of the trade (can be received via status command)
:param ordertype: Order type to use (must be market or limit)
:param amount: Amount to sell. Full sell if not given
health
Provides a quick health check of the running bot.
Provides a quick health check of the running bot.
lock_add
Manually lock a specific pair
@@ -222,22 +227,22 @@ lock_add
:param reason: Reason for the lock
locks
Return current locks
Return current locks
logs
Show latest logs.
Show latest logs.
:param limit: Limits log messages to the last <limit> logs. No limit to get the entire log.
pair_candles
Return live dataframe for <pair><timeframe>.
Return live dataframe for <pair><timeframe>.
:param pair: Pair to get data for
:param timeframe: Only pairs with this timeframe available.
:param limit: Limit result to the last n candles.
pair_history
Return historic, analyzed dataframe
Return historic, analyzed dataframe
:param pair: Pair to get data for
:param timeframe: Only pairs with this timeframe available.
@@ -245,59 +250,59 @@ pair_history
:param timerange: Timerange to get data for (same format than --timerange endpoints)
performance
Return the performance of the different coins.
Return the performance of the different coins.
ping
simple ping
simple ping
plot_config
Return plot configuration if the strategy defines one.
Return plot configuration if the strategy defines one.
profit
Return the profit summary.
Return the profit summary.
reload_config
Reload configuration.
Reload configuration.
show_config
Returns part of the configuration, relevant for trading operations.
Returns part of the configuration, relevant for trading operations.
start
Start the bot if it's in the stopped state.
Start the bot if it's in the stopped state.
pause
Pause the bot if it's in the running state. If triggered on stopped state will handle open positions.
Pause the bot if it's in the running state. If triggered on stopped state will handle open positions.
stats
Return the stats report (durations, sell-reasons).
Return the stats report (durations, sell-reasons).
status
Get the status of open trades.
Get the status of open trades.
stop
Stop the bot. Use `start` to restart.
Stop the bot. Use `start` to restart.
stopbuy
Stop buying (but handle sells gracefully). Use `reload_config` to reset.
Stop buying (but handle sells gracefully). Use `reload_config` to reset.
strategies
Lists available strategies
Lists available strategies
strategy
Get strategy details
Get strategy details
:param strategy: Strategy class name
sysinfo
Provides system information (CPU, RAM usage)
Provides system information (CPU, RAM usage)
trade
Return specific trade
Return specific trade
:param trade_id: Specify which trade to get.
trades
Return trades history, sorted by id
Return trades history, sorted by id
:param limit: Limits trades to the X last trades. Max 500 trades.
:param offset: Offset by this amount of trades.
@@ -316,10 +321,10 @@ list_custom_data
:param key: str, optional - Key of the custom-data
version
Return the version of the bot.
Return the version of the bot.
whitelist
Show the current whitelist.
Show the current whitelist.
```
@@ -339,32 +344,32 @@ All endpoints in the below table need to be prefixed with the base URL of the AP
| `/reload_config` | POST | Reloads the configuration file.
| `/trades` | GET | List last trades. Limited to 500 trades per call.
| `/trade/<tradeid>` | GET | Get specific trade.<br/>*Params:*<br/>- `tradeid` (`int`)
| `/trades/<tradeid>` | DELETE | Remove trade from the database. Tries to close open orders. Requires manual handling of this trade on the exchange.<br/>*Params:*<br/>- `tradeid` (`int`)
| `/trades/<tradeid>/open-order` | DELETE | Cancel open order for this trade.<br/>*Params:*<br/>- `tradeid` (`int`)
| `/trades/<tradeid>/reload` | POST | Reload a trade from the Exchange. Only works in live, and can potentially help recover a trade that was manually sold on the exchange.<br/>*Params:*<br/>- `tradeid` (`int`)
| `/trades/<tradeid>` | DELETE | Remove trade from the database. Tries to close open orders. Requires manual handling of this trade on the exchange.<br/>*Params:*<br/>- `tradeid` (`int`)
| `/trades/<tradeid>/open-order` | DELETE | Cancel open order for this trade.<br/>*Params:*<br/>- `tradeid` (`int`)
| `/trades/<tradeid>/reload` | POST | Reload a trade from the Exchange. Only works in live, and can potentially help recover a trade that was manually sold on the exchange.<br/>*Params:*<br/>- `tradeid` (`int`)
| `/show_config` | GET | Shows part of the current configuration with relevant settings to operation.
| `/logs` | GET | Shows last log messages.
| `/status` | GET | Lists all open trades.
| `/count` | GET | Displays number of trades used and available.
| `/entries` | GET | Shows profit statistics for each enter tags for given pair (or all pairs if pair isn't given). Pair is optional.<br/>*Params:*<br/>- `pair` (`str`)
| `/exits` | GET | Shows profit statistics for each exit reasons for given pair (or all pairs if pair isn't given). Pair is optional.<br/>*Params:*<br/>- `pair` (`str`)
| `/mix_tags` | GET | Shows profit statistics for each combinations of enter tag + exit reasons for given pair (or all pairs if pair isn't given). Pair is optional.<br/>*Params:*<br/>- `pair` (`str`)
| `/entries` | GET | Shows profit statistics for each enter tags for given pair (or all pairs if pair isn't given). Pair is optional.<br/>*Params:*<br/>- `pair` (`str`)
| `/exits` | GET | Shows profit statistics for each exit reasons for given pair (or all pairs if pair isn't given). Pair is optional.<br/>*Params:*<br/>- `pair` (`str`)
| `/mix_tags` | GET | Shows profit statistics for each combinations of enter tag + exit reasons for given pair (or all pairs if pair isn't given). Pair is optional.<br/>*Params:*<br/>- `pair` (`str`)
| `/locks` | GET | Displays currently locked pairs.
| `/locks` | POST | Locks a pair until "until". (Until will be rounded up to the nearest timeframe). Side is optional and is either `long` or `short` (default is `long`). Reason is optional.<br/>*Params:*<br/>- `<pair>` (`str`)<br/>- `<until>` (`datetime`)<br/>- `[side]` (`str`)<br/>- `[reason]` (`str`)
| `/locks/<lockid>` | DELETE | Deletes (disables) the lock by id.<br/>*Params:*<br/>- `lockid` (`int`)
| `/locks` | POST | Locks a pair until "until". (Until will be rounded up to the nearest timeframe). Side is optional and is either `long` or `short` (default is `long`). Reason is optional.<br/>*Params:*<br/>- `<pair>` (`str`)<br/>- `<until>` (`datetime`)<br/>- `[side]` (`str`)<br/>- `[reason]` (`str`)
| `/locks/<lockid>` | DELETE | Deletes (disables) the lock by id.<br/>*Params:*<br/>- `lockid` (`int`)
| `/profit` | GET | Display a summary of your profit/loss from close trades and some stats about your performance.
| `/forceexit` | POST | Instantly exits the given trade (ignoring `minimum_roi`), using the given order type ("market" or "limit", uses your config setting if not specified), and the chosen amount (full sell if not specified). If `all` is supplied as the `tradeid`, then all currently open trades will be forced to exit.<br/>*Params:*<br/>- `<tradeid>` (`int` or `str`)<br/>- `<ordertype>` (`str`)<br/>- `[amount]` (`float`)
| `/forceenter` | POST | Instantly enters the given pair. Side is optional and is either `long` or `short` (default is `long`). Rate is optional. (`force_entry_enable` must be set to True)<br/>*Params:*<br/>- `<pair>` (`str`)<br/>- `<side>` (`str`)<br/>- `[rate]` (`float`)
| `/performance` | GET | Show performance of each finished trade grouped by pair.
| `/balance` | GET | Show account balance per currency.
| `/daily` | GET | Shows profit or loss per day, over the last n days (n defaults to 7).<br/>*Params:*<br/>- `<n>` (`int`)
| `/weekly` | GET | Shows profit or loss per week, over the last n days (n defaults to 4).<br/>*Params:*<br/>- `<n>` (`int`)
| `/monthly` | GET | Shows profit or loss per month, over the last n days (n defaults to 3).<br/>*Params:*<br/>- `<n>` (`int`)
| `/daily` | GET | Shows profit or loss per day, over the last n days (n defaults to 7).<br/>*Params:*<br/>- `timescale` (`int`)
| `/weekly` | GET | Shows profit or loss per week, over the last n days (n defaults to 4).<br/>*Params:*<br/>- `timescale` (`int`)
| `/monthly` | GET | Shows profit or loss per month, over the last n days (n defaults to 3).<br/>*Params:*<br/>- `timescale` (`int`)
| `/stats` | GET | Display a summary of profit / loss reasons as well as average holding times.
| `/whitelist` | GET | Show the current whitelist.
| `/blacklist` | GET | Show the current blacklist.
| `/blacklist` | POST | Adds the specified pair to the blacklist.<br/>*Params:*<br/>- `pair` (`str`)
| `/blacklist` | DELETE | Deletes the specified list of pairs from the blacklist.<br/>*Params:*<br/>- `[pair,pair]` (`list[str]`)
| `/blacklist` | POST | Adds the specified pair to the blacklist.<br/>*Params:*<br/>- `blacklist` (`str`)
| `/blacklist` | DELETE | Deletes the specified list of pairs from the blacklist.<br/>*Params:*<br/>- `[pair,pair]` (`list[str]`)
| `/pair_candles` | GET | Returns dataframe for a pair / timeframe combination while the bot is running. **Alpha**
| `/pair_candles` | POST | Returns dataframe for a pair / timeframe combination while the bot is running, filtered by a provided list of columns to return. **Alpha**<br/>*Params:*<br/>- `<column_list>` (`list[str]`)
| `/pair_history` | GET | Returns an analyzed dataframe for a given timerange, analyzed by a given strategy. **Alpha**
@@ -488,7 +493,7 @@ To properly configure your reverse proxy (securely), please consult it's documen
### OpenAPI interface
To enable the builtin openAPI interface (Swagger UI), specify `"enable_openapi": true` in the api_server configuration.
This will enable the Swagger UI at the `/docs` endpoint. By default, that's running at http://localhost:8080/docs - but it'll depend on your settings.
This will enable the Swagger UI at the `/docs` endpoint. By default, that's running at <http://localhost:8080/docs> - but it'll depend on your settings.
### Advanced API usage using JWT tokens
+3 -12
View File
@@ -26,18 +26,9 @@ These modes can be configured with these values:
Stoploss on exchange is only supported for the following exchanges, and not all exchanges support both stop-limit and stop-market.
The Order-type will be ignored if only one mode is available.
| Exchange | stop-loss type |
|----------|-------------|
| Binance | limit |
| Binance Futures | market, limit |
| Bingx | market, limit |
| Bitget | market, limit |
| HTX | limit |
| kraken | market, limit |
| Gate | limit |
| Okx | limit |
| Kucoin | stop-limit, stop-market|
| Hyperliquid (futures only) | limit |
??? info "Supported exchanges and stoploss types"
--8<-- "includes/exchange-features.md"
!!! Note "Tight stoploss"
<ins>Do not set too low/tight stoploss value when using stop loss on exchange!</ins>
+32 -4
View File
@@ -1243,15 +1243,23 @@ class AwesomeStrategy(IStrategy):
```
!!! Tip "Learn more about storing data"
You can learn more about storing data on the [Storing custom trade data](strategy-advanced.md#storing-information-persistent) section.
Please keep in mind that this is considered advanced usage, and should be used with care.
## Plot annotations callback
The plot annotations callback is called whenever freqUI requests data to display a chart.
This callback has no meaning in the trade cycle context and is only used for charting purposes.
The strategy can then return a list of `AnnotationType` objects to be displayed on the chart.
Depending on the content returned - the chart can display horizontal areas, vertical areas, or boxes.
Depending on the content returned - the chart can display horizontal areas, vertical areas, boxes or lines.
The full object looks like this:
### Annotation types
Currently two types of annotations are supported, `area` and `line`.
#### Area
``` json
{
@@ -1261,10 +1269,29 @@ The full object looks like this:
"y_start": 94000.2, // Price / y axis value
"y_end": 98000, // Price / y axis value
"color": "",
"z_level": 5, // z-level, higher values are drawn on top of lower values. Positions relative to the Chart elements need to be set in freqUI.
"label": "some label"
}
```
#### Line
``` json
{
"type": "line", // Type of the annotation, currently only "line" is supported
"start": "2024-01-01 15:00:00", // Start date of the line
"end": "2024-01-01 16:00:00", // End date of the line
"y_start": 94000.2, // Price / y axis value
"y_end": 98000, // Price / y axis value
"color": "",
"z_level": 5, // z-level, higher values are drawn on top of lower values. Positions relative to the Chart elements need to be set in freqUI.
"label": "some label",
"width": 2, // Optional, line width in pixels. Defaults to 1
"line_style": "dashed", // Optional, can be "solid", "dashed" or "dotted". Defaults to "solid"
}
```
The below example will mark the chart with areas for the hours 8 and 15, with a grey color, highlighting the market open and close hours.
This is obviously a very basic example.
@@ -1332,7 +1359,7 @@ Entries will be validated, and won't be passed to the UI if they don't correspon
while start_dt < end_date:
start_dt += timedelta(hours=1)
if (start_dt.hour % 4) == 0:
mark_areas.append(
annotations.append(
{
"type": "area",
"label": "4h",
@@ -1343,7 +1370,7 @@ Entries will be validated, and won't be passed to the UI if they don't correspon
)
elif (start_dt.hour % 2) == 0:
price = dataframe.loc[dataframe["date"] == start_dt, ["close"]].mean()
mark_areas.append(
annotations.append(
{
"type": "area",
"label": "2h",
@@ -1352,6 +1379,7 @@ Entries will be validated, and won't be passed to the UI if they don't correspon
"y_end": price * 1.01,
"y_start": price * 0.99,
"color": "rgba(0, 255, 0, 0.4)",
"z_level": 5,
}
)
+74 -6
View File
@@ -84,6 +84,7 @@ Check the [configuration documentation](configuration.md) about how to set the b
**Always use dry mode when testing as this gives you an idea of how your strategy will work in reality without risking capital.**
## Diving in deeper
**For the following section we will use the [user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_strategy.py)
file as reference.**
@@ -99,9 +100,9 @@ file as reference.**
Some common patterns for this are listed in the [Common Mistakes](#common-mistakes-when-developing-strategies) section of this document.
??? Hint "Lookahead and recursive analysis"
Freqtrade includes two helpful commands to help assess common lookahead (using future data) and
recursive bias (variance in indicator values) issues. Before running a strategy in dry or live more,
you should always use these commands first. Please check the relevant documentation for
Freqtrade includes two helpful commands to help assess common lookahead (using future data) and
recursive bias (variance in indicator values) issues. Before running a strategy in dry or live more,
you should always use these commands first. Please check the relevant documentation for
[lookahead](lookahead-analysis.md) and [recursive](recursive-analysis.md) analysis.
### Dataframe
@@ -154,7 +155,7 @@ Vectorized operations perform calculations across the whole range of data and ar
!!! Warning "Trade order assumptions"
In backtesting, signals are generated on candle close. Trades are then initiated immeditely on next candle open.
In dry and live, this may be delayed due to all pair dataframes needing to be analysed first, then trade processing
for each of those pairs happens. This means that in dry/live you need to be mindful of having as low a computation
delay as possible, usually by running a low number of pairs and having a CPU with a good clock speed.
@@ -284,7 +285,7 @@ It's important to always return the dataframe without removing/modifying the col
This method will also define a new column, `"enter_long"` (`"enter_short"` for shorts), which needs to contain `1` for entries, and `0` for "no action". `enter_long` is a mandatory column that must be set even if the strategy is shorting only.
You can name your entry signals by using the `"enter_tag"` column, which can help debug and assess your strategy later.
You can name your entry signals by using the `"enter_tag"` column, which can help debug and assess your strategy later.
Sample from `user_data/strategies/sample_strategy.py`:
@@ -555,7 +556,7 @@ A full sample can be found [in the DataProvider section](#complete-dataprovider-
??? Note "Alternative candle types"
Informative_pairs can also provide a 3rd tuple element defining the candle type explicitly.
Availability of alternative candle-types will depend on the trading-mode and the exchange.
Availability of alternative candle-types will depend on the trading-mode and the exchange.
In general, spot pairs cannot be used in futures markets, and futures candles can't be used as informative pairs for spot bots.
Details about this may vary, if they do, this can be found in the exchange documentation.
@@ -783,6 +784,8 @@ Please always check the mode of operation to select the correct method to get da
- `ohlcv(pair, timeframe)` - Currently cached candle (OHLCV) data for the pair, returns DataFrame or empty DataFrame.
- [`orderbook(pair, maximum)`](#orderbookpair-maximum) - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries.
- [`ticker(pair)`](#tickerpair) - Returns current ticker data for the pair. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#price-tickers) for more details on the Ticker data structure.
- [`check_delisting(pair)`](#check_delistingpair) - Return Datetime of the pair delisting schedule if any, otherwise return None
- [`funding_rate(pair)`](#funding_ratepair) - Returns current funding rate data for the pair.
- `runmode` - Property containing the current runmode.
### Example Usages
@@ -854,6 +857,8 @@ dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=metadata['pair'],
### *orderbook(pair, maximum)*
Retrieve the current order book for a pair.
``` python
if self.dp.runmode.value in ('live', 'dry_run'):
ob = self.dp.orderbook(metadata['pair'], 1)
@@ -903,6 +908,69 @@ if self.dp.runmode.value in ('live', 'dry_run'):
!!! Warning "Warning about backtesting"
This method will always return up-to-date / real-time values. As such, usage during backtesting / hyperopt without runmode checks will lead to wrong results, e.g. your whole dataframe will contain the same single value in all rows.
### *check_delisting(pair)*
```python
def custom_exit(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, **kwargs):
if self.dp.runmode.value in ('live', 'dry_run'):
delisting_dt = self.dp.check_delisting(pair)
if delisting_dt is not None:
return "delist"
```
!!! Note "Availabiity of delisting information"
This method is only available for certain exchanges and will return `None` in cases this is not available or if the pair is not scheduled for delisting.
!!! Warning "Warning about backtesting"
This method will always return up-to-date / real-time values. As such, usage during backtesting / hyperopt without runmode checks will lead to wrong results, e.g. your whole dataframe will contain the same single value in all rows.
### *funding_rate(pair)*
Retrieves the current funding rate for the pair and only works for futures pairs in the format of `base/quote:settle` (e.g. `ETH/USDT:USDT`).
``` python
if self.dp.runmode.value in ('live', 'dry_run'):
funding_rate = self.dp.funding_rate(metadata['pair'])
dataframe['current_funding_rate'] = funding_rate['fundingRate']
dataframe['next_funding_timestamp'] = funding_rate['fundingTimestamp']
dataframe['next_funding_datetime'] = funding_rate['fundingDatetime']
```
The funding rate structure is aligned with the funding rate structure from [ccxt](https://github.com/ccxt/ccxt/wiki/Manual#funding-rate-structure), so the result will be formatted as follows:
``` python
{
"info": {
# ...
},
"symbol": "BTC/USDT:USDT",
"markPrice": 110730.7,
"indexPrice": 110782.52,
"interestRate": 0.0001,
"estimatedSettlePrice": 110822.67200153,
"timestamp": 1757146321001,
"datetime": "2025-09-06T08:12:01.001Z",
"fundingRate": 5.609e-05,
"fundingTimestamp": 1757174400000,
"fundingDatetime": "2025-09-06T16:00:00.000Z",
"nextFundingRate": None,
"nextFundingTimestamp": None,
"nextFundingDatetime": None,
"previousFundingRate": None,
"previousFundingTimestamp": None,
"previousFundingDatetime": None,
"interval": None,
}
```
Therefore, using `funding_rate['fundingRate']` as demonstrated above will use the current funding rate.
Actually available data will vary between exchanges, so this code may not work as expected across exchanges.
!!! Warning "Warning about backtesting"
Current funding-rate is not part of the historic data which means backtesting and hyperopt will not work correctly if this method is used, as the method will return up-to-date values.
We recommend to use the historically available funding rate for backtesting (which is automatically downloaded, and is at the frequency of what the exchange provides, usually 4h or 8h).
`self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='8h', candle_type="funding_rate")`
### Send Notification
The dataprovider `.send_msg()` function allows you to send custom notifications from your strategy.
+73 -5
View File
@@ -14,11 +14,20 @@ The following attributes / properties are available for each individual trade -
| Attribute | DataType | Description |
|------------|-------------|-------------|
| `pair` | string | Pair of this trade. |
| `safe_base_currency` | string | Compatibility layer for base currency . |
| `safe_quote_currency` | string | Compatibility layer for quote currency. |
| `is_open` | boolean | Is the trade currently open, or has it been concluded. |
| `exchange` | string | Exchange where this trade was executed. |
| `open_rate` | float | Rate this trade was entered at (Avg. entry rate in case of trade-adjustments). |
| `open_rate_requested` | float | The rate that was requested when the trade was opened. |
| `open_trade_value` | float | Value of the open trade including fees. |
| `close_rate` | float | Close rate - only set when is_open = False. |
| `close_rate_requested` | float | The close rate that was requested. |
| `safe_close_rate` | float | Close rate or `close_rate_requested` or 0.0 if neither is available. Only makes sense once the trade is closed. |
| `stake_amount` | float | Amount in Stake (or Quote) currency. |
| `max_stake_amount` | float | Maximum stake amount that was used in this trade (sum of all filled Entry orders). |
| `amount` | float | Amount in Asset / Base currency that is currently owned. Will be 0.0 until the initial order fills. |
| `amount_requested` | float | Amount that was originally requested for this trade as part of the first entry order. |
| `open_date` | datetime | Timestamp when trade was opened **use `open_date_utc` instead** |
| `open_date_utc` | datetime | Timestamp when trade was opened - in UTC. |
| `close_date` | datetime | Timestamp when trade was closed **use `close_date_utc` instead** |
@@ -28,15 +37,47 @@ The following attributes / properties are available for each individual trade -
| `realized_profit` | float | Absolute already realized profit (in stake currency) while the trade is still open. |
| `leverage` | float | Leverage used for this trade - defaults to 1.0 in spot markets. |
| `enter_tag` | string | Tag provided on entry via the `enter_tag` column in the dataframe. |
| `exit_reason` | string | Reason why the trade was exited. |
| `exit_order_status` | string | Status of the exit order. |
| `strategy` | string | Strategy name that was used for this trade. |
| `timeframe` | int | Timeframe used for this trade. |
| `is_short` | boolean | True for short trades, False otherwise. |
| `orders` | Order[] | List of order objects attached to this trade (includes both filled and cancelled orders). |
| `date_last_filled_utc` | datetime | Time of the last filled order. |
| `date_entry_fill_utc` | datetime | Date of the first filled entry order. |
| `entry_side` | "buy" / "sell" | Order Side the trade was entered. |
| `exit_side` | "buy" / "sell" | Order Side that will result in a trade exit / position reduction. |
| `trade_direction` | "long" / "short" | Trade direction in text - long or short. |
| `max_rate` | float | Highest price reached during this trade. Not 100% accurate. |
| `min_rate` | float | Lowest price reached during this trade. Not 100% accurate. |
| `nr_of_successful_entries` | int | Number of successful (filled) entry orders. |
| `nr_of_successful_exits` | int | Number of successful (filled) exit orders. |
| `has_open_position` | boolean | True if there is an open position (amount > 0) for this trade. Only false while the initial entry order is unfilled. |
| `has_open_orders` | boolean | Has the trade open orders (excluding stoploss orders). |
| `has_open_sl_orders` | boolean | True if there are open stoploss orders for this trade. |
| `open_orders` | Order[] | All open orders for this trade excluding stoploss orders. |
| `open_sl_orders` | Order[] | All open stoploss orders for this trade. |
| `fully_canceled_entry_order_count` | int | Number of fully canceled entry orders. |
| `canceled_exit_order_count` | int | Number of canceled exit orders. |
### Stop Loss related attributes
| Attribute | DataType | Description |
|------------|-------------|-------------|
| `stop_loss` | float | Absolute value of the stop loss. |
| `stop_loss_pct` | float | Relative value of the stop loss. |
| `initial_stop_loss` | float | Absolute value of the initial stop loss. |
| `initial_stop_loss_pct` | float | Relative value of the initial stop loss. |
| `stoploss_last_update_utc` | datetime | Timestamp of the last stoploss on exchange order update. |
| `stoploss_or_liquidation` | float | Returns the more restrictive of stoploss or liquidation price and corresponds to the price a stoploss would trigger at. |
### Futures/Margin trading attributes
| Attribute | DataType | Description |
|------------|-------------|-------------|
| `liquidation_price` | float | Liquidation price for leveraged trades. |
| `interest_rate` | float | Interest rate for margin trades. |
| `funding_fees` | float | Total funding fees for futures trades. |
## Class methods
@@ -102,6 +143,10 @@ from freqtrade.persistence import Trade
profit = Trade.total_open_trades_stakes()
```
## Class methods not supported in backtesting/hyperopt
The following class methods are not supported in backtesting/hyperopt mode.
### get_overall_performance
Retrieve the overall performance - similar to the `/performance` telegram command.
@@ -120,6 +165,17 @@ Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of
{"pair": "ETH/BTC", "profit": 0.015, "count": 5}
```
### get_trading_volume
Get total trading volume based on orders.
``` python
from freqtrade.persistence import Trade
# ...
volume = Trade.get_trading_volume()
```
## Order Object
An `Order` object represents an order on the exchange (or a simulated order in dry-run mode).
@@ -135,6 +191,10 @@ Most properties here can be None as they are dependent on the exchange response.
| `trade` | Trade | Trade object this order is attached to |
| `ft_pair` | string | Pair this order is for |
| `ft_is_open` | boolean | is the order still open? |
| `ft_order_side` | string | Order side ('buy', 'sell', or 'stoploss') |
| `ft_cancel_reason` | string | Reason why the order was canceled |
| `ft_order_tag` | string | Custom order tag |
| `order_id` | string | Exchange order ID |
| `order_type` | string | Order type as defined on the exchange - usually market, limit or stoploss |
| `status` | string | Status as defined by [ccxt's order structure](https://docs.ccxt.com/#/README?id=order-structure). Usually open, closed, expired, canceled or rejected |
| `side` | string | buy or sell |
@@ -143,12 +203,20 @@ Most properties here can be None as they are dependent on the exchange response.
| `amount` | float | Amount in base currency |
| `filled` | float | Filled amount (in base currency) (use `safe_filled` instead) |
| `safe_filled` | float | Filled amount (in base currency) - guaranteed to not be None |
| `safe_amount` | float | Amount - falls back to ft_amount if None |
| `safe_price` | float | Price - falls back through average, price, stop_price, ft_price |
| `safe_placement_price` | float | Price at which the order was placed |
| `remaining` | float | Remaining amount (use `safe_remaining` instead) |
| `safe_remaining` | float | Remaining amount - either taken from the exchange or calculated. |
| `cost` | float | Cost of the order - usually average * filled (*Exchange dependent on futures, may contain the cost with or without leverage and may be in contracts.*) |
| `stake_amount` | float | Stake amount used for this order. *Added in 2023.7.* |
| `stake_amount_filled` | float | Filled Stake amount used for this order. *Added in 2024.11.* |
| `safe_cost` | float | Cost of the order - guaranteed to not be None |
| `safe_fee_base` | float | Fee in base currency - guaranteed to not be None |
| `safe_amount_after_fee` | float | Amount after deducting fees |
| `cost` | float | Cost of the order - usually average * filled (*Exchange dependent on futures trading, may contain the cost with or without leverage and may be in contracts.*) |
| `stop_price` | float | Stop price for stop orders. Empty for non-stoploss orders. |
| `stake_amount` | float | Stake amount used for this order. |
| `stake_amount_filled` | float | Filled Stake amount used for this order. |
| `order_date` | datetime | Order creation date **use `order_date_utc` instead** |
| `order_date_utc` | datetime | Order creation date (in UTC) |
| `order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead** |
| `order_fill_date_utc` | datetime | Order fill date |
| `order_filled_date` | datetime | Order fill date **use `order_filled_utc` instead** |
| `order_filled_utc` | datetime | Order fill date |
| `order_update_date` | datetime | Last order update date |
+23
View File
@@ -80,6 +80,29 @@ When using the Form-Encoded or JSON-Encoded configuration you can configure any
The result would be a POST request with e.g. `Status: running` body and `Content-Type: text/plain` header.
### Nested Webhook Configuration
Some webhook targets require a nested structure.
This can be accomplished by setting the content as dictionary or list instead of as text directly.
This is only supported for the JSON format.
```json
"webhook": {
"enabled": true,
"url": "https://<yourhookurl>",
"format": "json",
"status": {
"msgtype": "text",
"text": {
"content": "Status update: {status}"
}
}
}
```
The result would be a POST request with e.g. `{"msgtype":"text","text":{"content":"Status update: running"}}` body and `Content-Type: application/json` header.
## Additional configurations
The `webhook.retries` parameter can be set for the maximum number of retries the webhook request should attempt if it is unsuccessful (i.e. HTTP response status is not 200). By default this is set to `0` which is disabled. An additional `webhook.retry_delay` parameter can be set to specify the time in seconds between retry attempts. By default this is set to `0.1` (i.e. 100ms). Note that increasing the number of retries or retry delay may slow down the trader if there are connectivity issues with the webhook.
+1 -1
View File
@@ -1,6 +1,6 @@
"""Freqtrade bot"""
__version__ = "2025.8"
__version__ = "2025.10"
if "dev" in __version__:
from pathlib import Path
+8 -2
View File
@@ -49,6 +49,7 @@ ARGS_BACKTEST = [
*ARGS_COMMON_OPTIMIZE,
"position_stacking",
"enable_protections",
"enable_dynamic_pairlist",
"dry_run_wallet",
"timeframe_detail",
"strategy_list",
@@ -63,7 +64,6 @@ ARGS_BACKTEST = [
ARGS_HYPEROPT = [
*ARGS_COMMON_OPTIMIZE,
"hyperopt",
"hyperopt_path",
"position_stacking",
"enable_protections",
@@ -164,6 +164,7 @@ ARGS_DOWNLOAD_DATA = [
"days",
"new_pairs_days",
"include_inactive",
"no_parallel_download",
"timerange",
"download_trades",
"convert_trades",
@@ -259,7 +260,12 @@ ARGS_LOOKAHEAD_ANALYSIS = [
a
for a in ARGS_BACKTEST
if a not in ("position_stacking", "backtest_cache", "backtest_breakdown", "backtest_notes")
] + ["minimum_trade_amount", "targeted_trade_amount", "lookahead_analysis_exportfilename"]
] + [
"minimum_trade_amount",
"targeted_trade_amount",
"lookahead_analysis_exportfilename",
"lookahead_allow_limit_orders",
]
ARGS_RECURSIVE_ANALYSIS = ["timeframe", "timerange", "dataformat_ohlcv", "pairs", "startup_candle"]
+24 -9
View File
@@ -2,7 +2,7 @@
Definition of cli arguments used in arguments.py
"""
from argparse import SUPPRESS, ArgumentTypeError
from argparse import ArgumentTypeError
from freqtrade import constants
from freqtrade.constants import HYPEROPT_LOSS_BUILTIN
@@ -184,12 +184,20 @@ AVAILABLE_CLI_OPTIONS = {
"enable_protections": Arg(
"--enable-protections",
"--enableprotections",
help="Enable protections for backtesting."
help="Enable protections for backtesting. "
"Will slow backtesting down by a considerable amount, but will include "
"configured protections",
action="store_true",
default=False,
),
"enable_dynamic_pairlist": Arg(
"--enable-dynamic-pairlist",
help="Enables dynamic pairlist refreshes in backtesting. "
"The pairlist will be generated for each new candle if you're using a "
"pairlist handler that supports this feature, for example, ShuffleFilter.",
action="store_true",
default=False,
),
"strategy_list": Arg(
"--strategy-list",
help="Provide a space-separated list of strategies to backtest. "
@@ -237,7 +245,7 @@ AVAILABLE_CLI_OPTIONS = {
),
"backtest_breakdown": Arg(
"--breakdown",
help="Show backtesting breakdown per [day, week, month, year].",
help="Show backtesting breakdown per [day, week, month, year, weekday].",
nargs="+",
choices=constants.BACKTEST_BREAKDOWNS,
),
@@ -248,12 +256,6 @@ AVAILABLE_CLI_OPTIONS = {
choices=constants.BACKTEST_CACHE_AGE,
),
# Hyperopt
"hyperopt": Arg(
"--hyperopt",
help=SUPPRESS,
metavar="NAME",
required=False,
),
"hyperopt_path": Arg(
"--hyperopt-path",
help="Specify additional lookup path for Hyperopt Loss functions.",
@@ -454,6 +456,11 @@ AVAILABLE_CLI_OPTIONS = {
help="Also download data from inactive pairs.",
action="store_true",
),
"no_parallel_download": Arg(
"--no-parallel-download",
help="Disable parallel startup download. Only use this if you experience issues.",
action="store_true",
),
"new_pairs_days": Arg(
"--new-pairs-days",
help="Download data of new pairs for given number of days. Default: `%(default)s`.",
@@ -801,6 +808,14 @@ AVAILABLE_CLI_OPTIONS = {
help="Specify startup candles to be checked (`199`, `499`, `999`, `1999`).",
nargs="+",
),
"lookahead_allow_limit_orders": Arg(
"--allow-limit-orders",
help=(
"Allow limit orders in lookahead analysis (could cause false positives "
"in lookahead analysis results)."
),
action="store_true",
),
"show_sensitive": Arg(
"--show-sensitive",
help="Show secrets in the output.",
+1 -1
View File
@@ -66,7 +66,7 @@ def start_list_exchanges(args: dict[str, Any]) -> None:
if exchange["is_alias"]:
name.stylize("strike")
classname.stylize("strike")
classname.append(f" (use {exchange['alias_for']})", style="italic")
classname.append(f"\n -> use {exchange['alias_for']}", style="italic")
trade_modes = Text(
", ".join(
+9
View File
@@ -1142,6 +1142,15 @@ CONF_SCHEMA = {
"type": "boolean",
"default": False,
},
"override_exchange_check": {
"description": (
"Override the exchange check to force FreqAI to use exchanges "
"that may not have enough historic data. Turn this to True if "
"you know your FreqAI model and strategy do not require historical data."
),
"type": "boolean",
"default": False,
},
"feature_parameters": {
"description": "The parameters used to engineer the feature set",
"type": "object",
@@ -113,7 +113,6 @@ def _validate_price_config(conf: dict[str, Any]) -> None:
"""
When using market orders, price sides must be using the "other" side of the price
"""
# TODO: The below could be an enforced setting when using market orders
if conf.get("order_types", {}).get("entry") == "market" and conf.get("entry_pricing", {}).get(
"price_side"
) not in ("ask", "other"):
+24 -5
View File
@@ -12,13 +12,16 @@ from typing import Any
from freqtrade import constants
from freqtrade.configuration.deprecated_settings import process_temporary_deprecated_settings
from freqtrade.configuration.directory_operations import create_datadir, create_userdata_dir
from freqtrade.configuration.environment_vars import enironment_vars_to_dict
from freqtrade.configuration.environment_vars import environment_vars_to_dict
from freqtrade.configuration.load_config import load_file, load_from_files
from freqtrade.constants import Config
from freqtrade.enums import (
NON_UTIL_MODES,
TRADE_MODES,
CandleType,
MarginMode,
RunMode,
TradingMode,
)
from freqtrade.exceptions import OperationalException
from freqtrade.loggers import setup_logging
@@ -77,7 +80,7 @@ class Configuration:
from freqtrade.commands.arguments import NO_CONF_ALLOWED
if self.args.get("command") not in NO_CONF_ALLOWED:
env_data = enironment_vars_to_dict()
env_data = environment_vars_to_dict()
config = deep_merge_dicts(env_data, config)
# Normalize config
@@ -230,6 +233,9 @@ class Configuration:
config["exportdirectory"] = config["user_data_dir"] / "backtest_results"
if not config.get("exportfilename"):
config["exportfilename"] = None
if config.get("exportfilename"):
# ensure exportfilename is a Path object
config["exportfilename"] = Path(config["exportfilename"])
config["exportdirectory"] = Path(config["exportdirectory"])
if self.args.get("show_sensitive"):
@@ -256,7 +262,13 @@ class Configuration:
self._args_to_config(
config,
argname="enable_protections",
logstring="Parameter --enable-protections detected, enabling Protections. ...",
logstring="Parameter --enable-protections detected, enabling Protections ...",
)
self._args_to_config(
config,
argname="enable_dynamic_pairlist",
logstring="Parameter --enable-dynamic-pairlist detected, enabling dynamic pairlist ...",
)
if self.args.get("max_open_trades"):
@@ -312,7 +324,6 @@ class Configuration:
"recursive_strategy_search",
"Recursively searching for a strategy in the strategies folder.",
),
("timeframe", "Overriding timeframe with Command line argument"),
("export", "Parameter --export detected: {} ..."),
("backtest_breakdown", "Parameter --breakdown detected ..."),
("backtest_cache", "Parameter --cache={} detected ..."),
@@ -325,7 +336,6 @@ class Configuration:
# Hyperopt section
configurations = [
("hyperopt", "Using Hyperopt class name: {}"),
("hyperopt_path", "Using additional Hyperopt lookup path: {}"),
("hyperoptexportfilename", "Using hyperopt file: {}"),
("lookahead_analysis_exportfilename", "Saving lookahead analysis results into {} ..."),
@@ -391,6 +401,7 @@ class Configuration:
("timeframes", "timeframes --timeframes: {}"),
("days", "Detected --days: {}"),
("include_inactive", "Detected --include-inactive-pairs: {}"),
("no_parallel_download", "Detected --no-parallel-download: {}"),
("download_trades", "Detected --dl-trades: {}"),
("convert_trades", "Detected --convert: {} - Converting Trade data to OHCV {}"),
("dataformat_ohlcv", 'Using "{}" to store OHLCV data.'),
@@ -406,6 +417,14 @@ class Configuration:
self._args_to_config(
config, argname="trading_mode", logstring="Detected --trading-mode: {}"
)
# TODO: The following 3 lines (candle_type_def, trading_mode, margin_mode) are actually
# set in the exchange class. They're however necessary as fallback to avoid
# random errors in commands that don't initialize an exchange.
config["candle_type_def"] = CandleType.get_default(
config.get("trading_mode", "spot") or "spot"
)
config["trading_mode"] = TradingMode(config.get("trading_mode", "spot") or "spot")
config["margin_mode"] = MarginMode(config.get("margin_mode", "") or "")
self._args_to_config(
config, argname="candle_types", logstring="Detected --candle-types: {}"
)
+1 -1
View File
@@ -73,7 +73,7 @@ def _flat_vars_to_nested_dict(env_dict: dict[str, Any], prefix: str) -> dict[str
return relevant_vars
def enironment_vars_to_dict() -> dict[str, Any]:
def environment_vars_to_dict() -> dict[str, Any]:
"""
Read environment variables and return a nested dict for relevant variables
Relevant variables must follow the FREQTRADE__{section}__{key} pattern
+3
View File
@@ -80,6 +80,9 @@ class TimeRange:
val = stopdt.strftime(DATETIME_PRINT_FORMAT)
return val
def __repr__(self) -> str:
return f"TimeRange({self.timerange_str})"
def __eq__(self, other):
"""Override the default Equals behavior"""
return (
+2 -1
View File
@@ -49,6 +49,7 @@ AVAILABLE_PAIRLISTS = [
"RemotePairList",
"MarketCapPairList",
"AgeFilter",
"DelistFilter",
"FullTradesFilter",
"OffsetFilter",
"PerformanceFilter",
@@ -60,7 +61,7 @@ AVAILABLE_PAIRLISTS = [
"VolatilityFilter",
]
AVAILABLE_DATAHANDLERS = ["json", "jsongz", "feather", "parquet"]
BACKTEST_BREAKDOWNS = ["day", "week", "month", "year"]
BACKTEST_BREAKDOWNS = ["day", "week", "month", "year", "weekday"]
BACKTEST_CACHE_AGE = ["none", "day", "week", "month"]
BACKTEST_CACHE_DEFAULT = "day"
DRY_RUN_WALLET = 1000
+2 -2
View File
@@ -511,8 +511,8 @@ def trade_list_to_dataframe(trades: list[Trade] | list[LocalTrade]) -> pd.DataFr
"""
df = pd.DataFrame.from_records([t.to_json(True) for t in trades], columns=BT_DATA_COLUMNS)
if len(df) > 0:
df["close_date"] = pd.to_datetime(df["close_date"], utc=True)
df["open_date"] = pd.to_datetime(df["open_date"], utc=True)
df["close_date"] = pd.to_datetime(df["close_timestamp"], unit="ms", utc=True)
df["open_date"] = pd.to_datetime(df["open_timestamp"], unit="ms", utc=True)
df["close_rate"] = df["close_rate"].astype("float64")
return df
-1
View File
@@ -181,7 +181,6 @@ def trim_dataframes(
def order_book_to_dataframe(bids: list, asks: list) -> DataFrame:
"""
TODO: This should get a dedicated test
Gets order book list, returns dataframe with below format per suggested by creslin
-------------------------------------------------------------------
b_sum b_size bids asks a_size a_sum
+43 -4
View File
@@ -23,7 +23,7 @@ from freqtrade.data.history import get_datahandler, load_pair_history
from freqtrade.enums import CandleType, RPCMessageType, RunMode, TradingMode
from freqtrade.exceptions import ExchangeError, OperationalException
from freqtrade.exchange import Exchange, timeframe_to_prev_date, timeframe_to_seconds
from freqtrade.exchange.exchange_types import OrderBook
from freqtrade.exchange.exchange_types import FundingRate, OrderBook
from freqtrade.misc import append_candles_to_dataframe
from freqtrade.rpc import RPCManager
from freqtrade.rpc.rpc_types import RPCAnalyzedDFMsg
@@ -498,7 +498,12 @@ class DataProvider:
return DataFrame()
def trades(
self, pair: str, timeframe: str | None = None, copy: bool = True, candle_type: str = ""
self,
pair: str,
timeframe: str | None = None,
copy: bool = True,
candle_type: str = "",
timerange: TimeRange | None = None,
) -> DataFrame:
"""
Get candle (TRADES) data for the given pair as DataFrame
@@ -526,7 +531,7 @@ class DataProvider:
self._config["datadir"], data_format=self._config["dataformat_trades"]
)
trades_df = data_handler.trades_load(
pair, self._config.get("trading_mode", TradingMode.SPOT)
pair, self._config.get("trading_mode", TradingMode.SPOT), timerange=timerange
)
return trades_df
@@ -543,6 +548,7 @@ class DataProvider:
def ticker(self, pair: str):
"""
Return last ticker data from exchange
Warning: Performs a network request - so use with common sense.
:param pair: Pair to get the data for
:return: Ticker dict from exchange or empty dict if ticker is not available for the pair
"""
@@ -556,7 +562,7 @@ class DataProvider:
def orderbook(self, pair: str, maximum: int) -> OrderBook:
"""
Fetch latest l2 orderbook data
Warning: Does a network request - so use with common sense.
Warning: Performs a network request - so use with common sense.
:param pair: pair to get the data for
:param maximum: Maximum number of orderbook entries to query
:return: dict including bids/asks with a total of `maximum` entries.
@@ -565,6 +571,23 @@ class DataProvider:
raise OperationalException(NO_EXCHANGE_EXCEPTION)
return self._exchange.fetch_l2_order_book(pair, maximum)
def funding_rate(self, pair: str) -> FundingRate:
"""
Return Funding rate from the exchange
Warning: Performs a network request - so use with common sense.
:param pair: Pair to get the data for
:return: Funding rate dict from exchange or empty dict if funding rate is not available
If available, the "fundingRate" field will contain the funding rate.
"fundingTimestamp" and "fundingDatetime" will contain the next funding times.
Actually filled fields may vary between exchanges.
"""
if self._exchange is None:
raise OperationalException(NO_EXCHANGE_EXCEPTION)
try:
return self._exchange.fetch_funding_rate(pair)
except ExchangeError:
return {}
def send_msg(self, message: str, *, always_send: bool = False) -> None:
"""
Send custom RPC Notifications from your bot.
@@ -581,3 +604,19 @@ class DataProvider:
if always_send or message not in self.__msg_cache:
self._msg_queue.append(message)
self.__msg_cache[message] = True
def check_delisting(self, pair: str) -> datetime | None:
"""
Check if a pair gonna be delisted on the exchange.
Will only return datetime if the pair is gonna be delisted.
:param pair: Pair to check
:return: Datetime of the pair's delisting, None otherwise
"""
if self._exchange is None:
raise OperationalException(NO_EXCHANGE_EXCEPTION)
try:
return self._exchange.check_delisting_time(pair)
except ExchangeError:
logger.warning(f"Could not fetch market data for {pair}. Assuming no delisting.")
return None
@@ -1,6 +1,7 @@
import logging
from pandas import DataFrame, read_feather, to_datetime
from pyarrow import dataset
from freqtrade.configuration import TimeRange
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS
@@ -111,22 +112,71 @@ class FeatherDataHandler(IDataHandler):
"""
raise NotImplementedError()
def _build_arrow_time_filter(self, timerange: TimeRange | None):
"""
Build Arrow predicate filter for timerange filtering.
Treats 0 as unbounded (no filter on that side).
:param timerange: TimeRange object with start/stop timestamps
:return: Arrow filter expression or None if fully unbounded
"""
if not timerange:
return None
# Treat 0 as unbounded
start_set = bool(timerange.startts and timerange.startts > 0)
stop_set = bool(timerange.stopts and timerange.stopts > 0)
if not (start_set or stop_set):
return None
ts_field = dataset.field("timestamp")
exprs = []
if start_set:
exprs.append(ts_field >= timerange.startts)
if stop_set:
exprs.append(ts_field <= timerange.stopts)
if len(exprs) == 1:
return exprs[0]
else:
return exprs[0] & exprs[1]
def _trades_load(
self, pair: str, trading_mode: TradingMode, timerange: TimeRange | None = None
) -> DataFrame:
"""
Load a pair from file, either .json.gz or .json
# TODO: respect timerange ...
:param pair: Load trades for this pair
:param trading_mode: Trading mode to use (used to determine the filename)
:param timerange: Timerange to load trades for - currently not implemented
:param timerange: Timerange to load trades for - filters data to this range if provided
:return: Dataframe containing trades
"""
filename = self._pair_trades_filename(self._datadir, pair, trading_mode)
if not filename.exists():
return DataFrame(columns=DEFAULT_TRADES_COLUMNS)
tradesdata = read_feather(filename)
# Use Arrow dataset with optional timerange filtering, fallback to read_feather
try:
dataset_reader = dataset.dataset(filename, format="feather")
time_filter = self._build_arrow_time_filter(timerange)
if time_filter is not None and timerange is not None:
tradesdata = dataset_reader.to_table(filter=time_filter).to_pandas()
start_desc = timerange.startts if timerange.startts > 0 else "unbounded"
stop_desc = timerange.stopts if timerange.stopts > 0 else "unbounded"
logger.debug(
f"Loaded {len(tradesdata)} trades for {pair} "
f"(filtered start={start_desc}, stop={stop_desc})"
)
else:
tradesdata = dataset_reader.to_table().to_pandas()
logger.debug(f"Loaded {len(tradesdata)} trades for {pair} (unfiltered)")
except (ImportError, AttributeError, ValueError) as e:
# Fallback: load entire file
logger.warning(f"Unable to use Arrow filtering, loading entire trades file: {e}")
tradesdata = read_feather(filename)
return tradesdata
+107 -15
View File
@@ -6,7 +6,14 @@ from pathlib import Path
from pandas import DataFrame, concat
from freqtrade.configuration import TimeRange
from freqtrade.constants import DATETIME_PRINT_FORMAT, DL_DATA_TIMEFRAMES, DOCS_LINK, Config
from freqtrade.constants import (
DATETIME_PRINT_FORMAT,
DL_DATA_TIMEFRAMES,
DOCS_LINK,
Config,
ListPairsWithTimeframes,
PairWithTimeframe,
)
from freqtrade.data.converter import (
clean_ohlcv_dataframe,
convert_trades_to_ohlcv,
@@ -17,6 +24,7 @@ from freqtrade.data.history.datahandlers import IDataHandler, get_datahandler
from freqtrade.enums import CandleType, TradingMode
from freqtrade.exceptions import OperationalException
from freqtrade.exchange import Exchange
from freqtrade.exchange.exchange_utils import date_minus_candles
from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist
from freqtrade.util import dt_now, dt_ts, format_ms_time, format_ms_time_det
from freqtrade.util.migrations import migrate_data
@@ -226,6 +234,7 @@ def _download_pair_history(
candle_type: CandleType,
erase: bool = False,
prepend: bool = False,
pair_candles: DataFrame | None = None,
) -> bool:
"""
Download latest candles from the exchange for the pair and timeframe passed in parameters
@@ -238,6 +247,7 @@ def _download_pair_history(
:param timerange: range of time to download
:param candle_type: Any of the enum CandleType (must match trading mode!)
:param erase: Erase existing data
:param pair_candles: Optional with "1 call" pair candles.
:return: bool with success state
"""
data_handler = get_datahandler(datadir, data_handler=data_handler)
@@ -271,21 +281,40 @@ def _download_pair_history(
"Current End: %s",
f"{data.iloc[-1]['date']:{DATETIME_PRINT_FORMAT}}" if not data.empty else "None",
)
# Default since_ms to 30 days if nothing is given
new_dataframe = exchange.get_historic_ohlcv(
pair=pair,
timeframe=timeframe,
since_ms=(
since_ms
if since_ms
else int((datetime.now() - timedelta(days=new_pairs_days)).timestamp()) * 1000
),
is_new_pair=data.empty,
candle_type=candle_type,
until_ms=until_ms if until_ms else None,
# used to check if the passed in pair_candles (parallel downloaded) covers since_ms.
# If we need more data, we have to fall back to the standard method.
pair_candles_since_ms = (
dt_ts(pair_candles.iloc[0]["date"])
if pair_candles is not None and len(pair_candles.index) > 0
else 0
)
logger.info(f"Downloaded data for {pair} with length {len(new_dataframe)}.")
if (
pair_candles is None
or len(pair_candles.index) == 0
or data.empty
or prepend is True
or erase is True
or pair_candles_since_ms > (since_ms if since_ms else 0)
):
new_dataframe = exchange.get_historic_ohlcv(
pair=pair,
timeframe=timeframe,
since_ms=(
since_ms
if since_ms
else int((datetime.now() - timedelta(days=new_pairs_days)).timestamp()) * 1000
),
is_new_pair=data.empty,
candle_type=candle_type,
until_ms=until_ms if until_ms else None,
)
logger.info(f"Downloaded data for {pair} with length {len(new_dataframe)}.")
else:
new_dataframe = pair_candles
logger.info(
f"Downloaded data for {pair} with length {len(new_dataframe)}. Parallel Method."
)
if data.empty:
data = new_dataframe
else:
@@ -330,6 +359,7 @@ def refresh_backtest_ohlcv_data(
data_format: str | None = None,
prepend: bool = False,
progress_tracker: CustomProgress | None = None,
no_parallel_download: bool = False,
) -> list[str]:
"""
Refresh stored ohlcv data for backtesting and hyperopt operations.
@@ -339,6 +369,7 @@ def refresh_backtest_ohlcv_data(
progress_tracker = retrieve_progress_tracker(progress_tracker)
pairs_not_available = []
fast_candles: dict[PairWithTimeframe, DataFrame] = {}
data_handler = get_datahandler(datadir, data_format)
candle_type = CandleType.get_default(trading_mode)
with progress_tracker as progress:
@@ -355,6 +386,30 @@ def refresh_backtest_ohlcv_data(
logger.info(f"Skipping pair {pair}...")
continue
for timeframe in timeframes:
# Get fast candles via parallel method on first loop through per timeframe
# and candle type. Downloads all the pairs in the list and stores them.
if (
not no_parallel_download
and exchange.get_option("download_data_parallel_quick", True)
and (
((pair, timeframe, candle_type) not in fast_candles)
and (erase is False)
and (prepend is False)
)
):
fast_candles.update(
_download_all_pairs_history_parallel(
exchange=exchange,
pairs=pairs,
timeframe=timeframe,
candle_type=candle_type,
timerange=timerange,
)
)
# get the already downloaded pair candles if they exist
pair_candles = fast_candles.pop((pair, timeframe, candle_type), None)
progress.update(timeframe_task, description=f"Timeframe {timeframe}")
logger.debug(f"Downloading pair {pair}, {candle_type}, interval {timeframe}.")
_download_pair_history(
@@ -368,6 +423,7 @@ def refresh_backtest_ohlcv_data(
candle_type=candle_type,
erase=erase,
prepend=prepend,
pair_candles=pair_candles, # optional pass of dataframe of parallel candles
)
progress.update(timeframe_task, advance=1)
if trading_mode == "futures":
@@ -404,6 +460,41 @@ def refresh_backtest_ohlcv_data(
return pairs_not_available
def _download_all_pairs_history_parallel(
exchange: Exchange,
pairs: list[str],
timeframe: str,
candle_type: CandleType,
timerange: TimeRange | None = None,
) -> dict[PairWithTimeframe, DataFrame]:
"""
Allows to use the faster parallel async download method for many coins
but only if the data is short enough to be retrieved in one call.
Used by freqtrade download-data subcommand.
:return: Candle pairs with timeframes
"""
candles: dict[PairWithTimeframe, DataFrame] = {}
since = 0
if timerange:
if timerange.starttype == "date":
since = timerange.startts * 1000
candle_limit = exchange.ohlcv_candle_limit(timeframe, candle_type)
one_call_min_time_dt = dt_ts(date_minus_candles(timeframe, candle_limit))
# check if we can get all candles in one go, if so then we can download them in parallel
if since > one_call_min_time_dt:
logger.info(
f"Downloading parallel candles for {timeframe} for all pairs "
f"since {format_ms_time(since)}"
)
needed_pairs: ListPairsWithTimeframes = [
(p, timeframe, candle_type) for p in [p for p in pairs]
]
candles = exchange.refresh_latest_ohlcv(needed_pairs, since_ms=since, cache=False)
return candles
def _download_trades_history(
exchange: Exchange,
pair: str,
@@ -702,6 +793,7 @@ def download_data(
trading_mode=config.get("trading_mode", "spot"),
prepend=config.get("prepend_data", False),
progress_tracker=progress_tracker,
no_parallel_download=config.get("no_parallel_download", False),
)
finally:
if pairs_not_available:
+2 -1
View File
@@ -11,6 +11,7 @@ from freqtrade.exchange.bitmart import Bitmart
from freqtrade.exchange.bitpanda import Bitpanda
from freqtrade.exchange.bitvavo import Bitvavo
from freqtrade.exchange.bybit import Bybit
from freqtrade.exchange.coinex import Coinex
from freqtrade.exchange.cryptocom import Cryptocom
from freqtrade.exchange.exchange_utils import (
ROUND_DOWN,
@@ -46,4 +47,4 @@ from freqtrade.exchange.kucoin import Kucoin
from freqtrade.exchange.lbank import Lbank
from freqtrade.exchange.luno import Luno
from freqtrade.exchange.modetrade import Modetrade
from freqtrade.exchange.okx import MyOkx, Okx
from freqtrade.exchange.okx import Myokx, Okx, Okxus
+114 -2
View File
@@ -5,10 +5,11 @@ from datetime import UTC, datetime
from pathlib import Path
import ccxt
from cachetools import TTLCache
from pandas import DataFrame
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode
from freqtrade.enums import TRADE_MODES, CandleType, MarginMode, PriceType, RunMode, TradingMode
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
from freqtrade.exchange import Exchange
from freqtrade.exchange.binance_public_data import (
@@ -27,6 +28,10 @@ logger = logging.getLogger(__name__)
class Binance(Exchange):
"""Binance exchange class.
Contains adjustments needed for Freqtrade to work with this exchange.
"""
_ft_has: FtHas = {
"stoploss_on_exchange": True,
"stop_price_param": "stopPrice",
@@ -40,6 +45,7 @@ class Binance(Exchange):
"fetch_orders_limit_minutes": None,
"l2_limit_range": [5, 10, 20, 50, 100, 500, 1000],
"ws_enabled": True,
"has_delisting": True,
}
_ft_has_futures: FtHas = {
"funding_fee_candle_limit": 1000,
@@ -68,6 +74,10 @@ class Binance(Exchange):
(TradingMode.FUTURES, MarginMode.ISOLATED),
]
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self._spot_delist_schedule_cache: TTLCache = TTLCache(maxsize=100, ttl=300)
def get_proxy_coin(self) -> str:
"""
Get the proxy coin for the given coin
@@ -391,7 +401,7 @@ class Binance(Exchange):
async def _async_get_trade_history_id(
self, pair: str, until: int, since: int, from_id: str | None = None
) -> tuple[str, list[list]]:
logger.info(f"Fetching trades from Binance, {from_id=}, {since=}, {until=}")
logger.info(f"Fetching trades for {pair} from Binance, {from_id=}, {since=}, {until=}")
if not self._config["exchange"].get("only_from_ccxt", False):
if from_id is None or not since:
@@ -432,3 +442,105 @@ class Binance(Exchange):
return await super()._async_get_trade_history_id(
pair, until=until, since=since, from_id=from_id
)
def _check_delisting_futures(self, pair: str) -> datetime | None:
delivery_time = self.markets.get(pair, {}).get("info", {}).get("deliveryDate", None)
if delivery_time:
if isinstance(delivery_time, str) and (delivery_time != ""):
delivery_time = int(delivery_time)
# Binance set a very high delivery time for all perpetuals.
# We compare with delivery time of BTC/USDT:USDT which assumed to never be delisted
btc_delivery_time = (
self.markets.get("BTC/USDT:USDT", {}).get("info", {}).get("deliveryDate", None)
)
if delivery_time == btc_delivery_time:
return None
delivery_time = dt_from_ts(delivery_time)
return delivery_time
def check_delisting_time(self, pair: str) -> datetime | None:
"""
Check if the pair gonna be delisted.
By default, it returns None.
:param pair: Market symbol
:return: Datetime if the pair gonna be delisted, None otherwise
"""
if self._config["runmode"] not in TRADE_MODES:
return None
if self.trading_mode == TradingMode.FUTURES:
return self._check_delisting_futures(pair)
return self._get_spot_pair_delist_time(pair, refresh=False)
def _get_spot_delist_schedule(self):
"""
Get the delisting schedule for spot pairs
Only works in live mode as it requires API keys,
Return sample:
[{
"delistTime": "1759114800000",
"symbols": [
"OMNIBTC",
"OMNIFDUSD",
"OMNITRY",
"OMNIUSDC",
"OMNIUSDT"
]
}]
"""
try:
delist_schedule = self._api.sapi_get_spot_delist_schedule()
return delist_schedule
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.OperationFailed, ccxt.ExchangeError) as e:
raise TemporaryError(
f"Could not get delist schedule {e.__class__.__name__}. Message: {e}"
) from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
def _get_spot_pair_delist_time(self, pair: str, refresh: bool = False) -> datetime | None:
"""
Get the delisting time for a pair if it will be delisted
:param pair: Pair to get the delisting time for
:param refresh: true if you need fresh data
:return: int: delisting time None if not delisting
"""
if not pair or not self._config["runmode"] == RunMode.LIVE:
# Endpoint only works in live mode as it requires API keys
return None
cache = self._spot_delist_schedule_cache
if not refresh:
if delist_time := cache.get(pair, None):
return delist_time
delist_schedule = self._get_spot_delist_schedule()
if delist_schedule is None:
return None
for schedule in delist_schedule:
delist_dt = dt_from_ts(int(schedule["delistTime"]))
for symbol in schedule["symbols"]:
ft_symbol = next(
(
pair
for pair, market in self.markets.items()
if market.get("id", None) == symbol
),
None,
)
if ft_symbol is None:
continue
cache[ft_symbol] = delist_dt
return cache.get(pair, None)
File diff suppressed because it is too large Load Diff
+118 -8
View File
@@ -3,7 +3,8 @@ from datetime import timedelta
import ccxt
from freqtrade.enums import CandleType
from freqtrade.constants import BuySell
from freqtrade.enums import CandleType, MarginMode, TradingMode
from freqtrade.exceptions import (
DDosProtection,
OperationalException,
@@ -20,27 +21,30 @@ logger = logging.getLogger(__name__)
class Bitget(Exchange):
"""
Bitget exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
Please note that this exchange is not included in the list of exchanges
officially supported by the Freqtrade development team. So some features
may still not work as expected.
"""Bitget exchange class.
Contains adjustments needed for Freqtrade to work with this exchange.
"""
_ft_has: FtHas = {
"stoploss_on_exchange": True,
"stop_price_param": "stopPrice",
"stop_price_prop": "stopPrice",
"stoploss_blocks_assets": False, # Stoploss orders do not block assets
"stoploss_order_types": {"limit": "limit", "market": "market"},
"ohlcv_candle_limit": 200, # 200 for historical candles, 1000 for recent ones.
"order_time_in_force": ["GTC", "FOK", "IOC", "PO"],
}
_ft_has_futures: FtHas = {
"mark_ohlcv_timeframe": "4h",
"funding_fee_candle_limit": 100,
}
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
(TradingMode.SPOT, MarginMode.NONE),
(TradingMode.FUTURES, MarginMode.ISOLATED),
# (TradingMode.FUTURES, MarginMode.CROSS),
]
def ohlcv_candle_limit(
self, timeframe: str, candle_type: CandleType, since_ms: int | None = None
) -> int:
@@ -126,3 +130,109 @@ class Bitget(Exchange):
def cancel_stoploss_order(self, order_id: str, pair: str, params: dict | None = None) -> dict:
return self.cancel_order(order_id=order_id, pair=pair, params={"stop": True})
@retrier
def additional_exchange_init(self) -> None:
"""
Additional exchange initialization logic.
.api will be available at this point.
Must be overridden in child methods if required.
"""
try:
if not self._config["dry_run"]:
if self.trading_mode == TradingMode.FUTURES:
position_mode = self._api.set_position_mode(False)
self._log_exchange_response("set_position_mode", position_mode)
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.OperationFailed, ccxt.ExchangeError) as e:
raise TemporaryError(
f"Error in additional_exchange_init due to {e.__class__.__name__}. Message: {e}"
) from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
def _lev_prep(self, pair: str, leverage: float, side: BuySell, accept_fail: bool = False):
if self.trading_mode != TradingMode.SPOT:
# Explicitly setting margin_mode is not necessary as marginMode can be set per order.
# self.set_margin_mode(pair, self.margin_mode, accept_fail)
self._set_leverage(leverage, pair, accept_fail)
def _get_params(
self,
side: BuySell,
ordertype: str,
leverage: float,
reduceOnly: bool,
time_in_force: str = "GTC",
) -> dict:
params = super()._get_params(
side=side,
ordertype=ordertype,
leverage=leverage,
reduceOnly=reduceOnly,
time_in_force=time_in_force,
)
if self.trading_mode == TradingMode.FUTURES and self.margin_mode:
params["marginMode"] = self.margin_mode.value.lower()
return params
def dry_run_liquidation_price(
self,
pair: str,
open_rate: float,
is_short: bool,
amount: float,
stake_amount: float,
leverage: float,
wallet_balance: float,
open_trades: list,
) -> float | None:
"""
Important: Must be fetching data from cached values as this is used by backtesting!
https://www.bitget.com/support/articles/12560603808759
MMR: Maintenance margin rate of the trading pair.
CoinMainIndexPrice: The index price for Coin-M futures. For USDT-M futures,
the index price is: 1.
TakerFeeRatio: The fee rate applied when placing taker orders.
Position direction: The current position direction of the trading pair.
1 indicates a long position, and -1 indicates a short position.
Formula:
Estimated liquidation price = [
position margin - position size x average entry price x position direction
] ÷ [position size x (MMR + TakerFeeRatio - position direction)]
:param pair: Pair to calculate liquidation price for
:param open_rate: Entry price of position
:param is_short: True if the trade is a short, false otherwise
:param amount: Absolute value of position size incl. leverage (in base currency)
:param stake_amount: Stake amount - Collateral in settle currency.
:param leverage: Leverage used for this position.
:param wallet_balance: Amount of margin_mode in the wallet being used to trade
Cross-Margin Mode: crossWalletBalance
Isolated-Margin Mode: isolatedWalletBalance
:param open_trades: List of other open trades in the same wallet
"""
market = self.markets[pair]
taker_fee_rate = market["taker"] or self._api.describe().get("fees", {}).get(
"trading", {}
).get("taker", 0.001)
mm_ratio, _ = self.get_maintenance_ratio_and_amt(pair, stake_amount)
if self.trading_mode == TradingMode.FUTURES and self.margin_mode == MarginMode.ISOLATED:
position_direction = -1 if is_short else 1
return (wallet_balance - (amount * open_rate * position_direction)) / (
amount * (mm_ratio + taker_fee_rate - position_direction)
)
else:
raise OperationalException(
"Freqtrade currently only supports isolated futures for bitget"
)
-10
View File
@@ -2,8 +2,6 @@
import logging
from ccxt import DECIMAL_PLACES
from freqtrade.exchange import Exchange
from freqtrade.exchange.exchange_types import FtHas
@@ -24,11 +22,3 @@ class Bitvavo(Exchange):
_ft_has: FtHas = {
"ohlcv_candle_limit": 1440,
}
@property
def precisionMode(self) -> int:
"""
Exchange ccxt precisionMode
Override due to https://github.com/ccxt/ccxt/issues/20408
"""
return DECIMAL_PLACES
+2 -7
View File
@@ -16,13 +16,8 @@ logger = logging.getLogger(__name__)
class Bybit(Exchange):
"""
Bybit exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
Please note that this exchange is not included in the list of exchanges
officially supported by the Freqtrade development team. So some features
may still not work as expected.
"""Bybit exchange class.
Contains adjustments needed for Freqtrade to work with this exchange.
"""
unified_account = False
+24
View File
@@ -0,0 +1,24 @@
import logging
from freqtrade.exchange import Exchange
from freqtrade.exchange.exchange_types import FtHas
logger = logging.getLogger(__name__)
class Coinex(Exchange):
"""
CoinEx exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
Please note that this exchange is not included in the list of exchanges
officially supported by the Freqtrade development team. So some features
may still not work as expected.
"""
_ft_has: FtHas = {
"l2_limit_range": [5, 10, 20, 50],
"tickers_have_bid_ask": False,
"tickers_have_quoteVolume": False,
}
+1 -2
View File
@@ -48,7 +48,6 @@ MAP_EXCHANGE_CHILDCLASS = {
"binanceus": "binance",
"binanceusdm": "binance",
"okex": "okx",
"okxus": "okx",
"gateio": "gate",
"huboi": "htx",
}
@@ -57,6 +56,7 @@ SUPPORTED_EXCHANGES = [
"binance",
"bingx",
"bitmart",
"bitget",
"bybit",
"gate",
"htx",
@@ -96,7 +96,6 @@ EXCHANGE_HAS_OPTIONAL = [
# 'fetchPositions', # Futures trading
# 'fetchLeverageTiers', # Futures initialization
# 'fetchMarketLeverageTiers', # Futures initialization
# 'fetchOpenOrder', 'fetchClosedOrder', # replacement for fetchOrder
# 'fetchOpenOrders', 'fetchClosedOrders', # 'fetchOrders', # Refinding balance...
# ccxt.pro
"watchOHLCV",
+107 -19
View File
@@ -73,6 +73,7 @@ from freqtrade.exchange.exchange_types import (
CcxtOrder,
CcxtPosition,
FtHas,
FundingRate,
OHLCVResponse,
OrderBook,
Ticker,
@@ -137,6 +138,7 @@ class Exchange:
"ohlcv_has_history": True, # Some exchanges (Kraken) don't provide history via ohlcv
"ohlcv_partial_candle": True,
"ohlcv_require_since": False,
"download_data_parallel_quick": True,
"always_require_api_keys": False, # purge API keys for Dry-run. Must default to false.
# Check https://github.com/ccxt/ccxt/issues/10767 for removal of ohlcv_volume_currency
"ohlcv_volume_currency": "base", # "base" or "quote"
@@ -164,6 +166,7 @@ class Exchange:
"proxy_coin_mapping": {}, # Mapping for proxy coins
# Expected to be in the format {"fetchOHLCV": True} or {"fetchOHLCV": False}
"ws_enabled": False, # Set to true for exchanges with tested websocket support
"has_delisting": False, # Set to true for exchanges that have delisting pair checks
}
_ft_has: FtHas = {}
_ft_has_futures: FtHas = {}
@@ -297,7 +300,7 @@ class Exchange:
if self.trading_mode != TradingMode.SPOT and load_leverage_tiers:
self.fill_leverage_tiers()
self.additional_exchange_init()
self.ft_additional_exchange_init()
def __del__(self):
"""
@@ -452,6 +455,12 @@ class Exchange:
"""
return self._api.precisionMode
def ft_additional_exchange_init(self) -> None:
"""
Wrapper around additional_exchange_init to simplify testing
"""
self.additional_exchange_init()
def additional_exchange_init(self) -> None:
"""
Additional exchange initialization logic.
@@ -690,12 +699,13 @@ class Exchange:
# Reload async markets, then assign them to sync api
retrier(self._load_async_markets, retries=retries)(reload=True)
self._markets = self._api_async.markets
self._api.set_markets(self._api_async.markets, self._api_async.currencies)
self._api.set_markets_from_exchange(self._api_async)
# Assign options array, as it contains some temporary information from the exchange.
# TODO: investigate with ccxt if it's safe to remove `.options`
self._api.options = self._api_async.options
if self._exchange_ws:
# Set markets to avoid reloading on websocket api
self._ws_async.set_markets(self._api.markets, self._api.currencies)
self._ws_async.set_markets_from_exchange(self._api_async)
self._ws_async.options = self._api.options
self._last_markets_refresh = dt_ts()
@@ -828,10 +838,16 @@ class Exchange:
def validate_freqai(self, config: Config) -> None:
freqai_enabled = config.get("freqai", {}).get("enabled", False)
if freqai_enabled and not self._ft_has["ohlcv_has_history"]:
override = config.get("freqai", {}).get("override_exchange_checks", False)
if not override and freqai_enabled and not self._ft_has["ohlcv_has_history"]:
raise ConfigurationError(
f"Historic OHLCV data not available for {self.name}. Can't use freqAI."
)
elif override and freqai_enabled and not self._ft_has["ohlcv_has_history"]:
logger.warning(
"Overriding exchange checks for freqAI. Make sure that your exchange supports "
"fetching historic OHLCV data, otherwise freqAI will not work."
)
def validate_required_startup_candles(self, startup_candles: int, timeframe: str) -> int:
"""
@@ -890,6 +906,19 @@ class Exchange:
f"Freqtrade does not support '{mm_value}' '{trading_mode}' on {self.name}."
)
@classmethod
def combine_ft_has(cls, include_futures: bool) -> FtHas:
"""
Combine all ft_has options from the class hierarchy.
Child classes override parent classes.
Doesn't apply overrides from the configuration.
"""
_ft_has = deep_merge_dicts(cls._ft_has, deepcopy(cls._ft_has_default))
if include_futures:
_ft_has = deep_merge_dicts(cls._ft_has_futures, _ft_has)
return _ft_has
def build_ft_has(self, exchange_conf: ExchangeConfig) -> None:
"""
Deep merge ft_has with default ft_has options
@@ -897,9 +926,8 @@ class Exchange:
This is called on initialization of the exchange object.
It must be called before ft_has is used.
"""
self._ft_has = deep_merge_dicts(self._ft_has, deepcopy(self._ft_has_default))
if self.trading_mode == TradingMode.FUTURES:
self._ft_has = deep_merge_dicts(self._ft_has_futures, self._ft_has)
self._ft_has = self.combine_ft_has(include_futures=self.trading_mode == TradingMode.FUTURES)
if exchange_conf.get("_ft_has_params"):
self._ft_has = deep_merge_dicts(exchange_conf.get("_ft_has_params"), self._ft_has)
logger.info("Overriding exchange._ft_has with config params, result: %s", self._ft_has)
@@ -2001,6 +2029,30 @@ class Exchange:
except ccxt.BaseError as e:
raise OperationalException(e) from e
@retrier
def fetch_funding_rate(self, pair: str) -> FundingRate:
"""
Get current Funding rate from exchange.
On Futures markets, this is the interest rate for holding a position.
Won't work for non-futures markets
"""
try:
if pair not in self.markets or self.markets[pair].get("active", False) is False:
raise ExchangeError(f"Pair {pair} not available")
return self._api.fetch_funding_rate(pair)
except ccxt.NotSupported as e:
raise OperationalException(
f"Exchange {self._api.name} does not support fetching funding rate. Message: {e}"
) from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.OperationFailed, ccxt.ExchangeError) as e:
raise TemporaryError(
f"Could not get funding rate due to {e.__class__.__name__}. Message: {e}"
) from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
@staticmethod
def get_next_limit_in_list(
limit: int,
@@ -2456,7 +2508,14 @@ class Exchange:
data.extend(new_data)
# Sort data again after extending the result - above calls return in "async order"
data = sorted(data, key=lambda x: x[0])
return pair, timeframe, candle_type, data, self._ohlcv_partial_candle
return (
pair,
timeframe,
candle_type,
data,
# funding_rates are always complete, so never need to be dropped.
self._ohlcv_partial_candle if candle_type != CandleType.FUNDING_RATE else False,
)
def _try_build_from_websocket(
self, pair: str, timeframe: str, candle_type: CandleType
@@ -2566,14 +2625,24 @@ class Exchange:
input_coroutines: list[Coroutine[Any, Any, OHLCVResponse]] = []
cached_pairs = []
for pair, timeframe, candle_type in set(pair_list):
if timeframe not in self.timeframes and candle_type in (
invalid_funding = (
candle_type == CandleType.FUNDING_RATE
and timeframe != self.get_option("funding_fee_timeframe")
)
invalid_timeframe = timeframe not in self.timeframes and candle_type in (
CandleType.SPOT,
CandleType.FUTURES,
):
)
if invalid_timeframe or invalid_funding:
timeframes_ = (
", ".join(self.timeframes)
if candle_type != CandleType.FUNDING_RATE
else self.get_option("funding_fee_timeframe")
)
logger.warning(
f"Cannot download ({pair}, {timeframe}) combination as this timeframe is "
f"not available on {self.name}. Available timeframes are "
f"{', '.join(self.timeframes)}."
f"Cannot download ({pair}, {timeframe}, {candle_type}) combination as this "
f"timeframe is not available on {self.name}. Available timeframes are "
f"{timeframes_}."
)
continue
@@ -2756,7 +2825,7 @@ class Exchange:
timeframe, candle_type=candle_type, since_ms=since_ms
)
if candle_type and candle_type != CandleType.SPOT:
if candle_type and candle_type not in (CandleType.SPOT, CandleType.FUTURES):
params.update({"price": candle_type.value})
if candle_type != CandleType.FUNDING_RATE:
data = await self._api_async.fetch_ohlcv(
@@ -2771,8 +2840,6 @@ class Exchange:
since_ms=since_ms,
)
# Some exchanges sort OHLCV in ASC order and others in DESC.
# Ex: Bittrex returns the list of OHLCV in ASC order (oldest first, newest last)
# while GDAX returns the list of OHLCV in DESC order (newest first, oldest last)
# Only sort if necessary to save computing time
try:
if data and data[0][0] > data[-1][0]:
@@ -2781,7 +2848,14 @@ class Exchange:
logger.exception("Error loading %s. Result was %s.", pair, data)
return pair, timeframe, candle_type, [], self._ohlcv_partial_candle
logger.debug("Done fetching pair %s, %s interval %s...", pair, candle_type, timeframe)
return pair, timeframe, candle_type, data, self._ohlcv_partial_candle
return (
pair,
timeframe,
candle_type,
data,
# funding_rates are always complete, so never need to be dropped.
self._ohlcv_partial_candle if candle_type != CandleType.FUNDING_RATE else False,
)
except ccxt.NotSupported as e:
raise OperationalException(
@@ -3229,7 +3303,7 @@ class Exchange:
for sig in [signal.SIGINT, signal.SIGTERM]:
try:
self.loop.add_signal_handler(sig, task.cancel)
except NotImplementedError:
except (NotImplementedError, RuntimeError):
# Not all platforms implement signals (e.g. windows)
pass
return self.loop.run_until_complete(task)
@@ -3811,7 +3885,10 @@ class Exchange:
"""
market = self.markets[pair]
taker_fee_rate = market["taker"]
# default to some default fee if not available from exchange
taker_fee_rate = market["taker"] or self._api.describe().get("fees", {}).get(
"trading", {}
).get("taker", 0.001)
mm_ratio, _ = self.get_maintenance_ratio_and_amt(pair, stake_amount)
if self.trading_mode == TradingMode.FUTURES and self.margin_mode == MarginMode.ISOLATED:
@@ -3863,3 +3940,14 @@ class Exchange:
# describes the min amt for a tier, and the lowest tier will always go down to 0
else:
raise ExchangeError(f"Cannot get maintenance ratio using {self.name}")
def check_delisting_time(self, pair: str) -> datetime | None:
"""
Check if the pair gonna be delisted.
This function should be overridden by the exchange class if the exchange
provides such information.
By default, it returns None.
:param pair: Market symbol
:return: Datetime if the pair gonna be delisted, None otherwise
"""
return None
+8
View File
@@ -1,5 +1,8 @@
from typing import Any, Literal, TypedDict
# Re-export for easier use
from ccxt.base.types import FundingRate # noqa: F401
from freqtrade.enums import CandleType
@@ -25,6 +28,8 @@ class FtHas(TypedDict, total=False):
ohlcv_volume_currency: str
ohlcv_candle_limit_per_timeframe: dict[str, int]
always_require_api_keys: bool
# allow disabling of parallel download-data for specific exchanges
download_data_parallel_quick: bool
# Tickers
tickers_have_quoteVolume: bool
tickers_have_percentage: bool
@@ -58,6 +63,9 @@ class FtHas(TypedDict, total=False):
# Websocket control
ws_enabled: bool
# Delisting check
has_delisting: bool
class Ticker(TypedDict):
symbol: str
+2 -7
View File
@@ -18,13 +18,8 @@ logger = logging.getLogger(__name__)
class Gate(Exchange):
"""
Gate.io exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
Please note that this exchange is not included in the list of exchanges
officially supported by the Freqtrade development team. So some features
may still not work as expected.
"""Gate.io exchange class.
Contains adjustments needed for Freqtrade to work with this exchange.
"""
unified_account = False
+2 -3
View File
@@ -11,9 +11,8 @@ logger = logging.getLogger(__name__)
class Htx(Exchange):
"""
HTX exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
"""HTX exchange class.
Contains adjustments needed for Freqtrade to work with this exchange.
"""
_ft_has: FtHas = {
+10 -3
View File
@@ -28,6 +28,7 @@ class Hyperliquid(Exchange):
"stoploss_on_exchange": False,
"exchange_has_overrides": {"fetchTrades": False},
"marketOrderRequiresPrice": True,
"download_data_parallel_quick": False,
"ws_enabled": True,
}
_ft_has_futures: FtHas = {
@@ -43,6 +44,7 @@ class Hyperliquid(Exchange):
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
(TradingMode.SPOT, MarginMode.NONE),
(TradingMode.FUTURES, MarginMode.ISOLATED),
(TradingMode.FUTURES, MarginMode.CROSS),
]
@property
@@ -98,7 +100,6 @@ class Hyperliquid(Exchange):
'SOL/USDC:USDC': 43}}
"""
# Defining/renaming variables to match the documentation
isolated_margin = wallet_balance
position_size = amount
price = open_rate
position_value = price * position_size
@@ -116,8 +117,14 @@ class Hyperliquid(Exchange):
# 3. Divide this by 2
maintenance_margin_required = position_value / max_leverage / 2
# Docs: margin_available (isolated) = isolated_margin - maintenance_margin_required
margin_available = isolated_margin - maintenance_margin_required
if self.margin_mode == MarginMode.ISOLATED:
# Docs: margin_available (isolated) = isolated_margin - maintenance_margin_required
margin_available = stake_amount - maintenance_margin_required
elif self.margin_mode == MarginMode.CROSS:
# Docs: margin_available (cross) = account_value - maintenance_margin_required
margin_available = wallet_balance - maintenance_margin_required
else:
raise OperationalException("Unsupported margin mode for liquidation price calculation")
# Docs: The maintenance margin is half of the initial margin at max leverage
# The docs don't explicitly specify maintenance leverage, but this works.
+4
View File
@@ -19,6 +19,10 @@ logger = logging.getLogger(__name__)
class Kraken(Exchange):
"""Kraken exchange class.
Contains adjustments needed for Freqtrade to work with this exchange.
"""
_params: dict = {"trading_agreement": "agree"}
_ft_has: FtHas = {
"stoploss_on_exchange": True,
+21 -10
View File
@@ -11,7 +11,7 @@ from freqtrade.exceptions import (
RetryableOrderError,
TemporaryError,
)
from freqtrade.exchange import Exchange, date_minus_candles
from freqtrade.exchange import Exchange
from freqtrade.exchange.common import API_RETRY_COUNT, retrier
from freqtrade.exchange.exchange_types import CcxtOrder, FtHas
from freqtrade.misc import safe_value_fallback2
@@ -65,17 +65,19 @@ class Okx(Exchange):
"""
Exchange ohlcv candle limit
OKX has the following behaviour:
* 300 candles for up-to-date data
* 100 candles for historic data
* 100 candles for additional candles (not futures or spot).
* spot and futures:
* 300 candles for regular candles
* mark and premium-index:
* 300 candles for up-to-date data
* 100 candles for historic data
* additional data:
* 100 candles for additional candles
:param timeframe: Timeframe to check
:param candle_type: Candle-type
:param since_ms: Starting timestamp
:return: Candle limit as integer
"""
if candle_type in (CandleType.FUTURES, CandleType.SPOT) and (
not since_ms or since_ms > (date_minus_candles(timeframe, 300).timestamp() * 1000)
):
if candle_type in (CandleType.FUTURES, CandleType.SPOT):
return 300
return super().ohlcv_candle_limit(timeframe, candle_type, since_ms)
@@ -289,12 +291,21 @@ class Okx(Exchange):
return orders
class MyOkx(Okx):
"""
MyOkx exchange class.
class Myokx(Okx):
"""MyOkx exchange class.
Minimal adjustment to disable futures trading for the EU subsidiary of Okx
"""
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
(TradingMode.SPOT, MarginMode.NONE),
]
class Okxus(Okx):
"""Okxus exchange class.
Minimal adjustment to disable futures trading for the US subsidiary of Okx
"""
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
(TradingMode.SPOT, MarginMode.NONE),
]
@@ -6,6 +6,7 @@ import numpy as np
import numpy.typing as npt
from pandas import DataFrame
from freqtrade.exceptions import DependencyException
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from freqtrade.freqai.freqai_interface import IFreqaiModel
@@ -63,12 +64,19 @@ class BaseRegressionModel(IFreqaiModel):
dd["train_labels"], _, _ = dk.label_pipeline.fit_transform(dd["train_labels"])
if self.freqai_info.get("data_split_parameters", {}).get("test_size", 0.1) != 0:
(dd["test_features"], dd["test_labels"], dd["test_weights"]) = (
dk.feature_pipeline.transform(
dd["test_features"], dd["test_labels"], dd["test_weights"]
if dd["test_labels"].shape[0] == 0:
raise DependencyException(
f"{pair}: test set is empty after filtering. "
f"This is usually caused by overly strict SVM thresholds or insufficient data. "
f"Try reducing 'test_size' or relaxing your SVM conditions."
)
)
dd["test_labels"], _, _ = dk.label_pipeline.transform(dd["test_labels"])
else:
(dd["test_features"], dd["test_labels"], dd["test_weights"]) = (
dk.feature_pipeline.transform(
dd["test_features"], dd["test_labels"], dd["test_weights"]
)
)
dd["test_labels"], _, _ = dk.label_pipeline.transform(dd["test_labels"])
logger.info(
f"Training model on {len(dk.data_dictionary['train_features'].columns)} features"
+3 -1
View File
@@ -1617,7 +1617,9 @@ class FreqtradeBot(LoggingMixin):
f"Emergency exiting trade {trade}, as the exit order "
f"timed out {max_timeouts} times. force selling {order['amount']}."
)
self.emergency_exit(trade, order["price"], order["amount"])
# Trade.session.refresh(order_obj)
self.emergency_exit(trade, order["price"], order_obj.safe_remaining)
return canceled
def emergency_exit(
+15 -3
View File
@@ -5,14 +5,26 @@ from pydantic import TypeAdapter
from typing_extensions import TypedDict
class AnnotationType(TypedDict, total=False):
type: Required[Literal["area"]]
class _BaseAnnotationType(TypedDict, total=False):
start: str | datetime
end: str | datetime
y_start: float
y_end: float
color: str
label: str
z_level: int
AnnotationTypeTA = TypeAdapter(AnnotationType)
class AreaAnnotationType(_BaseAnnotationType, total=False):
type: Required[Literal["area"]]
class LineAnnotationType(_BaseAnnotationType, total=False):
type: Required[Literal["line"]]
width: int
line_style: Literal["solid", "dashed", "dotted"]
AnnotationType = AreaAnnotationType | LineAnnotationType
AnnotationTypeTA: TypeAdapter[AnnotationType] = TypeAdapter(AnnotationType)
+3 -1
View File
@@ -92,9 +92,11 @@ def _set_log_levels(
# Set default levels for third party libraries
third_party_loggers = {
"freqtrade": logging.INFO if verbosity <= 1 else logging.DEBUG,
"freqtrade": logging.INFO if verbosity < 1 else logging.DEBUG,
"freqtrade.exchange.exchange_ws": logging.INFO if verbosity <= 1 else logging.DEBUG,
"requests": logging.INFO if verbosity <= 1 else logging.DEBUG,
"urllib3": logging.INFO if verbosity <= 1 else logging.DEBUG,
"asyncio": logging.INFO if verbosity <= 1 else logging.DEBUG,
"httpcore": logging.INFO if verbosity <= 1 else logging.DEBUG,
"ccxt.base.exchange": logging.INFO if verbosity <= 2 else logging.DEBUG,
"telegram": logging.INFO,
+7 -1
View File
@@ -18,7 +18,12 @@ from freqtrade.commands import Arguments
from freqtrade.constants import DOCS_LINK
from freqtrade.exceptions import ConfigurationError, FreqtradeException, OperationalException
from freqtrade.loggers import setup_logging_pre
from freqtrade.system import asyncio_setup, gc_set_threshold, print_version_info
from freqtrade.system import (
asyncio_setup,
gc_set_threshold,
print_version_info,
set_mp_start_method,
)
logger = logging.getLogger("freqtrade")
@@ -44,6 +49,7 @@ def main(sysargv: list[str] | None = None) -> None:
elif "func" in args:
logger.info(f"freqtrade {__version__}")
gc_set_threshold()
set_mp_start_method()
return_code = args["func"](args)
else:
# No subcommand was issued.
+1 -1
View File
@@ -51,7 +51,7 @@ def file_dump_json(filename: Path, data: Any, is_zip: bool = False, log: bool =
with filename.open("w") as fp:
dump_json_to_file(fp, data)
logger.debug(f'done json to "{filename}"')
logger.debug(f'done writing json to "{filename}"')
def json_load(datafile: TextIO) -> Any:
@@ -145,9 +145,19 @@ class LookaheadAnalysisSubFunctions:
config["enable_protections"] = False
logger.info(
"Protections were enabled. "
"Disabling protections now "
"since they could otherwise produce false positives."
"Disabling protections now since they can produce false positives."
)
if not config.get("lookahead_allow_limit_orders", False):
logger.info("Forced order_types to market orders.")
config["order_types"] = {
"entry": "market",
"exit": "market",
"stoploss": "market",
"stoploss_on_exchange": False,
}
else:
logger.info("Using configured order_types, skipping order_types override.")
if config["targeted_trade_amount"] < config["minimum_trade_amount"]:
# this combo doesn't make any sense.
raise OperationalException(
+18 -2
View File
@@ -8,6 +8,7 @@ from typing import Any
from pandas import DataFrame
from freqtrade.exceptions import ConfigurationError
from freqtrade.exchange import timeframe_to_minutes
from freqtrade.loggers.set_log_levels import (
reduce_verbosity_for_bias_tester,
@@ -37,10 +38,12 @@ class RecursiveAnalysis(BaseAnalysis):
self.dict_recursive: dict[str, Any] = dict()
self.pair_to_used: str | None = None
# For recursive bias check
# analyzes two data frames with processed indicators and shows differences between them.
def analyze_indicators(self):
pair_to_check = self.local_config["pairs"][0]
pair_to_check = self.pair_to_used
logger.info("Start checking for recursive bias")
# check and report signals
@@ -85,7 +88,7 @@ class RecursiveAnalysis(BaseAnalysis):
# For lookahead bias check
# analyzes two data frames with processed indicators and shows differences between them.
def analyze_indicators_lookahead(self):
pair_to_check = self.local_config["pairs"][0]
pair_to_check = self.pair_to_used
logger.info("Start checking for lookahead bias on indicators only")
part = self.partial_varHolder_lookahead_array[0]
@@ -138,12 +141,25 @@ class RecursiveAnalysis(BaseAnalysis):
backtesting = Backtesting(prepare_data_config, self.exchange)
self.exchange = backtesting.exchange
if self.pair_to_used is None:
self.pair_to_used = backtesting.pairlists.whitelist[0]
logger.info(
f"Using pair {self.pair_to_used} only for recursive analysis. Replacing whitelist."
)
self.local_config["candle_type_def"] = prepare_data_config["candle_type_def"]
backtesting.pairlists._whitelist = [self.pair_to_used]
backtesting._set_strategy(backtesting.strategylist[0])
strat = backtesting.strategy
self._strat_scc = strat.startup_candle_count
if self._strat_scc < 1:
raise ConfigurationError(
f"The strategy defines invalid startup candle count of {self._strat_scc}. "
f"This will lead to recursive issues on some indicators. "
f"Please define a proper startup_candle_count in the strategy."
)
if self._strat_scc not in self._startup_candle:
self._startup_candle.append(self._strat_scc)
self._startup_candle.sort()
+24 -16
View File
@@ -211,6 +211,7 @@ class Backtesting:
self._can_short = self.trading_mode != TradingMode.SPOT
self._position_stacking: bool = self.config.get("position_stacking", False)
self.enable_protections: bool = self.config.get("enable_protections", False)
self.dynamic_pairlist: bool = self.config.get("enable_dynamic_pairlist", False)
migrate_data(config, self.exchange)
self.init_backtest()
@@ -272,7 +273,7 @@ class Backtesting:
self.futures_data: dict[str, DataFrame] = {}
def init_backtest(self):
self.prepare_backtest(False)
self.reset_backtest(False)
self.wallets = Wallets(self.config, self.exchange, is_backtest=True)
@@ -426,7 +427,7 @@ class Backtesting:
def disable_database_use(self):
disable_database_use(self.timeframe)
def prepare_backtest(self, enable_protections):
def reset_backtest(self, enable_protections: bool = False):
"""
Backtesting setup method - called once for every call to "backtest()".
"""
@@ -966,7 +967,7 @@ class Backtesting:
)
)
def get_valid_price_and_stake(
def get_valid_entry_price_and_stake(
self,
pair: str,
row: tuple,
@@ -1089,18 +1090,20 @@ class Backtesting:
stake_amount_ = stake_amount or (trade.stake_amount if trade else 0.0)
precision_price, precision_mode_price = self.get_pair_precision(pair, current_time)
propose_rate, stake_amount, leverage, min_stake_amount = self.get_valid_price_and_stake(
pair,
row,
row[OPEN_IDX],
stake_amount_,
direction,
current_time,
entry_tag,
trade,
order_type,
precision_price,
precision_mode_price,
propose_rate, stake_amount, leverage, min_stake_amount = (
self.get_valid_entry_price_and_stake(
pair,
row,
row[OPEN_IDX],
stake_amount_,
direction,
current_time,
entry_tag,
trade,
order_type,
precision_price,
precision_mode_price,
)
)
# replace proposed rate if another rate was requested
@@ -1582,6 +1585,11 @@ class Backtesting:
for current_time in self._time_generator(start_date, end_date):
# Loop for each main candle.
self.check_abort()
if self.dynamic_pairlist and self.pairlists:
self.pairlists.refresh_pairlist()
pairs = self.pairlists.whitelist
# Reset open trade count for this candle
# Critical to avoid exceeding max_open_trades in backtesting
# when timeframe-detail is used and trades close within the opening candle.
@@ -1684,7 +1692,7 @@ class Backtesting:
:param end_date: backtesting timerange end datetime
:return: DataFrame with trades (results of backtesting)
"""
self.prepare_backtest(self.enable_protections)
self.reset_backtest(self.enable_protections)
# Ensure wallets are up-to-date (important for --strategy-list)
self.wallets.update()
# Use dict of lists with data for performance
+2 -32
View File
@@ -9,7 +9,6 @@ import logging
import random
from datetime import datetime
from math import ceil
from multiprocessing import Manager
from pathlib import Path
from typing import Any
@@ -19,9 +18,7 @@ from optuna.trial import FrozenTrial, Trial, TrialState
from freqtrade.constants import FTHYPT_FILEVERSION, LAST_BT_RESULT_FN, Config
from freqtrade.enums import HyperoptState
from freqtrade.exceptions import OperationalException
from freqtrade.misc import file_dump_json, plural
from freqtrade.optimize.hyperopt.hyperopt_logger import logging_mp_handle, logging_mp_setup
from freqtrade.optimize.hyperopt.hyperopt_optimizer import INITIAL_POINTS, HyperOptimizer
from freqtrade.optimize.hyperopt.hyperopt_output import HyperoptOutput
from freqtrade.optimize.hyperopt_tools import (
@@ -35,9 +32,6 @@ from freqtrade.util import get_progress_tracker
logger = logging.getLogger(__name__)
log_queue: Any
class Hyperopt:
"""
Hyperopt class, this class contains all the logic to run a hyperopt simulation
@@ -55,12 +49,6 @@ class Hyperopt:
self.analyze_per_epoch = self.config.get("analyze_per_epoch", False)
HyperoptStateContainer.set_state(HyperoptState.STARTUP)
if self.config.get("hyperopt"):
raise OperationalException(
"Using separate Hyperopt files has been removed in 2021.9. Please convert "
"your existing Hyperopt file to the new Hyperoptable strategy interface"
)
time_now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
strategy = str(self.config["strategy"])
self.results_file: Path = (
@@ -149,15 +137,7 @@ class Hyperopt:
def run_optimizer_parallel(self, parallel: Parallel, asked: list[list]) -> list[dict[str, Any]]:
"""Start optimizer in a parallel way"""
def optimizer_wrapper(*args, **kwargs):
# global log queue. This must happen in the file that initializes Parallel
logging_mp_setup(
log_queue, logging.INFO if self.config["verbosity"] < 1 else logging.DEBUG
)
return self.hyperopter.generate_optimizer_wrapped(*args, **kwargs)
return parallel(optimizer_wrapper(v) for v in asked)
return parallel(self.hyperopter.generate_optimizer_wrapped(v) for v in asked)
def _set_random_state(self, random_state: int | None) -> int:
return random_state or random.randint(1, 2**16 - 1) # noqa: S311
@@ -236,15 +216,6 @@ class Hyperopt:
self._save_result(val)
def _setup_logging_mp_workaround(self) -> None:
"""
Workaround for logging in child processes.
local_queue must be a global in the file that initializes Parallel.
"""
global log_queue
m = Manager()
log_queue = m.Queue()
def start(self) -> None:
self.random_state = self._set_random_state(self.config.get("hyperopt_random_state"))
logger.info(f"Using optimizer random state: {self.random_state}")
@@ -257,7 +228,6 @@ class Hyperopt:
logger.info(f"Number of parallel jobs set as: {config_jobs}")
self.opt = self.hyperopter.get_optimizer(self.random_state)
self._setup_logging_mp_workaround()
try:
with Parallel(n_jobs=config_jobs) as parallel:
jobs = parallel._effective_n_jobs()
@@ -307,7 +277,7 @@ class Hyperopt:
self.evaluate_result(val, current, is_random[j])
pbar.update(task, advance=1)
logging_mp_handle(log_queue)
self.hyperopter.handle_mp_logging()
gc.collect()
if (
@@ -7,6 +7,7 @@ import logging
import sys
import warnings
from datetime import UTC, datetime
from multiprocessing import Manager
from pathlib import Path
from typing import Any
@@ -29,6 +30,7 @@ from freqtrade.optimize.backtesting import Backtesting
# Import IHyperOptLoss to allow unpickling classes from these modules
from freqtrade.optimize.hyperopt.hyperopt_auto import HyperOptAuto
from freqtrade.optimize.hyperopt.hyperopt_logger import logging_mp_handle, logging_mp_setup
from freqtrade.optimize.hyperopt_loss.hyperopt_loss_interface import IHyperOptLoss
from freqtrade.optimize.hyperopt_tools import HyperoptStateContainer, HyperoptTools
from freqtrade.optimize.optimize_reports import generate_strategy_stats
@@ -58,6 +60,8 @@ optuna_samplers_dict = {
"QMCSampler": optuna.samplers.QMCSampler,
}
log_queue: Any
class HyperOptimizer:
"""
@@ -85,13 +89,7 @@ class HyperOptimizer:
self.custom_hyperopt: HyperOptAuto
self.analyze_per_epoch = self.config.get("analyze_per_epoch", False)
if not self.config.get("hyperopt"):
self.custom_hyperopt = HyperOptAuto(self.config)
else:
raise OperationalException(
"Using separate Hyperopt files has been removed in 2021.9. Please convert "
"your existing Hyperopt file to the new Hyperoptable strategy interface"
)
self.custom_hyperopt = HyperOptAuto(self.config)
self.backtesting._set_strategy(self.backtesting.strategylist[0])
self.custom_hyperopt.strategy = self.backtesting.strategy
@@ -113,6 +111,24 @@ class HyperOptimizer:
if HyperoptTools.has_space(self.config, "sell"):
# Make sure use_exit_signal is enabled
self.config["use_exit_signal"] = True
self._setup_logging_mp_workaround()
def _setup_logging_mp_workaround(self) -> None:
"""
Workaround for logging in child processes.
local_queue must be a global and passed to the child process via inheritance.
"""
global log_queue
m = Manager()
log_queue = m.Queue()
logger.info(f"manager queue {type(log_queue)}")
def handle_mp_logging(self) -> None:
"""
Handle logging from child processes.
Must be called in the parent process to handle log messages from the child process.
"""
logging_mp_handle(log_queue)
def prepare_hyperopt(self) -> None:
# Initialize spaces ...
@@ -264,6 +280,7 @@ class HyperOptimizer:
@delayed
@wrap_non_picklable_objects
def generate_optimizer_wrapped(self, params_dict: dict[str, Any]) -> dict[str, Any]:
logging_mp_setup(log_queue, logging.INFO if self.config["verbosity"] < 1 else logging.DEBUG)
return self.generate_optimizer(params_dict)
def generate_optimizer(self, params_dict: dict[str, Any]) -> dict[str, Any]:
@@ -256,40 +256,66 @@ def _get_resample_from_period(period: str) -> str:
return "1ME"
if period == "year":
return "1YE"
if period == "weekday":
# Required to pass the test
return "weekday"
raise ValueError(f"Period {period} is not supported.")
def _calculate_stats_for_period(data: DataFrame) -> dict[str, Any]:
profit_abs = data["profit_abs"].sum().round(10)
wins = sum(data["profit_abs"] > 0)
draws = sum(data["profit_abs"] == 0)
losses = sum(data["profit_abs"] < 0)
trades = wins + draws + losses
winning_profit = data.loc[data["profit_abs"] > 0, "profit_abs"].sum()
losing_profit = data.loc[data["profit_abs"] < 0, "profit_abs"].sum()
profit_factor = winning_profit / abs(losing_profit) if losing_profit else 0.0
return {
"profit_abs": profit_abs,
"wins": wins,
"draws": draws,
"losses": losses,
"trades": trades,
"profit_factor": round(profit_factor, 8),
}
def generate_periodic_breakdown_stats(
trade_list: list | DataFrame, period: str
) -> list[dict[str, Any]]:
results = trade_list if not isinstance(trade_list, list) else DataFrame.from_records(trade_list)
if len(results) == 0:
return []
results["close_date"] = to_datetime(results["close_date"], utc=True)
resample_period = _get_resample_from_period(period)
resampled = results.resample(resample_period, on="close_date")
stats = []
for name, day in resampled:
profit_abs = day["profit_abs"].sum().round(10)
wins = sum(day["profit_abs"] > 0)
draws = sum(day["profit_abs"] == 0)
losses = sum(day["profit_abs"] < 0)
trades = wins + draws + losses
winning_profit = day.loc[day["profit_abs"] > 0, "profit_abs"].sum()
losing_profit = day.loc[day["profit_abs"] < 0, "profit_abs"].sum()
profit_factor = winning_profit / abs(losing_profit) if losing_profit else 0.0
stats.append(
{
"date": name.strftime("%d/%m/%Y"),
"date_ts": int(name.to_pydatetime().timestamp() * 1000),
"profit_abs": profit_abs,
"wins": wins,
"draws": draws,
"losses": losses,
"trades": trades,
"profit_factor": round(profit_factor, 8),
}
)
if period == "weekday":
day_names = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
results["weekday"] = results["close_date"].dt.dayofweek
stats = []
for day_num in range(7):
day_data = results[results["weekday"] == day_num]
if len(day_data) > 0:
period_stats = _calculate_stats_for_period(day_data)
stats.append({"date": day_names[day_num], "date_ts": day_num, **period_stats})
else:
resample_period = _get_resample_from_period(period)
resampled = results.resample(resample_period, on="close_date")
stats = []
for name, period_data in resampled:
period_stats = _calculate_stats_for_period(period_data)
stats.append(
{
"date": name.strftime("%d/%m/%Y"),
"date_ts": int(name.to_pydatetime().timestamp() * 1000),
**period_stats,
}
)
return stats
@@ -0,0 +1,95 @@
"""
Delist pair list filter
"""
import logging
from datetime import UTC, datetime, timedelta
from freqtrade.exceptions import ConfigurationError
from freqtrade.exchange.exchange_types import Ticker
from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting
from freqtrade.util import format_date
logger = logging.getLogger(__name__)
class DelistFilter(IPairList):
supports_backtesting = SupportsBacktesting.NO
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self._max_days_from_now = self._pairlistconfig.get("max_days_from_now", 0)
if self._max_days_from_now < 0:
raise ConfigurationError("DelistFilter requires max_days_from_now to be >= 0")
if not self._exchange._ft_has["has_delisting"]:
raise ConfigurationError(
"DelistFilter doesn't support this exchange and trading mode combination.",
)
@property
def needstickers(self) -> bool:
"""
Boolean property defining if tickers are necessary.
If no Pairlist requires tickers, an empty Dict is passed
as tickers argument to filter_pairlist
"""
return False
def short_desc(self) -> str:
"""
Short whitelist method description - used for startup-messages
"""
return (
f"{self.name} - Filtering pairs that will be delisted"
+ (
f" in the next {self._max_days_from_now} days"
if self._max_days_from_now > 0
else ""
)
+ "."
)
@staticmethod
def description() -> str:
return "Filter pairs that will be delisted on exchange."
@staticmethod
def available_parameters() -> dict[str, PairlistParameter]:
return {
"max_days_from_now": {
"type": "number",
"default": 0,
"description": "Max days from now",
"help": (
"Remove pairs that will be delisted in the next X days. Set to 0 to remove all."
),
},
}
def _validate_pair(self, pair: str, ticker: Ticker | None) -> bool:
"""
Check if pair will be delisted.
:param pair: Pair that's currently validated
:param ticker: ticker dict as returned from ccxt.fetch_ticker
:return: True if the pair can stay, false if it should be removed
"""
delist_date = self._exchange.check_delisting_time(pair)
if delist_date is not None:
remove_pair = self._max_days_from_now == 0
if self._max_days_from_now > 0:
current_datetime = datetime.now(UTC)
max_delist_date = current_datetime + timedelta(days=self._max_days_from_now)
remove_pair = delist_date <= max_delist_date
if remove_pair:
self.log_once(
f"Removed {pair} from whitelist, because it will be delisted on "
f"{format_date(delist_date)}.",
logger.info,
)
return False
return True
+3 -1
View File
@@ -93,6 +93,8 @@ class ShuffleFilter(IPairList):
return pairlist_new
# Shuffle is done inplace
self._random.shuffle(pairlist)
self.__pairlist_cache[pairlist_bef] = pairlist
if self._config.get("runmode") in (RunMode.LIVE, RunMode.DRY_RUN):
self.__pairlist_cache[pairlist_bef] = pairlist
return pairlist
+22 -9
View File
@@ -7,6 +7,9 @@ Provides pair white list as it configured in config
import logging
from copy import deepcopy
from cachetools import LRUCache
from freqtrade.enums import RunMode
from freqtrade.exchange.exchange_types import Tickers
from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting
@@ -22,6 +25,8 @@ class StaticPairList(IPairList):
super().__init__(*args, **kwargs)
self._allow_inactive = self._pairlistconfig.get("allow_inactive", False)
# Pair cache - only used for optimize modes
self._bt_pair_cache: LRUCache = LRUCache(maxsize=1)
@property
def needstickers(self) -> bool:
@@ -60,15 +65,23 @@ class StaticPairList(IPairList):
:param tickers: Tickers (from exchange.get_tickers). May be cached.
:return: List of pairs
"""
wl = self.verify_whitelist(
self._config["exchange"]["pair_whitelist"], logger.info, keep_invalid=True
)
if self._allow_inactive:
return wl
else:
# Avoid implicit filtering of "verify_whitelist" to keep
# proper warnings in the log
return self._whitelist_for_active_markets(wl)
pairlist = self._bt_pair_cache.get("pairlist")
if not pairlist:
wl = self.verify_whitelist(
self._config["exchange"]["pair_whitelist"], logger.info, keep_invalid=True
)
if self._allow_inactive:
pairlist = wl
else:
# Avoid implicit filtering of "verify_whitelist" to keep
# proper warnings in the log
pairlist = self._whitelist_for_active_markets(wl)
if self._config["runmode"] in (RunMode.BACKTEST, RunMode.HYPEROPT):
self._bt_pair_cache["pairlist"] = pairlist.copy()
return pairlist
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
"""
@@ -247,7 +247,6 @@ class VolumePairList(IPairList):
* 1000
)
# todo: utc date output for starting date
self.log_once(
f"Using volume range of {self._lookback_period} candles, timeframe: "
f"{self._lookback_timeframe}, starting from {format_ms_time(since_ms)} "
+22 -12
View File
@@ -5,7 +5,7 @@ PairList manager class
import logging
from functools import partial
from cachetools import TTLCache, cached
from cachetools import LRUCache, TTLCache, cached
from freqtrade.constants import Config, ListPairsWithTimeframes
from freqtrade.data.dataprovider import DataProvider
@@ -56,6 +56,7 @@ class PairListManager(LoggingMixin):
)
self._check_backtest()
self._not_expiring_cache: LRUCache = LRUCache(maxsize=1)
refresh_period = config.get("pairlist_refresh_period", 3600)
LoggingMixin.__init__(self, logger, refresh_period)
@@ -109,7 +110,15 @@ class PairListManager(LoggingMixin):
@property
def expanded_blacklist(self) -> list[str]:
"""The expanded blacklist (including wildcard expansion)"""
return expand_pairlist(self._blacklist, self._exchange.get_markets().keys())
eblacklist = self._not_expiring_cache.get("eblacklist")
if not eblacklist:
eblacklist = expand_pairlist(self._blacklist, self._exchange.get_markets().keys())
if self._config["runmode"] in (RunMode.BACKTEST, RunMode.HYPEROPT):
self._not_expiring_cache["eblacklist"] = eblacklist.copy()
return eblacklist
@property
def name_list(self) -> list[str]:
@@ -157,16 +166,17 @@ class PairListManager(LoggingMixin):
:param logmethod: Function that'll be called, `logger.info` or `logger.warning`.
:return: pairlist - blacklisted pairs
"""
try:
blacklist = self.expanded_blacklist
except ValueError as err:
logger.error(f"Pair blacklist contains an invalid Wildcard: {err}")
return []
log_once = partial(self.log_once, logmethod=logmethod)
for pair in pairlist.copy():
if pair in blacklist:
log_once(f"Pair {pair} in your blacklist. Removing it from whitelist...")
pairlist.remove(pair)
if self._blacklist:
try:
blacklist = self.expanded_blacklist
except ValueError as err:
logger.error(f"Pair blacklist contains an invalid Wildcard: {err}")
return []
log_once = partial(self.log_once, logmethod=logmethod)
for pair in pairlist.copy():
if pair in blacklist:
log_once(f"Pair {pair} in your blacklist. Removing it from whitelist...")
pairlist.remove(pair)
return pairlist
def verify_whitelist(
+8 -6
View File
@@ -86,13 +86,13 @@ class IResolver:
Tuple format: [Object, source]
"""
# Generate spec based on absolute path
# Pass object_name as first argument to have logging print a reasonable name.
with PathModifier(module_path.parent):
module_name = module_path.stem or ""
# Generate spec based on absolute path
# Pass object_name as first argument to have logging print a reasonable name.
spec = importlib.util.spec_from_file_location(module_name, str(module_path))
if not spec:
return iter([None])
return iter([])
module = importlib.util.module_from_spec(spec)
try:
@@ -149,9 +149,7 @@ class IResolver:
continue
module_path = entry.resolve()
obj = next(cls._get_valid_object(module_path, object_name), None)
if obj:
if obj := next(cls._get_valid_object(module_path, object_name), None):
obj[0].__file__ = str(entry)
if add_source:
obj[0].__source__ = obj[1]
@@ -164,6 +162,10 @@ class IResolver:
) -> Any | None:
"""
Try to load object from path list.
:param paths: list of absolute paths to search
:param object_name: name of the module to import
:param add_source: add the source code as __source__ attribute to theloaded object.
:param kwargs: keyword arguments to pass to the object constructor
"""
for _path in paths:
+6 -5
View File
@@ -87,7 +87,7 @@ class StrategyResolver(IResolver):
# Loop this list again to have output combined
for attribute, _ in attributes:
if attribute in config:
logger.info("Strategy using %s: %s", attribute, config[attribute])
logger.info(f"Strategy using {attribute}: {config[attribute]}")
StrategyResolver._normalize_attributes(strategy)
@@ -109,9 +109,8 @@ class StrategyResolver(IResolver):
# Ensure Properties are not overwritten
setattr(strategy, attribute, config[attribute])
logger.info(
"Override strategy '%s' with value in config file: %s.",
attribute,
config[attribute],
f"Override strategy '{attribute}' with value from the configuration: "
f"{config[attribute]}.",
)
elif hasattr(strategy, attribute):
val = getattr(strategy, attribute)
@@ -151,7 +150,9 @@ class StrategyResolver(IResolver):
# Ensure necessary migrations are performed first.
validate_migrated_strategy_settings(strategy.config)
if not all(k in strategy.order_types for k in REQUIRED_ORDERTYPES):
if not strategy.order_types or not all(
k in strategy.order_types for k in REQUIRED_ORDERTYPES
):
raise ImportError(
f"Impossible to load Strategy '{strategy.__class__.__name__}'. "
f"Order-types mapping is incomplete."

Some files were not shown because too many files have changed in this diff Show More