Compare commits

..

467 Commits

Author SHA1 Message Date
Matthias 5c8c53cff8 Merge pull request #9607 from freqtrade/new_release
New release 2023.12
2023-12-30 08:49:40 +01:00
Matthias 846b7734e1 Bump version to 2023.12 2023-12-29 18:24:18 +01:00
Matthias c72d18270e Merge branch 'stable' into new_release 2023-12-29 18:24:07 +01:00
Matthias 02836368fb add default --dist loadscope arg to pytest options 2023-12-28 11:07:41 +01:00
Matthias d282027858 Bump CI python version to 3.11 2023-12-26 17:49:01 +01:00
Matthias d329ad28c2 Merge pull request #9590 from freqtrade/enable/xdist
add pytest-xdist to speed up tests
2023-12-25 15:57:06 +01:00
Matthias 2de86af51e Merge pull request #9601 from freqtrade/dependabot/pip/develop/pyarrow-14.0.2
Bump pyarrow from 14.0.1 to 14.0.2
2023-12-25 15:34:20 +01:00
Matthias 97780ee5bf Revert build-online to 3.9 for now 2023-12-25 15:07:06 +01:00
Matthias e162f98cf5 Update pre-built wheels for pyarrow 2023-12-25 15:02:27 +01:00
Matthias c6967b11be Align spelling of "cancelling" 2023-12-25 11:53:50 +01:00
Matthias 1e5d353cf7 use safe_value_fallback when parsing orders
closes #9591
2023-12-25 11:44:14 +01:00
Matthias 17a538b5ba Merge pull request #9596 from freqtrade/dependabot/pip/develop/lightgbm-4.2.0
Bump lightgbm from 4.1.0 to 4.2.0
2023-12-25 11:36:35 +01:00
Matthias fc746214f6 Merge pull request #9600 from freqtrade/dependabot/pip/develop/ccxt-4.1.98
Bump ccxt from 4.1.91 to 4.1.98
2023-12-25 11:32:05 +01:00
dependabot[bot] 58432c1cfa Bump lightgbm from 4.1.0 to 4.2.0
Bumps [lightgbm](https://github.com/microsoft/LightGBM) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/microsoft/LightGBM/releases)
- [Commits](https://github.com/microsoft/LightGBM/compare/v4.1.0...v4.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 09:08:35 +00:00
Matthias 69119764bf Merge pull request #9594 from freqtrade/dependabot/pip/develop/xgboost-2.0.3
Bump xgboost from 2.0.2 to 2.0.3
2023-12-25 10:07:51 +01:00
Matthias a20e641bcd Merge pull request #9595 from freqtrade/dependabot/pip/develop/pydantic-2.5.3
Bump pydantic from 2.5.2 to 2.5.3
2023-12-25 08:17:04 +01:00
Matthias ad68eff8f4 Merge pull request #9592 from ArturoGamRod/docs/fix-typo
fix typo in stoploss_from_absolute code example doc
2023-12-25 08:16:40 +01:00
Matthias 68552a61bd Merge pull request #9598 from freqtrade/dependabot/pip/develop/mkdocs-material-9.5.3
Bump mkdocs-material from 9.5.2 to 9.5.3
2023-12-25 07:26:35 +01:00
Matthias b7419305d4 Merge pull request #9599 from freqtrade/dependabot/pip/develop/ruff-0.1.9
Bump ruff from 0.1.8 to 0.1.9
2023-12-25 07:16:11 +01:00
dependabot[bot] 8cc2c5010a Bump pydantic from 2.5.2 to 2.5.3
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.5.2 to 2.5.3.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v2.5.3/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.5.2...v2.5.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 06:15:46 +00:00
Matthias 872154a6fc Merge pull request #9597 from freqtrade/dependabot/pip/develop/nbconvert-7.13.1
Bump nbconvert from 7.12.0 to 7.13.1
2023-12-25 07:15:07 +01:00
Matthias c8ee8e82f9 Merge pull request #9593 from freqtrade/dependabot/pip/develop/uvicorn-0.25.0
Bump uvicorn from 0.24.0.post1 to 0.25.0
2023-12-25 07:14:37 +01:00
dependabot[bot] 5cbcf72501 Bump pyarrow from 14.0.1 to 14.0.2
Bumps [pyarrow](https://github.com/apache/arrow) from 14.0.1 to 14.0.2.
- [Commits](https://github.com/apache/arrow/compare/go/v14.0.1...go/v14.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 03:43:48 +00:00
dependabot[bot] 35876cf8ee Bump ccxt from 4.1.91 to 4.1.98
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.91 to 4.1.98.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.91...4.1.98)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 03:43:41 +00:00
dependabot[bot] ac60871ff9 Bump ruff from 0.1.8 to 0.1.9
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.8 to 0.1.9.
- [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/v0.1.8...v0.1.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 03:43:34 +00:00
dependabot[bot] 866e34a983 Bump mkdocs-material from 9.5.2 to 9.5.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.2 to 9.5.3.
- [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.5.2...9.5.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 03:43:17 +00:00
dependabot[bot] 7107971820 Bump nbconvert from 7.12.0 to 7.13.1
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.12.0 to 7.13.1.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.12.0...v7.13.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 03:43:07 +00:00
dependabot[bot] 3484590640 Bump xgboost from 2.0.2 to 2.0.3
Bumps [xgboost](https://github.com/dmlc/xgboost) from 2.0.2 to 2.0.3.
- [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/v2.0.2...v2.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 03:42:48 +00:00
dependabot[bot] 971b7d074c Bump uvicorn from 0.24.0.post1 to 0.25.0
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.24.0.post1 to 0.25.0.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.24.0.post1...0.25.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 03:42:42 +00:00
agamboa-caylent ec89aad10b fix typo in stoploss_from_absolute code example 2023-12-24 21:02:22 -06:00
Matthias fc13a99b33 Use intelligent scheduling to improve online test performance 2023-12-24 16:27:18 +01:00
Matthias 03fb204408 use Loadscope to improve parallel test performance 2023-12-24 13:57:42 +01:00
Matthias 0a96aa69b9 Only run parallel on online tests 2023-12-24 12:15:36 +01:00
Matthias ddbfce01b5 Show slowest tests 2023-12-24 12:13:02 +01:00
Matthias 12e75e849d Don't do coverge on --longrun tests 2023-12-24 12:09:46 +01:00
Matthias 916a847639 add pytest-xdist to speed up tests 2023-12-24 08:30:21 +01:00
Matthias 4769b50709 Fix RPC tests 2023-12-23 15:17:26 +01:00
Matthias 18dd9cf803 Use a trade for test that actually has an open stop order 2023-12-23 15:17:26 +01:00
Matthias def204448a Merge pull request #9589 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2023-12-23 10:06:49 +01:00
Matthias 63e652619f Bump mypy to 1.8.0 2023-12-23 09:11:40 +01:00
Matthias 3cb4b10656 Specify python version for pre-commit update 2023-12-23 09:08:55 +01:00
xmatthias 23c3757c7a chore: update pre-commit hooks 2023-12-23 08:04:51 +00:00
Matthias b20aee7653 Merge pull request #9585 from freqtrade/update/pre-commit-hooks
Update pre-commit hooks
2023-12-22 06:27:58 +01:00
Matthias 4d7c4352a7 Merge pull request #9519 from freqtrade/ci_mac_13
Add macos-13 to ci matrix
2023-12-21 20:24:08 +01:00
xmatthias a5c914951f chore: update pre-commit hooks 2023-12-21 19:18:40 +00:00
Matthias 9ab08d513a Update committer in pre-commit workflow 2023-12-21 20:13:52 +01:00
Matthias 87ce7dc02c Reduce permissions 2023-12-21 20:12:23 +01:00
Matthias 3c7c4bc02f Use repo scoped token 2023-12-21 19:54:11 +01:00
Matthias 0484b891f1 Add tech maintenance label 2023-12-21 19:39:45 +01:00
Matthias 71689d9d6f Allow write access to action to allow creating the branch 2023-12-21 19:34:21 +01:00
Matthias 881247a823 use isinstance for type checks 2023-12-21 19:26:52 +01:00
Matthias d26154f994 Import logging ... 2023-12-21 19:26:36 +01:00
Matthias 0e14dd6190 Set proper log-level for test 2023-12-21 19:20:27 +01:00
Matthias 3676514ba6 Add pre-commit auto-update workflow 2023-12-21 19:18:50 +01:00
Matthias 9ec23a0292 Improve rpc typing 2023-12-21 18:14:43 +01:00
Matthias 1272a15c35 Properly name Entry / exit types 2023-12-21 18:11:49 +01:00
Matthias a3a175e332 Reduce logging verbosity message in webhooks 2023-12-21 06:49:26 +01:00
Matthias 71b777ef34 Fix missing rm line 2023-12-19 21:51:31 +01:00
Matthias c4cd547451 Merge pull request #9579 from slimatic/develop
typo (configuration.md) fixed value USDT value  in example for clarity
2023-12-19 19:57:34 +01:00
Matthias b4e8122fd3 Attempt to properly remove 3.12 symlinks 2023-12-19 19:55:18 +01:00
slimatic b1393f1bd4 (configuration.md) fixed value USDT value in example for clarity 2023-12-19 10:58:22 -05:00
Matthias 34c5c68a91 Add macos-13 to ci matrix 2023-12-19 06:41:54 +01:00
Matthias c9a018cf0e Improve output if a strategy wasn't found in the backtest result 2023-12-19 06:30:40 +01:00
Matthias 0333abcbdc Merge pull request #9576 from freqtrade/simplify-freqai-example
Make freqai example strat *even* simpler
2023-12-18 20:01:02 +01:00
Matthias 0440b3ef75 Merge pull request #9577 from freqtrade/feat/add-random-forest-classifier
Add SKLearnRandomForestClassifier
2023-12-18 18:15:55 +01:00
Matthias d9ed8c6560 Merge pull request #9568 from freqtrade/dependabot/pip/develop/ccxt-4.1.91
Bump ccxt from 4.1.84 to 4.1.91
2023-12-18 18:14:46 +01:00
robcaulk 2f2467256c feat: add SKLearnRandomForestClassifier 2023-12-18 12:56:04 +01:00
robcaulk 26f0fe2383 make example strat *even* simpler and make sure it buys and sells a lot ;) 2023-12-18 12:38:34 +01:00
Matthias 5e3da30ab9 Fix remaining bittrex instances 2023-12-18 07:15:24 +01:00
Matthias 651d2c06b9 Update tests to use new file 2023-12-18 07:15:24 +01:00
Matthias b371593084 Move previous test config to tests 2023-12-18 07:15:24 +01:00
Matthias 3096cddbcf further remove bittrex from docs 2023-12-18 07:15:24 +01:00
Matthias 5bbe6aacfd Remove Bittrex subclass 2023-12-18 07:15:24 +01:00
Matthias fe4bf271b4 Remove futher bittrex tests 2023-12-18 07:15:24 +01:00
Matthias 0d3d1e6d9a Remove bittrex from more tests 2023-12-18 07:15:24 +01:00
dependabot[bot] 57e01329ce Bump ccxt from 4.1.84 to 4.1.91
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.84 to 4.1.91.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.84...4.1.91)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 05:49:40 +00:00
Matthias 99359a7f85 Merge pull request #9575 from freqtrade/dependabot/github_actions/develop/actions/download-artifact-4
Bump actions/download-artifact from 3 to 4
2023-12-18 06:37:53 +01:00
Matthias 5f0932f5ed Merge pull request #9574 from freqtrade/dependabot/github_actions/develop/actions/upload-artifact-4
Bump actions/upload-artifact from 3 to 4
2023-12-18 06:37:35 +01:00
Matthias fece88e7cd Merge pull request #9570 from freqtrade/dependabot/pip/develop/fastapi-0.105.0
Bump fastapi from 0.104.1 to 0.105.0
2023-12-18 06:36:42 +01:00
Matthias c8eb2523ac Merge pull request #9564 from freqtrade/dependabot/pip/develop/torch-2.1.2
Bump torch from 2.1.1 to 2.1.2
2023-12-18 06:35:15 +01:00
Matthias 964b439119 Merge pull request #9569 from freqtrade/dependabot/pip/develop/isort-5.13.2
Bump isort from 5.13.0 to 5.13.2
2023-12-18 06:34:51 +01:00
Matthias ee4f4f2d0d Merge pull request #9566 from freqtrade/dependabot/pip/develop/ruff-0.1.8
Bump ruff from 0.1.7 to 0.1.8
2023-12-18 06:34:31 +01:00
Matthias 7c215688c0 Merge pull request #9565 from freqtrade/dependabot/pip/develop/python-rapidjson-1.14
Bump python-rapidjson from 1.13 to 1.14
2023-12-18 06:33:40 +01:00
Matthias 087ca2bd4a Merge pull request #9571 from freqtrade/dependabot/pip/develop/psutil-5.9.7
Bump psutil from 5.9.6 to 5.9.7
2023-12-18 06:33:20 +01:00
Matthias 6193df36a3 Merge pull request #9573 from freqtrade/dependabot/pip/develop/mkdocs-material-9.5.2
Bump mkdocs-material from 9.5.1 to 9.5.2
2023-12-18 06:33:08 +01:00
Matthias 893b43766f Merge pull request #9567 from freqtrade/dependabot/pip/develop/technical-1.4.2
Bump technical from 1.4.1 to 1.4.2
2023-12-18 06:32:56 +01:00
dependabot[bot] a70ca6f612 Bump actions/download-artifact from 3 to 4
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:50:19 +00:00
dependabot[bot] e5c783d2db Bump actions/upload-artifact from 3 to 4
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:50:16 +00:00
dependabot[bot] e1b652d890 Bump mkdocs-material from 9.5.1 to 9.5.2
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.1 to 9.5.2.
- [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.5.1...9.5.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:17:18 +00:00
dependabot[bot] 4e98b5f710 Bump psutil from 5.9.6 to 5.9.7
Bumps [psutil](https://github.com/giampaolo/psutil) from 5.9.6 to 5.9.7.
- [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst)
- [Commits](https://github.com/giampaolo/psutil/compare/release-5.9.6...release-5.9.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:17:09 +00:00
dependabot[bot] 901b3f6fe7 Bump fastapi from 0.104.1 to 0.105.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.104.1 to 0.105.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.104.1...0.105.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:17:03 +00:00
dependabot[bot] d0a9d927dd Bump isort from 5.13.0 to 5.13.2
Bumps [isort](https://github.com/pycqa/isort) from 5.13.0 to 5.13.2.
- [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/5.13.0...5.13.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:16:57 +00:00
dependabot[bot] 16eb95c71d Bump technical from 1.4.1 to 1.4.2
Bumps [technical](https://github.com/freqtrade/technical) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/freqtrade/technical/releases)
- [Commits](https://github.com/freqtrade/technical/compare/1.4.1...1.4.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:16:40 +00:00
dependabot[bot] 054ed0a7b6 Bump ruff from 0.1.7 to 0.1.8
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.7 to 0.1.8.
- [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/v0.1.7...v0.1.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:16:36 +00:00
dependabot[bot] 82853e37a1 Bump python-rapidjson from 1.13 to 1.14
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 1.13 to 1.14.
- [Changelog](https://github.com/python-rapidjson/python-rapidjson/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-rapidjson/python-rapidjson/compare/v1.13...v1.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:16:26 +00:00
dependabot[bot] 81c6336e11 Bump torch from 2.1.1 to 2.1.2
Bumps [torch](https://github.com/pytorch/pytorch) from 2.1.1 to 2.1.2.
- [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.1.1...v2.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 03:16:14 +00:00
Matthias 6404bd8b2b Merge pull request #9561 from freqtrade/revert/9450-freqai-startup-candle-mr
Revert "Merge pull request #9450 from freqtrade/fix/startup-candle-count"
2023-12-17 19:42:06 +01:00
robcaulk 9a9a6eaa63 Revert "Merge pull request #9450 from freqtrade/fix/startup-candle-count"
This reverts commit 15771043f7, reversing
changes made to b417a0297b.
2023-12-17 17:44:15 +01:00
Matthias 67cdab6ee9 Provide strategy timeframe via API 2023-12-17 15:03:11 +01:00
Matthias 546ea430c9 Merge pull request #9558 from freqtrade/pyproject_toml
Pyproject toml, improve release CI
2023-12-17 13:10:18 +01:00
Matthias 4cc4f0ffa2 Merge pull request #9559 from stevanStevic/improve-no-hyperopt-result-log
Improve log message when no good hyperopt result is found
2023-12-17 10:03:36 +01:00
Matthias 58470ba9d0 Fix missing files in wheels 2023-12-17 09:30:09 +01:00
Stevan Stevic c580e8783f fixup 2023-12-16 22:36:56 +01:00
Stevan Stevic bc1ad3acbd Improve logging 2023-12-16 22:09:02 +01:00
Matthias d2e328b8bd Update artifact name 2023-12-16 21:32:36 +01:00
Matthias 93e9c4fa65 Update job names in ci.yml 2023-12-16 21:14:06 +01:00
Matthias 8d231dbf31 Update build-system to use "build" insead of "setup.py" 2023-12-16 20:54:30 +01:00
Matthias b178cc5f31 Migrate from setup.cfg to pyproject.toml 2023-12-16 20:51:46 +01:00
Matthias 6ee0f16e4f Migrate flake8 config to pyproject.toml 2023-12-16 20:32:37 +01:00
Matthias 1d701967b7 exclude tests from build 2023-12-16 20:27:47 +01:00
Matthias d6b43c5eed re-work deploy CI 2023-12-16 20:06:18 +01:00
Matthias 3670699ea2 Add trusted publishing for next release 2023-12-16 17:31:48 +01:00
Matthias 9b11091fc7 Merge pull request #9555 from amargedon/mapping-btc
Add FIAT mapping for BTC
2023-12-16 08:13:46 +01:00
amargedon 58dfffe87a Add FIAT mapping for BTC 2023-12-15 09:09:31 +01:00
Matthias e573409925 Add windows ta-lib 3.12 wheels 2023-12-15 07:02:56 +01:00
Matthias e3fda16d16 Don't overpopulate points at the first iteration
improves hyperopt-performance quite some.
2023-12-15 06:19:50 +01:00
Matthias 71d3572c27 Support webserver strategy without max_open_trades 2023-12-14 18:17:10 +01:00
Matthias 62667d123f Merge pull request #9540 from freqtrade/fix/issue_9538
Prevent config modification during webserver startup
2023-12-14 06:36:50 +01:00
Matthias cfd5af67ca Add max-open-trades param to get_trade_stake_amount 2023-12-13 06:51:26 +01:00
Matthias 47a952e41c Don't use config['stake_amount'] in wallets 2023-12-12 22:43:46 +01:00
Matthias c9f43587ec Bump binance leverage tiers 2023-12-12 21:30:52 +01:00
Matthias e79a58e1c4 Add test case to verify behavior in #9432 2023-12-12 19:59:56 +01:00
Matthias c62e52c759 Add test for dp_get_required_startup 2023-12-12 19:48:17 +01:00
Matthias 5ab61d9da4 Improve missing data output 2023-12-12 07:08:26 +01:00
Matthias 55efaec83d Merge pull request #9522 from freqtrade/bt/improve_futures_speed
Improve funding fee calculation
2023-12-12 06:33:57 +01:00
Matthias c5c2c8c185 Enforce kwargs for preliminary 2023-12-11 20:35:49 +01:00
Matthias 755ce3a858 Prevent config modification during webserver startup 2023-12-11 20:32:37 +01:00
Matthias 105cd99395 use max_open_trades from straetgy instead of config 2023-12-11 19:52:49 +01:00
Matthias db7799d2fb Use variable instead of config for startup_candle_count 2023-12-11 19:42:13 +01:00
Matthias 30f94ef5b7 Use LocalTrade for typehint 2023-12-11 19:12:08 +01:00
Matthias 6c259ddca1 Merge pull request #9536 from freqtrade/dependabot/pip/develop/ccxt-4.1.84
Bump ccxt from 4.1.76 to 4.1.84
2023-12-11 18:18:44 +01:00
Matthias 0f82ea8767 Merge pull request #9533 from freqtrade/dependabot/pip/develop/pre-commit-3.6.0
Bump pre-commit from 3.5.0 to 3.6.0
2023-12-11 15:45:51 +01:00
Matthias eac5d53a64 Add mock to backtest adjust position 2023-12-11 06:48:05 +01:00
dependabot[bot] 4b43ccae11 Bump ccxt from 4.1.76 to 4.1.84
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.76 to 4.1.84.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.76...4.1.84)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 05:29:11 +00:00
Matthias 8a2763d275 Merge pull request #9532 from freqtrade/dependabot/pip/develop/pandas-2.1.4
Bump pandas from 2.1.3 to 2.1.4
2023-12-11 06:28:16 +01:00
dependabot[bot] 4b3230689c Bump pre-commit from 3.5.0 to 3.6.0
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v3.5.0...v3.6.0)

---
updated-dependencies:
- dependency-name: pre-commit
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 05:26:12 +00:00
Matthias aa86c49640 Merge pull request #9529 from freqtrade/dependabot/pip/develop/ruff-0.1.7
Bump ruff from 0.1.6 to 0.1.7
2023-12-11 06:25:25 +01:00
Matthias 1adc8836dd Merge pull request #9530 from freqtrade/dependabot/pip/develop/mkdocs-material-9.5.1
Bump mkdocs-material from 9.4.14 to 9.5.1
2023-12-11 06:22:05 +01:00
Matthias 92993c0c4c Merge pull request #9527 from freqtrade/dependabot/pip/develop/technical-1.4.1
Bump technical from 1.4.0 to 1.4.1
2023-12-11 06:21:53 +01:00
Matthias 9b2c116d9b Merge pull request #9528 from freqtrade/dependabot/pip/develop/isort-5.13.0
Bump isort from 5.12.0 to 5.13.0
2023-12-11 06:21:42 +01:00
Matthias 2ad85a6957 Merge pull request #9526 from freqtrade/dependabot/github_actions/develop/actions/setup-python-5
Bump actions/setup-python from 4 to 5
2023-12-11 06:21:20 +01:00
dependabot[bot] a0e92f5a47 Bump pandas from 2.1.3 to 2.1.4
Bumps [pandas](https://github.com/pandas-dev/pandas) from 2.1.3 to 2.1.4.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Commits](https://github.com/pandas-dev/pandas/compare/v2.1.3...v2.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 03:53:12 +00:00
dependabot[bot] 17f0697c43 Bump mkdocs-material from 9.4.14 to 9.5.1
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.14 to 9.5.1.
- [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.4.14...9.5.1)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 03:52:56 +00:00
dependabot[bot] 199e3f91f2 Bump ruff from 0.1.6 to 0.1.7
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.6 to 0.1.7.
- [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/v0.1.6...v0.1.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 03:52:51 +00:00
dependabot[bot] cc14cf23b1 Bump isort from 5.12.0 to 5.13.0
Bumps [isort](https://github.com/pycqa/isort) from 5.12.0 to 5.13.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/5.12.0...5.13.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 03:52:41 +00:00
dependabot[bot] 327f750ead Bump technical from 1.4.0 to 1.4.1
Bumps [technical](https://github.com/freqtrade/technical) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/freqtrade/technical/releases)
- [Commits](https://github.com/freqtrade/technical/compare/1.4.0...1.4.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 03:52:31 +00:00
dependabot[bot] a304080c08 Bump actions/setup-python from 4 to 5
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 03:33:18 +00:00
Robert Caulk 020d4b5b4d Merge pull request #9523 from freqtrade/fix/freqai-append-bug
Bugfix: ensure zeros are properly appended after each inference
2023-12-10 17:29:51 +01:00
robcaulk 78cb1e608f fix: ensure we have a row of zeros appended (not the function) 2023-12-10 15:30:19 +01:00
Matthias b84a2fcac7 Merge pull request #9521 from freqtrade/robcaulk-patch-1
Ensure the documentation gets read
2023-12-10 14:21:59 +01:00
Robert Caulk c0119d7baa Merge pull request #9449 from freqtrade/dependabot/pip/develop/torch-2.1.1
Bump torch from 2.0.1 to 2.1.1
2023-12-10 14:11:01 +01:00
Matthias 0bd513012a enhance further test for funding-fee checking 2023-12-10 14:00:21 +01:00
Matthias 3f6cd9ee51 Patch funding_fee calculation for unrelated test 2023-12-10 14:00:06 +01:00
Matthias 8964c138f1 Call funding fee calculation whenever a trade is closed 2023-12-10 14:00:06 +01:00
Matthias ef23f0fcba Fix test to account for new funding_fee count 2023-12-10 14:00:06 +01:00
Matthias 074343f0f1 Don't calculate funding_fees on every iteration 2023-12-10 14:00:06 +01:00
Matthias 966eb59fd3 Extract funding fee calculation to separate method 2023-12-10 14:00:06 +01:00
Matthias 778bd7b3b0 enhance further test for funding-fee checking 2023-12-10 13:57:52 +01:00
Matthias b4cd46d6db Further improve funding_Fee test 2023-12-10 13:21:05 +01:00
Matthias 1d73b57e8c Extract some assert values from bt test 2023-12-10 12:57:55 +01:00
Robert Caulk 476703bf76 Update data_kitchen.py
Ensure our exception is raised when users dont download the data
2023-12-10 12:26:39 +01:00
Matthias cd09d3567f Add spy test on funding_fees in backtesting 2023-12-09 19:42:13 +01:00
Matthias 4c25e9d21a Merge pull request #9387 from freqtrade/dependabot/pip/develop/scikit-learn-1.3.2
Bump scikit-learn from 1.1.3 to 1.3.2
2023-12-09 14:20:15 +01:00
Matthias dd08c134b4 Remove macos 13 ci again 2023-12-09 13:40:00 +01:00
Matthias aa8bb27cf0 Merge branch 'develop' into dependabot/pip/develop/scikit-learn-1.3.2 2023-12-09 13:39:46 +01:00
Matthias d428d48393 Ease install dependencies for scikit-learn 2023-12-09 12:12:52 +01:00
Matthias 3bdfa85237 Update scikit-optimize to ft-scikit-optimize
Compatibility fork of scikit-optimize.
2023-12-09 12:12:30 +01:00
Matthias 95a824fbe7 Merge pull request #9509 from freqtrade/ci_mac_13
macos-13 CI
2023-12-09 07:55:42 +01:00
Matthias bb85efd6ad Add test for informative weekly merging
closes #9518
2023-12-08 20:41:57 +01:00
Matthias 7321a14c35 Fix generate-test-data for 1w data 2023-12-08 20:38:41 +01:00
Matthias 2745a5d334 Rename informative_pair test 2023-12-08 20:07:44 +01:00
Matthias d123d3bb82 Completely mock Torch on macos
we already skip tests - now we also need to skip it's imports.
2023-12-07 07:25:34 +01:00
Matthias b14873400d Fix odd import in freqai tests 2023-12-07 07:15:05 +01:00
Robert Caulk d9b95a4c27 Merge pull request #9514 from freqtrade/freqai/xgboost_activate
Remove "activate" kwarg to xgboost calls
2023-12-06 21:18:07 +01:00
Matthias 71178ff1d2 Remove "activate" activator
they raise warnings as they're unused.
2023-12-06 19:48:19 +01:00
Matthias d3d9f3281e Fix torch logging setup mess 2023-12-06 19:26:09 +01:00
Matthias 3b4b833dd0 Remove unused mock 2023-12-06 18:22:28 +01:00
Matthias fcc87399cd Merge pull request #9505 from freqtrade/fix/merge-warning
Fix multiple new Pandas 2.1 future warnings in FreqAI startup
2023-12-05 19:25:57 +01:00
Matthias 654f8a7573 Merge pull request #9508 from freqtrade/dependabot/pip/develop/nbconvert-7.12.0
Bump nbconvert from 7.11.0 to 7.12.0
2023-12-05 19:24:22 +01:00
Matthias 2fdb9663d7 Merge branch 'develop' into fix/merge-warning 2023-12-05 18:12:34 +01:00
dependabot[bot] 3739a10735 Bump nbconvert from 7.11.0 to 7.12.0
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.11.0 to 7.12.0.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.11.0...v7.12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-05 17:10:09 +00:00
Matthias 9a425af76f Remove unnecessary conditions in Ci run 2023-12-05 18:08:24 +01:00
Matthias 3c48208b31 Fix cache keys 2023-12-05 18:08:24 +01:00
Matthias 68db8d0201 install libomp 2023-12-05 18:08:24 +01:00
Matthias 2207773678 Attempt more granular cache for macos 2023-12-05 18:08:24 +01:00
Matthias cbe6d52a73 Try macos-13 CI 2023-12-05 18:08:24 +01:00
Matthias b7fc0190f7 Merge pull request #9512 from freqtrade/revert-9500-dependabot/pip/develop/tables-3.9.2
Revert "Bump tables from 3.9.1 to 3.9.2"
2023-12-05 18:04:56 +01:00
Matthias 4061eaf888 Remove online tests for bittrex 2023-12-05 18:03:55 +01:00
Matthias ef042ae5ec Remove exchange tests on bittrex 2023-12-05 18:03:48 +01:00
Matthias 6ee792069d Remove bitrex-specific section 2023-12-05 18:03:34 +01:00
Matthias 46c81d7018 Revert "Bump tables from 3.9.1 to 3.9.2" 2023-12-05 17:04:16 +01:00
Robert Caulk caac77c90b Update data_drawer.py 2023-12-05 12:16:08 +01:00
Matthias af05e3d747 Merge pull request #9506 from freqtrade/dependabot/pip/develop/ccxt-4.1.76
Bump ccxt from 4.1.75 to 4.1.76
2023-12-04 20:48:37 +01:00
dependabot[bot] 59a287106d Bump ccxt from 4.1.75 to 4.1.76
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.75 to 4.1.76.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.75...4.1.76)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 18:21:30 +00:00
robcaulk 8b5e6bf9be chore: fix pandas warning about merging on datetime. fix pandas warning about inconsistent key lists in concat 2023-12-04 16:23:55 +01:00
Matthias d9882978d5 Merge pull request #9500 from freqtrade/dependabot/pip/develop/tables-3.9.2
Bump tables from 3.9.1 to 3.9.2
2023-12-04 07:25:18 +01:00
Matthias 04f2b7bad6 Add support for different timeInForce for bybit 2023-12-04 07:23:52 +01:00
Matthias 8597709b2e Merge pull request #9501 from freqtrade/dependabot/pip/develop/ccxt-4.1.75
Bump ccxt from 4.1.66 to 4.1.75
2023-12-04 06:33:38 +01:00
Matthias 2fea75e312 Merge pull request #9498 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.8.11
Bump pypa/gh-action-pypi-publish from 1.8.10 to 1.8.11
2023-12-04 06:33:17 +01:00
Matthias 511e4d16d5 Merge pull request #9502 from freqtrade/dependabot/pip/develop/python-telegram-bot-20.7
Bump python-telegram-bot from 20.6 to 20.7
2023-12-04 06:32:46 +01:00
dependabot[bot] e0f780f10e Bump python-telegram-bot from 20.6 to 20.7
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 20.6 to 20.7.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v20.6...v20.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 03:35:49 +00:00
dependabot[bot] 44689d058b Bump ccxt from 4.1.66 to 4.1.75
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.66 to 4.1.75.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.66...4.1.75)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 03:35:42 +00:00
dependabot[bot] 1431b2b44a Bump tables from 3.9.1 to 3.9.2
Bumps [tables](https://github.com/PyTables/PyTables) from 3.9.1 to 3.9.2.
- [Release notes](https://github.com/PyTables/PyTables/releases)
- [Changelog](https://github.com/PyTables/PyTables/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/PyTables/PyTables/compare/v3.9.1...v3.9.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 03:35:27 +00:00
dependabot[bot] 106bda51d4 Bump pypa/gh-action-pypi-publish from 1.8.10 to 1.8.11
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.10 to 1.8.11.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.10...v1.8.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 03:10:11 +00:00
Matthias 90e4eb59b2 Improve multi-strategy backtest docs 2023-12-03 15:27:33 +01:00
Matthias 701f6fc050 Update outdated docs
closes #9489
2023-12-03 15:27:03 +01:00
Matthias 0235db48a8 Prevent merge artifacts in "informative" pair 2023-12-03 13:31:16 +01:00
Matthias e9e7bf3caf Slight cleanup of unused comment 2023-12-03 13:31:16 +01:00
Matthias 4464b02719 Add handling to properly merge 1M data to
closes #9490
2023-12-03 13:31:16 +01:00
Matthias 4ed9ffbf31 Add test for behavior in #9490. 2023-12-03 13:31:16 +01:00
Matthias c017366086 Ensure testdata generation works for 1M data 2023-12-03 13:31:16 +01:00
Matthias 34bce4d251 Merge pull request #9493 from freqtrade/chore/future-warning-datadrawer
chore: fix future warning on pandas
2023-12-03 13:25:01 +01:00
Robert Caulk 6754072bca chore: fix future warning on pandas 2023-12-03 12:55:16 +01:00
Robert Caulk 15771043f7 Merge pull request #9450 from freqtrade/fix/startup-candle-count
Bug: freqai backtesting startup_candle_count handling
2023-12-02 21:01:11 +01:00
Robert Caulk b417a0297b Merge pull request #9468 from freqtrade/freqai/fix_dump
Use cloudpickle to pickle freqai models
2023-12-02 18:51:31 +01:00
Matthias 5daafaabc2 Add explicit test for "now_is_time_to_refresh 2023-12-01 07:05:33 +01:00
Matthias 08db2f05aa Merge pull request #9485 from stash86/bt-metrics
exposing bot_name to discord rpc field
2023-11-30 19:04:34 +01:00
Matthias 0654186400 Merge pull request #9486 from freqtrade/new_release
New release 2023.11
2023-11-30 17:25:25 +01:00
Matthias d85518ccb2 Improve release documentation 2023-11-30 07:10:20 +01:00
Matthias c34cb9eb12 Bump version to 2023.12-dev 2023-11-30 07:04:38 +01:00
Matthias cb01a46089 Version bump to 2023.11 2023-11-30 07:00:25 +01:00
Matthias 0bcbb28d51 Merge branch 'stable' into new_release 2023-11-30 07:00:11 +01:00
Matthias e2a47ee95a Merge pull request #9482 from freqtrade/bitmart
Add support for Bitmart
2023-11-30 06:49:41 +01:00
Stefano Ariestasia 36836ea803 add bot_name to discord rpc field 2023-11-30 14:11:09 +09:00
Matthias 19d9adaf9c Merge pull request #9483 from freqtrade/dependabot/pip/cryptography-41.0.6
Bump cryptography from 41.0.5 to 41.0.6
2023-11-29 12:43:15 +01:00
Matthias cf078f8093 Bump to 41.0.7 to avoid install problems 2023-11-29 06:57:00 +01:00
dependabot[bot] 5ddca4e9f9 Bump cryptography from 41.0.5 to 41.0.6
Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.5 to 41.0.6.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/41.0.5...41.0.6)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 05:27:01 +00:00
Matthias 6db66b1e58 Add bitmart to "official supported" exchanges 2023-11-28 18:18:19 +01:00
Matthias 0a903e45f2 Add Bitmart to list of supported exchnanges for spot 2023-11-28 18:14:42 +01:00
Matthias d0a2b9403e Fix typo 2023-11-28 18:14:33 +01:00
Matthias a18c85ec64 Explicitly disable stoploss on exchange for bitmart 2023-11-28 18:13:21 +01:00
Matthias 0914b8b5f4 Add note about verification on Bitmart 2023-11-28 18:13:21 +01:00
Matthias cb2a871538 Bitmart: add section in exchange docs 2023-11-28 18:13:21 +01:00
Matthias ef877b5fcc Add bitmart to ccxt compat tested exchanges 2023-11-28 18:13:21 +01:00
Matthias 2738f3e437 Add minimal Exchange class for bitmart 2023-11-28 18:13:21 +01:00
Matthias 79f765a930 Merge pull request #9472 from freqtrade/dependabot/pip/develop/ccxt-4.1.66
Bump ccxt from 4.1.57 to 4.1.66
2023-11-27 07:56:47 +01:00
Matthias 696f8b308a Merge pull request #9476 from freqtrade/dependabot/pip/develop/aiohttp-3.9.1
Bump aiohttp from 3.9.0 to 3.9.1
2023-11-27 07:40:39 +01:00
Matthias 4a2473e7e9 Merge pull request #9475 from freqtrade/dependabot/pip/develop/mkdocs-material-9.4.14
Bump mkdocs-material from 9.4.10 to 9.4.14
2023-11-27 07:02:54 +01:00
Matthias a0caa7c5a2 Merge pull request #9477 from freqtrade/dependabot/pip/develop/pydantic-2.5.2
Bump pydantic from 2.5.1 to 2.5.2
2023-11-27 07:02:25 +01:00
Matthias 388a0c605c Merge pull request #9470 from stash86/bt-metrics2
fix typo on API docs
2023-11-27 06:46:50 +01:00
Matthias 55e4d08fd8 Merge pull request #9436 from stash86/bt-metrics
Remove order list from /status, and add new /order command
2023-11-27 06:40:00 +01:00
Matthias 7c00a4ed13 Remove no longer existing exchange aliases from tests 2023-11-27 06:39:14 +01:00
dependabot[bot] 793cc1acc0 Bump mkdocs-material from 9.4.10 to 9.4.14
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.10 to 9.4.14.
- [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.4.10...9.4.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 05:31:12 +00:00
Matthias 33d910ccea Merge pull request #9474 from freqtrade/dependabot/pip/develop/mypy-1.7.1
Bump mypy from 1.7.0 to 1.7.1
2023-11-27 06:29:46 +01:00
Matthias 8a44337c30 Merge pull request #9473 from freqtrade/dependabot/pip/develop/pymdown-extensions-10.5
Bump pymdown-extensions from 10.4 to 10.5
2023-11-27 06:28:44 +01:00
dependabot[bot] 35871d7b4b Bump pydantic from 2.5.1 to 2.5.2
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.5.1 to 2.5.2.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v2.5.2/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.5.1...v2.5.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 03:20:23 +00:00
dependabot[bot] 786d4e03fc Bump aiohttp from 3.9.0 to 3.9.1
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.0 to 3.9.1.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.0...v3.9.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 03:20:08 +00:00
dependabot[bot] 5e5b56e445 Bump mypy from 1.7.0 to 1.7.1
Bumps [mypy](https://github.com/python/mypy) from 1.7.0 to 1.7.1.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.7.0...v1.7.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 03:19:43 +00:00
dependabot[bot] 384ebc5b38 Bump pymdown-extensions from 10.4 to 10.5
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 10.4 to 10.5.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/10.4...10.5)

---
updated-dependencies:
- dependency-name: pymdown-extensions
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 03:19:35 +00:00
dependabot[bot] 8567af8d28 Bump ccxt from 4.1.57 to 4.1.66
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.57 to 4.1.66.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.57...4.1.66)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 03:19:22 +00:00
Stefano Ariestasia 88e818926a fix typo on API docs 2023-11-27 10:57:50 +09:00
Stefano Ariestasia 4bcb4fdd82 Merge branch 'freqtrade:develop' into bt-metrics 2023-11-27 10:46:21 +09:00
Matthias 0b3a6aa9de Merge pull request #9469 from freqtrade/ci/pi_image_3.11
Update various docker images
2023-11-26 19:23:03 +01:00
Matthias 12ea1cde80 Bump dockerfile to use bookworm (debian12) 2023-11-26 16:34:31 +01:00
Matthias df73b8288c Bump armhf image to bookworm 2023-11-26 14:53:34 +01:00
Matthias a50291cd90 RPI dockerfile - 3.11 2023-11-26 14:52:52 +01:00
Matthias be8ea685de Remove unused function in freqAI example 2023-11-26 13:37:02 +01:00
dependabot[bot] d050beb627 Bump torch from 2.0.1 to 2.1.1
Bumps [torch](https://github.com/pytorch/pytorch) from 2.0.1 to 2.1.1.
- [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.0.1...v2.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-26 11:40:46 +00:00
Robert Caulk 1380cadf15 Merge pull request #9448 from freqtrade/dependabot/pip/develop/stable-baselines3-2.2.1
Bump stable-baselines3 from 2.1.0 to 2.2.1
2023-11-26 12:39:46 +01:00
Matthias 72eeb6561c use Cloudpickle also for reading 2023-11-25 19:37:49 +01:00
Matthias eeb460e55c Use cloudpickle throughout 2023-11-25 19:36:14 +01:00
Matthias e8d0b01991 Correctly import time 2023-11-25 16:17:43 +01:00
Matthias 94020a664b Add slight sleep to avoid random test failure on windows 2023-11-25 15:58:28 +01:00
Matthias 8c5194d5e2 force-reload markets when BadSymbol appears
closes #9463
2023-11-25 15:05:56 +01:00
Matthias 67e81c9018 Fix wrong/faulty docstring 2023-11-25 13:10:45 +01:00
Matthias 25ebdb4cb3 use strategy_wrapper for bot_loop_start in plotting
closes #9464
2023-11-25 12:51:17 +01:00
Matthias 1657fd1f0f Merge pull request #9435 from freqtrade/revisit_relative_intratrade
Improve trade close profit assertions
2023-11-23 20:02:02 +01:00
Stefano Ariestasia 63e702a3bf remove unused comments 2023-11-23 15:55:21 +09:00
Matthias e9f21d0209 Improve logging for #9460 2023-11-23 07:22:44 +01:00
Matthias a044649eef Also have "badrequest" act as InvalidOrderException
causing an emergencyexit.

closes #9456
2023-11-23 06:51:29 +01:00
dependabot[bot] 48317c2307 Bump scikit-learn from 1.1.3 to 1.3.2
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 1.1.3 to 1.3.2.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/1.1.3...1.3.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-22 11:13:58 +00:00
Matthias d598c91de3 Merge pull request #9458 from freqtrade/hyperopt_tests
Improve hyperopt Tests
2023-11-22 12:13:14 +01:00
Matthias 5003c2af21 training_env is a property, also, so types can't be overridden 2023-11-22 07:22:40 +01:00
Matthias 6963a92332 Improve hyperopt Tests
ensure scikit-learn has to generate new random points by reducing initial points
this will uncover a failure in newer scikit-learn versions
2023-11-22 07:21:07 +01:00
Matthias e2863e1620 fix: logger has been converted to a property
so it can't be assigned anymore
https://github.com/DLR-RM/stable-baselines3/commit/e9f0f23ce4b4479968e40698b991b49b7f59bd90#diff-d668633497da171f21b8069c33d594b1ee2ad47c1be4848bea33292bc80b7f5c
2023-11-22 06:54:41 +01:00
Matthias 869756d87d Merge pull request #9454 from freqtrade/ci/bittrex_removal
Remove Bittrex from supported exchanges
2023-11-21 20:52:43 +01:00
Matthias 203890844b Remove non-existing pairs 2023-11-21 19:16:34 +01:00
Matthias ba76b87952 Merge pull request #9453 from chasdabigone/fixing-docs
Removed redundant 'cpu_count'
2023-11-21 18:06:24 +01:00
Matthias fbab18b081 Add missing config file 2023-11-21 18:01:18 +01:00
Matthias f7178ecd6f Update test config name and exchange 2023-11-21 07:10:23 +01:00
Matthias 59cbac7147 Merge pull request #9452 from chasdabigone/fix-hyperopt-typo
Removed redudant negative from sentence
2023-11-21 06:58:12 +01:00
Matthias fbc70a60f7 Update test with no bittrex ... 2023-11-21 06:57:18 +01:00
Matthias b45365d385 Update tests to run for binance 2023-11-21 06:47:50 +01:00
Matthias 9990780e6b Update binance config to be for usdt pairs 2023-11-21 06:44:44 +01:00
Matthias 65df2f30c1 Update some more docs with bittrex removal 2023-11-21 06:42:53 +01:00
Matthias e7aa706f73 Update samples with binance 2023-11-21 06:39:38 +01:00
Matthias 3619247123 Remove bittrex from code for suppored exchanges 2023-11-21 06:39:29 +01:00
Matthias 047dac7b7d Remove bittrex from supported exchanges 2023-11-21 06:37:58 +01:00
chas s 7646849405 Removed redundant 'cpu_count' 2023-11-20 23:25:28 -06:00
chas s 10ae0ed9c1 Removed redudant negative from sentence 2023-11-20 16:33:22 -06:00
Matthias e060e729df Merge pull request #9451 from freqtrade/remove_blosc
Remove dependency on blosc
2023-11-20 14:53:04 +01:00
Matthias d81bbba4c2 Remove dependency on blosc 2023-11-20 13:50:59 +01:00
robcaulk d52936fd42 chore: try to keep startup_candle_count behaving the same as a normal FT strat 2023-11-20 09:13:01 +01:00
robcaulk 21a5abf25d fix: make sure that get_required_startup is timeframe independent 2023-11-20 08:42:27 +01:00
Matthias c3980a2746 Merge pull request #9442 from freqtrade/dependabot/pip/develop/ccxt-4.1.57
Bump ccxt from 4.1.52 to 4.1.57
2023-11-20 07:57:19 +01:00
Matthias 2cadbd1229 Merge pull request #9443 from freqtrade/dependabot/pip/develop/ruff-0.1.6
Bump ruff from 0.1.5 to 0.1.6
2023-11-20 07:42:58 +01:00
Matthias 0f57291aa7 Merge pull request #9446 from freqtrade/dependabot/pip/develop/urllib3-2.1.0
Bump urllib3 from 2.0.7 to 2.1.0
2023-11-20 07:36:33 +01:00
Stefano 0e9169e1ec update docs 2023-11-20 15:35:06 +09:00
Stefano 8680b5faa0 fix some tests, add new tests 2023-11-20 14:48:18 +09:00
Matthias 03149cfa42 Merge pull request #9445 from freqtrade/dependabot/pip/develop/pydantic-2.5.1
Bump pydantic from 2.4.2 to 2.5.1
2023-11-20 06:37:47 +01:00
Matthias 4eb4732de7 Merge pull request #9441 from freqtrade/dependabot/pip/develop/rich-13.7.0
Bump rich from 13.6.0 to 13.7.0
2023-11-20 06:36:20 +01:00
Matthias 3a5b22c397 Merge pull request #9438 from freqtrade/dependabot/pip/develop/scipy-1.11.4
Bump scipy from 1.11.3 to 1.11.4
2023-11-20 06:35:25 +01:00
Matthias c3a5d4b4e4 Merge pull request #9439 from freqtrade/dependabot/pip/develop/mkdocs-material-9.4.10
Bump mkdocs-material from 9.4.8 to 9.4.10
2023-11-20 06:34:47 +01:00
dependabot[bot] b97ff3a784 Bump ccxt from 4.1.52 to 4.1.57
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.52 to 4.1.57.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.52...4.1.57)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 05:33:47 +00:00
dependabot[bot] 806af7d796 Bump urllib3 from 2.0.7 to 2.1.0
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.7 to 2.1.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.0.7...2.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 05:33:14 +00:00
Matthias 3c25737f38 Merge pull request #9440 from freqtrade/dependabot/pip/develop/aiohttp-3.9.0
Bump aiohttp from 3.8.6 to 3.9.0
2023-11-20 06:32:58 +01:00
Matthias bf98851dc1 Merge pull request #9444 from freqtrade/dependabot/pip/develop/jsonschema-4.20.0
Bump jsonschema from 4.19.2 to 4.20.0
2023-11-20 06:32:01 +01:00
dependabot[bot] 202b72fd8e Bump stable-baselines3 from 2.1.0 to 2.2.1
Bumps [stable-baselines3](https://github.com/DLR-RM/stable-baselines3) from 2.1.0 to 2.2.1.
- [Release notes](https://github.com/DLR-RM/stable-baselines3/releases)
- [Commits](https://github.com/DLR-RM/stable-baselines3/compare/v2.1.0...v2.2.1)

---
updated-dependencies:
- dependency-name: stable-baselines3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:12:31 +00:00
dependabot[bot] 6f60117319 Bump pydantic from 2.4.2 to 2.5.1
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.4.2 to 2.5.1.
- [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.4.2...v2.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:12:12 +00:00
dependabot[bot] 7070ec30e4 Bump jsonschema from 4.19.2 to 4.20.0
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.19.2 to 4.20.0.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.19.2...v4.20.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:12:05 +00:00
dependabot[bot] bf77019d1c Bump ruff from 0.1.5 to 0.1.6
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.5 to 0.1.6.
- [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/v0.1.5...v0.1.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:12:00 +00:00
dependabot[bot] b776e5a8e0 Bump rich from 13.6.0 to 13.7.0
Bumps [rich](https://github.com/Textualize/rich) from 13.6.0 to 13.7.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/v13.6.0...v13.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:11:43 +00:00
dependabot[bot] ca208305a0 Bump aiohttp from 3.8.6 to 3.9.0
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.6 to 3.9.0.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.6...v3.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:11:37 +00:00
dependabot[bot] 972c5c327c Bump mkdocs-material from 9.4.8 to 9.4.10
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.8 to 9.4.10.
- [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.4.8...9.4.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:11:28 +00:00
dependabot[bot] 80edfd1531 Bump scipy from 1.11.3 to 1.11.4
Bumps [scipy](https://github.com/scipy/scipy) from 1.11.3 to 1.11.4.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.11.3...v1.11.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 03:11:23 +00:00
Stefano Ariestasia 58cd455642 fix unused vars 2023-11-19 20:32:28 +09:00
Stefano Ariestasia caf59d25e8 forgot comma 2023-11-19 18:07:45 +09:00
Stefano Ariestasia 7df32a34a0 remove order list from /status and add new /order 2023-11-19 18:01:32 +09:00
Matthias 48097f4a7d Update tests according to calculation update 2023-11-18 19:47:20 +01:00
Matthias ca3f349d84 Update intermediate close_profit calculation 2023-11-18 19:47:09 +01:00
Matthias 0815bb6244 Improve trade close profit assertions 2023-11-18 18:18:29 +01:00
Matthias 835cb54876 Merge pull request #9427 from froggleston/frog-bt-analysis-fix-1
Fix backtesting-analysis when no trades for a pair
2023-11-15 19:46:32 +01:00
Matthias 08c2765633 Merge pull request #9429 from froggleston/frog-hyperopt-docs-1
Clarify hyperopt docs for parameter options
2023-11-15 18:27:14 +01:00
froggleston f9202c3f6b Clarify hyperopt docs for parameter options 2023-11-15 12:11:47 +00:00
froggleston eb186e22d6 Fix backtesting-analysis when no trades for a pair 2023-11-15 11:52:25 +00:00
Matthias cbc323875b Improve contribution wording 2023-11-15 07:12:11 +01:00
Matthias 736b583ff4 Merge pull request #9425 from freqtrade/dependabot/pip/develop/ccxt-4.1.52
Bump ccxt from 4.1.40 to 4.1.52
2023-11-14 20:56:58 +01:00
dependabot[bot] 757ec53877 Bump ccxt from 4.1.40 to 4.1.52
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.40 to 4.1.52.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.40...4.1.52)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-14 19:16:20 +00:00
Matthias 7814927dd1 Merge pull request #9418 from freqtrade/dependabot/pip/develop/mypy-1.7.0
Bump mypy from 1.6.1 to 1.7.0
2023-11-13 19:28:46 +01:00
Matthias 5f8ff373ab Update mypy to v1.7.0 in pre-commit-config.yaml 2023-11-13 18:15:10 +01:00
Matthias f286cb0a90 Use BaseException in exception check 2023-11-13 18:14:18 +01:00
Matthias 59bd1a1f1f Merge pull request #9309 from freqtrade/dependabot/pip/develop/tables-3.9.1
Bump tables from 3.8.0 to 3.9.1
2023-11-13 13:49:20 +01:00
Matthias e52f6ca6c0 Merge pull request #9421 from konradbeck/patch-2
Update strategy-customization.md
2023-11-13 13:48:58 +01:00
konradbeck e6663c0304 Update strategy-customization.md
Shouldn't the timeperiod be 100 when defining a ema100?
2023-11-13 13:50:32 +02:00
dependabot[bot] ced92300e0 Bump tables from 3.8.0 to 3.9.1
Bumps [tables](https://github.com/PyTables/PyTables) from 3.8.0 to 3.9.1.
- [Release notes](https://github.com/PyTables/PyTables/releases)
- [Changelog](https://github.com/PyTables/PyTables/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/PyTables/PyTables/compare/v3.8.0...v3.9.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 09:19:19 +00:00
Matthias f9d061b648 Merge pull request #9413 from freqtrade/dependabot/pip/develop/xgboost-2.0.2
Bump xgboost from 2.0.1 to 2.0.2
2023-11-13 08:01:41 +01:00
Matthias e6661a33f9 Merge pull request #9419 from freqtrade/dependabot/pip/develop/pandas-2.1.3
Bump pandas from 2.1.2 to 2.1.3
2023-11-13 07:26:36 +01:00
Matthias d2afe281bf Add cancel order to new exchange docs 2023-11-13 07:23:50 +01:00
Matthias c237aa00b8 Remove non-used imports 2023-11-13 07:15:35 +01:00
Matthias 23efa4c9c3 Remove deprecated json_encoders key from model_config 2023-11-13 07:15:35 +01:00
dependabot[bot] 8b028734c2 Bump pandas from 2.1.2 to 2.1.3
Bumps [pandas](https://github.com/pandas-dev/pandas) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Commits](https://github.com/pandas-dev/pandas/compare/v2.1.2...v2.1.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 05:29:27 +00:00
dependabot[bot] 51feeddc5c Bump mypy from 1.6.1 to 1.7.0
Bumps [mypy](https://github.com/python/mypy) from 1.6.1 to 1.7.0.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.6.1...v1.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 05:29:25 +00:00
Matthias af3e42f59d Merge pull request #9415 from freqtrade/dependabot/pip/develop/numpy-1.26.2
Bump numpy from 1.26.1 to 1.26.2
2023-11-13 06:28:52 +01:00
Matthias 34d58eb7d5 Merge pull request #9417 from freqtrade/dependabot/pip/develop/ruff-0.1.5
Bump ruff from 0.1.4 to 0.1.5
2023-11-13 06:28:32 +01:00
Matthias ca0a04fba5 Merge pull request #9416 from freqtrade/dependabot/pip/develop/pymdown-extensions-10.4
Bump pymdown-extensions from 10.3.1 to 10.4
2023-11-13 06:27:44 +01:00
dependabot[bot] 84b3f9924a Bump ruff from 0.1.4 to 0.1.5
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.4 to 0.1.5.
- [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/v0.1.4...v0.1.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 03:34:19 +00:00
dependabot[bot] 50b264c6f8 Bump pymdown-extensions from 10.3.1 to 10.4
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 10.3.1 to 10.4.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/10.3.1...10.4)

---
updated-dependencies:
- dependency-name: pymdown-extensions
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 03:34:07 +00:00
dependabot[bot] 88e8a9fe2b Bump numpy from 1.26.1 to 1.26.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.26.1 to 1.26.2.
- [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/v1.26.1...v1.26.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 03:33:57 +00:00
dependabot[bot] d65aef72e8 Bump xgboost from 2.0.1 to 2.0.2
Bumps [xgboost](https://github.com/dmlc/xgboost) from 2.0.1 to 2.0.2.
- [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/v2.0.1...v2.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 03:33:44 +00:00
Matthias 8273c0c2cd Skip exchange validation in API server dependencies
Especially when validating pairlists for non-main exchanges (the exchange not in the config),
validation can mess with the exchange loading.
2023-11-12 17:34:16 +01:00
Matthias c7624b1ed6 Simplify LiveStats models 2023-11-11 17:18:18 +01:00
Matthias 54536a1c8e use profit_ratio for mix_tag_performance 2023-11-11 17:18:13 +01:00
Matthias 7daa06a207 Align mixtag response with other statistic models 2023-11-11 17:18:06 +01:00
Matthias da647735b6 Merge pull request #9407 from stash86/bt-metrics
add entries, exits, and mix_tags API endpoints
2023-11-11 16:10:10 +01:00
Matthias 7d0ecfde93 Add tests to ensure responses are as expected 2023-11-11 14:43:43 +01:00
Matthias 2ef716e94c Add response_models for new endpoints 2023-11-11 14:43:30 +01:00
Matthias de68850d28 Don't tag informative endpoints as "trading" 2023-11-11 14:31:18 +01:00
Matthias 59cefda283 Update strategy-callbacks.md with new information
on max_entry_position_adjustment
2023-11-11 13:11:17 +01:00
Matthias babcd5887f Merge pull request #9408 from konradbeck/patch-1
Update freqai-feature-engineering.md
2023-11-11 10:54:27 +01:00
Matthias c9a5e5a98c Fix another (identical) typo 2023-11-11 10:50:58 +01:00
konradbeck 51dc5811c2 Update freqai-feature-engineering.md
I cannot find any reference to 'include_periods_candles'
2023-11-11 09:38:52 +02:00
Stefano Ariestasia 05e36f7b21 increase API version 2023-11-11 15:33:15 +09:00
Stefano Ariestasia 0738cae4a0 fix pre-commit 2023-11-11 15:23:20 +09:00
Stefano Ariestasia da3c42bbbc add entries, exits, and mix_tags API endpoints 2023-11-11 15:16:40 +09:00
Matthias e728e3bc75 Merge pull request #9402 from freqtrade/dependabot/pip/pyarrow-14.0.1
Bump pyarrow from 14.0.0 to 14.0.1
2023-11-10 21:11:23 +01:00
Matthias 315783441d Update pyarrow wheels 2023-11-10 19:41:23 +01:00
dependabot[bot] 62f1421cfb Bump pyarrow from 14.0.0 to 14.0.1
Bumps [pyarrow](https://github.com/apache/arrow) from 14.0.0 to 14.0.1.
- [Commits](https://github.com/apache/arrow/compare/go/v14.0.0...apache-arrow-14.0.1)

---
updated-dependencies:
- dependency-name: pyarrow
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-09 22:48:16 +00:00
Matthias 52f12b704b Avoid time colision when creating orders in test
avoid flakyness of test.
2023-11-06 19:42:16 +01:00
Matthias ee5051f788 Merge pull request #9388 from freqtrade/dependabot/pip/develop/pyarrow-14.0.0
Bump pyarrow from 13.0.0 to 14.0.0
2023-11-06 17:46:19 +01:00
Matthias b30b1227e3 Merge pull request #9394 from freqtrade/dependabot/pip/develop/sqlalchemy-2.0.23
Bump sqlalchemy from 2.0.22 to 2.0.23
2023-11-06 17:45:36 +01:00
Matthias dd2f8db392 Merge pull request #9396 from freqtrade/dependabot/pip/develop/ccxt-4.1.40
Bump ccxt from 4.1.39 to 4.1.40
2023-11-06 17:45:20 +01:00
Matthias 5a76d81529 Merge pull request #9398 from freqtrade/dependabot/pip/develop/uvicorn-0.24.0.post1
Bump uvicorn from 0.23.2 to 0.24.0.post1
2023-11-06 17:21:57 +01:00
Matthias b9851c78ad Merge pull request #9397 from freqtrade/dependabot/pip/develop/nbconvert-7.11.0
Bump nbconvert from 7.10.0 to 7.11.0
2023-11-06 17:21:35 +01:00
Matthias 777cf2ae7a Merge pull request #9399 from freqtrade/dependabot/pip/develop/ruff-0.1.4
Bump ruff from 0.1.3 to 0.1.4
2023-11-06 17:21:17 +01:00
dependabot[bot] 3729b3d793 Bump ruff from 0.1.3 to 0.1.4
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.3 to 0.1.4.
- [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/v0.1.3...v0.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 14:54:26 +00:00
dependabot[bot] 39fc78205d Bump uvicorn from 0.23.2 to 0.24.0.post1
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.23.2 to 0.24.0.post1.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.23.2...0.24.0.post1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 14:54:11 +00:00
dependabot[bot] 46a67e8d4f Bump nbconvert from 7.10.0 to 7.11.0
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.10.0 to 7.11.0.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.10.0...v7.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 14:54:05 +00:00
dependabot[bot] 69017805c0 Bump ccxt from 4.1.39 to 4.1.40
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.39 to 4.1.40.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.39...4.1.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 14:54:00 +00:00
Matthias bcec611973 Add pre-built wheels for pyarrow 14 2023-11-06 15:43:55 +01:00
Matthias fbb11a394a Bump sqlalchemy pre-commit 2023-11-06 15:42:18 +01:00
Matthias 5cb916977e Merge pull request #9390 from freqtrade/dependabot/pip/develop/cachetools-5.3.2
Bump cachetools from 5.3.1 to 5.3.2
2023-11-06 15:40:54 +01:00
Matthias 7d4c9bc0cf Merge pull request #9395 from freqtrade/dependabot/pip/develop/markdown-3.5.1
Bump markdown from 3.5 to 3.5.1
2023-11-06 15:40:39 +01:00
Matthias ea2beb46e7 Merge pull request #9392 from freqtrade/dependabot/pip/develop/mkdocs-material-9.4.8
Bump mkdocs-material from 9.4.7 to 9.4.8
2023-11-06 15:40:29 +01:00
Matthias 216ee8117a Merge pull request #9393 from freqtrade/dependabot/pip/develop/tensorboard-2.15.1
Bump tensorboard from 2.15.0 to 2.15.1
2023-11-06 15:40:12 +01:00
Matthias 9c1210b34e Merge pull request #9391 from freqtrade/dependabot/pip/develop/filelock-3.13.1
Bump filelock from 3.12.4 to 3.13.1
2023-11-06 06:44:40 +01:00
dependabot[bot] 921e034266 Bump sqlalchemy from 2.0.22 to 2.0.23
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.22 to 2.0.23.
- [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-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 05:43:11 +00:00
Matthias 6f358b16c0 Merge pull request #9385 from freqtrade/dependabot/pip/develop/ccxt-4.1.39
Bump ccxt from 4.1.31 to 4.1.39
2023-11-06 06:42:10 +01:00
dependabot[bot] 264ab2c471 Bump pyarrow from 13.0.0 to 14.0.0
Bumps [pyarrow](https://github.com/apache/arrow) from 13.0.0 to 14.0.0.
- [Commits](https://github.com/apache/arrow/compare/go/v13.0.0...go/v14.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 05:40:25 +00:00
Matthias a9d6f0023a Merge pull request #9384 from freqtrade/dependabot/pip/develop/py-find-1st-1.1.6
Bump py-find-1st from 1.1.5 to 1.1.6
2023-11-06 06:39:37 +01:00
dependabot[bot] 31af1d5dc7 Bump markdown from 3.5 to 3.5.1
Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.5 to 3.5.1.
- [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.5...3.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 05:38:40 +00:00
dependabot[bot] 588bbb45b5 Bump cachetools from 5.3.1 to 5.3.2
Bumps [cachetools](https://github.com/tkem/cachetools) from 5.3.1 to 5.3.2.
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v5.3.1...v5.3.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 05:38:10 +00:00
Matthias 278c999f1f Merge pull request #9389 from freqtrade/dependabot/pip/develop/jsonschema-4.19.2
Bump jsonschema from 4.19.1 to 4.19.2
2023-11-06 06:38:09 +01:00
Matthias 825ae15109 Merge pull request #9386 from freqtrade/dependabot/pip/develop/nbconvert-7.10.0
Bump nbconvert from 7.9.2 to 7.10.0
2023-11-06 06:37:31 +01:00
Matthias 30cacc7cca Merge pull request #9383 from freqtrade/dependabot/pip/develop/fastapi-0.104.1
Bump fastapi from 0.104.0 to 0.104.1
2023-11-06 06:37:08 +01:00
dependabot[bot] 7ed037bad7 Bump tensorboard from 2.15.0 to 2.15.1
Bumps [tensorboard](https://github.com/tensorflow/tensorboard) from 2.15.0 to 2.15.1.
- [Release notes](https://github.com/tensorflow/tensorboard/releases)
- [Changelog](https://github.com/tensorflow/tensorboard/blob/2.15.1/RELEASE.md)
- [Commits](https://github.com/tensorflow/tensorboard/compare/2.15.0...2.15.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:52:46 +00:00
dependabot[bot] 77b00b2a12 Bump mkdocs-material from 9.4.7 to 9.4.8
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.7 to 9.4.8.
- [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.4.7...9.4.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:52:41 +00:00
dependabot[bot] 773bc386f7 Bump filelock from 3.12.4 to 3.13.1
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.12.4 to 3.13.1.
- [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.12.4...3.13.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:52:35 +00:00
dependabot[bot] 90dacaca09 Bump jsonschema from 4.19.1 to 4.19.2
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.19.1 to 4.19.2.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.19.1...v4.19.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:52:27 +00:00
dependabot[bot] 3689ad16b5 Bump nbconvert from 7.9.2 to 7.10.0
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.9.2 to 7.10.0.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.9.2...v7.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:52:09 +00:00
dependabot[bot] ab9954350e Bump ccxt from 4.1.31 to 4.1.39
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.31 to 4.1.39.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.31...4.1.39)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:52:05 +00:00
dependabot[bot] 533f11d9eb Bump py-find-1st from 1.1.5 to 1.1.6
Bumps [py-find-1st](https://github.com/roebel/py_find_1st) from 1.1.5 to 1.1.6.
- [Release notes](https://github.com/roebel/py_find_1st/releases)
- [Commits](https://github.com/roebel/py_find_1st/commits)

---
updated-dependencies:
- dependency-name: py-find-1st
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:51:57 +00:00
dependabot[bot] 551033a7c3 Bump fastapi from 0.104.0 to 0.104.1
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.104.0 to 0.104.1.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.104.0...0.104.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:51:55 +00:00
Matthias e003930e18 Merge pull request #9382 from freqtrade/test_reduce_time
Reduce wait for ws test
2023-11-05 18:09:50 +01:00
Matthias 2efef72ec2 Reduce wait for ws test 2023-11-05 17:17:07 +01:00
Matthias eb40fc698d Merge pull request #9381 from freqtrade/test_refactor
Test refactor
2023-11-05 17:16:35 +01:00
Matthias 751db2be78 fix: test typo mishap 2023-11-05 16:35:49 +01:00
Matthias 6ea353447e use tmp_path instead of tmpdir 2023-11-05 16:25:36 +01:00
Matthias 5a3839320d Remove further usages of Path(tmpdir) 2023-11-05 16:25:23 +01:00
Matthias 555f4b51e1 Further improvements to test setup 2023-11-05 16:23:22 +01:00
Matthias be82248e01 Remove futher usages of Path(tmpdir) 2023-11-05 16:18:28 +01:00
Matthias 7bed7801cc Further test simplifications 2023-11-05 16:15:36 +01:00
Matthias eb409de916 use tmp_path instead of Path(tmpdir) 2023-11-05 16:15:21 +01:00
Matthias 8ce39a6d75 Merge pull request #9378 from freqtrade/fix/transformer-dimensions
Bugfix: PyTorchTransformer
2023-11-04 15:51:54 +01:00
robcaulk 72dc65cb6a fix: swap tensor dimension to play nicely with pandas 2023-11-04 14:29:51 +01:00
Matthias c94c667fb1 Merge pull request #9375 from freqtrade/ci/pi_cache_talib
Update Dockerfile.armhf to use prebuilt wheels
2023-11-03 06:52:08 +01:00
Matthias 2a0175f629 Add "empty" config to disable default discord messages
closes #9372
2023-11-02 18:09:41 +01:00
Matthias cd68173440 Update Dockerfile.armhf to use prebuilt wheels 2023-11-02 07:08:36 +01:00
Matthias c920e3a031 Bump Dockerfile to 3.11.6 2023-11-02 07:05:10 +01:00
Matthias 83afc4ac7e Add pyarrow 3.11 wheel 2023-11-02 07:04:33 +01:00
Matthias 19f62649ea use "noindex" to install pyarrow on armhf 2023-11-02 07:03:22 +01:00
Matthias e4186cde9e Merge pull request #9369 from freqtrade/feat/informative_base
informative assets -> {base}
2023-11-02 06:36:55 +01:00
Matthias 61ed6aee62 Add test for new formatting 2023-11-01 11:02:50 +01:00
Matthias 051b6e9458 Update documentation 2023-11-01 11:02:03 +01:00
Matthias 44a24685ac Add support for {base} and {quote} in informative decorator 2023-11-01 11:01:55 +01:00
Matthias 1cde980c08 Extract pair_formating options 2023-11-01 10:14:19 +01:00
Matthias 05ef4f9b6f Fix forceenter - cancel dialog not working
closes #9368
2023-11-01 09:10:21 +01:00
Matthias 53f00f248e Merge pull request #9362 from freqtrade/dependabot/pip/develop/pandas-2.1.2
Bump pandas from 2.0.3 to 2.1.2
2023-10-31 14:29:09 +01:00
Matthias a9cd282500 Merge pull request #9349 from freqtrade/fix/issue_9346
Fix/issue 9346
2023-10-31 06:44:37 +01:00
Matthias 26aa14dbfc update binance leverage tiers 2023-10-30 20:10:01 +01:00
Matthias 04cd931cc8 Pass explicit stringIO type to pandas read_json 2023-10-30 19:20:59 +01:00
Matthias b8a6330c3f Improve pandas handling 2023-10-30 19:16:22 +01:00
Matthias 949c3c660b Ignore "nan" enter and exit tags
these happen if strings are assigned to individual rows without initializing the whole column
2023-10-30 19:05:15 +01:00
Matthias 9297a90d7f Use proper indexing to avoid deprecation warnings 2023-10-30 18:26:25 +01:00
Matthias b19f17fdfa Improve handling of bt results in optimize_reports 2023-10-30 18:26:01 +01:00
Matthias bbdc6c0f5c improve pandas syntax to avoid deprecation error 2023-10-30 18:11:38 +01:00
dependabot[bot] 528c65c194 Bump pandas from 2.0.3 to 2.1.2
Bumps [pandas](https://github.com/pandas-dev/pandas) from 2.0.3 to 2.1.2.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Commits](https://github.com/pandas-dev/pandas/compare/v2.0.3...v2.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 09:13:28 +00:00
Matthias a932df7320 Merge pull request #9356 from freqtrade/dependabot/pip/develop/orjson-3.9.10
Bump orjson from 3.9.9 to 3.9.10
2023-10-30 10:12:34 +01:00
Matthias 2d9b05a3ab Merge pull request #9354 from freqtrade/dependabot/pip/develop/ccxt-4.1.31
Bump ccxt from 4.1.22 to 4.1.31
2023-10-30 10:12:16 +01:00
Matthias 7cf1d25dc6 Merge pull request #9361 from freqtrade/dependabot/pip/develop/types-cachetools-5.3.0.7
Bump types-cachetools from 5.3.0.6 to 5.3.0.7
2023-10-30 10:11:57 +01:00
Matthias 19c955d505 Merge pull request #9358 from freqtrade/dependabot/pip/develop/pytest-7.4.3
Bump pytest from 7.4.2 to 7.4.3
2023-10-30 10:11:21 +01:00
Matthias bd243da47e Merge pull request #9352 from freqtrade/dependabot/pip/develop/plotly-5.18.0
Bump plotly from 5.17.0 to 5.18.0
2023-10-30 07:14:59 +01:00
Matthias bf24c3b279 BUmp cachetools types in pre-commit ocnfig 2023-10-30 07:07:51 +01:00
Matthias e9c72acff2 Merge pull request #9360 from freqtrade/dependabot/pip/develop/ast-comments-1.2.0
Bump ast-comments from 1.1.2 to 1.2.0
2023-10-30 06:55:35 +01:00
Matthias 09fd22c2f8 Merge pull request #9347 from freqtrade/ci/numpy_bump
Bump numpy on armhf devices
2023-10-30 06:48:46 +01:00
Matthias 45721ed62e Merge pull request #9355 from freqtrade/dependabot/pip/develop/xgboost-2.0.1
Bump xgboost from 2.0.0 to 2.0.1
2023-10-30 06:48:22 +01:00
dependabot[bot] 5182045cda Bump pytest from 7.4.2 to 7.4.3
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.2 to 7.4.3.
- [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/7.4.2...7.4.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 05:45:34 +00:00
Matthias 51ab8fecfc Merge pull request #9359 from freqtrade/dependabot/pip/develop/ruff-0.1.3
Bump ruff from 0.1.1 to 0.1.3
2023-10-30 06:44:45 +01:00
dependabot[bot] b36907133c Bump ccxt from 4.1.22 to 4.1.31
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.22 to 4.1.31.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/4.1.22...4.1.31)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 05:43:21 +00:00
Matthias b6d899344e Merge pull request #9357 from freqtrade/dependabot/pip/develop/mkdocs-material-9.4.7
Bump mkdocs-material from 9.4.6 to 9.4.7
2023-10-30 06:42:47 +01:00
Matthias 095f9fc1ab Merge pull request #9351 from freqtrade/dependabot/pip/develop/cryptography-41.0.5
Bump cryptography from 41.0.4 to 41.0.5
2023-10-30 06:42:32 +01:00
dependabot[bot] 0ab9eb7b05 Bump orjson from 3.9.9 to 3.9.10
Bumps [orjson](https://github.com/ijl/orjson) from 3.9.9 to 3.9.10.
- [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.9.9...3.9.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 05:42:04 +00:00
Matthias d0c582e137 Merge pull request #9353 from freqtrade/dependabot/pip/develop/python-rapidjson-1.13
Bump python-rapidjson from 1.12 to 1.13
2023-10-30 06:40:54 +01:00
dependabot[bot] d3d4464983 Bump types-cachetools from 5.3.0.6 to 5.3.0.7
Bumps [types-cachetools](https://github.com/python/typeshed) from 5.3.0.6 to 5.3.0.7.
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:37:57 +00:00
dependabot[bot] 1d0934074c Bump ast-comments from 1.1.2 to 1.2.0
Bumps [ast-comments](https://github.com/t3rn0/ast-comments) from 1.1.2 to 1.2.0.
- [Release notes](https://github.com/t3rn0/ast-comments/releases)
- [Commits](https://github.com/t3rn0/ast-comments/compare/1.1.2...1.2.0)

---
updated-dependencies:
- dependency-name: ast-comments
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:37:53 +00:00
dependabot[bot] 9382fb3be8 Bump ruff from 0.1.1 to 0.1.3
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.1 to 0.1.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/v0.1.1...v0.1.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:37:49 +00:00
dependabot[bot] 223af95da7 Bump mkdocs-material from 9.4.6 to 9.4.7
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.6 to 9.4.7.
- [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.4.6...9.4.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:37:23 +00:00
dependabot[bot] 8b68b55de4 Bump xgboost from 2.0.0 to 2.0.1
Bumps [xgboost](https://github.com/dmlc/xgboost) from 2.0.0 to 2.0.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/v2.0.0...v2.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:37:06 +00:00
dependabot[bot] 99592d1a12 Bump python-rapidjson from 1.12 to 1.13
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 1.12 to 1.13.
- [Changelog](https://github.com/python-rapidjson/python-rapidjson/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-rapidjson/python-rapidjson/compare/v1.12...v1.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:36:47 +00:00
dependabot[bot] b69f5aaac3 Bump plotly from 5.17.0 to 5.18.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.17.0 to 5.18.0.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v5.17.0...v5.18.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:36:34 +00:00
dependabot[bot] 0c1fefe6e7 Bump cryptography from 41.0.4 to 41.0.5
Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.4 to 41.0.5.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/41.0.4...41.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 03:36:27 +00:00
Matthias a049ff9371 Improve special testcase 2023-10-29 14:32:15 +01:00
Matthias 0c51e2637f Fix calculation issue for #9346
Closes #9346
2023-10-29 14:29:07 +01:00
Matthias 7492b75e1c Bump version to 2023.11-dev 2023-10-29 13:55:51 +01:00
Matthias 24dfd9b93b Add test for #9346, showing current behavior 2023-10-29 10:52:45 +01:00
Matthias 7d65b3e1b4 install libopenblas-base to base image 2023-10-29 10:48:19 +01:00
Matthias cf43427be5 armhf: Move pip install to base image 2023-10-28 10:22:54 +02:00
Matthias 7ae41be975 Remove numpy armv7l lock since wheels are now available 2023-10-28 08:30:27 +02:00
133 changed files with 4655 additions and 1353 deletions
+93 -58
View File
@@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
@@ -44,7 +44,6 @@ jobs:
- name: pip cache (linux)
uses: actions/cache@v3
if: runner.os == 'Linux'
with:
path: ~/.cache/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
@@ -55,7 +54,6 @@ jobs:
cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies/; cd ..
- name: Installation - *nix
if: runner.os == 'Linux'
run: |
python -m pip install --upgrade pip wheel
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
@@ -90,7 +88,7 @@ jobs:
- name: Backtesting (multi)
run: |
cp config_examples/config_bittrex.example.json config.json
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade new-strategy -s AwesomeStrategy
freqtrade new-strategy -s AwesomeStrategyMin --template minimal
@@ -98,7 +96,7 @@ jobs:
- name: Hyperopt
run: |
cp config_examples/config_bittrex.example.json config.json
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 6 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
@@ -122,18 +120,18 @@ jobs:
details: Freqtrade CI failed on ${{ matrix.os }}
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
build_macos:
build-macos:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ macos-latest ]
os: [ "macos-latest", "macos-13" ]
python-version: ["3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -143,14 +141,13 @@ jobs:
id: cache
with:
path: ~/dependencies/
key: ${{ runner.os }}-dependencies
key: ${{ matrix.os }}-dependencies
- name: pip cache (macOS)
uses: actions/cache@v3
if: runner.os == 'macOS'
with:
path: ~/Library/Caches/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
key: ${{ matrix.os }}-${{ matrix.python-version }}-pip
- name: TA binary *nix
if: steps.cache.outputs.cache-hit != 'true'
@@ -158,7 +155,6 @@ jobs:
cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies/; cd ..
- name: Installation - macOS
if: runner.os == 'macOS'
run: |
# brew update
# TODO: Should be the brew upgrade
@@ -166,16 +162,21 @@ jobs:
# 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 hdf5 c-blosc
brew install hdf5 c-blosc libomp
python -m pip install --upgrade pip wheel
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
export TA_LIBRARY_PATH=${HOME}/dependencies/lib
@@ -200,14 +201,14 @@ jobs:
- name: Backtesting
run: |
cp config_examples/config_bittrex.example.json config.json
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade new-strategy -s AwesomeStrategyAdv --template advanced
freqtrade backtesting --datadir tests/testdata --strategy AwesomeStrategyAdv
- name: Hyperopt
run: |
cp config_examples/config_bittrex.example.json config.json
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
@@ -231,7 +232,7 @@ jobs:
details: Test Succeeded!
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
build_windows:
build-windows:
runs-on: ${{ matrix.os }}
strategy:
@@ -243,7 +244,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
@@ -275,13 +276,13 @@ jobs:
- name: Backtesting
run: |
cp config_examples/config_bittrex.example.json config.json
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt
run: |
cp config_examples/config_bittrex.example.json config.json
cp tests/testdata/config.tests.json config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
@@ -301,13 +302,13 @@ jobs:
details: Test Failed
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
mypy_version_check:
mypy-version-check:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.10"
@@ -321,12 +322,12 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- uses: pre-commit/action@v3.0.0
docs_check:
docs-check:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
@@ -336,7 +337,7 @@ jobs:
./tests/test_docs.sh
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
@@ -362,9 +363,9 @@ jobs:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.11"
- name: Cache_dependencies
uses: actions/cache@v3
@@ -375,7 +376,6 @@ jobs:
- name: pip cache (linux)
uses: actions/cache@v3
if: runner.os == 'Linux'
with:
path: ~/.cache/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
@@ -386,7 +386,6 @@ jobs:
cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies/; cd ..
- name: Installation - *nix
if: runner.os == 'Linux'
run: |
python -m pip install --upgrade pip wheel
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
@@ -399,17 +398,17 @@ jobs:
env:
CI_WEB_PROXY: http://152.67.78.211:13128
run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc --longrun
pytest --random-order --longrun --durations 20 -n auto --dist loadscope
# Notify only once - when CI completes (and after deploy) in case it's successfull
notify-complete:
needs: [
build_linux,
build_macos,
build_windows,
docs_check,
mypy_version_check,
build-macos,
build-windows,
docs-check,
mypy-version-check,
pre-commit,
build_linux_online
]
@@ -436,8 +435,63 @@ jobs:
details: Test Completed!
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
deploy:
needs: [ build_linux, build_macos, build_windows, docs_check, mypy_version_check, pre-commit ]
build:
name: "Build"
needs: [ build_linux, build-macos, build-windows, docs-check, mypy-version-check, pre-commit ]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Build distribution
run: |
pip install -U build
python -m build --sdist --wheel
- name: Upload artifacts 📦
uses: actions/upload-artifact@v4
with:
name: freqtrade-build
path: |
dist
retention-days: 10
deploy-pypi:
name: "Deploy to PyPI"
needs: [ build ]
runs-on: ubuntu-22.04
if: (github.event_name == 'release')
environment:
name: release
url: https://pypi.org/p/freqtrade
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- name: Download artifact 📦
uses: actions/download-artifact@v4
with:
name: freqtrade-build
path: dist
- name: Publish to PyPI (Test)
uses: pypa/gh-action-pypi-publish@v1.8.11
with:
repository-url: https://test.pypi.org/legacy/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.8.11
deploy-docker:
needs: [ build_linux, build-macos, build-windows, docs-check, mypy-version-check, pre-commit ]
runs-on: ubuntu-22.04
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade'
@@ -446,7 +500,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
@@ -455,26 +509,6 @@ jobs:
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
id: extract_branch
- name: Build distribution
run: |
pip install -U setuptools wheel
python setup.py sdist bdist_wheel
- name: Publish to PyPI (Test)
uses: pypa/gh-action-pypi-publish@v1.8.10
if: (github.event_name == 'release')
with:
user: __token__
password: ${{ secrets.pypi_test_password }}
repository_url: https://test.pypi.org/legacy/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.8.10
if: (github.event_name == 'release')
with:
user: __token__
password: ${{ secrets.pypi_password }}
- name: Dockerhub login
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
@@ -506,10 +540,11 @@ jobs:
run: |
build_helpers/publish_docker_multi.sh
deploy_arm:
deploy-arm:
name: "Deploy Docker"
permissions:
packages: write
needs: [ deploy ]
needs: [ deploy-docker ]
# Only run on 64bit machines
runs-on: [self-hosted, linux, ARM64]
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade'
+44
View File
@@ -0,0 +1,44 @@
name: Pre-commit auto-update
on:
# every day at midnight
schedule:
- cron: "0 3 * * 2"
# on demand
workflow_dispatch:
permissions:
contents: read
jobs:
auto-update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install pre-commit
run: pip install pre-commit
- name: Run auto-update
run: pre-commit autoupdate
- name: Run pre-commit
run: pre-commit run --all-files
- uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.REPO_SCOPED_TOKEN }}
add-paths: .pre-commit-config.yaml
labels: |
Tech maintenance
branch: update/pre-commit-hooks
title: Update pre-commit hooks
commit-message: "chore: update pre-commit hooks"
committer: Freqtrade Bot <noreply@github.com>
body: Update versions of pre-commit hooks to latest version.
delete-branch: true
-1
View File
@@ -111,7 +111,6 @@ target/
#exceptions
!*.gitkeep
!config_examples/config_binance.example.json
!config_examples/config_bittrex.example.json
!config_examples/config_full.example.json
!config_examples/config_kraken.example.json
!config_examples/config_freqai.example.json
+8 -7
View File
@@ -2,27 +2,28 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pycqa/flake8
rev: "6.0.0"
rev: "6.1.0"
hooks:
- id: flake8
additional_dependencies: [Flake8-pyproject]
# stages: [push]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.5.1"
rev: "v1.8.0"
hooks:
- id: mypy
exclude: build_helpers
additional_dependencies:
- types-cachetools==5.3.0.6
- types-cachetools==5.3.0.7
- types-filelock==3.2.7
- types-requests==2.31.0.10
- types-tabulate==0.9.0.3
- types-python-dateutil==2.8.19.14
- SQLAlchemy==2.0.22
- SQLAlchemy==2.0.23
# stages: [push]
- repo: https://github.com/pycqa/isort
rev: "5.12.0"
rev: "5.13.2"
hooks:
- id: isort
name: isort (python)
@@ -30,12 +31,12 @@ repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
# Ruff version.
rev: 'v0.1.1'
rev: 'v0.1.9'
hooks:
- id: ruff
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: end-of-file-fixer
exclude: |
+1 -1
View File
@@ -125,7 +125,7 @@ Exceptions:
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. 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.
+1 -1
View File
@@ -1,4 +1,4 @@
FROM python:3.11.5-slim-bullseye as base
FROM python:3.11.6-slim-bookworm as base
# Setup env
ENV LANG C.UTF-8
+2
View File
@@ -5,3 +5,5 @@ recursive-include freqtrade/templates/ *.j2 *.ipynb
include freqtrade/exchange/binance_leverage_tiers.json
include freqtrade/rpc/api_server/ui/fallback_file.html
include freqtrade/rpc/api_server/ui/favicon.ico
prune tests
+1 -1
View File
@@ -28,7 +28,7 @@ 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] [Bittrex](https://bittrex.com/)
- [X] [Bitmart](https://bitmart.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Huobi](http://huobi.com/)
- [X] [Kraken](https://kraken.com/)
+1 -1
View File
@@ -54,7 +54,7 @@ docker tag freqtrade:$TAG_FREQAI_ARM ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker tag freqtrade:$TAG_FREQAI_RL_ARM ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM
# Run backtest
docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG_ARM} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
docker run --rm -v $(pwd)/tests/testdata/config.tests.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG_ARM} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
if [ $? -ne 0 ]; then
echo "failed running backtest"
+1 -1
View File
@@ -67,7 +67,7 @@ docker tag freqtrade:$TAG_FREQAI ${CACHE_IMAGE}:$TAG_FREQAI
docker tag freqtrade:$TAG_FREQAI_RL ${CACHE_IMAGE}:$TAG_FREQAI_RL
# Run backtest
docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
docker run --rm -v $(pwd)/tests/testdata/config.tests.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
if [ $? -ne 0 ]; then
echo "failed running backtest"
+16 -16
View File
@@ -1,6 +1,6 @@
{
"max_open_trades": 3,
"stake_currency": "BTC",
"stake_currency": "USDT",
"stake_amount": 0.05,
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD",
@@ -36,21 +36,21 @@
"ccxt_async_config": {
},
"pair_whitelist": [
"ALGO/BTC",
"ATOM/BTC",
"BAT/BTC",
"BCH/BTC",
"BRD/BTC",
"EOS/BTC",
"ETH/BTC",
"IOTA/BTC",
"LINK/BTC",
"LTC/BTC",
"NEO/BTC",
"NXS/BTC",
"XMR/BTC",
"XRP/BTC",
"XTZ/BTC"
"ALGO/USDT",
"ATOM/USDT",
"BAT/USDT",
"BCH/USDT",
"BRD/USDT",
"EOS/USDT",
"ETH/USDT",
"IOTA/USDT",
"LINK/USDT",
"LTC/USDT",
"NEO/USDT",
"NXS/USDT",
"XMR/USDT",
"XRP/USDT",
"XTZ/USDT"
],
"pair_blacklist": [
"BNB/.*"
+7 -10
View File
@@ -1,4 +1,4 @@
FROM python:3.9.16-slim-bullseye as base
FROM python:3.11.6-slim-bookworm as base
# Setup env
ENV LANG C.UTF-8
@@ -11,34 +11,31 @@ ENV FT_APP_ENV="docker"
# Prepare environment
RUN mkdir /freqtrade \
&& apt-get update \
&& apt-get -y install sudo libatlas3-base curl sqlite3 libhdf5-dev libutf8proc-dev libsnappy-dev \
&& apt-get -y install sudo libatlas3-base libopenblas-dev curl sqlite3 libhdf5-dev libutf8proc-dev libsnappy-dev \
&& apt-get clean \
&& useradd -u 1000 -G sudo -U -m ftuser \
&& chown ftuser:ftuser /freqtrade \
# Allow sudoers
&& echo "ftuser ALL=(ALL) NOPASSWD: /bin/chown" >> /etc/sudoers
&& echo "ftuser ALL=(ALL) NOPASSWD: /bin/chown" >> /etc/sudoers \
&& pip install --upgrade pip
WORKDIR /freqtrade
# Install dependencies
FROM base as python-deps
RUN apt-get update \
&& apt-get -y install build-essential libssl-dev libffi-dev libopenblas-dev libgfortran5 pkg-config cmake gcc \
&& apt-get -y install build-essential libssl-dev libffi-dev libgfortran5 pkg-config cmake gcc \
&& apt-get clean \
&& pip install --upgrade pip \
&& echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > /etc/pip.conf
# Install TA-lib
COPY build_helpers/* /tmp/
RUN cd /tmp && /tmp/install_ta-lib.sh && rm -r /tmp/*ta-lib*
ENV LD_LIBRARY_PATH /usr/local/lib
# Install dependencies
COPY --chown=ftuser:ftuser requirements.txt /freqtrade/
USER ftuser
RUN pip install --user --no-cache-dir numpy==1.25.2 \
&& pip install --user /tmp/pyarrow-*.whl \
&& pip install --user --no-build-isolation TA-Lib==0.4.28 \
RUN pip install --user --no-cache-dir numpy \
&& pip install --user --no-index --find-links /tmp/ pyarrow TA-Lib==0.4.28 \
&& pip install --user --no-cache-dir -r requirements.txt
# Copy dependencies to runtime-image
+4 -4
View File
@@ -170,11 +170,11 @@ freqtrade backtesting --strategy AwesomeStrategy --dry-run-wallet 1000
Using a different on-disk historical candle (OHLCV) data source
Assume you downloaded the history data from the Bittrex exchange and kept it in the `user_data/data/bittrex-20180101` directory.
Assume you downloaded the history data from the Binance exchange and kept it in the `user_data/data/binance-20180101` directory.
You can then use this data for backtesting as follows:
```bash
freqtrade backtesting --strategy AwesomeStrategy --datadir user_data/data/bittrex-20180101
freqtrade backtesting --strategy AwesomeStrategy --datadir user_data/data/binance-20180101
```
---
@@ -618,13 +618,13 @@ To compare multiple strategies, a list of Strategies can be provided to backtest
This is limited to 1 timeframe value per run. However, data is only loaded once from disk so if you have multiple
strategies you'd like to compare, this will give a nice runtime boost.
All listed Strategies need to be in the same directory.
All listed Strategies need to be in the same directory, unless also `--recursive-strategy-search` is specified, where sub-directories within the strategy directory are also considered.
``` bash
freqtrade backtesting --timerange 20180401-20180410 --timeframe 5m --strategy-list Strategy001 Strategy002 --export trades
```
This will save the results to `user_data/backtest_results/backtest-result-<strategy>.json`, injecting the strategy-name into the target filename.
This will save the results to `user_data/backtest_results/backtest-result-<datetime>.json`, including results for both `Strategy001` and `Strategy002`.
There will be an additional table comparing win/losses of the different strategies (identical to the "Total" row in the first table).
Detailed output for all strategies one after the other will be available, so make sure to scroll up to see the details per strategy.
+3 -3
View File
@@ -321,7 +321,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr
To fully utilize compounding profits when using multiple bots on the same exchange account, you'll want to limit each bot to a certain starting balance.
This can be accomplished by setting `available_capital` to the desired starting balance.
Assuming your account has 10.000 USDT and you want to run 2 different strategies on this exchange.
Assuming your account has 10000 USDT and you want to run 2 different strategies on this exchange.
You'd set `available_capital=5000` - granting each bot an initial capital of 5000 USDT.
The bot will then split this starting balance equally into `max_open_trades` buckets.
Profitable trades will result in increased stake-sizes for this bot - without affecting the stake-sizes of the other bot.
@@ -594,7 +594,7 @@ creating trades on the exchange.
```json
"exchange": {
"name": "bittrex",
"name": "binance",
"key": "key",
"secret": "secret",
...
@@ -644,7 +644,7 @@ API Keys are usually only required for live trading (trading for real money, bot
```json
{
"exchange": {
"name": "bittrex",
"name": "binance",
"key": "af8ddd35195e9dc500b9a6f799f6f5c93d89193b",
"secret": "08a9dc6db3d7b53e1acebd9275677f4b0a04f1a5",
//"password": "", // Optional, not needed by all exchanges)
+5 -4
View File
@@ -318,6 +318,7 @@ Additional tests / steps to complete:
* Check if balance shows correctly (*)
* Create market order (*)
* Create limit order (*)
* Cancel order (*)
* Complete trade (enter + exit) (*)
* Compare result calculation between exchange and bot
* Ensure fees are applied correctly (check the database against the exchange)
@@ -418,6 +419,9 @@ This part of the documentation is aimed at maintainers, and shows how to create
### Create release branch
!!! Note
Make sure that the `stable` branch is up-to-date!
First, pick a commit that's about one week old (to not include latest additions to releases).
``` bash
@@ -430,14 +434,11 @@ Determine if crucial bugfixes have been made between this commit and the current
* Merge the release branch (stable) into this branch.
* Edit `freqtrade/__init__.py` and add the version matching the current date (for example `2019.7` for July 2019). Minor versions can be `2019.7.1` should we need to do a second release that month. Version numbers must follow allowed versions from PEP0440 to avoid failures pushing to pypi.
* Commit this part.
* push that branch to the remote and create a PR against the stable branch.
* Push that branch to the remote and create a PR against the **stable branch**.
* Update develop version to next version following the pattern `2019.8-dev`.
### Create changelog from git commits
!!! Note
Make sure that the `stable` branch is up-to-date!
``` bash
# Needs to be done before merging / pulling that branch.
git log --oneline --no-decorate --no-merges stable..new_release
+18 -42
View File
@@ -181,48 +181,6 @@ freqtrade download-data --exchange kraken --dl-trades -p BTC/EUR BCH/EUR
Please pay attention that rateLimit configuration entry holds delay in milliseconds between requests, NOT requests\sec rate.
So, in order to mitigate Kraken API "Rate limit exceeded" exception, this configuration should be increased, NOT decreased.
## Bittrex
### Order types
Bittrex does not support market orders. If you have a message at the bot startup about this, you should change order type values set in your configuration and/or in the strategy from `"market"` to `"limit"`. See some more details on this [here in the FAQ](faq.md#im-getting-the-exchange-bittrex-does-not-support-market-orders-message-and-cannot-run-my-strategy).
Bittrex also does not support `VolumePairlist` due to limited / split API constellation at the moment.
Please use `StaticPairlist`. Other pairlists (other than `VolumePairlist`) should not be affected.
### Volume pairlist
Bittrex does not support the direct usage of VolumePairList. This can however be worked around by using the advanced mode with `lookback_days: 1` (or more), which will emulate 24h volume.
Read more in the [pairlist documentation](plugins.md#volumepairlist-advanced-mode).
### Restricted markets
Bittrex split its exchange into US and International versions.
The International version has more pairs available, however the API always returns all pairs, so there is currently no automated way to detect if you're affected by the restriction.
If you have restricted pairs in your whitelist, you'll get a warning message in the log on Freqtrade startup for each restricted pair.
The warning message will look similar to the following:
``` output
[...] Message: bittrex {"success":false,"message":"RESTRICTED_MARKET","result":null,"explanation":null}"
```
If you're an "International" customer on the Bittrex exchange, then this warning will probably not impact you.
If you're a US customer, the bot will fail to create orders for these pairs, and you should remove them from your whitelist.
You can get a list of restricted markets by using the following snippet:
``` python
import ccxt
ct = ccxt.bittrex()
lm = ct.load_markets()
res = [p for p, x in lm.items() if 'US' in x['info']['prohibitedIn']]
print(res)
```
## Kucoin
Kucoin requires a passphrase for each api key, you will therefore need to add this key into the configuration so your exchange section looks as follows:
@@ -302,6 +260,24 @@ We do strongly recommend to limit all API keys to the IP you're going to use it
Bybit (futures only) supports `stoploss_on_exchange` and uses `stop-loss-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange.
On futures, Bybit supports both `stop-limit` as well as `stop-market` orders. You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide which type to use.
## Bitmart
Bitmart requires the API key Memo (the name you give the API key) to go along with the exchange key and secret.
It's therefore required to pass the UID as well.
```json
"exchange": {
"name": "bitmart",
"uid": "your_bitmart_api_key_memo",
"secret": "your_exchange_secret",
"password": "your_exchange_api_key_password",
// ...
}
```
!!! Warning "Necessary Verification"
Bitmart requires Verification Lvl2 to successfully trade on the spot market through the API - even though trading via UI works just fine with just Lvl1 verification.
## All exchanges
Should you experience constant errors with Nonce (like `InvalidNonce`), it is best to regenerate the API keys. Resetting Nonce is difficult and it's usually easier to regenerate the API keys.
+1 -7
View File
@@ -128,15 +128,9 @@ This warning can point to one of the below problems:
* Barely traded pair -> Check the pair on the exchange webpage, look at the timeframe your strategy uses. If the pair does not have any volume in some candles (usually visualized with a "volume 0" bar, and a "_" as candle), this pair did not have any trades in this timeframe. These pairs should ideally be avoided, as they can cause problems with order-filling.
* API problem -> API returns wrong data (this only here for completeness, and should not happen with supported exchanges).
### I'm getting the "RESTRICTED_MARKET" message in the log
Currently known to happen for US Bittrex users.
Read [the Bittrex section about restricted markets](exchanges.md#restricted-markets) for more information.
### I'm getting the "Exchange XXX does not support market orders." message and cannot run my strategy
As the message says, your exchange does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Your strategy was probably written with other exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of the exchanges supporting market orders (but not for Bittrex and Gate.io).
As the message says, your exchange does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Your strategy was probably written with other exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of the exchanges supporting market orders (but not for Gate.io).
To fix this, redefine order types in the strategy to use "limit" instead of "market":
+1 -1
View File
@@ -7,7 +7,7 @@ Low level feature engineering is performed in the user strategy within a set of
| Function | Description |
|---------------|-------------|
| `feature_engineering_expand_all()` | This optional function will automatically expand the defined features on the config defined `indicator_periods_candles`, `include_timeframes`, `include_shifted_candles`, and `include_corr_pairs`.
| `feature_engineering_expand_basic()` | This optional function will automatically expand the defined features on the config defined `include_timeframes`, `include_shifted_candles`, and `include_corr_pairs`. Note: this function does *not* expand across `include_periods_candles`.
| `feature_engineering_expand_basic()` | This optional function will automatically expand the defined features on the config defined `include_timeframes`, `include_shifted_candles`, and `include_corr_pairs`. Note: this function does *not* expand across `indicator_periods_candles`.
| `feature_engineering_standard()` | This optional function will be called once with the dataframe of the base timeframe. This is the final function to be called, which means that the dataframe entering this function will contain all the features and columns from the base asset created by the other `feature_engineering_expand` functions. This function is a good place to do custom exotic feature extractions (e.g. tsfresh). This function is also a good place for any feature that should not be auto-expanded upon (e.g., day of the week).
| `set_freqai_targets()` | Required function to set the targets for the model. All targets must be prepended with `&` to be recognized by the FreqAI internals.
-1
View File
@@ -74,7 +74,6 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| | **Reinforcement Learning Parameters within the `freqai.rl_config` sub dictionary**
| `rl_config` | A dictionary containing the control parameters for a Reinforcement Learning model. <br> **Datatype:** Dictionary.
| `train_cycles` | Training time steps will be set based on the `train_cycles * number of training data points. <br> **Datatype:** Integer.
| `cpu_count` | Number of processors to dedicate to the Reinforcement Learning training process. <br> **Datatype:** int.
| `max_trade_duration_candles`| Guides the agent training to keep trades below desired length. Example usage shown in `prediction_models/ReinforcementLearner.py` within the customizable `calculate_reward()` function. <br> **Datatype:** int.
| `model_type` | Model string from stable_baselines3 or SBcontrib. Available strings include: `'TRPO', 'ARS', 'RecurrentPPO', 'MaskablePPO', 'PPO', 'A2C', 'DQN'`. User should ensure that `model_training_parameters` match those available to the corresponding stable_baselines3 model by visiting their documentaiton. [PPO doc](https://stable-baselines3.readthedocs.io/en/master/modules/ppo.html) (external website) <br> **Datatype:** string.
| `policy_type` | One of the available policy types from stable_baselines3 <br> **Datatype:** string.
+9 -5
View File
@@ -337,11 +337,15 @@ There are four parameter types each suited for different purposes.
* `CategoricalParameter` - defines a parameter with a predetermined number of choices.
* `BooleanParameter` - Shorthand for `CategoricalParameter([True, False])` - great for "enable" parameters.
!!! Tip "Disabling parameter optimization"
Each parameter takes two boolean parameters:
* `load` - when set to `False` it will not load values configured in `buy_params` and `sell_params`.
* `optimize` - when set to `False` parameter will not be included in optimization process.
Use these parameters to quickly prototype various ideas.
### Parameter options
There are two parameter options that can help you to quickly test various ideas:
* `optimize` - when set to `False`, the parameter will not be included in optimization process. (Default: True)
* `load` - when set to `False`, results of a previous hyperopt run (in `buy_params` and `sell_params` either in your strategy or the JSON output file) will not be used as the starting value for subsequent hyperopts. The default value specified in the parameter will be used instead. (Default: True)
!!! Tip "Effects of `load=False` on backtesting"
Be aware that setting the `load` option to `False` will mean backtesting will also use the default value specified in the parameter and *not* the value found through hyperoptimisation.
!!! Warning
Hyperoptable parameters cannot be used in `populate_indicators` - as hyperopt does not recalculate indicators for each epoch, so the starting value would be used in this case.
+2 -2
View File
@@ -112,8 +112,8 @@ For convenience `lookback_days` can be specified, which will imply that 1d candl
!!! Warning "Performance implications when using lookback range"
If used in first position in combination with lookback, the computation of the range based volume can be time and resource consuming, as it downloads candles for all tradable pairs. Hence it's highly advised to use the standard approach with `VolumeFilter` to narrow the pairlist down for further range volume calculation.
??? Tip "Unsupported exchanges (Bittrex, Gemini)"
On some exchanges (like Bittrex and Gemini), regular VolumePairList does not work as the api does not natively provide 24h volume. This can be worked around by using candle data to build the volume.
??? Tip "Unsupported exchanges"
On some exchanges (like Gemini), regular VolumePairList does not work as the api does not natively provide 24h volume. This can be worked around by using candle data to build the volume.
To roughly simulate 24h volume, you can use the following configuration.
Please note that These pairlists will only refresh once per day.
+1 -1
View File
@@ -40,7 +40,7 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is
Please read the [exchange specific notes](exchanges.md) to learn about eventual, special configurations needed for each exchange.
- [X] [Binance](https://www.binance.com/)
- [X] [Bittrex](https://bittrex.com/)
- [X] [Bitmart](https://bitmart.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Huobi](http://huobi.com/)
- [X] [Kraken](https://kraken.com/)
+3 -3
View File
@@ -1,6 +1,6 @@
markdown==3.5
markdown==3.5.1
mkdocs==1.5.3
mkdocs-material==9.4.6
mkdocs-material==9.5.3
mdx_truly_sane_lists==1.3
pymdown-extensions==10.3.1
pymdown-extensions==10.5
jinja2==3.1.2
+6 -3
View File
@@ -134,13 +134,16 @@ python3 scripts/rest_client.py --config rest_config.json <command> [optional par
| `reload_config` | Reloads the configuration file.
| `trades` | List last trades. Limited to 500 trades per call.
| `trade/<tradeid>` | Get specific trade.
| `trade/<tradeid>` | DELETE - Remove trade from the database. Tries to close open orders. Requires manual handling of this trade on the exchange.
| `trade/<tradeid>/open-order` | DELETE - Cancel open order for this trade.
| `trade/<tradeid>/reload` | GET - Reload a trade from the Exchange. Only works in live, and can potentially help recover a trade that was manually sold on the exchange.
| `trades/<tradeid>` | DELETE - Remove trade from the database. Tries to close open orders. Requires manual handling of this trade on the exchange.
| `trades/<tradeid>/open-order` | DELETE - Cancel open order for this trade.
| `trades/<tradeid>/reload` | GET - Reload a trade from the Exchange. Only works in live, and can potentially help recover a trade that was manually sold on the exchange.
| `show_config` | Shows part of the current configuration with relevant settings to operation.
| `logs` | Shows last log messages.
| `status` | Lists all open trades.
| `count` | Displays number of trades used and available.
| `entries [pair]` | Shows profit statistics for each enter tags for given pair (or all pairs if pair isn't given). Pair is optional.
| `exits [pair]` | Shows profit statistics for each exit reasons for given pair (or all pairs if pair isn't given). Pair is optional.
| `mix_tags [pair]` | 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.
| `locks` | Displays currently locked pairs.
| `delete_lock <lock_id>` | Deletes (disables) the lock by id.
| `profit` | Display a summary of your profit/loss from close trades and some stats about your performance.
+7 -5
View File
@@ -489,7 +489,7 @@ The helper function `stoploss_from_absolute()` can be used to convert from an ab
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
trade_date = timeframe_to_prev_date(self.timeframe, trade.open_date_utc)
candle = dataframe.iloc[-1].squeeze()
sign = 1 if trade.is_short else -1
side = 1 if trade.is_short else -1
return stoploss_from_absolute(current_rate + (side * candle['atr'] * 2),
current_rate, is_short=trade.is_short,
leverage=trade.leverage)
@@ -760,9 +760,9 @@ The `position_adjustment_enable` strategy property enables the usage of `adjust_
For performance reasons, it's disabled by default and freqtrade will show a warning message on startup if enabled.
`adjust_trade_position()` can be used to perform additional orders, for example to manage risk with DCA (Dollar Cost Averaging) or to increase or decrease positions.
`max_entry_position_adjustment` property is used to limit the number of additional buys per trade (on top of the first buy) that the bot can execute. By default, the value is -1 which means the bot have no limit on number of adjustment buys.
`max_entry_position_adjustment` property is used to limit the number of additional entries per trade (on top of the first entry order) that the bot can execute. By default, the value is -1 which means the bot have no limit on number of adjustment entries.
The strategy is expected to return a stake_amount (in stake currency) between `min_stake` and `max_stake` if and when an additional buy order should be made (position is increased).
The strategy is expected to return a stake_amount (in stake currency) between `min_stake` and `max_stake` if and when an additional entry order should be made (position is increased -> buy order for long trades, sell order for short trades).
If there are not enough funds in the wallet (the return value is above `max_stake`) then the signal will be ignored.
Additional orders also result in additional fees and those orders don't count towards `max_open_trades`.
@@ -770,9 +770,11 @@ This callback is **not** called when there is an open order (either buy or sell)
`adjust_trade_position()` is called very frequently for the duration of a trade, so you must keep your implementation as performant as possible.
Additional Buys are ignored once you have reached the maximum amount of extra buys that you have set on `max_entry_position_adjustment`, but the callback is called anyway looking for partial exits.
Additional entries are ignored once you have reached the maximum amount of extra entries that you have set on `max_entry_position_adjustment`, but the callback is called anyway looking for partial exits.
Position adjustments will always be applied in the direction of the trade, so a positive value will always increase your position (negative values will decrease your position), no matter if it's a long or short trade. Modifications to leverage are not possible, and the stake-amount is assumed to be before applying leverage.
Position adjustments will always be applied in the direction of the trade, so a positive value will always increase your position (negative values will decrease your position), no matter if it's a long or short trade.
Modifications to leverage are not possible, and the stake-amount returned is assumed to be before applying leverage.
!!! Note "About stake size"
Using fixed stake size means it will be the amount used for the first order, just like without position adjustment.
+6 -5
View File
@@ -173,7 +173,7 @@ You can use [recursive-analysis](recursive-analysis.md) to check and find the co
In this example strategy, this should be set to 400 (`startup_candle_count = 400`), since the minimum needed history for ema100 calculation to make sure the value is correct is 400 candles.
``` python
dataframe['ema100'] = ta.EMA(dataframe, timeperiod=400)
dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)
```
By letting the bot know how much history is needed, backtest trades can start at the specified timerange during backtesting and hyperopt.
@@ -486,17 +486,18 @@ for more information.
:param timeframe: Informative timeframe. Must always be equal or higher than strategy timeframe.
:param asset: Informative asset, for example BTC, BTC/USDT, ETH/BTC. Do not specify to use
current pair.
current pair. Also supports limited pair format strings (see below)
:param fmt: Column format (str) or column formatter (callable(name, asset, timeframe)). When not
specified, defaults to:
* {base}_{quote}_{column}_{timeframe} if asset is specified.
* {base}_{quote}_{column}_{timeframe} if asset is specified.
* {column}_{timeframe} if asset is not specified.
Format string supports these format variables:
* {asset} - full name of the asset, for example 'BTC/USDT'.
Pair format supports these format variables:
* {base} - base currency in lower case, for example 'eth'.
* {BASE} - same as {base}, except in upper case.
* {quote} - quote currency in lower case, for example 'usdt'.
* {QUOTE} - same as {quote}, except in upper case.
Format string additionally supports this variables.
* {asset} - full name of the asset, for example 'BTC/USDT'.
* {column} - name of dataframe column.
* {timeframe} - timeframe of informative dataframe.
:param ffill: ffill dataframe after merging informative pair.
+1 -1
View File
@@ -570,7 +570,7 @@ def populate_any_indicators(
```
1. Features - Move to `feature_engineering_expand_all`
2. Basic features, not expanded across `include_periods_candles` - move to`feature_engineering_expand_basic()`.
2. Basic features, not expanded across `indicator_periods_candles` - move to`feature_engineering_expand_basic()`.
3. Standard features which should not be expanded - move to `feature_engineering_standard()`.
4. Targets - Move this part to `set_freqai_targets()`.
+1
View File
@@ -175,6 +175,7 @@ official commands. You can ask at any moment for help with `/help`.
| `/status` | Lists all open trades
| `/status <trade_id>` | Lists one or more specific trade. Separate multiple <trade_id> with a blank space.
| `/status table` | List all open trades in a table format. Pending buy orders are marked with an asterisk (*) Pending sell orders are marked with a double asterisk (**)
| `/order <trade_id>` | Lists orders of one or more specific trade. Separate multiple <trade_id> with a blank space.
| `/trades [limit]` | List all recently closed trades in a table format.
| `/count` | Displays number of trades used and available
| `/locks` | Show currently locked pairs.
+30 -26
View File
@@ -242,7 +242,6 @@ bitkk True missing opt: fetchMyTrades
bitmart True
bitmax True missing opt: fetchMyTrades
bitpanda True
bittrex True
bitvavo True
bitz True missing opt: fetchMyTrades
btcalpha True missing opt: fetchTicker, fetchTickers
@@ -324,7 +323,6 @@ bitpanda True
bitso False missing: fetchOHLCV
bitstamp True missing opt: fetchTickers
bitstamp1 False missing: fetchOrder, fetchOHLCV
bittrex True
bitvavo True
bitz True missing opt: fetchMyTrades
bl3p False missing: fetchOrder, fetchOHLCV
@@ -427,25 +425,33 @@ zb True missing opt: fetchMyTrades
Use the `list-timeframes` subcommand to see the list of timeframes available for the exchange.
```
usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-1]
usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[--exchange EXCHANGE] [-1]
optional arguments:
options:
-h, --help show this help message and exit
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided.
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
-1, --one-column Print output in one column.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details.
--logfile FILE, --log-file FILE
Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-`
to read config from stdin.
-d PATH, --datadir PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH, --data-dir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
* Example: see the timeframes for the 'binance' exchange, set in the configuration file:
@@ -479,20 +485,17 @@ usage: freqtrade list-markets [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a]
[--trading-mode {spot,margin,futures}]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
[-a] [--trading-mode {spot,margin,futures}]
usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a]
[--trading-mode {spot,margin,futures}]
optional arguments:
options:
-h, --help show this help message and exit
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no
config is provided.
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
--print-list Print list of pairs or market symbols. By default data
is printed in the tabular format.
--print-json Print list of pairs or market symbols in JSON format.
@@ -504,20 +507,22 @@ optional arguments:
Specify quote currency(-ies). Space-separated list.
-a, --all Print all pairs or market symbols. By default only
active ones are shown.
--trading-mode {spot,margin,futures}
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
Select Trading mode
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
--logfile FILE, --log-file FILE
Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH, --data-dir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
@@ -532,7 +537,7 @@ Pairs/markets are sorted by its symbol string in the printed output.
### Examples
* Print the list of active pairs with quote currency USD on exchange, specified in the default
configuration file (i.e. pairs on the "Bittrex" exchange) in JSON format:
configuration file (i.e. pairs on the "Binance" exchange) in JSON format:
```
$ freqtrade list-pairs --quote USD --print-json
@@ -564,7 +569,7 @@ usage: freqtrade test-pairlist [-h] [--userdir PATH] [-v] [-c PATH]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
[-1] [--print-json] [--exchange EXCHANGE]
optional arguments:
options:
-h, --help show this help message and exit
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
@@ -578,8 +583,7 @@ optional arguments:
Specify quote currency(-ies). Space-separated list.
-1, --one-column Print output in one column.
--print-json Print list of pairs or market symbols in JSON format.
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no
config is provided.
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
```
+1
View File
@@ -302,6 +302,7 @@ You can configure this as follows:
```
The above represents the default (`exit_fill` and `entry_fill` are optional and will default to the above configuration) - modifications are obviously possible.
To disable either of the two default values (`entry_fill` / `exit_fill`), you can assign them an empty array (`exit_fill: []`).
Available fields correspond to the fields for webhooks and are documented in the corresponding webhook sections.
+1 -1
View File
@@ -1,5 +1,5 @@
""" Freqtrade bot """
__version__ = '2023.10'
__version__ = '2023.12'
if 'dev' in __version__:
from pathlib import Path
@@ -108,7 +108,6 @@ def ask_user_config() -> Dict[str, Any]:
"choices": [
"binance",
"binanceus",
"bittrex",
"gate",
"huobi",
"kraken",
+4 -4
View File
@@ -67,7 +67,7 @@ def validate_config_schema(conf: Dict[str, Any], preliminary: bool = False) -> D
)
def validate_config_consistency(conf: Dict[str, Any], preliminary: bool = False) -> None:
def validate_config_consistency(conf: Dict[str, Any], *, preliminary: bool = False) -> None:
"""
Validate the configuration consistency.
Should be ran after loading both configuration and strategy,
@@ -86,7 +86,7 @@ def validate_config_consistency(conf: Dict[str, Any], preliminary: bool = False)
_validate_ask_orderbook(conf)
_validate_freqai_hyperopt(conf)
_validate_freqai_backtest(conf)
_validate_freqai_include_timeframes(conf)
_validate_freqai_include_timeframes(conf, preliminary=preliminary)
_validate_consumers(conf)
validate_migrated_strategy_settings(conf)
@@ -335,7 +335,7 @@ def _validate_freqai_hyperopt(conf: Dict[str, Any]) -> None:
'Using analyze-per-epoch parameter is not supported with a FreqAI strategy.')
def _validate_freqai_include_timeframes(conf: Dict[str, Any]) -> None:
def _validate_freqai_include_timeframes(conf: Dict[str, Any], preliminary: bool) -> None:
freqai_enabled = conf.get('freqai', {}).get('enabled', False)
if freqai_enabled:
main_tf = conf.get('timeframe', '5m')
@@ -355,7 +355,7 @@ def _validate_freqai_include_timeframes(conf: Dict[str, Any]) -> None:
f"`include_timeframes`.Offending include-timeframes: {', '.join(offending_lines)}")
# Ensure that the base timeframe is included in the include_timeframes list
if main_tf not in freqai_include_timeframes:
if not preliminary and main_tf not in freqai_include_timeframes:
feature_parameters = conf.get('freqai', {}).get('feature_parameters', {})
include_timeframes = [main_tf] + freqai_include_timeframes
conf.get('freqai', {}).get('feature_parameters', {}) \
+4 -1
View File
@@ -326,7 +326,10 @@ def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = Non
"Please specify a strategy.")
if strategy not in data['strategy']:
raise ValueError(f"Strategy {strategy} not available in the backtest result.")
raise ValueError(
f"Strategy {strategy} not available in the backtest result. "
f"Available strategies are '{','.join(data['strategy'].keys())}'"
)
data = data['strategy'][strategy]['trades']
df = pd.DataFrame(data)
+2 -2
View File
@@ -116,8 +116,8 @@ def ohlcv_fill_up_missing_data(dataframe: DataFrame, timeframe: str, pair: str)
len_after = len(df)
pct_missing = (len_after - len_before) / len_before if len_before > 0 else 0
if len_before != len_after:
message = (f"Missing data fillup for {pair}: before: {len_before} - after: {len_after}"
f" - {pct_missing:.2%}")
message = (f"Missing data fillup for {pair}, {timeframe}: "
f"before: {len_before} - after: {len_after} - {pct_missing:.2%}")
if pct_missing > 0.01:
logger.info(message)
else:
+3 -2
View File
@@ -211,8 +211,9 @@ def prepare_results(analysed_trades, stratname,
timerange=None):
res_df = pd.DataFrame()
for pair, trades in analysed_trades[stratname].items():
trades.dropna(subset=['close_date'], inplace=True)
res_df = pd.concat([res_df, trades], ignore_index=True)
if (trades.shape[0] > 0):
trades.dropna(subset=['close_date'], inplace=True)
res_df = pd.concat([res_df, trades], ignore_index=True)
res_df = _select_rows_within_dates(res_df, timerange)
+1 -1
View File
@@ -4,8 +4,8 @@ from freqtrade.exchange.common import remove_exchange_credentials, MAP_EXCHANGE_
from freqtrade.exchange.exchange import Exchange
# isort: on
from freqtrade.exchange.binance import Binance
from freqtrade.exchange.bitmart import Bitmart
from freqtrade.exchange.bitpanda import Bitpanda
from freqtrade.exchange.bittrex import Bittrex
from freqtrade.exchange.bitvavo import Bitvavo
from freqtrade.exchange.bybit import Bybit
from freqtrade.exchange.coinbasepro import Coinbasepro
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
""" Bitmart exchange subclass """
import logging
from typing import Dict
from freqtrade.exchange import Exchange
logger = logging.getLogger(__name__)
class Bitmart(Exchange):
"""
Bitmart exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
"""
_ft_has: Dict = {
"stoploss_on_exchange": False, # Bitmart API does not support stoploss orders
"ohlcv_candle_limit": 200,
}
-25
View File
@@ -1,25 +0,0 @@
""" Bittrex exchange subclass """
import logging
from typing import Dict
from freqtrade.exchange import Exchange
logger = logging.getLogger(__name__)
class Bittrex(Exchange):
"""
Bittrex exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
"""
_ft_has: Dict = {
"ohlcv_candle_limit_per_timeframe": {
'1m': 1440,
'5m': 288,
'1h': 744,
'1d': 365,
},
"l2_limit_range": [1, 25, 500],
}
+1
View File
@@ -29,6 +29,7 @@ class Bybit(Exchange):
_ft_has: Dict = {
"ohlcv_candle_limit": 1000,
"ohlcv_has_history": True,
"order_time_in_force": ["GTC", "FOK", "IOC", "PO"],
}
_ft_has_futures: Dict = {
"ohlcv_has_history": True,
+1 -1
View File
@@ -52,7 +52,7 @@ MAP_EXCHANGE_CHILDCLASS = {
SUPPORTED_EXCHANGES = [
'binance',
'bittrex',
'bitmart',
'gate',
'huobi',
'kraken',
+23 -12
View File
@@ -330,6 +330,7 @@ class Exchange:
Exchange ohlcv candle limit
Uses ohlcv_candle_limit_per_timeframe if the exchange has different limits
per timeframe (e.g. bittrex), otherwise falls back to ohlcv_candle_limit
TODO: this is most likely no longer needed since only bittrex needed this.
:param timeframe: Timeframe to check
:param candle_type: Candle-type
:param since_ms: Starting timestamp
@@ -486,11 +487,14 @@ class Exchange:
except ccxt.BaseError:
logger.exception('Unable to initialize markets.')
def reload_markets(self) -> None:
def reload_markets(self, force: bool = False) -> None:
"""Reload markets both sync and async if refresh interval has passed """
# Check whether markets have to be reloaded
if (self._last_markets_refresh > 0) and (
self._last_markets_refresh + self.markets_refresh_interval > dt_ts()):
if (
not force
and self._last_markets_refresh > 0
and (self._last_markets_refresh + self.markets_refresh_interval > dt_ts())
):
return None
logger.debug("Performing scheduled market reload..")
try:
@@ -1228,16 +1232,16 @@ class Exchange:
return order
except ccxt.InsufficientFunds as e:
raise InsufficientFundsError(
f'Insufficient funds to create {ordertype} sell order on market {pair}. '
f'Tried to sell amount {amount} at rate {limit_rate}. '
f'Message: {e}') from e
except ccxt.InvalidOrder as e:
f'Insufficient funds to create {ordertype} {side} order on market {pair}. '
f'Tried to {side} amount {amount} at rate {limit_rate} with '
f'stop-price {stop_price_norm}. Message: {e}') from e
except (ccxt.InvalidOrder, ccxt.BadRequest) as e:
# Errors:
# `Order would trigger immediately.`
raise InvalidOrderException(
f'Could not create {ordertype} sell order on market {pair}. '
f'Tried to sell amount {amount} at rate {limit_rate}. '
f'Message: {e}') from e
f'Could not create {ordertype} {side} order on market {pair}. '
f'Tried to {side} amount {amount} at rate {limit_rate} with '
f'stop-price {stop_price_norm}. Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
@@ -1496,8 +1500,9 @@ class Exchange:
@retrier
def fetch_bids_asks(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict:
"""
:param symbols: List of symbols to fetch
:param cached: Allow cached result
:return: fetch_tickers result
:return: fetch_bids_asks result
"""
if not self.exchange_has('fetchBidsAsks'):
return {}
@@ -1546,6 +1551,12 @@ class Exchange:
raise OperationalException(
f'Exchange {self._api.name} does not support fetching tickers in batch. '
f'Message: {e}') from e
except ccxt.BadSymbol as e:
logger.warning(f"Could not load tickers due to {e.__class__.__name__}. Message: {e} ."
"Reloading markets.")
self.reload_markets(True)
# Re-raise exception to repeat the call.
raise TemporaryError from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
@@ -1954,7 +1965,7 @@ class Exchange:
results = await asyncio.gather(*input_coro, return_exceptions=True)
for res in results:
if isinstance(res, Exception):
if isinstance(res, BaseException):
logger.warning(f"Async code raised an exception: {repr(res)}")
if raise_:
raise
+13 -6
View File
@@ -12,7 +12,6 @@ import numpy as np
import pandas as pd
import psutil
import rapidjson
from joblib import dump, load
from joblib.externals import cloudpickle
from numpy.typing import NDArray
from pandas import DataFrame
@@ -285,6 +284,10 @@ class FreqaiDataDrawer:
new_pred["date_pred"] = dataframe["date"]
hist_preds = self.historic_predictions[pair].copy()
# ensure both dataframes have the same date format so they can be merged
new_pred["date_pred"] = pd.to_datetime(new_pred["date_pred"])
hist_preds["date_pred"] = pd.to_datetime(hist_preds["date_pred"])
# find the closest common date between new_pred and historic predictions
# and cut off the new_pred dataframe at that date
common_dates = pd.merge(new_pred, hist_preds, on="date_pred", how="inner")
@@ -295,7 +298,9 @@ class FreqaiDataDrawer:
"predictions. You likely left your FreqAI instance offline "
f"for more than {len(dataframe.index)} candles.")
df_concat = pd.concat([hist_preds, new_pred], ignore_index=True, keys=hist_preds.keys())
# reindex new_pred columns to match the historic predictions dataframe
new_pred_reindexed = new_pred.reindex(columns=hist_preds.columns)
df_concat = pd.concat([hist_preds, new_pred_reindexed], ignore_index=True)
# any missing values will get zeroed out so users can see the exact
# downtime in FreqUI
@@ -318,9 +323,9 @@ class FreqaiDataDrawer:
index = self.historic_predictions[pair].index[-1:]
columns = self.historic_predictions[pair].columns
nan_df = pd.DataFrame(np.nan, index=index, columns=columns)
zeros_df = pd.DataFrame(np.zeros((1, len(columns))), index=index, columns=columns)
self.historic_predictions[pair] = pd.concat(
[self.historic_predictions[pair], nan_df], ignore_index=True, axis=0)
[self.historic_predictions[pair], zeros_df], ignore_index=True, axis=0)
df = self.historic_predictions[pair]
# model outputs and associated statistics
@@ -471,7 +476,8 @@ class FreqaiDataDrawer:
# Save the trained model
if self.model_type == 'joblib':
dump(model, save_path / f"{dk.model_filename}_model.joblib")
with (save_path / f"{dk.model_filename}_model.joblib").open("wb") as fp:
cloudpickle.dump(model, fp)
elif self.model_type == 'keras':
model.save(save_path / f"{dk.model_filename}_model.h5")
elif self.model_type in ["stable_baselines3", "sb3_contrib", "pytorch"]:
@@ -558,7 +564,8 @@ class FreqaiDataDrawer:
if dk.live and coin in self.model_dictionary:
model = self.model_dictionary[coin]
elif self.model_type == 'joblib':
model = load(dk.data_path / f"{dk.model_filename}_model.joblib")
with (dk.data_path / f"{dk.model_filename}_model.joblib").open("rb") as fp:
model = cloudpickle.load(fp)
elif 'stable_baselines' in self.model_type or 'sb3_contrib' == self.model_type:
mod = importlib.import_module(
self.model_type, self.freqai_info['rl_config']['model_type'])
+1 -1
View File
@@ -244,7 +244,7 @@ class FreqaiDataKitchen:
f"{self.pair}: dropped {len(unfiltered_df) - len(filtered_df)} training points"
f" due to NaNs in populated dataset {len(unfiltered_df)}."
)
if len(unfiltered_df) == 0 and not self.live:
if len(filtered_df) == 0 and not self.live:
raise OperationalException(
f"{self.pair}: all training data dropped due to NaNs. "
"You likely did not download enough training data prior "
@@ -27,6 +27,12 @@ class PyTorchTransformerRegressor(BasePyTorchRegressor):
...
"freqai": {
...
"conv_width": 30, // PyTorchTransformer is based on windowing
"feature_parameters": {
...
"include_shifted_candles": 0, // which removes the need for shifted candles
...
},
"model_training_parameters" : {
"learning_rate": 3e-4,
"trainer_kwargs": {
@@ -120,16 +126,16 @@ class PyTorchTransformerRegressor(BasePyTorchRegressor):
# create empty torch tensor
self.model.model.eval()
yb = torch.empty(0).to(self.device)
if x.shape[1] > 1:
if x.shape[1] > self.window_size:
ws = self.window_size
for i in range(0, x.shape[1] - ws):
xb = x[:, i:i + ws, :].to(self.device)
y = self.model.model(xb)
yb = torch.cat((yb, y), dim=0)
yb = torch.cat((yb, y), dim=1)
else:
yb = self.model.model(x)
yb = yb.cpu().squeeze()
yb = yb.cpu().squeeze(0)
pred_df = pd.DataFrame(yb.detach().numpy(), columns=dk.label_list)
pred_df, _, _ = dk.label_pipeline.inverse_transform(pred_df)
@@ -0,0 +1,82 @@
import logging
from typing import Any, Dict, Tuple
import numpy as np
import numpy.typing as npt
from pandas import DataFrame
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
from freqtrade.freqai.base_models.BaseClassifierModel import BaseClassifierModel
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
logger = logging.getLogger(__name__)
class SKLearnRandomForestClassifier(BaseClassifierModel):
"""
User created prediction model. The class inherits IFreqaiModel, which
means it has full access to all Frequency AI functionality. Typically,
users would use this to override the common `fit()`, `train()`, or
`predict()` methods to add their custom data handling tools or change
various aspects of the training that cannot be configured via the
top level config.json file.
"""
def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
"""
User sets up the training and test data to fit their desired model here
:param data_dictionary: the dictionary holding all data for train, test,
labels, weights
:param dk: The datakitchen object for the current coin/model
"""
X = data_dictionary["train_features"].to_numpy()
y = data_dictionary["train_labels"].to_numpy()[:, 0]
if self.freqai_info.get('data_split_parameters', {}).get('test_size', 0.1) == 0:
eval_set = None
else:
test_features = data_dictionary["test_features"].to_numpy()
test_labels = data_dictionary["test_labels"].to_numpy()[:, 0]
eval_set = (test_features, test_labels)
if self.freqai_info.get("continual_learning", False):
logger.warning("Continual learning is not supported for "
"SKLearnRandomForestClassifier, ignoring.")
train_weights = data_dictionary["train_weights"]
model = RandomForestClassifier(**self.model_training_parameters)
model.fit(X=X, y=y, sample_weight=train_weights)
if eval_set:
logger.info("Score: %s", model.score(eval_set[0], eval_set[1]))
return model
def predict(
self, unfiltered_df: DataFrame, dk: FreqaiDataKitchen, **kwargs
) -> Tuple[DataFrame, npt.NDArray[np.int_]]:
"""
Filter the prediction features data and predict with it.
:param unfiltered_df: Full dataframe for the current backtest period.
:return:
:pred_df: dataframe containing the predictions
:do_predict: np.array of 1s and 0s to indicate places where freqai needed to remove
data (NaNs) or felt uncertain about data (PCA and DI index)
"""
(pred_df, dk.do_predict) = super().predict(unfiltered_df, dk, **kwargs)
le = LabelEncoder()
label = dk.label_list[0]
labels_before = list(dk.data['labels_std'].keys())
labels_after = le.fit_transform(labels_before).tolist()
pred_df[label] = le.inverse_transform(pred_df[label])
pred_df = pred_df.rename(
columns={labels_after[i]: labels_before[i] for i in range(len(labels_before))})
return (pred_df, dk.do_predict)
@@ -45,7 +45,7 @@ class XGBoostRFRegressor(BaseRegressionModel):
model = XGBRFRegressor(**self.model_training_parameters)
model.set_params(callbacks=[TBCallback(dk.data_path)], activate=self.activate_tensorboard)
model.set_params(callbacks=[TBCallback(dk.data_path)])
model.fit(X=X, y=y, sample_weight=sample_weight, eval_set=eval_set,
sample_weight_eval_set=eval_weights, xgb_model=xgb_model)
# set the callbacks to empty so that we can serialize to disk later
@@ -45,7 +45,7 @@ class XGBoostRegressor(BaseRegressionModel):
model = XGBRegressor(**self.model_training_parameters)
model.set_params(callbacks=[TBCallback(dk.data_path)], activate=self.activate_tensorboard)
model.set_params(callbacks=[TBCallback(dk.data_path)])
model.fit(X=X, y=y, sample_weight=sample_weight, eval_set=eval_set,
sample_weight_eval_set=eval_weights, xgb_model=xgb_model)
# set the callbacks to empty so that we can serialize to disk later
@@ -3,7 +3,6 @@ from typing import Any, Dict, Type, Union
from stable_baselines3.common.callbacks import BaseCallback
from stable_baselines3.common.logger import HParam
from stable_baselines3.common.vec_env import VecEnv
from freqtrade.freqai.RL.BaseEnvironment import BaseActions
@@ -13,13 +12,9 @@ class TensorboardCallback(BaseCallback):
Custom callback for plotting additional values in tensorboard and
episodic summary reports.
"""
# Override training_env type to fix type errors
training_env: Union[VecEnv, None] = None
def __init__(self, verbose=1, actions: Type[Enum] = BaseActions):
super().__init__(verbose)
self.model: Any = None
self.logger: Any = None
self.actions: Type[Enum] = actions
def _on_training_start(self) -> None:
@@ -47,8 +42,6 @@ class TensorboardCallback(BaseCallback):
def _on_step(self) -> bool:
local_info = self.locals["infos"][0]
if self.training_env is None:
return True
if hasattr(self.training_env, 'envs'):
tensorboard_metrics = self.training_env.envs[0].unwrapped.tensorboard_metrics
+10 -9
View File
@@ -33,8 +33,8 @@ from freqtrade.plugins.protectionmanager import ProtectionManager
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.rpc import RPCManager
from freqtrade.rpc.external_message_consumer import ExternalMessageConsumer
from freqtrade.rpc.rpc_types import (RPCBuyMsg, RPCCancelMsg, RPCProtectionMsg, RPCSellCancelMsg,
RPCSellMsg)
from freqtrade.rpc.rpc_types import (ProfitLossStr, RPCCancelMsg, RPCEntryMsg, RPCExitCancelMsg,
RPCExitMsg, RPCProtectionMsg)
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
from freqtrade.util import FtPrecise
@@ -580,7 +580,8 @@ class FreqtradeBot(LoggingMixin):
else:
self.log_once(f"Pair {pair} is currently locked.", logger.info)
return False
stake_amount = self.wallets.get_trade_stake_amount(pair, self.edge)
stake_amount = self.wallets.get_trade_stake_amount(
pair, self.config['max_open_trades'], self.edge)
bid_check_dom = self.config.get('entry_pricing', {}).get('check_depth_of_market', {})
if ((bid_check_dom.get('enabled', False)) and
@@ -903,7 +904,7 @@ class FreqtradeBot(LoggingMixin):
# First cancelling stoploss on exchange ...
if trade.stoploss_order_id:
try:
logger.info(f"Canceling stoploss on exchange for {trade}")
logger.info(f"Cancelling stoploss on exchange for {trade}")
co = self.exchange.cancel_stoploss_order_with_result(
trade.stoploss_order_id, trade.pair, trade.amount)
self.update_trade_state(trade, trade.stoploss_order_id, co, stoploss_order=True)
@@ -1014,7 +1015,7 @@ class FreqtradeBot(LoggingMixin):
current_rate = self.exchange.get_rate(
trade.pair, side='entry', is_short=trade.is_short, refresh=False)
msg: RPCBuyMsg = {
msg: RPCEntryMsg = {
'trade_id': trade.id,
'type': RPCMessageType.ENTRY_FILL if fill else RPCMessageType.ENTRY,
'buy_tag': trade.enter_tag,
@@ -1791,9 +1792,9 @@ class FreqtradeBot(LoggingMixin):
order_rate = trade.safe_close_rate
profit = trade.calculate_profit(rate=order_rate)
amount = trade.amount
gain = "profit" if profit.profit_ratio > 0 else "loss"
gain: ProfitLossStr = "profit" if profit.profit_ratio > 0 else "loss"
msg: RPCSellMsg = {
msg: RPCExitMsg = {
'type': (RPCMessageType.EXIT_FILL if fill
else RPCMessageType.EXIT),
'trade_id': trade.id,
@@ -1845,9 +1846,9 @@ class FreqtradeBot(LoggingMixin):
profit = trade.calculate_profit(rate=profit_rate)
current_rate = self.exchange.get_rate(
trade.pair, side='exit', is_short=trade.is_short, refresh=False)
gain = "profit" if profit.profit_ratio > 0 else "loss"
gain: ProfitLossStr = "profit" if profit.profit_ratio > 0 else "loss"
msg: RPCSellCancelMsg = {
msg: RPCExitCancelMsg = {
'type': RPCMessageType.EXIT_CANCEL,
'trade_id': trade.id,
'exchange': trade.exchange.capitalize(),
+2 -1
View File
@@ -3,6 +3,7 @@ Various tool function for Freqtrade and scripts
"""
import gzip
import logging
from io import StringIO
from pathlib import Path
from typing import Any, Dict, Iterator, List, Mapping, Optional, TextIO, Union
from urllib.parse import urlparse
@@ -231,7 +232,7 @@ def json_to_dataframe(data: str) -> pd.DataFrame:
:param data: A JSON string
:returns: A pandas DataFrame from the JSON string
"""
dataframe = pd.read_json(data, orient='split')
dataframe = pd.read_json(StringIO(data), orient='split')
if 'date' in dataframe.columns:
dataframe['date'] = pd.to_datetime(dataframe['date'], unit='ms', utc=True)
+2 -2
View File
@@ -94,8 +94,8 @@ class LookaheadAnalysis(BaseAnalysis):
# compare_df now comprises tuples with [1] having either 'self' or 'other'
if 'other' in col_name[1]:
continue
self_value = compare_df_row[col_idx]
other_value = compare_df_row[col_idx + 1]
self_value = compare_df_row.iloc[col_idx]
other_value = compare_df_row.iloc[col_idx + 1]
# output differences
if self_value != other_value:
+31 -14
View File
@@ -276,11 +276,13 @@ class Backtesting:
else:
self.detail_data = {}
if self.trading_mode == TradingMode.FUTURES:
self.funding_fee_timeframe: str = self.exchange.get_option('mark_ohlcv_timeframe')
self.funding_fee_timeframe_secs: int = timeframe_to_seconds(self.funding_fee_timeframe)
# Load additional futures data.
funding_rates_dict = history.load_data(
datadir=self.config['datadir'],
pairs=self.pairlists.whitelist,
timeframe=self.exchange.get_option('mark_ohlcv_timeframe'),
timeframe=self.funding_fee_timeframe,
timerange=self.timerange,
startup_candles=0,
fail_without_data=True,
@@ -292,7 +294,7 @@ class Backtesting:
mark_rates_dict = history.load_data(
datadir=self.config['datadir'],
pairs=self.pairlists.whitelist,
timeframe=self.exchange.get_option('mark_ohlcv_timeframe'),
timeframe=self.funding_fee_timeframe,
timerange=self.timerange,
startup_candles=0,
fail_without_data=True,
@@ -597,6 +599,8 @@ class Backtesting:
"""
if order and self._get_order_filled(order.ft_price, row):
order.close_bt_order(current_date, trade)
self._run_funding_fees(trade, current_date, force=True)
if not (order.ft_order_side == trade.exit_side and order.safe_amount == trade.amount):
# trade is still open
trade.set_liquidation_price(self.exchange.get_liquidation_price(
@@ -718,16 +722,7 @@ class Backtesting:
self, trade: LocalTrade, row: Tuple, current_time: datetime
) -> Optional[LocalTrade]:
if self.trading_mode == TradingMode.FUTURES:
trade.set_funding_fees(
self.exchange.calculate_funding_fees(
self.futures_data[trade.pair],
amount=trade.amount,
is_short=trade.is_short,
open_date=trade.date_last_filled_utc,
close_date=current_time
)
)
self._run_funding_fees(trade, current_time)
# Check if we need to adjust our current positions
if self.strategy.position_adjustment_enable:
@@ -746,6 +741,27 @@ class Backtesting:
return t
return None
def _run_funding_fees(self, trade: LocalTrade, current_time: datetime, force: bool = False):
"""
Calculate funding fees if necessary and add them to the trade.
"""
if self.trading_mode == TradingMode.FUTURES:
if (
force
or (current_time.timestamp() % self.funding_fee_timeframe_secs) == 0
):
# Funding fee interval.
trade.set_funding_fees(
self.exchange.calculate_funding_fees(
self.futures_data[trade.pair],
amount=trade.amount,
is_short=trade.is_short,
open_date=trade.date_last_filled_utc,
close_date=current_time
)
)
def get_valid_price_and_stake(
self, pair: str, row: Tuple, propose_rate: float, stake_amount: float,
direction: LongShort, current_time: datetime, entry_tag: Optional[str],
@@ -775,7 +791,8 @@ class Backtesting:
leverage = trade.leverage if trade else 1.0
if not pos_adjust:
try:
stake_amount = self.wallets.get_trade_stake_amount(pair, None, update=False)
stake_amount = self.wallets.get_trade_stake_amount(
pair, self.strategy.max_open_trades, update=False)
except DependencyException:
return 0, 0, 0, 0
@@ -957,7 +974,7 @@ class Backtesting:
def trade_slot_available(self, open_trade_count: int) -> bool:
# Always allow trades when max_open_trades is enabled.
max_open_trades: IntOrInf = self.config['max_open_trades']
max_open_trades: IntOrInf = self.strategy.max_open_trades
if max_open_trades <= 0 or open_trade_count < max_open_trades:
return True
# Rejected trade
+5 -1
View File
@@ -500,7 +500,7 @@ class Hyperopt:
while i < 5 and len(asked_non_tried) < n_points:
if i < 3:
self.opt.cache_ = {}
asked = unique_list(self.opt.ask(n_points=n_points * 5))
asked = unique_list(self.opt.ask(n_points=n_points * 5 if i > 0 else n_points))
is_random = [False for _ in range(len(asked))]
else:
asked = unique_list(self.opt.space.rvs(n_samples=n_points * 5))
@@ -637,6 +637,10 @@ class Hyperopt:
HyperoptTools.show_epoch_details(self.current_best_epoch, self.total_epochs,
self.print_json)
elif self.num_epochs_saved > 0:
print(
f"No good result found for given optimization function in {self.num_epochs_saved} "
f"{plural(self.num_epochs_saved, 'epoch')}.")
else:
# This is printed when Ctrl+C is pressed quickly, before first epochs have
# a chance to be evaluated.
+1 -1
View File
@@ -21,7 +21,7 @@ logger = logging.getLogger(__name__)
def _format_exception_message(space: str, ignore_missing_space: bool) -> None:
msg = (f"The '{space}' space is included into the hyperoptimization "
f"but no parameter for this space was not found in your Strategy. "
f"but no parameter for this space was found in your Strategy. "
)
if ignore_missing_space:
logger.warning(msg + "This space will be ignored.")
+7 -3
View File
@@ -429,14 +429,18 @@ class HyperoptTools:
trials = trials.drop(columns=['Total profit'])
if print_colorized:
trials2 = trials.astype(str)
for i in range(len(trials)):
if trials.loc[i]['is_profit']:
for j in range(len(trials.loc[i]) - 3):
trials.iat[i, j] = f"{Fore.GREEN}{str(trials.loc[i][j])}{Fore.RESET}"
trials2.iat[i, j] = f"{Fore.GREEN}{str(trials.iloc[i, j])}{Fore.RESET}"
if trials.loc[i]['is_best'] and highlight_best:
for j in range(len(trials.loc[i]) - 3):
trials.iat[i, j] = f"{Style.BRIGHT}{str(trials.loc[i][j])}{Style.RESET_ALL}"
trials2.iat[i, j] = (
f"{Style.BRIGHT}{str(trials.iloc[i, j])}{Style.RESET_ALL}"
)
trials = trials2
del trials2
trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit', 'is_random'])
if remove_header > 0:
table = tabulate.tabulate(
@@ -219,8 +219,10 @@ def _get_resample_from_period(period: str) -> str:
raise ValueError(f"Period {period} is not supported.")
def generate_periodic_breakdown_stats(trade_list: List, period: str) -> List[Dict[str, Any]]:
results = DataFrame.from_records(trade_list)
def generate_periodic_breakdown_stats(
trade_list: Union[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)
+35 -31
View File
@@ -156,20 +156,20 @@ class Order(ModelBase):
if self.order_id != str(order['id']):
raise DependencyException("Order-id's don't match")
self.status = order.get('status', self.status)
self.symbol = order.get('symbol', self.symbol)
self.order_type = order.get('type', self.order_type)
self.side = order.get('side', self.side)
self.price = order.get('price', self.price)
self.amount = order.get('amount', self.amount)
self.filled = order.get('filled', self.filled)
self.average = order.get('average', self.average)
self.remaining = order.get('remaining', self.remaining)
self.cost = order.get('cost', self.cost)
self.stop_price = order.get('stopPrice', self.stop_price)
if 'timestamp' in order and order['timestamp'] is not None:
self.order_date = datetime.fromtimestamp(order['timestamp'] / 1000, tz=timezone.utc)
self.status = safe_value_fallback(order, 'status', default_value=self.status)
self.symbol = safe_value_fallback(order, 'symbol', default_value=self.symbol)
self.order_type = safe_value_fallback(order, 'type', default_value=self.order_type)
self.side = safe_value_fallback(order, 'side', default_value=self.side)
self.price = safe_value_fallback(order, 'price', default_value=self.price)
self.amount = safe_value_fallback(order, 'amount', default_value=self.amount)
self.filled = safe_value_fallback(order, 'filled', default_value=self.filled)
self.average = safe_value_fallback(order, 'average', default_value=self.average)
self.remaining = safe_value_fallback(order, 'remaining', default_value=self.remaining)
self.cost = safe_value_fallback(order, 'cost', default_value=self.cost)
self.stop_price = safe_value_fallback(order, 'stopPrice', default_value=self.stop_price)
order_date = safe_value_fallback(order, 'timestamp')
if order_date:
self.order_date = datetime.fromtimestamp(order_date / 1000, tz=timezone.utc)
self.ft_is_open = True
if self.status in NON_OPEN_EXCHANGE_STATES:
@@ -1053,7 +1053,7 @@ class LocalTrade:
price = avg_price if is_exit else tmp_price
current_stake += price * tmp_amount * side
if current_amount > ZERO:
if current_amount > ZERO and not is_exit:
avg_price = current_stake / current_amount
if is_exit:
@@ -1066,7 +1066,10 @@ class LocalTrade:
exit_amount = o.safe_amount_after_fee
prof = self.calculate_profit(exit_rate, exit_amount, float(avg_price))
close_profit_abs += prof.profit_abs
close_profit = prof.profit_ratio
if total_stake > 0:
# This needs to be calculated based on the last occuring exit to be aligned
# with realized_profit.
close_profit = (close_profit_abs / total_stake) * self.leverage
else:
total_stake = total_stake + self._calc_open_trade_value(tmp_amount, price)
max_stake_amount += (tmp_amount * price)
@@ -1780,7 +1783,7 @@ class Trade(ModelBase, LocalTrade):
.order_by(desc('profit_sum_abs'))
).all()
return_list: List[Dict] = []
resp: List[Dict] = []
for id, enter_tag, exit_reason, profit, profit_abs, count in mix_tag_perf:
enter_tag = enter_tag if enter_tag is not None else "Other"
exit_reason = exit_reason if exit_reason is not None else "Other"
@@ -1788,24 +1791,25 @@ class Trade(ModelBase, LocalTrade):
if (exit_reason is not None and enter_tag is not None):
mix_tag = enter_tag + " " + exit_reason
i = 0
if not any(item["mix_tag"] == mix_tag for item in return_list):
return_list.append({'mix_tag': mix_tag,
'profit': profit,
'profit_pct': round(profit * 100, 2),
'profit_abs': profit_abs,
'count': count})
if not any(item["mix_tag"] == mix_tag for item in resp):
resp.append({'mix_tag': mix_tag,
'profit_ratio': profit,
'profit_pct': round(profit * 100, 2),
'profit_abs': profit_abs,
'count': count})
else:
while i < len(return_list):
if return_list[i]["mix_tag"] == mix_tag:
return_list[i] = {
while i < len(resp):
if resp[i]["mix_tag"] == mix_tag:
resp[i] = {
'mix_tag': mix_tag,
'profit': profit + return_list[i]["profit"],
'profit_pct': round(profit + return_list[i]["profit"] * 100, 2),
'profit_abs': profit_abs + return_list[i]["profit_abs"],
'count': 1 + return_list[i]["count"]}
'profit_ratio': profit + resp[i]["profit_ratio"],
'profit_pct': round(profit + resp[i]["profit_ratio"] * 100, 2),
'profit_abs': profit_abs + resp[i]["profit_abs"],
'count': 1 + resp[i]["count"]
}
i += 1
return return_list
return resp
@staticmethod
def get_best_pair(start_date: datetime = datetime.fromtimestamp(0)):
+2 -1
View File
@@ -21,6 +21,7 @@ from freqtrade.misc import pair_to_filename
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.strategy import IStrategy
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
logger = logging.getLogger(__name__)
@@ -636,7 +637,7 @@ def load_and_plot_trades(config: Config):
exchange = ExchangeResolver.load_exchange(config)
IStrategy.dp = DataProvider(config, exchange)
strategy.ft_bot_start()
strategy.bot_loop_start(datetime.now(timezone.utc))
strategy_safe_wrapper(strategy.bot_loop_start)(current_time=datetime.now(timezone.utc))
plot_elements = init_plotscript(config, list(exchange.markets), strategy.startup_candle_count)
timerange = plot_elements['timerange']
trades = plot_elements['trades']
+21 -10
View File
@@ -1,9 +1,9 @@
from datetime import date, datetime
from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel, ConfigDict, RootModel, SerializeAsAny
from pydantic import BaseModel, RootModel, SerializeAsAny
from freqtrade.constants import DATETIME_PRINT_FORMAT, IntOrInf
from freqtrade.constants import IntOrInf
from freqtrade.enums import MarginMode, OrderTypeValues, SignalDirection, TradingMode
from freqtrade.types import ValidExchangesType
@@ -95,15 +95,30 @@ class Count(BaseModel):
total_stake: float
class PerformanceEntry(BaseModel):
pair: str
profit: float
class __BaseStatsModel(BaseModel):
profit_ratio: float
profit_pct: float
profit_abs: float
count: int
class Entry(__BaseStatsModel):
enter_tag: str
class Exit(__BaseStatsModel):
exit_reason: str
class MixTag(__BaseStatsModel):
mix_tag: str
class PerformanceEntry(__BaseStatsModel):
pair: str
profit: float
class Profit(BaseModel):
profit_closed_coin: float
profit_closed_percent_mean: float
@@ -456,6 +471,7 @@ class FreqAIModelListResponse(BaseModel):
class StrategyResponse(BaseModel):
strategy: str
code: str
timeframe: Optional[str]
class AvailablePairs(BaseModel):
@@ -484,11 +500,6 @@ class PairHistory(BaseModel):
data_start: str
data_stop: str
data_stop_ts: int
# TODO[pydantic]: The following keys were removed: `json_encoders`.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
model_config = ConfigDict(json_encoders={
datetime: lambda v: v.strftime(DATETIME_PRINT_FORMAT),
})
class BacktestFreqAIInputs(BaseModel):
+25 -8
View File
@@ -12,15 +12,15 @@ from freqtrade.exceptions import OperationalException
from freqtrade.rpc import RPC
from freqtrade.rpc.api_server.api_schemas import (AvailablePairs, Balances, BlacklistPayload,
BlacklistResponse, Count, DailyWeeklyMonthly,
DeleteLockRequest, DeleteTrade,
ExchangeListResponse, ForceEnterPayload,
DeleteLockRequest, DeleteTrade, Entry,
ExchangeListResponse, Exit, ForceEnterPayload,
ForceEnterResponse, ForceExitPayload,
FreqAIModelListResponse, Health, Locks, Logs,
OpenTradeSchema, PairHistory, PerformanceEntry,
Ping, PlotConfig, Profit, ResultMsg, ShowConfig,
Stats, StatusMsg, StrategyListResponse,
StrategyResponse, SysInfo, Version,
WhitelistResponse)
MixTag, OpenTradeSchema, PairHistory,
PerformanceEntry, Ping, PlotConfig, Profit,
ResultMsg, ShowConfig, Stats, StatusMsg,
StrategyListResponse, StrategyResponse, SysInfo,
Version, WhitelistResponse)
from freqtrade.rpc.api_server.deps import get_config, get_exchange, get_rpc, get_rpc_optional
from freqtrade.rpc.rpc import RPCException
@@ -52,7 +52,8 @@ logger = logging.getLogger(__name__)
# 2.31: new /backtest/history/ delete endpoint
# 2.32: new /backtest/history/ patch endpoint
# 2.33: Additional weekly/monthly metrics
API_VERSION = 2.33
# 2.34: new entries/exits/mix_tags endpoints
API_VERSION = 2.34
# Public API, requires no auth.
router_public = APIRouter()
@@ -83,6 +84,21 @@ def count(rpc: RPC = Depends(get_rpc)):
return rpc._rpc_count()
@router.get('/entries', response_model=List[Entry], tags=['info'])
def entries(pair: Optional[str] = None, rpc: RPC = Depends(get_rpc)):
return rpc._rpc_enter_tag_performance(pair)
@router.get('/exits', response_model=List[Exit], tags=['info'])
def exits(pair: Optional[str] = None, rpc: RPC = Depends(get_rpc)):
return rpc._rpc_exit_reason_performance(pair)
@router.get('/mix_tags', response_model=List[MixTag], tags=['info'])
def mix_tags(pair: Optional[str] = None, rpc: RPC = Depends(get_rpc)):
return rpc._rpc_mix_tag_performance(pair)
@router.get('/performance', response_model=List[PerformanceEntry], tags=['info'])
def performance(rpc: RPC = Depends(get_rpc)):
return rpc._rpc_performance()
@@ -334,6 +350,7 @@ def get_strategy(strategy: str, config=Depends(get_config)):
return {
'strategy': strategy_obj.get_strategy_name(),
'code': strategy_obj.__source__,
'timeframe': getattr(strategy_obj, 'timeframe', None),
}
+1 -1
View File
@@ -56,7 +56,7 @@ def get_exchange(config=Depends(get_config)):
if not (exchange := ApiBG.exchanges.get(exchange_key)):
from freqtrade.resolvers import ExchangeResolver
exchange = ExchangeResolver.load_exchange(
config, load_leverage_tiers=False)
config, validate=False, load_leverage_tiers=False)
ApiBG.exchanges[exchange_key] = exchange
return exchange
+3 -2
View File
@@ -15,6 +15,7 @@ class Discord(Webhook):
self.rpc = rpc
self.strategy = config.get('strategy', '')
self.timeframe = config.get('timeframe', '')
self.bot_name = config.get('bot_name', '')
self._url = config['discord']['webhook_url']
self._format = 'json'
@@ -31,12 +32,12 @@ class Discord(Webhook):
def send_msg(self, msg) -> None:
if msg['type'].value in self._config['discord']:
if (fields := self._config['discord'].get(msg['type'].value)):
logger.info(f"Sending discord message: {msg}")
msg['strategy'] = self.strategy
msg['timeframe'] = self.timeframe
fields = self._config['discord'].get(msg['type'].value)
msg['bot_name'] = self.bot_name
color = 0x0000FF
if msg['type'] in (RPCMessageType.EXIT, RPCMessageType.EXIT_FILL):
profit_ratio = msg.get('profit_ratio')
+1
View File
@@ -28,6 +28,7 @@ coingecko_mapping = {
'busd': 'binance-usd',
'tusd': 'true-usd',
'usdc': 'usd-coin',
'btc': 'bitcoin'
}
+4 -3
View File
@@ -121,8 +121,8 @@ class RPC:
'stake_currency_decimals': decimals_per_coin(config['stake_currency']),
'stake_amount': str(config['stake_amount']),
'available_capital': config.get('available_capital'),
'max_open_trades': (config['max_open_trades']
if config['max_open_trades'] != float('inf') else -1),
'max_open_trades': (config.get('max_open_trades', 0)
if config.get('max_open_trades', 0) != float('inf') else -1),
'minimal_roi': config['minimal_roi'].copy() if 'minimal_roi' in config else {},
'stoploss': config.get('stoploss'),
'stoploss_on_exchange': config.get('order_types',
@@ -914,7 +914,8 @@ class RPC:
if not stake_amount:
# gen stake amount
stake_amount = self._freqtrade.wallets.get_trade_stake_amount(pair)
stake_amount = self._freqtrade.wallets.get_trade_stake_amount(
pair, self._config['max_open_trades'])
# execute buy
if not order_type:
+13 -10
View File
@@ -5,6 +5,9 @@ from freqtrade.constants import PairWithTimeframe
from freqtrade.enums import RPCMessageType
ProfitLossStr = Literal["profit", "loss"]
class RPCSendMsgBase(TypedDict):
pass
# ty1pe: Literal[RPCMessageType]
@@ -41,7 +44,7 @@ class RPCWhitelistMsg(RPCSendMsgBase):
data: List[str]
class __RPCBuyMsgBase(RPCSendMsgBase):
class __RPCEntryExitMsgBase(RPCSendMsgBase):
trade_id: int
buy_tag: Optional[str]
enter_tag: Optional[str]
@@ -62,19 +65,19 @@ class __RPCBuyMsgBase(RPCSendMsgBase):
sub_trade: bool
class RPCBuyMsg(__RPCBuyMsgBase):
class RPCEntryMsg(__RPCEntryExitMsgBase):
type: Literal[RPCMessageType.ENTRY, RPCMessageType.ENTRY_FILL]
class RPCCancelMsg(__RPCBuyMsgBase):
class RPCCancelMsg(__RPCEntryExitMsgBase):
type: Literal[RPCMessageType.ENTRY_CANCEL]
reason: str
class RPCSellMsg(__RPCBuyMsgBase):
class RPCExitMsg(__RPCEntryExitMsgBase):
type: Literal[RPCMessageType.EXIT, RPCMessageType.EXIT_FILL]
cumulative_profit: float
gain: str # Literal["profit", "loss"]
gain: ProfitLossStr
close_rate: float
profit_amount: float
profit_ratio: float
@@ -85,10 +88,10 @@ class RPCSellMsg(__RPCBuyMsgBase):
order_rate: Optional[float]
class RPCSellCancelMsg(__RPCBuyMsgBase):
class RPCExitCancelMsg(__RPCEntryExitMsgBase):
type: Literal[RPCMessageType.EXIT_CANCEL]
reason: str
gain: str # Literal["profit", "loss"]
gain: ProfitLossStr
profit_amount: float
profit_ratio: float
sell_reason: Optional[str]
@@ -119,10 +122,10 @@ RPCSendMsg = Union[
RPCStrategyMsg,
RPCProtectionMsg,
RPCWhitelistMsg,
RPCBuyMsg,
RPCEntryMsg,
RPCCancelMsg,
RPCSellMsg,
RPCSellCancelMsg,
RPCExitMsg,
RPCExitCancelMsg,
RPCAnalyzedDFMsg,
RPCNewCandleMsg
]
+63 -15
View File
@@ -223,7 +223,8 @@ class Telegram(RPCHandler):
CommandHandler('health', self._health),
CommandHandler('help', self._help),
CommandHandler('version', self._version),
CommandHandler('marketdir', self._changemarketdir)
CommandHandler('marketdir', self._changemarketdir),
CommandHandler('order', self._order),
]
callbacks = [
CallbackQueryHandler(self._status_table, pattern='update_status_table'),
@@ -240,7 +241,7 @@ class Telegram(RPCHandler):
CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'),
CallbackQueryHandler(self._count, pattern='update_count'),
CallbackQueryHandler(self._force_exit_inline, pattern=r"force_exit__\S+"),
CallbackQueryHandler(self._force_enter_inline, pattern=r"\S+\/\S+"),
CallbackQueryHandler(self._force_enter_inline, pattern=r"force_enter__\S+"),
]
for handle in handles:
self._app.add_handler(handle)
@@ -555,6 +556,47 @@ class Telegram(RPCHandler):
return lines_detail
@authorized_only
async def _order(self, update: Update, context: CallbackContext) -> None:
"""
Handler for /order.
Returns the orders of the trade
:param bot: telegram bot
:param update: message update
:return: None
"""
trade_ids = []
if context.args and len(context.args) > 0:
trade_ids = [int(i) for i in context.args if i.isnumeric()]
results = self._rpc._rpc_trade_status(trade_ids=trade_ids)
for r in results:
lines = [
"*Order List for Trade #*`{trade_id}`"
]
lines_detail = self._prepare_order_details(
r['orders'], r['quote_currency'], r['is_open'])
lines.extend(lines_detail if lines_detail else "")
await self.__send_order_msg(lines, r)
async def __send_order_msg(self, lines: List[str], r: Dict[str, Any]) -> None:
"""
Send status message.
"""
msg = ''
for line in lines:
if line:
if (len(msg) + len(line) + 1) < MAX_MESSAGE_LENGTH:
msg += line + '\n'
else:
await self._send_msg(msg.format(**r))
msg = "*Order List for Trade #*`{trade_id}` - continued\n" + line + '\n'
await self._send_msg(msg.format(**r))
@authorized_only
async def _status(self, update: Update, context: CallbackContext) -> None:
"""
@@ -652,9 +694,6 @@ class Telegram(RPCHandler):
"*Open Order:* `{open_orders}`"
+ ("- `{exit_order_status}`" if r['exit_order_status'] else ""))
lines_detail = self._prepare_order_details(
r['orders'], r['quote_currency'], r['is_open'])
lines.extend(lines_detail if lines_detail else "")
await self.__send_status_msg(lines, r)
async def __send_status_msg(self, lines: List[str], r: Dict[str, Any]) -> None:
@@ -1149,12 +1188,19 @@ class Telegram(RPCHandler):
async def _force_enter_inline(self, update: Update, _: CallbackContext) -> None:
if update.callback_query:
query = update.callback_query
if query.data and '_||_' in query.data:
pair, side = query.data.split('_||_')
order_side = SignalDirection(side)
await query.answer()
await query.edit_message_text(text=f"Manually entering {order_side} for {pair}")
await self._force_enter_action(pair, None, order_side)
if query.data and '__' in query.data:
# Input data is "force_enter__<pair|cancel>_<side>"
payload = query.data.split("__")[1]
if payload == 'cancel':
await query.answer()
await query.edit_message_text(text="Force enter canceled.")
return
if payload and '_||_' in payload:
pair, side = payload.split('_||_')
order_side = SignalDirection(side)
await query.answer()
await query.edit_message_text(text=f"Manually entering {order_side} for {pair}")
await self._force_enter_action(pair, None, order_side)
@staticmethod
def _layout_inline_keyboard(
@@ -1183,12 +1229,14 @@ class Telegram(RPCHandler):
else:
whitelist = self._rpc._rpc_whitelist()['whitelist']
pair_buttons = [
InlineKeyboardButton(text=pair, callback_data=f"{pair}_||_{order_side}")
for pair in sorted(whitelist)
InlineKeyboardButton(
text=pair, callback_data=f"force_enter__{pair}_||_{order_side}"
) for pair in sorted(whitelist)
]
buttons_aligned = self._layout_inline_keyboard(pair_buttons)
buttons_aligned.append([InlineKeyboardButton(text='Cancel', callback_data='cancel')])
buttons_aligned.append([InlineKeyboardButton(text='Cancel',
callback_data='force_enter__cancel')])
await self._send_msg(msg="Which pair?",
keyboard=buttons_aligned,
query=update.callback_query)
@@ -1369,7 +1417,7 @@ class Telegram(RPCHandler):
stat_line = (
f"{i+1}.\t <code>{trade['mix_tag']}\t"
f"{round_coin_value(trade['profit_abs'], self._config['stake_currency'])} "
f"({trade['profit']:.2%}) "
f"({trade['profit_ratio']:.2%}) "
f"({trade['count']})</code>\n")
if len(output + stat_line) >= MAX_MESSAGE_LENGTH:
+1 -1
View File
@@ -84,7 +84,7 @@ class Webhook(RPCHandler):
valuedict = self._get_value_dict(msg)
if not valuedict:
logger.info("Message type '%s' not configured for webhooks", msg['type'])
logger.debug("Message type '%s' not configured for webhooks", msg['type'])
return
payload = {key: value.format(**msg) for (key, value) in valuedict.items()}
+27 -14
View File
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Any, Callable, Optional, Union
from typing import Any, Callable, Dict, Optional, Union
from pandas import DataFrame
@@ -38,17 +38,18 @@ def informative(timeframe: str, asset: str = '',
:param timeframe: Informative timeframe. Must always be equal or higher than strategy timeframe.
:param asset: Informative asset, for example BTC, BTC/USDT, ETH/BTC. Do not specify to use
current pair.
current pair. Also supports limited pair format strings (see below)
:param fmt: Column format (str) or column formatter (callable(name, asset, timeframe)). When not
specified, defaults to:
* {base}_{quote}_{column}_{timeframe} if asset is specified.
* {column}_{timeframe} if asset is not specified.
Format string supports these format variables:
* {asset} - full name of the asset, for example 'BTC/USDT'.
Pair format supports these format variables:
* {base} - base currency in lower case, for example 'eth'.
* {BASE} - same as {base}, except in upper case.
* {quote} - quote currency in lower case, for example 'usdt'.
* {QUOTE} - same as {quote}, except in upper case.
Format string additionally supports this variables.
* {asset} - full name of the asset, for example 'BTC/USDT'.
* {column} - name of dataframe column.
* {timeframe} - timeframe of informative dataframe.
:param ffill: ffill dataframe after merging informative pair.
@@ -68,9 +69,25 @@ def informative(timeframe: str, asset: str = '',
return decorator
def _format_pair_name(config, pair: str) -> str:
return pair.format(stake_currency=config['stake_currency'],
stake=config['stake_currency']).upper()
def __get_pair_formats(market: Optional[Dict[str, Any]]) -> Dict[str, str]:
if not market:
return {}
base = market['base']
quote = market['quote']
return {
'base': base.lower(),
'BASE': base.upper(),
'quote': quote.lower(),
'QUOTE': quote.upper(),
}
def _format_pair_name(config, pair: str, market: Optional[Dict[str, Any]] = None) -> str:
return pair.format(
stake_currency=config['stake_currency'],
stake=config['stake_currency'],
**__get_pair_formats(market),
).upper()
def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata: dict,
@@ -85,7 +102,8 @@ def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata:
if asset:
# Insert stake currency if needed.
asset = _format_pair_name(config, asset)
market1 = strategy.dp.market(metadata['pair'])
asset = _format_pair_name(config, asset, market1)
else:
# Not specifying an asset will define informative dataframe for current pair.
asset = metadata['pair']
@@ -93,8 +111,6 @@ def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata:
market = strategy.dp.market(asset)
if market is None:
raise OperationalException(f'Market {asset} is not available.')
base = market['base']
quote = market['quote']
# Default format. This optimizes for the common case: informative pairs using same stake
# currency. When quote currency matches stake currency, column name will omit base currency.
@@ -117,10 +133,7 @@ def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata:
formatter = fmt.format # A default string formatter.
fmt_args = {
'BASE': base.upper(),
'QUOTE': quote.upper(),
'base': base.lower(),
'quote': quote.lower(),
**__get_pair_formats(market),
'asset': asset,
'timeframe': timeframe,
}
+25 -14
View File
@@ -756,12 +756,23 @@ class IStrategy(ABC, HyperStrategyMixin):
candle_type = (inf_data.candle_type if inf_data.candle_type
else self.config.get('candle_type_def', CandleType.SPOT))
if inf_data.asset:
pair_tf = (
_format_pair_name(self.config, inf_data.asset),
inf_data.timeframe,
candle_type,
)
informative_pairs.append(pair_tf)
if any(s in inf_data.asset for s in ("{BASE}", "{base}")):
for pair in self.dp.current_whitelist():
pair_tf = (
_format_pair_name(self.config, inf_data.asset, self.dp.market(pair)),
inf_data.timeframe,
candle_type,
)
informative_pairs.append(pair_tf)
else:
pair_tf = (
_format_pair_name(self.config, inf_data.asset),
inf_data.timeframe,
candle_type,
)
informative_pairs.append(pair_tf)
else:
for pair in self.dp.current_whitelist():
informative_pairs.append((pair, inf_data.timeframe, candle_type))
@@ -1006,7 +1017,7 @@ class IStrategy(ABC, HyperStrategyMixin):
exit_ = latest.get(SignalType.EXIT_LONG.value, 0) == 1
exit_tag = latest.get(SignalTagType.EXIT_TAG.value, None)
# Tags can be None, which does not resolve to False.
exit_tag = exit_tag if isinstance(exit_tag, str) else None
exit_tag = exit_tag if isinstance(exit_tag, str) and exit_tag != 'nan' else None
logger.debug(f"exit-trigger: {latest['date']} (pair={pair}) "
f"enter={enter} exit={exit_}")
@@ -1038,17 +1049,17 @@ class IStrategy(ABC, HyperStrategyMixin):
exit_short = latest.get(SignalType.EXIT_SHORT.value, 0) == 1
enter_signal: Optional[SignalDirection] = None
enter_tag_value: Optional[str] = None
enter_tag: Optional[str] = None
if enter_long == 1 and not any([exit_long, enter_short]):
enter_signal = SignalDirection.LONG
enter_tag_value = latest.get(SignalTagType.ENTER_TAG.value, None)
enter_tag = latest.get(SignalTagType.ENTER_TAG.value, None)
if (self.config.get('trading_mode', TradingMode.SPOT) != TradingMode.SPOT
and self.can_short
and enter_short == 1 and not any([exit_short, enter_long])):
enter_signal = SignalDirection.SHORT
enter_tag_value = latest.get(SignalTagType.ENTER_TAG.value, None)
enter_tag = latest.get(SignalTagType.ENTER_TAG.value, None)
enter_tag_value = enter_tag_value if isinstance(enter_tag_value, str) else None
enter_tag = enter_tag if isinstance(enter_tag, str) and enter_tag != 'nan' else None
timeframe_seconds = timeframe_to_seconds(timeframe)
@@ -1058,11 +1069,11 @@ class IStrategy(ABC, HyperStrategyMixin):
timeframe_seconds=timeframe_seconds,
enter=bool(enter_signal)
):
return None, enter_tag_value
return None, enter_tag
logger.debug(f"entry trigger: {latest['date']} (pair={pair}) "
f"enter={enter_long} enter_tag_value={enter_tag_value}")
return enter_signal, enter_tag_value
f"enter={enter_long} enter_tag_value={enter_tag}")
return enter_signal, enter_tag
def ignore_expired_candle(
self,
+11 -8
View File
@@ -36,7 +36,7 @@ def merge_informative_pair(dataframe: pd.DataFrame, informative: pd.DataFrame,
:return: Merged dataframe
:raise: ValueError if the secondary timeframe is shorter than the dataframe timeframe
"""
informative = informative.copy()
minutes_inf = timeframe_to_minutes(timeframe_inf)
minutes = timeframe_to_minutes(timeframe)
if minutes == minutes_inf:
@@ -46,10 +46,16 @@ def merge_informative_pair(dataframe: pd.DataFrame, informative: pd.DataFrame,
# Subtract "small" timeframe so merging is not delayed by 1 small candle
# Detailed explanation in https://github.com/freqtrade/freqtrade/issues/4073
if not informative.empty:
informative['date_merge'] = (
informative[date_column] + pd.to_timedelta(minutes_inf, 'm') -
pd.to_timedelta(minutes, 'm')
)
if timeframe_inf == '1M':
informative['date_merge'] = (
(informative[date_column] + pd.offsets.MonthBegin(1))
- pd.to_timedelta(minutes, 'm')
)
else:
informative['date_merge'] = (
informative[date_column] + pd.to_timedelta(minutes_inf, 'm') -
pd.to_timedelta(minutes, 'm')
)
else:
informative['date_merge'] = informative[date_column]
else:
@@ -80,9 +86,6 @@ def merge_informative_pair(dataframe: pd.DataFrame, informative: pd.DataFrame,
right_on=date_merge, how='left')
dataframe = dataframe.drop(date_merge, axis=1)
# if ffill:
# dataframe = dataframe.ffill()
return dataframe
+5 -21
View File
@@ -6,7 +6,7 @@ import talib.abstract as ta
from pandas import DataFrame
from technical import qtpylib
from freqtrade.strategy import CategoricalParameter, IStrategy
from freqtrade.strategy import IStrategy
logger = logging.getLogger(__name__)
@@ -45,11 +45,6 @@ class FreqaiExampleStrategy(IStrategy):
startup_candle_count: int = 40
can_short = True
std_dev_multiplier_buy = CategoricalParameter(
[0.75, 1, 1.25, 1.5, 1.75], default=1.25, space="buy", optimize=True)
std_dev_multiplier_sell = CategoricalParameter(
[0.75, 1, 1.25, 1.5, 1.75], space="sell", default=1.25, optimize=True)
def feature_engineering_expand_all(self, dataframe: DataFrame, period: int,
metadata: Dict, **kwargs) -> DataFrame:
"""
@@ -239,21 +234,13 @@ class FreqaiExampleStrategy(IStrategy):
dataframe = self.freqai.start(dataframe, metadata, self)
for val in self.std_dev_multiplier_buy.range:
dataframe[f'target_roi_{val}'] = (
dataframe["&-s_close_mean"] + dataframe["&-s_close_std"] * val
)
for val in self.std_dev_multiplier_sell.range:
dataframe[f'sell_roi_{val}'] = (
dataframe["&-s_close_mean"] - dataframe["&-s_close_std"] * val
)
return dataframe
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
enter_long_conditions = [
df["do_predict"] == 1,
df["&-s_close"] > df[f"target_roi_{self.std_dev_multiplier_buy.value}"],
df["&-s_close"] > 0.01,
]
if enter_long_conditions:
@@ -263,7 +250,7 @@ class FreqaiExampleStrategy(IStrategy):
enter_short_conditions = [
df["do_predict"] == 1,
df["&-s_close"] < df[f"sell_roi_{self.std_dev_multiplier_sell.value}"],
df["&-s_close"] < -0.01,
]
if enter_short_conditions:
@@ -276,23 +263,20 @@ class FreqaiExampleStrategy(IStrategy):
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
exit_long_conditions = [
df["do_predict"] == 1,
df["&-s_close"] < df[f"sell_roi_{self.std_dev_multiplier_sell.value}"] * 0.25,
df["&-s_close"] < 0
]
if exit_long_conditions:
df.loc[reduce(lambda x, y: x & y, exit_long_conditions), "exit_long"] = 1
exit_short_conditions = [
df["do_predict"] == 1,
df["&-s_close"] > df[f"target_roi_{self.std_dev_multiplier_buy.value}"] * 0.25,
df["&-s_close"] > 0
]
if exit_short_conditions:
df.loc[reduce(lambda x, y: x & y, exit_short_conditions), "exit_short"] = 1
return df
def get_ticker_indicator(self):
return int(self.config["timeframe"][:-1])
def confirm_trade_entry(
self,
pair: str,
+1 -1
View File
@@ -39,7 +39,7 @@
},
{{ exchange | indent(4) }},
"pairlists": [
{{ '{"method": "StaticPairList"}' if exchange_name == 'bittrex' else volume_pairlist }}
{{ volume_pairlist }}
],
"telegram": {
"enabled": {{ telegram | lower }},
+7 -6
View File
@@ -6,7 +6,7 @@ from copy import deepcopy
from datetime import datetime, timedelta
from typing import Dict, NamedTuple, Optional
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT, Config
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT, Config, IntOrInf
from freqtrade.enums import RunMode, TradingMode
from freqtrade.exceptions import DependencyException
from freqtrade.exchange import Exchange
@@ -262,15 +262,15 @@ class Wallets:
return min(self.get_total_stake_amount() - Trade.total_open_trades_stakes(), free)
def _calculate_unlimited_stake_amount(self, available_amount: float,
val_tied_up: float) -> float:
val_tied_up: float, max_open_trades: IntOrInf) -> float:
"""
Calculate stake amount for "unlimited" stake amount
:return: 0 if max number of trades reached, else stake_amount to use.
"""
if self._config['max_open_trades'] == 0:
if max_open_trades == 0:
return 0
possible_stake = (available_amount + val_tied_up) / self._config['max_open_trades']
possible_stake = (available_amount + val_tied_up) / max_open_trades
# Theoretical amount can be above available amount - therefore limit to available amount!
return min(possible_stake, available_amount)
@@ -298,7 +298,8 @@ class Wallets:
return stake_amount
def get_trade_stake_amount(self, pair: str, edge=None, update: bool = True) -> float:
def get_trade_stake_amount(
self, pair: str, max_open_trades: IntOrInf, edge=None, update: bool = True) -> float:
"""
Calculate stake amount for the trade
:return: float: Stake amount
@@ -322,7 +323,7 @@ class Wallets:
stake_amount = self._config['stake_amount']
if stake_amount == UNLIMITED_STAKE_AMOUNT:
stake_amount = self._calculate_unlimited_stake_amount(
available_amount, val_tied_up)
available_amount, val_tied_up, max_open_trades)
return self._check_available_stake_amount(stake_amount, available_amount)
+65
View File
@@ -2,6 +2,55 @@
requires = ["setuptools >= 64.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "freqtrade"
dynamic = ["version", "dependencies", "optional-dependencies"]
authors = [
{name = "Freqtrade Team"},
{name = "Freqtrade Team", email = "freqtrade@protonmail.com"},
]
description = "Freqtrade - Crypto Trading Bot"
readme = "README.md"
requires-python = ">=3.9"
license = {text = "GPLv3"}
# license = "GPLv3"
classifiers = [
"Environment :: Console",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Operating System :: MacOS",
"Operating System :: Unix",
"Topic :: Office/Business :: Financial :: Investment",
]
[project.urls]
Homepage = "https://github.com/freqtrade/freqtrade"
Documentation = "https://freqtrade.io"
"Bug Tracker" = "https://github.com/freqtrade/freqtrade/issues"
[project.scripts]
freqtrade = "freqtrade.main:main"
[tool.setuptools]
include-package-data = true
zip-safe = false
[tool.setuptools.packages.find]
where = ["."]
include = ["freqtrade*"]
exclude = ["tests", "tests.*"]
namespaces = true
[tool.setuptools.dynamic]
version = {attr = "freqtrade.__version__"}
[tool.black]
line-length = 100
exclude = '''
@@ -31,6 +80,7 @@ skip_glob = ["**/.env*", "**/env/*", "**/.venv/*", "**/docs/*", "**/user_data/*"
[tool.pytest.ini_options]
asyncio_mode = "auto"
addopts = "--dist loadscope"
[tool.mypy]
ignore_missing_imports = true
@@ -93,3 +143,18 @@ max-complexity = 12
[tool.ruff.per-file-ignores]
"tests/*" = ["S"]
[tool.flake8]
# Default from https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-ignore
# minus E226
ignore = ["E121","E123","E126","E24","E704","W503","W504"]
max-line-length = 100
max-complexity = 12
exclude = [
".git",
"__pycache__",
".eggs",
"user_data",
".venv",
".env",
]
+8 -7
View File
@@ -7,23 +7,24 @@
-r docs/requirements-docs.txt
coveralls==3.3.1
ruff==0.1.1
mypy==1.6.1
pre-commit==3.5.0
pytest==7.4.2
ruff==0.1.9
mypy==1.8.0
pre-commit==3.6.0
pytest==7.4.3
pytest-asyncio==0.21.1
pytest-cov==4.1.0
pytest-mock==3.12.0
pytest-random-order==1.1.0
isort==5.12.0
pytest-xdist==3.5.0
isort==5.13.2
# For datetime mocking
time-machine==2.13.0
# Convert jupyter notebooks to markdown documents
nbconvert==7.9.2
nbconvert==7.13.1
# mypy types
types-cachetools==5.3.0.6
types-cachetools==5.3.0.7
types-filelock==3.2.7
types-requests==2.31.0.10
types-tabulate==0.9.0.3
+2 -2
View File
@@ -2,10 +2,10 @@
-r requirements-freqai.txt
# Required for freqai-rl
torch==2.0.1
torch==2.1.2
#until these branches will be released we can use this
gymnasium==0.29.1
stable_baselines3==2.1.0
stable_baselines3==2.2.1
sb3_contrib>=2.0.0a9
# Progress bar for stable-baselines3 and sb3-contrib
tqdm==4.66.1
+4 -4
View File
@@ -3,10 +3,10 @@
-r requirements-plot.txt
# Required for freqai
scikit-learn==1.1.3
scikit-learn==1.3.2
joblib==1.3.2
catboost==1.2.2; 'arm' not in platform_machine
lightgbm==4.1.0
xgboost==2.0.0
tensorboard==2.15.0
lightgbm==4.2.0
xgboost==2.0.3
tensorboard==2.15.1
datasieve==0.1.7
+4 -4
View File
@@ -2,7 +2,7 @@
-r requirements.txt
# Required for hyperopt
scipy==1.11.3
scikit-learn==1.1.3
scikit-optimize==0.9.0
filelock==3.12.4
scipy==1.11.4
scikit-learn==1.3.2
ft-scikit-optimize==0.9.2
filelock==3.13.1
+1 -1
View File
@@ -1,4 +1,4 @@
# Include all requirements to run the bot.
-r requirements.txt
plotly==5.17.0
plotly==5.18.0
+22 -24
View File
@@ -1,49 +1,47 @@
numpy==1.25.2; platform_machine == 'armv7l'
numpy==1.26.1; platform_machine != 'armv7l'
pandas==2.0.3
numpy==1.26.2
pandas==2.1.4
pandas-ta==0.3.14b
ccxt==4.1.22
cryptography==41.0.4
aiohttp==3.8.6
SQLAlchemy==2.0.22
python-telegram-bot==20.6
ccxt==4.1.98
cryptography==41.0.7
aiohttp==3.9.1
SQLAlchemy==2.0.23
python-telegram-bot==20.7
# can't be hard-pinned due to telegram-bot pinning httpx with ~
httpx>=0.24.1
arrow==1.3.0
cachetools==5.3.1
cachetools==5.3.2
requests==2.31.0
urllib3==2.0.7
jsonschema==4.19.1
urllib3==2.1.0
jsonschema==4.20.0
TA-Lib==0.4.28
technical==1.4.0
technical==1.4.2
tabulate==0.9.0
pycoingecko==3.1.0
jinja2==3.1.2
tables==3.8.0
blosc==1.11.1
tables==3.9.1
joblib==1.3.2
rich==13.6.0
pyarrow==13.0.0; platform_machine != 'armv7l'
rich==13.7.0
pyarrow==14.0.2; platform_machine != 'armv7l'
# find first, C search in arrays
py_find_1st==1.1.5
py_find_1st==1.1.6
# Load ticker files 30% faster
python-rapidjson==1.12
python-rapidjson==1.14
# Properly format api responses
orjson==3.9.9
orjson==3.9.10
# Notify systemd
sdnotify==0.3.2
# API Server
fastapi==0.104.0
pydantic==2.4.2
uvicorn==0.23.2
fastapi==0.105.0
pydantic==2.5.3
uvicorn==0.25.0
pyjwt==2.8.0
aiofiles==23.2.1
psutil==5.9.6
psutil==5.9.7
# Support for colorized terminal output
colorama==0.4.6
@@ -60,5 +58,5 @@ schedule==1.2.1
websockets==12.0
janus==1.0.0
ast-comments==1.1.2
ast-comments==1.2.0
packaging==23.2
+24
View File
@@ -112,6 +112,30 @@ class FtRestClient:
"""
return self._get("count")
def entries(self, pair=None):
"""Returns List of dicts containing all Trades, based on buy tag performance
Can either be average for all pairs or a specific pair provided
:return: json object
"""
return self._get("entries", params={"pair": pair} if pair else None)
def exits(self, pair=None):
"""Returns List of dicts containing all Trades, based on exit reason performance
Can either be average for all pairs or a specific pair provided
:return: json object
"""
return self._get("exits", params={"pair": pair} if pair else None)
def mix_tags(self, pair=None):
"""Returns List of dicts containing all Trades, based on entry_tag + exit_reason performance
Can either be average for all pairs or a specific pair provided
:return: json object
"""
return self._get("mix_tags", params={"pair": pair} if pair else None)
def locks(self):
"""Return current locks
-53
View File
@@ -1,53 +0,0 @@
[metadata]
name = freqtrade
version = attr: freqtrade.__version__
author = Freqtrade Team
author_email = freqtrade@protonmail.com
description = Freqtrade - Crypto Trading Bot
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/freqtrade/freqtrade
project_urls =
Bug Tracker = https://github.com/freqtrade/freqtrade/issues
license = GPLv3
classifiers =
Environment :: Console
Intended Audience :: Science/Research
License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Operating System :: MacOS
Operating System :: Unix
Topic :: Office/Business :: Financial :: Investment
[options]
zip_safe = False
include_package_data = True
tests_require =
pytest
pytest-asyncio
pytest-cov
pytest-mock
packages = find:
python_requires = >=3.9
[options.entry_points]
console_scripts =
freqtrade = freqtrade.main:main
[flake8]
# Default from https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-ignore
# minus E226
ignore = E121,E123,E126,E24,E704,W503,W504
max-line-length = 100
max-complexity = 12
exclude =
.git,
__pycache__,
.eggs,
user_data,
.venv
.env
+3 -2
View File
@@ -5,8 +5,8 @@ from setuptools import setup
plot = ['plotly>=4.0']
hyperopt = [
'scipy',
'scikit-learn<=1.1.3',
'scikit-optimize>=0.7.0',
'scikit-learn',
'ft-scikit-optimize>=0.9.2',
'filelock',
]
@@ -122,4 +122,5 @@ setup(
'freqai_rl': freqai_rl,
'all': all_extra,
},
url="https://github.com/freqtrade/freqtrade",
)
+1 -1
View File
@@ -30,7 +30,7 @@ def test_validate_is_int():
assert not validate_is_int('-ee')
@pytest.mark.parametrize('exchange', ['bittrex', 'binance', 'kraken'])
@pytest.mark.parametrize('exchange', ['bybit', 'binance', 'kraken'])
def test_start_new_config(mocker, caplog, exchange):
wt_mock = mocker.patch.object(Path, "write_text", MagicMock())
mocker.patch.object(Path, "exists", MagicMock(return_value=True))
+65 -65
View File
@@ -32,7 +32,7 @@ from tests.conftest_trades import MOCK_TRADE_COUNT
def test_setup_utils_configuration():
args = [
'list-exchanges', '--config', 'config_examples/config_bittrex.example.json',
'list-exchanges', '--config', 'tests/testdata/testconfigs/main_test_config.json',
]
config = setup_utils_configuration(get_args(args), RunMode.OTHER)
@@ -49,7 +49,7 @@ def test_start_trading_fail(mocker, caplog):
exitmock = mocker.patch("freqtrade.worker.Worker.exit", MagicMock())
args = [
'trade',
'-c', 'config_examples/config_bittrex.example.json'
'-c', 'tests/testdata/testconfigs/main_test_config.json'
]
start_trading(get_args(args))
assert exitmock.call_count == 1
@@ -68,7 +68,7 @@ def test_start_webserver(mocker, caplog):
args = [
'webserver',
'-c', 'config_examples/config_bittrex.example.json'
'-c', 'tests/testdata/testconfigs/main_test_config.json'
]
start_webserver(get_args(args))
assert api_server_mock.call_count == 1
@@ -84,7 +84,7 @@ def test_list_exchanges(capsys):
captured = capsys.readouterr()
assert re.match(r"Exchanges available for Freqtrade.*", captured.out)
assert re.search(r".*binance.*", captured.out)
assert re.search(r".*bittrex.*", captured.out)
assert re.search(r".*bybit.*", captured.out)
# Test with --one-column
args = [
@@ -95,7 +95,7 @@ def test_list_exchanges(capsys):
start_list_exchanges(get_args(args))
captured = capsys.readouterr()
assert re.search(r"^binance$", captured.out, re.MULTILINE)
assert re.search(r"^bittrex$", captured.out, re.MULTILINE)
assert re.search(r"^bybit$", captured.out, re.MULTILINE)
# Test with --all
args = [
@@ -107,7 +107,7 @@ def test_list_exchanges(capsys):
captured = capsys.readouterr()
assert re.match(r"All exchanges supported by the ccxt library.*", captured.out)
assert re.search(r".*binance.*", captured.out)
assert re.search(r".*bittrex.*", captured.out)
assert re.search(r".*bingx.*", captured.out)
assert re.search(r".*bitmex.*", captured.out)
# Test with --one-column --all
@@ -120,7 +120,7 @@ def test_list_exchanges(capsys):
start_list_exchanges(get_args(args))
captured = capsys.readouterr()
assert re.search(r"^binance$", captured.out, re.MULTILINE)
assert re.search(r"^bittrex$", captured.out, re.MULTILINE)
assert re.search(r"^bingx$", captured.out, re.MULTILINE)
assert re.search(r"^bitmex$", captured.out, re.MULTILINE)
@@ -133,7 +133,7 @@ def test_list_timeframes(mocker, capsys):
'1h': 'hour',
'1d': 'day',
}
patch_exchange(mocker, api_mock=api_mock, id='bittrex')
patch_exchange(mocker, api_mock=api_mock, id='bybit')
args = [
"list-timeframes",
]
@@ -143,25 +143,25 @@ def test_list_timeframes(mocker, capsys):
match=r"This command requires a configured exchange.*"):
start_list_timeframes(pargs)
# Test with --config config_examples/config_bittrex.example.json
# Test with --config tests/testdata/testconfigs/main_test_config.json
args = [
"list-timeframes",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
]
start_list_timeframes(get_args(args))
captured = capsys.readouterr()
assert re.match("Timeframes available for the exchange `Bittrex`: "
assert re.match("Timeframes available for the exchange `Bybit`: "
"1m, 5m, 30m, 1h, 1d",
captured.out)
# Test with --exchange bittrex
# Test with --exchange bybit
args = [
"list-timeframes",
"--exchange", "bittrex",
"--exchange", "bybit",
]
start_list_timeframes(get_args(args))
captured = capsys.readouterr()
assert re.match("Timeframes available for the exchange `Bittrex`: "
assert re.match("Timeframes available for the exchange `Bybit`: "
"1m, 5m, 30m, 1h, 1d",
captured.out)
@@ -190,7 +190,7 @@ def test_list_timeframes(mocker, capsys):
# Test with --one-column
args = [
"list-timeframes",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--one-column",
]
start_list_timeframes(get_args(args))
@@ -217,7 +217,7 @@ def test_list_timeframes(mocker, capsys):
def test_list_markets(mocker, markets_static, capsys):
api_mock = MagicMock()
patch_exchange(mocker, api_mock=api_mock, id='bittrex', mock_markets=markets_static)
patch_exchange(mocker, api_mock=api_mock, id='binance', mock_markets=markets_static)
# Test with no --config
args = [
@@ -229,15 +229,15 @@ def test_list_markets(mocker, markets_static, capsys):
match=r"This command requires a configured exchange.*"):
start_list_markets(pargs, False)
# Test with --config config_examples/config_bittrex.example.json
# Test with --config tests/testdata/testconfigs/main_test_config.json
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 12 active markets: "
assert ("Exchange Binance has 12 active markets: "
"ADA/USDT:USDT, BLK/BTC, ETH/BTC, ETH/USDT, ETH/USDT:USDT, LTC/BTC, "
"LTC/ETH, LTC/USD, NEO/BTC, TKN/BTC, XLTCUSDT, XRP/BTC.\n"
in captured.out)
@@ -255,16 +255,16 @@ def test_list_markets(mocker, markets_static, capsys):
assert re.match("\nExchange Binance has 12 active markets:\n",
captured.out)
patch_exchange(mocker, api_mock=api_mock, id="bittrex", mock_markets=markets_static)
patch_exchange(mocker, api_mock=api_mock, id="binance", mock_markets=markets_static)
# Test with --all: all markets
args = [
"list-markets", "--all",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 14 markets: "
assert ("Exchange Binance has 14 markets: "
"ADA/USDT:USDT, BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, ETH/USDT:USDT, "
"LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, TKN/BTC, XLTCUSDT, XRP/BTC.\n"
in captured.out)
@@ -272,24 +272,24 @@ def test_list_markets(mocker, markets_static, capsys):
# Test list-pairs subcommand: active pairs
args = [
"list-pairs",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--print-list",
]
start_list_markets(get_args(args), True)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 9 active pairs: "
assert ("Exchange Binance has 9 active pairs: "
"BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, NEO/BTC, TKN/BTC, XRP/BTC.\n"
in captured.out)
# Test list-pairs subcommand with --all: all pairs
args = [
"list-pairs", "--all",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--print-list",
]
start_list_markets(get_args(args), True)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 11 pairs: "
assert ("Exchange Binance has 11 pairs: "
"BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, "
"TKN/BTC, XRP/BTC.\n"
in captured.out)
@@ -297,133 +297,133 @@ def test_list_markets(mocker, markets_static, capsys):
# active markets, base=ETH, LTC
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--base", "ETH", "LTC",
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 7 active markets with ETH, LTC as base currencies: "
assert ("Exchange Binance has 7 active markets with ETH, LTC as base currencies: "
"ETH/BTC, ETH/USDT, ETH/USDT:USDT, LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n"
in captured.out)
# active markets, base=LTC
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--base", "LTC",
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 4 active markets with LTC as base currency: "
assert ("Exchange Binance has 4 active markets with LTC as base currency: "
"LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n"
in captured.out)
# active markets, quote=USDT, USD
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--quote", "USDT", "USD",
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 5 active markets with USDT, USD as quote currencies: "
assert ("Exchange Binance has 5 active markets with USDT, USD as quote currencies: "
"ADA/USDT:USDT, ETH/USDT, ETH/USDT:USDT, LTC/USD, XLTCUSDT.\n"
in captured.out)
# active markets, quote=USDT
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--quote", "USDT",
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 4 active markets with USDT as quote currency: "
assert ("Exchange Binance has 4 active markets with USDT as quote currency: "
"ADA/USDT:USDT, ETH/USDT, ETH/USDT:USDT, XLTCUSDT.\n"
in captured.out)
# active markets, base=LTC, quote=USDT
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--base", "LTC", "--quote", "USDT",
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 1 active market with LTC as base currency and "
assert ("Exchange Binance has 1 active market with LTC as base currency and "
"with USDT as quote currency: XLTCUSDT.\n"
in captured.out)
# active pairs, base=LTC, quote=USDT
args = [
"list-pairs",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--base", "LTC", "--quote", "USD",
"--print-list",
]
start_list_markets(get_args(args), True)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 1 active pair with LTC as base currency and "
assert ("Exchange Binance has 1 active pair with LTC as base currency and "
"with USD as quote currency: LTC/USD.\n"
in captured.out)
# active markets, base=LTC, quote=USDT, NONEXISTENT
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--base", "LTC", "--quote", "USDT", "NONEXISTENT",
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 1 active market with LTC as base currency and "
assert ("Exchange Binance has 1 active market with LTC as base currency and "
"with USDT, NONEXISTENT as quote currencies: XLTCUSDT.\n"
in captured.out)
# active markets, base=LTC, quote=NONEXISTENT
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--base", "LTC", "--quote", "NONEXISTENT",
"--print-list",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 0 active markets with LTC as base currency and "
assert ("Exchange Binance has 0 active markets with LTC as base currency and "
"with NONEXISTENT as quote currency.\n"
in captured.out)
# Test tabular output
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 12 active markets:\n"
assert ("Exchange Binance has 12 active markets:\n"
in captured.out)
# Test tabular output, no markets found
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--base", "LTC", "--quote", "NONEXISTENT",
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
assert ("Exchange Bittrex has 0 active markets with LTC as base currency and "
assert ("Exchange Binance has 0 active markets with LTC as base currency and "
"with NONEXISTENT as quote currency.\n"
in captured.out)
# Test --print-json
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--print-json"
]
start_list_markets(get_args(args), False)
@@ -435,7 +435,7 @@ def test_list_markets(mocker, markets_static, capsys):
# Test --print-csv
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--print-csv"
]
start_list_markets(get_args(args), False)
@@ -447,7 +447,7 @@ def test_list_markets(mocker, markets_static, capsys):
# Test --one-column
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--one-column"
]
start_list_markets(get_args(args), False)
@@ -459,7 +459,7 @@ def test_list_markets(mocker, markets_static, capsys):
# Test --one-column
args = [
"list-markets",
'--config', 'config_examples/config_bittrex.example.json',
'--config', 'tests/testdata/testconfigs/main_test_config.json',
"--one-column"
]
with pytest.raises(OperationalException, match=r"Cannot get markets.*"):
@@ -550,7 +550,7 @@ def test_start_install_ui(mocker):
assert download_mock.call_count == 0
def test_clean_ui_subdir(mocker, tmpdir, caplog):
def test_clean_ui_subdir(mocker, tmp_path, caplog):
mocker.patch("freqtrade.commands.deploy_commands.Path.is_dir",
side_effect=[True, True])
mocker.patch("freqtrade.commands.deploy_commands.Path.is_file",
@@ -560,14 +560,14 @@ def test_clean_ui_subdir(mocker, tmpdir, caplog):
mocker.patch("freqtrade.commands.deploy_commands.Path.glob",
return_value=[Path('test1'), Path('test2'), Path('.gitkeep')])
folder = Path(tmpdir) / "uitests"
folder = tmp_path / "uitests"
clean_ui_subdir(folder)
assert log_has("Removing UI directory content.", caplog)
assert rd_mock.call_count == 1
assert ul_mock.call_count == 1
def test_download_and_install_ui(mocker, tmpdir):
def test_download_and_install_ui(mocker, tmp_path):
# Create zipfile
requests_mock = MagicMock()
file_like_object = BytesIO()
@@ -583,7 +583,7 @@ def test_download_and_install_ui(mocker, tmpdir):
side_effect=[True, False])
wb_mock = mocker.patch("freqtrade.commands.deploy_commands.Path.write_bytes")
folder = Path(tmpdir) / "uitests_dl"
folder = tmp_path / "uitests_dl"
folder.mkdir(exist_ok=True)
assert read_ui_version(folder) is None
@@ -971,7 +971,7 @@ def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
patched_configuration_load_config_file(mocker, default_conf)
args = [
'test-pairlist',
'-c', 'config_examples/config_bittrex.example.json'
'-c', 'tests/testdata/testconfigs/main_test_config.json'
]
start_test_pairlist(get_args(args))
@@ -985,7 +985,7 @@ def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
args = [
'test-pairlist',
'-c', 'config_examples/config_bittrex.example.json',
'-c', 'tests/testdata/testconfigs/main_test_config.json',
'--one-column',
]
start_test_pairlist(get_args(args))
@@ -994,7 +994,7 @@ def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
args = [
'test-pairlist',
'-c', 'config_examples/config_bittrex.example.json',
'-c', 'tests/testdata/testconfigs/main_test_config.json',
'--print-json',
]
start_test_pairlist(get_args(args))
@@ -1010,8 +1010,8 @@ def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
pytest.fail(f'Expected well formed JSON, but failed to parse: {captured.out}')
def test_hyperopt_list(mocker, capsys, caplog, saved_hyperopt_results, tmpdir):
csv_file = Path(tmpdir) / "test.csv"
def test_hyperopt_list(mocker, capsys, caplog, saved_hyperopt_results, tmp_path):
csv_file = tmp_path / "test.csv"
mocker.patch(
'freqtrade.optimize.hyperopt_tools.HyperoptTools._test_hyperopt_results_exist',
return_value=True
@@ -1512,10 +1512,10 @@ def test_backtesting_show(mocker, testdatadir, capsys):
assert "Pairs for Strategy" in out
def test_start_convert_db(mocker, fee, tmpdir, caplog):
db_src_file = Path(f"{tmpdir}/db.sqlite")
def test_start_convert_db(fee, tmp_path):
db_src_file = tmp_path / "db.sqlite"
db_from = f"sqlite:///{db_src_file}"
db_target_file = Path(f"{tmpdir}/db_target.sqlite")
db_target_file = tmp_path / "db_target.sqlite"
db_to = f"sqlite:///{db_target_file}"
args = [
"convert-db",
@@ -1542,13 +1542,13 @@ def test_start_convert_db(mocker, fee, tmpdir, caplog):
assert db_target_file.is_file()
def test_start_strategy_updater(mocker, tmpdir):
def test_start_strategy_updater(mocker, tmp_path):
sc_mock = mocker.patch('freqtrade.commands.strategy_utils_commands.start_conversion')
teststrats = Path(__file__).parent.parent / 'strategy/strats'
args = [
"strategy-updater",
"--userdir",
str(tmpdir),
str(tmp_path),
"--strategy-path",
str(teststrats),
]
@@ -1562,7 +1562,7 @@ def test_start_strategy_updater(mocker, tmpdir):
args = [
"strategy-updater",
"--userdir",
str(tmpdir),
str(tmp_path),
"--strategy-path",
str(teststrats),
"--strategy-list",
+31 -5
View File
@@ -11,6 +11,7 @@ from unittest.mock import MagicMock, Mock, PropertyMock
import numpy as np
import pandas as pd
import pytest
from xdist.scheduler.loadscope import LoadScopeScheduling
from freqtrade import constants
from freqtrade.commands import Arguments
@@ -56,6 +57,27 @@ def pytest_configure(config):
setattr(config.option, 'markexpr', 'not longrun')
class FixtureScheduler(LoadScopeScheduling):
# Based on the suggestion in
# https://github.com/pytest-dev/pytest-xdist/issues/18
def _split_scope(self, nodeid):
if 'exchange_online' in nodeid:
try:
# Extract exchange ID from nodeid
exchange_id = nodeid.split('[')[1].split('-')[0].rstrip(']')
return exchange_id
except Exception as e:
print(e)
pass
return nodeid
def pytest_xdist_make_scheduler(config, log):
return FixtureScheduler(config, log)
def log_has(line, logs):
"""Check if line is found on some caplog's message."""
return any(line == message for message in logs.messages)
@@ -87,11 +109,15 @@ def get_args(args):
def generate_test_data(timeframe: str, size: int, start: str = '2020-07-05'):
np.random.seed(42)
tf_mins = timeframe_to_minutes(timeframe)
base = np.random.normal(20, 2, size=size)
date = pd.date_range(start, periods=size, freq=f'{tf_mins}min', tz='UTC')
if timeframe == '1M':
date = pd.date_range(start, periods=size, freq='1MS', tz='UTC')
elif timeframe == '1w':
date = pd.date_range(start, periods=size, freq='1W-MON', tz='UTC')
else:
tf_mins = timeframe_to_minutes(timeframe)
date = pd.date_range(start, periods=size, freq=f'{tf_mins}min', tz='UTC')
df = pd.DataFrame({
'date': date,
'open': base,
@@ -413,8 +439,8 @@ def patch_gc(mocker) -> None:
@pytest.fixture(autouse=True)
def user_dir(mocker, tmpdir) -> Path:
user_dir = Path(tmpdir) / "user_data"
def user_dir(mocker, tmp_path) -> Path:
user_dir = tmp_path / "user_data"
mocker.patch('freqtrade.configuration.configuration.create_userdata_dir',
return_value=user_dir)
return user_dir
+24 -28
View File
@@ -1,6 +1,5 @@
# pragma pylint: disable=missing-docstring, C0103
import logging
from pathlib import Path
from shutil import copyfile
import numpy as np
@@ -50,8 +49,8 @@ def test_trades_to_ohlcv(trades_history_df, caplog):
assert 'high' in df.columns
assert 'low' in df.columns
assert 'close' in df.columns
assert df.loc[:, 'high'][0] == 0.019627
assert df.loc[:, 'low'][0] == 0.019626
assert df.iloc[0, :]['high'] == 0.019627
assert df.iloc[0, :]['low'] == 0.019626
def test_ohlcv_fill_up_missing_data(testdatadir, caplog):
@@ -65,7 +64,7 @@ def test_ohlcv_fill_up_missing_data(testdatadir, caplog):
# Column names should not change
assert (data.columns == data2.columns).all()
assert log_has_re(f"Missing data fillup for UNITTEST/BTC: before: "
assert log_has_re(f"Missing data fillup for UNITTEST/BTC, 1m: before: "
f"{len(data)} - after: {len(data2)}.*", caplog)
# Test fillup actually fixes invalid backtest data
@@ -129,7 +128,7 @@ def test_ohlcv_fill_up_missing_data2(caplog):
# Column names should not change
assert (data.columns == data2.columns).all()
assert log_has_re(f"Missing data fillup for UNITTEST/BTC: before: "
assert log_has_re(f"Missing data fillup for UNITTEST/BTC, {timeframe}: before: "
f"{len(data)} - after: {len(data2)}.*", caplog)
@@ -323,18 +322,17 @@ def test_trades_dict_to_list(fetch_trades_result):
assert t[6] == fetch_trades_result[i]['cost']
def test_convert_trades_format(default_conf, testdatadir, tmpdir):
tmpdir1 = Path(tmpdir)
files = [{'old': tmpdir1 / "XRP_ETH-trades.json.gz",
'new': tmpdir1 / "XRP_ETH-trades.json"},
{'old': tmpdir1 / "XRP_OLD-trades.json.gz",
'new': tmpdir1 / "XRP_OLD-trades.json"},
def test_convert_trades_format(default_conf, testdatadir, tmp_path):
files = [{'old': tmp_path / "XRP_ETH-trades.json.gz",
'new': tmp_path / "XRP_ETH-trades.json"},
{'old': tmp_path / "XRP_OLD-trades.json.gz",
'new': tmp_path / "XRP_OLD-trades.json"},
]
for file in files:
copyfile(testdatadir / file['old'].name, file['old'])
assert not file['new'].exists()
default_conf['datadir'] = tmpdir1
default_conf['datadir'] = tmp_path
convert_trades_format(default_conf, convert_from='jsongz',
convert_to='json', erase=False)
@@ -362,16 +360,15 @@ def test_convert_trades_format(default_conf, testdatadir, tmpdir):
(['UNITTEST_USDT_USDT-1h-mark', 'XRP_USDT_USDT-1h-mark'], CandleType.MARK),
(['XRP_USDT_USDT-1h-futures'], CandleType.FUTURES),
])
def test_convert_ohlcv_format(default_conf, testdatadir, tmpdir, file_base, candletype):
tmpdir1 = Path(tmpdir)
def test_convert_ohlcv_format(default_conf, testdatadir, tmp_path, file_base, candletype):
prependix = '' if candletype == CandleType.SPOT else 'futures/'
files_orig = []
files_temp = []
files_new = []
for file in file_base:
file_orig = testdatadir / f"{prependix}{file}.feather"
file_temp = tmpdir1 / f"{prependix}{file}.feather"
file_new = tmpdir1 / f"{prependix}{file}.json.gz"
file_temp = tmp_path / f"{prependix}{file}.feather"
file_new = tmp_path / f"{prependix}{file}.json.gz"
IDataHandler.create_dir_if_needed(file_temp)
copyfile(file_orig, file_temp)
@@ -379,7 +376,7 @@ def test_convert_ohlcv_format(default_conf, testdatadir, tmpdir, file_base, cand
files_temp.append(file_temp)
files_new.append(file_new)
default_conf['datadir'] = tmpdir1
default_conf['datadir'] = tmp_path
default_conf['candle_types'] = [candletype]
if candletype == CandleType.SPOT:
@@ -445,30 +442,29 @@ def test_reduce_dataframe_footprint():
assert df2['close_copy'].dtype == np.float32
def test_convert_trades_to_ohlcv(testdatadir, tmpdir, caplog):
tmpdir1 = Path(tmpdir)
def test_convert_trades_to_ohlcv(testdatadir, tmp_path, caplog):
pair = 'XRP/ETH'
file1 = tmpdir1 / 'XRP_ETH-1m.feather'
file5 = tmpdir1 / 'XRP_ETH-5m.feather'
filetrades = tmpdir1 / 'XRP_ETH-trades.json.gz'
file1 = tmp_path / 'XRP_ETH-1m.feather'
file5 = tmp_path / 'XRP_ETH-5m.feather'
filetrades = tmp_path / 'XRP_ETH-trades.json.gz'
copyfile(testdatadir / file1.name, file1)
copyfile(testdatadir / file5.name, file5)
copyfile(testdatadir / filetrades.name, filetrades)
# Compare downloaded dataset with converted dataset
dfbak_1m = load_pair_history(datadir=tmpdir1, timeframe="1m", pair=pair)
dfbak_5m = load_pair_history(datadir=tmpdir1, timeframe="5m", pair=pair)
dfbak_1m = load_pair_history(datadir=tmp_path, timeframe="1m", pair=pair)
dfbak_5m = load_pair_history(datadir=tmp_path, timeframe="5m", pair=pair)
tr = TimeRange.parse_timerange('20191011-20191012')
convert_trades_to_ohlcv([pair], timeframes=['1m', '5m'],
data_format_trades='jsongz',
datadir=tmpdir1, timerange=tr, erase=True)
datadir=tmp_path, timerange=tr, erase=True)
assert log_has("Deleting existing data for pair XRP/ETH, interval 1m.", caplog)
# Load new data
df_1m = load_pair_history(datadir=tmpdir1, timeframe="1m", pair=pair)
df_5m = load_pair_history(datadir=tmpdir1, timeframe="5m", pair=pair)
df_1m = load_pair_history(datadir=tmp_path, timeframe="1m", pair=pair)
df_5m = load_pair_history(datadir=tmp_path, timeframe="5m", pair=pair)
assert_frame_equal(dfbak_1m, df_1m, check_exact=True)
assert_frame_equal(dfbak_5m, df_5m, check_exact=True)
@@ -477,5 +473,5 @@ def test_convert_trades_to_ohlcv(testdatadir, tmpdir, caplog):
convert_trades_to_ohlcv(['NoDatapair'], timeframes=['1m', '5m'],
data_format_trades='jsongz',
datadir=tmpdir1, timerange=tr, erase=True)
datadir=tmp_path, timerange=tr, erase=True)
assert log_has(msg, caplog)
+14 -17
View File
@@ -328,17 +328,16 @@ def test_hdf5datahandler_trades_load(testdatadir):
])
def test_hdf5datahandler_ohlcv_load_and_resave(
testdatadir,
tmpdir,
tmp_path,
pair,
timeframe,
candle_type,
candle_append,
startdt, enddt
):
tmpdir1 = Path(tmpdir)
tmpdir2 = tmpdir1
tmpdir2 = tmp_path
if candle_type not in ('', 'spot'):
tmpdir2 = tmpdir1 / 'futures'
tmpdir2 = tmp_path / 'futures'
tmpdir2.mkdir()
dh = get_datahandler(testdatadir, 'hdf5')
ohlcv = dh._ohlcv_load(pair, timeframe, None, candle_type=candle_type)
@@ -348,7 +347,7 @@ def test_hdf5datahandler_ohlcv_load_and_resave(
file = tmpdir2 / f"UNITTEST_NEW-{timeframe}{candle_append}.h5"
assert not file.is_file()
dh1 = get_datahandler(tmpdir1, 'hdf5')
dh1 = get_datahandler(tmp_path, 'hdf5')
dh1.ohlcv_store('UNITTEST/NEW', timeframe, ohlcv, candle_type=candle_type)
assert file.is_file()
@@ -379,17 +378,16 @@ def test_hdf5datahandler_ohlcv_load_and_resave(
def test_generic_datahandler_ohlcv_load_and_resave(
datahandler,
testdatadir,
tmpdir,
tmp_path,
pair,
timeframe,
candle_type,
candle_append,
startdt, enddt
):
tmpdir1 = Path(tmpdir)
tmpdir2 = tmpdir1
tmpdir2 = tmp_path
if candle_type not in ('', 'spot'):
tmpdir2 = tmpdir1 / 'futures'
tmpdir2 = tmp_path / 'futures'
tmpdir2.mkdir()
# Load data from one common file
dhbase = get_datahandler(testdatadir, 'feather')
@@ -403,7 +401,7 @@ def test_generic_datahandler_ohlcv_load_and_resave(
file = tmpdir2 / f"UNITTEST_NEW-{timeframe}{candle_append}.{dh._get_file_extension()}"
assert not file.is_file()
dh1 = get_datahandler(tmpdir1, datahandler)
dh1 = get_datahandler(tmp_path, datahandler)
dh1.ohlcv_store('UNITTEST/NEW', timeframe, ohlcv, candle_type=candle_type)
assert file.is_file()
@@ -459,15 +457,14 @@ def test_datahandler_trades_load(testdatadir, datahandler):
@pytest.mark.parametrize('datahandler', ['jsongz', 'hdf5', 'feather', 'parquet'])
def test_datahandler_trades_store(testdatadir, tmpdir, datahandler):
tmpdir1 = Path(tmpdir)
def test_datahandler_trades_store(testdatadir, tmp_path, datahandler):
dh = get_datahandler(testdatadir, datahandler)
trades = dh.trades_load('XRP/ETH')
dh1 = get_datahandler(tmpdir1, datahandler)
dh1 = get_datahandler(tmp_path, datahandler)
dh1.trades_store('XRP/NEW', trades)
file = tmpdir1 / f'XRP_NEW-trades.{dh1._get_file_extension()}'
file = tmp_path / f'XRP_NEW-trades.{dh1._get_file_extension()}'
assert file.is_file()
# Load trades back
trades_new = dh1.trades_load('XRP/NEW')
@@ -516,11 +513,11 @@ def test_gethandlerclass():
def test_get_datahandler(testdatadir):
dh = get_datahandler(testdatadir, 'json')
assert type(dh) == JsonDataHandler
assert isinstance(dh, JsonDataHandler)
dh = get_datahandler(testdatadir, 'jsongz')
assert type(dh) == JsonGzDataHandler
assert isinstance(dh, JsonGzDataHandler)
dh1 = get_datahandler(testdatadir, 'jsongz', dh)
assert id(dh1) == id(dh)
dh = get_datahandler(testdatadir, 'hdf5')
assert type(dh) == HDF5DataHandler
assert isinstance(dh, HDF5DataHandler)
+86
View File
@@ -500,3 +500,89 @@ def test_dp__add_external_df(default_conf_usdt):
# 36 hours - from 2022-01-03 12:00:00+00:00 to 2022-01-05 00:00:00+00:00
assert isinstance(res[1], int)
assert res[1] == 0
def test_dp_get_required_startup(default_conf_usdt):
timeframe = '1h'
default_conf_usdt["timeframe"] = timeframe
dp = DataProvider(default_conf_usdt, None)
# No FreqAI config
assert dp.get_required_startup('5m', False) == 0
assert dp.get_required_startup('1h', False) == 0
assert dp.get_required_startup('1d', False) == 0
assert dp.get_required_startup('1d', True) == 0
assert dp.get_required_startup('1d') == 0
dp._config['startup_candle_count'] = 20
assert dp.get_required_startup('5m', False) == 20
assert dp.get_required_startup('5m', True) == 20
assert dp.get_required_startup('1h', False) == 20
assert dp.get_required_startup('1h') == 20
# With freqAI config
dp._config['freqai'] = {
'enabled': True,
'train_period_days': 20,
'feature_parameters': {
'indicator_periods_candles': [
5,
20,
]
}
}
assert dp.get_required_startup('5m', False) == 20
assert dp.get_required_startup('5m', True) == 5780
assert dp.get_required_startup('1h', False) == 20
assert dp.get_required_startup('1h', True) == 500
assert dp.get_required_startup('1d', False) == 20
assert dp.get_required_startup('1d', True) == 40
assert dp.get_required_startup('1d') == 40
# FreqAI kindof ignores startup_candle_count if it's below indicator_periods_candles
dp._config['startup_candle_count'] = 0
assert dp.get_required_startup('5m', False) == 20
assert dp.get_required_startup('5m', True) == 5780
assert dp.get_required_startup('1h', False) == 20
assert dp.get_required_startup('1h', True) == 500
assert dp.get_required_startup('1d', False) == 20
assert dp.get_required_startup('1d', True) == 40
assert dp.get_required_startup('1d') == 40
dp._config['freqai']['feature_parameters']['indicator_periods_candles'][1] = 50
assert dp.get_required_startup('5m', False) == 50
assert dp.get_required_startup('5m', True) == 5810
assert dp.get_required_startup('1h', False) == 50
assert dp.get_required_startup('1h', True) == 530
assert dp.get_required_startup('1d', False) == 50
assert dp.get_required_startup('1d', True) == 70
assert dp.get_required_startup('1d') == 70
# scenario from issue https://github.com/freqtrade/freqtrade/issues/9432
dp._config['freqai'] = {
'enabled': True,
'train_period_days': 180,
'feature_parameters': {
'indicator_periods_candles': [
10,
20,
]
}
}
dp._config['startup_candle_count'] = 40
assert dp.get_required_startup('5m', False) == 40
assert dp.get_required_startup('5m', True) == 51880
assert dp.get_required_startup('1h', False) == 40
assert dp.get_required_startup('1h', True) == 4360
assert dp.get_required_startup('1d', False) == 40
assert dp.get_required_startup('1d', True) == 220
assert dp.get_required_startup('1d') == 220
+20 -24
View File
@@ -106,17 +106,16 @@ def test_load_data_startup_candles(mocker, testdatadir) -> None:
@pytest.mark.parametrize('candle_type', ['mark', ''])
def test_load_data_with_new_pair_1min(ohlcv_history_list, mocker, caplog,
default_conf, tmpdir, candle_type) -> None:
default_conf, tmp_path, candle_type) -> None:
"""
Test load_pair_history() with 1 min timeframe
"""
tmpdir1 = Path(tmpdir)
mocker.patch(f'{EXMS}.get_historic_ohlcv', return_value=ohlcv_history_list)
exchange = get_patched_exchange(mocker, default_conf)
file = tmpdir1 / 'MEME_BTC-1m.feather'
file = tmp_path / 'MEME_BTC-1m.feather'
# do not download a new pair if refresh_pairs isn't set
load_pair_history(datadir=tmpdir1, timeframe='1m', pair='MEME/BTC', candle_type=candle_type)
load_pair_history(datadir=tmp_path, timeframe='1m', pair='MEME/BTC', candle_type=candle_type)
assert not file.is_file()
assert log_has(
f"No history for MEME/BTC, {candle_type}, 1m found. "
@@ -124,10 +123,10 @@ def test_load_data_with_new_pair_1min(ohlcv_history_list, mocker, caplog,
)
# download a new pair if refresh_pairs is set
refresh_data(datadir=tmpdir1, timeframe='1m', pairs=['MEME/BTC'],
refresh_data(datadir=tmp_path, timeframe='1m', pairs=['MEME/BTC'],
exchange=exchange, candle_type=CandleType.SPOT
)
load_pair_history(datadir=tmpdir1, timeframe='1m', pair='MEME/BTC', candle_type=candle_type)
load_pair_history(datadir=tmp_path, timeframe='1m', pair='MEME/BTC', candle_type=candle_type)
assert file.is_file()
assert log_has_re(
r'\(0/1\) - Download history data for "MEME/BTC", 1m, '
@@ -273,27 +272,26 @@ def test_download_pair_history(
ohlcv_history_list,
mocker,
default_conf,
tmpdir,
tmp_path,
candle_type,
subdir,
file_tail
) -> None:
mocker.patch(f'{EXMS}.get_historic_ohlcv', return_value=ohlcv_history_list)
exchange = get_patched_exchange(mocker, default_conf)
tmpdir1 = Path(tmpdir)
file1_1 = tmpdir1 / f'{subdir}MEME_BTC-1m{file_tail}.feather'
file1_5 = tmpdir1 / f'{subdir}MEME_BTC-5m{file_tail}.feather'
file2_1 = tmpdir1 / f'{subdir}CFI_BTC-1m{file_tail}.feather'
file2_5 = tmpdir1 / f'{subdir}CFI_BTC-5m{file_tail}.feather'
file1_1 = tmp_path / f'{subdir}MEME_BTC-1m{file_tail}.feather'
file1_5 = tmp_path / f'{subdir}MEME_BTC-5m{file_tail}.feather'
file2_1 = tmp_path / f'{subdir}CFI_BTC-1m{file_tail}.feather'
file2_5 = tmp_path / f'{subdir}CFI_BTC-5m{file_tail}.feather'
assert not file1_1.is_file()
assert not file2_1.is_file()
assert _download_pair_history(datadir=tmpdir1, exchange=exchange,
assert _download_pair_history(datadir=tmp_path, exchange=exchange,
pair='MEME/BTC',
timeframe='1m',
candle_type=candle_type)
assert _download_pair_history(datadir=tmpdir1, exchange=exchange,
assert _download_pair_history(datadir=tmp_path, exchange=exchange,
pair='CFI/BTC',
timeframe='1m',
candle_type=candle_type)
@@ -308,11 +306,11 @@ def test_download_pair_history(
assert not file1_5.is_file()
assert not file2_5.is_file()
assert _download_pair_history(datadir=tmpdir1, exchange=exchange,
assert _download_pair_history(datadir=tmp_path, exchange=exchange,
pair='MEME/BTC',
timeframe='5m',
candle_type=candle_type)
assert _download_pair_history(datadir=tmpdir1, exchange=exchange,
assert _download_pair_history(datadir=tmp_path, exchange=exchange,
pair='CFI/BTC',
timeframe='5m',
candle_type=candle_type)
@@ -340,13 +338,12 @@ def test_download_pair_history2(mocker, default_conf, testdatadir) -> None:
assert json_dump_mock.call_count == 3
def test_download_backtesting_data_exception(mocker, caplog, default_conf, tmpdir) -> None:
def test_download_backtesting_data_exception(mocker, caplog, default_conf, tmp_path) -> None:
mocker.patch(f'{EXMS}.get_historic_ohlcv',
side_effect=Exception('File Error'))
tmpdir1 = Path(tmpdir)
exchange = get_patched_exchange(mocker, default_conf)
assert not _download_pair_history(datadir=tmpdir1, exchange=exchange,
assert not _download_pair_history(datadir=tmp_path, exchange=exchange,
pair='MEME/BTC',
timeframe='1m', candle_type='spot')
assert log_has('Failed to download history data for pair: "MEME/BTC", timeframe: 1m.', caplog)
@@ -570,16 +567,15 @@ def test_refresh_backtest_trades_data(mocker, default_conf, markets, caplog, tes
def test_download_trades_history(trades_history, mocker, default_conf, testdatadir, caplog,
tmpdir, time_machine) -> None:
tmp_path, time_machine) -> None:
start_dt = dt_utc(2023, 1, 1)
time_machine.move_to(start_dt, tick=False)
tmpdir1 = Path(tmpdir)
ght_mock = MagicMock(side_effect=lambda pair, *args, **kwargs: (pair, trades_history))
mocker.patch(f'{EXMS}.get_historic_trades', ght_mock)
exchange = get_patched_exchange(mocker, default_conf)
file1 = tmpdir1 / 'ETH_BTC-trades.json.gz'
data_handler = get_datahandler(tmpdir1, data_format='jsongz')
file1 = tmp_path / 'ETH_BTC-trades.json.gz'
data_handler = get_datahandler(tmp_path, data_format='jsongz')
assert not file1.is_file()
@@ -614,7 +610,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
pair='ETH/BTC')
assert log_has_re('Failed to download historic trades for pair: "ETH/BTC".*', caplog)
file2 = tmpdir1 / 'XRP_ETH-trades.json.gz'
file2 = tmp_path / 'XRP_ETH-trades.json.gz'
copyfile(testdatadir / file2.name, file2)
ght_mock.reset_mock()
+5 -7
View File
@@ -1,5 +1,4 @@
from datetime import datetime, timezone
from pathlib import Path
from shutil import copytree
from unittest.mock import PropertyMock
@@ -11,7 +10,7 @@ from freqtrade.exceptions import OperationalException
from tests.conftest import EXMS, log_has, log_has_re, patch_exchange
def test_import_kraken_trades_from_csv(testdatadir, tmpdir, caplog, default_conf_usdt, mocker):
def test_import_kraken_trades_from_csv(testdatadir, tmp_path, caplog, default_conf_usdt, mocker):
with pytest.raises(OperationalException, match="This function is only for the kraken exchange"):
import_kraken_trades_from_csv(default_conf_usdt, 'feather')
@@ -21,10 +20,9 @@ def test_import_kraken_trades_from_csv(testdatadir, tmpdir, caplog, default_conf
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={
'BCH/EUR': {'symbol': 'BCH/EUR', 'id': 'BCHEUR', 'altname': 'BCHEUR'},
}))
tmpdir1 = Path(tmpdir)
dstfile = tmpdir1 / 'BCH_EUR-trades.feather'
dstfile = tmp_path / 'BCH_EUR-trades.feather'
assert not dstfile.is_file()
default_conf_usdt['datadir'] = tmpdir1
default_conf_usdt['datadir'] = tmp_path
# There's 2 files in this tree, containing a total of 2 days.
# tests/testdata/kraken/
# └── trades_csv
@@ -32,7 +30,7 @@ def test_import_kraken_trades_from_csv(testdatadir, tmpdir, caplog, default_conf
# └── incremental_q2
# └── BCHEUR.csv <-- 2023-01-02
copytree(testdatadir / 'kraken/trades_csv', tmpdir1 / 'trades_csv')
copytree(testdatadir / 'kraken/trades_csv', tmp_path / 'trades_csv')
import_kraken_trades_from_csv(default_conf_usdt, 'feather')
assert log_has("Found csv files for BCHEUR.", caplog)
@@ -40,7 +38,7 @@ def test_import_kraken_trades_from_csv(testdatadir, tmpdir, caplog, default_conf
assert dstfile.is_file()
dh = get_datahandler(tmpdir1, 'feather')
dh = get_datahandler(tmp_path, 'feather')
trades = dh.trades_load('BCH_EUR')
assert len(trades) == 340
+63 -26
View File
@@ -13,7 +13,7 @@ from freqtrade.enums import CandleType, MarginMode, TradingMode
from freqtrade.exceptions import (DDosProtection, DependencyException, ExchangeError,
InsufficientFundsError, InvalidOrderException,
OperationalException, PricingError, TemporaryError)
from freqtrade.exchange import (Binance, Bittrex, Exchange, Kraken, market_is_active,
from freqtrade.exchange import (Binance, Bybit, Exchange, Kraken, market_is_active,
timeframe_to_prev_date)
from freqtrade.exchange.common import (API_FETCH_ORDER_RETRY_COUNT, API_RETRY_COUNT,
calculate_backoff, remove_exchange_credentials)
@@ -24,7 +24,7 @@ from tests.conftest import (EXMS, generate_test_data_raw, get_mock_coro, get_pat
# Make sure to always keep one exchange here which is NOT subclassed!!
EXCHANGES = ['bittrex', 'binance', 'kraken', 'gate', 'kucoin', 'bybit', 'okx']
EXCHANGES = ['binance', 'kraken', 'gate', 'kucoin', 'bybit', 'okx']
get_entry_rate_data = [
('other', 20, 19, 10, 0.0, 20), # Full ask side
@@ -228,10 +228,10 @@ def test_exchange_resolver(default_conf, mocker, caplog):
assert log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog)
caplog.clear()
default_conf['exchange']['name'] = 'Bittrex'
default_conf['exchange']['name'] = 'Bybit'
exchange = ExchangeResolver.load_exchange(default_conf)
assert isinstance(exchange, Exchange)
assert isinstance(exchange, Bittrex)
assert isinstance(exchange, Bybit)
assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.",
caplog)
caplog.clear()
@@ -263,8 +263,8 @@ def test_exchange_resolver(default_conf, mocker, caplog):
def test_validate_order_time_in_force(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
# explicitly test bittrex, exchanges implementing other policies need separate tests
ex = get_patched_exchange(mocker, default_conf, id="bittrex")
# explicitly test bybit, exchanges implementing other policies need separate tests
ex = get_patched_exchange(mocker, default_conf, id="bybit")
tif = {
"buy": "gtc",
"sell": "gtc",
@@ -273,11 +273,14 @@ def test_validate_order_time_in_force(default_conf, mocker, caplog):
ex.validate_order_time_in_force(tif)
tif2 = {
"buy": "fok",
"sell": "ioc",
"sell": "ioc22",
}
with pytest.raises(OperationalException, match=r"Time in force.*not supported for .*"):
ex.validate_order_time_in_force(tif2)
tif2 = {
"buy": "fok",
"sell": "ioc",
}
# Patch to see if this will pass if the values are in the ft dict
ex._ft_has.update({"order_time_in_force": ["GTC", "FOK", "IOC"]})
ex.validate_order_time_in_force(tif2)
@@ -915,7 +918,6 @@ def test_validate_ordertypes(default_conf, mocker):
mocker.patch(f'{EXMS}.validate_timeframes')
mocker.patch(f'{EXMS}.validate_stakecurrency')
mocker.patch(f'{EXMS}.validate_pricing')
mocker.patch(f'{EXMS}.name', 'Bittrex')
default_conf['order_types'] = {
'entry': 'limit',
@@ -1851,7 +1853,7 @@ def test_fetch_bids_asks(default_conf, mocker):
@pytest.mark.parametrize("exchange_name", EXCHANGES)
def test_get_tickers(default_conf, mocker, exchange_name):
def test_get_tickers(default_conf, mocker, exchange_name, caplog):
api_mock = MagicMock()
tick = {'ETH/BTC': {
'symbol': 'ETH/BTC',
@@ -1900,6 +1902,14 @@ def test_get_tickers(default_conf, mocker, exchange_name):
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
exchange.get_tickers()
caplog.clear()
api_mock.fetch_tickers = MagicMock(side_effect=[ccxt.BadSymbol("SomeSymbol"), []])
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
x = exchange.get_tickers()
assert x == []
assert log_has_re(r'Could not load tickers due to BadSymbol\..*SomeSymbol', caplog)
caplog.clear()
api_mock.fetch_tickers = MagicMock(return_value={})
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
exchange.get_tickers()
@@ -1969,6 +1979,34 @@ def test_fetch_ticker(default_conf, mocker, exchange_name):
exchange.fetch_ticker(pair='XRP/ETH')
@pytest.mark.parametrize("exchange_name", EXCHANGES)
def test___now_is_time_to_refresh(default_conf, mocker, exchange_name, time_machine):
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
pair = 'BTC/USDT'
candle_type = CandleType.SPOT
start_dt = datetime(2023, 12, 1, 0, 10, 0, tzinfo=timezone.utc)
time_machine.move_to(start_dt, tick=False)
assert (pair, '5m', candle_type) not in exchange._pairs_last_refresh_time
# not refreshed yet
assert exchange._now_is_time_to_refresh(pair, '5m', candle_type) is True
last_closed_candle = (start_dt - timedelta(minutes=5)).timestamp()
exchange._pairs_last_refresh_time[(pair, '5m', candle_type)] = last_closed_candle
# next candle not closed yet
time_machine.move_to(start_dt + timedelta(minutes=4, seconds=59), tick=False)
assert exchange._now_is_time_to_refresh(pair, '5m', candle_type) is False
# next candle closed
time_machine.move_to(start_dt + timedelta(minutes=5, seconds=0), tick=False)
assert exchange._now_is_time_to_refresh(pair, '5m', candle_type) is True
# 1 second later (last_refresh_time didn't change)
time_machine.move_to(start_dt + timedelta(minutes=5, seconds=1), tick=False)
assert exchange._now_is_time_to_refresh(pair, '5m', candle_type) is True
@pytest.mark.parametrize("exchange_name", EXCHANGES)
@pytest.mark.parametrize('candle_type', ['mark', ''])
def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name, candle_type):
@@ -2730,7 +2768,6 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na
assert res_ohlcv[9][4] == 0.07668
assert res_ohlcv[9][5] == 16.65244264
# Bittrex use-case (real data from Bittrex)
# This OHLCV data is ordered ASC (oldest first, newest last)
ohlcv = [
[1527827700000, 0.07659999, 0.0766, 0.07627, 0.07657998, 1.85216924],
@@ -3374,7 +3411,7 @@ def test_get_fee(default_conf, mocker, exchange_name):
def test_stoploss_order_unsupported_exchange(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, id='bittrex')
exchange = get_patched_exchange(mocker, default_conf, id='bitpanda')
with pytest.raises(OperationalException, match=r"stoploss is not implemented .*"):
exchange.create_stoploss(
pair='ETH/BTC',
@@ -3570,10 +3607,10 @@ def test_ohlcv_candle_limit(default_conf, mocker, exchange_name):
timeframes = ('1m', '5m', '1h')
expected = exchange._ft_has['ohlcv_candle_limit']
for timeframe in timeframes:
if 'ohlcv_candle_limit_per_timeframe' in exchange._ft_has:
expected = exchange._ft_has['ohlcv_candle_limit_per_timeframe'][timeframe]
# This should only run for bittrex
assert exchange_name == 'bittrex'
# if 'ohlcv_candle_limit_per_timeframe' in exchange._ft_has:
# expected = exchange._ft_has['ohlcv_candle_limit_per_timeframe'][timeframe]
# This should only run for bittrex
# assert exchange_name == 'bittrex'
assert exchange.ohlcv_candle_limit(timeframe, CandleType.SPOT) == expected
@@ -3865,11 +3902,11 @@ def test_set_margin_mode(mocker, default_conf, margin_mode):
("kraken", TradingMode.SPOT, None, False),
("kraken", TradingMode.MARGIN, MarginMode.ISOLATED, True),
("kraken", TradingMode.FUTURES, MarginMode.ISOLATED, True),
("bittrex", TradingMode.SPOT, None, False),
("bittrex", TradingMode.MARGIN, MarginMode.CROSS, True),
("bittrex", TradingMode.MARGIN, MarginMode.ISOLATED, True),
("bittrex", TradingMode.FUTURES, MarginMode.CROSS, True),
("bittrex", TradingMode.FUTURES, MarginMode.ISOLATED, True),
("bitmart", TradingMode.SPOT, None, False),
("bitmart", TradingMode.MARGIN, MarginMode.CROSS, True),
("bitmart", TradingMode.MARGIN, MarginMode.ISOLATED, True),
("bitmart", TradingMode.FUTURES, MarginMode.CROSS, True),
("bitmart", TradingMode.FUTURES, MarginMode.ISOLATED, True),
("gate", TradingMode.MARGIN, MarginMode.ISOLATED, True),
("okx", TradingMode.SPOT, None, False),
("okx", TradingMode.MARGIN, MarginMode.CROSS, True),
@@ -4486,10 +4523,10 @@ def test_amount_to_contract_precision(
@pytest.mark.parametrize('exchange_name,open_rate,is_short,trading_mode,margin_mode', [
# Bittrex
('bittrex', 2.0, False, 'spot', None),
('bittrex', 2.0, False, 'spot', 'cross'),
('bittrex', 2.0, True, 'spot', 'isolated'),
# Bybit
('bybit', 2.0, False, 'spot', None),
('bybit', 2.0, False, 'spot', 'cross'),
('bybit', 2.0, True, 'spot', 'isolated'),
# Binance
('binance', 2.0, False, 'spot', None),
('binance', 2.0, False, 'spot', 'cross'),
@@ -4911,7 +4948,7 @@ def test_get_max_leverage_futures(default_conf, mocker, leverage_tiers):
exchange.get_max_leverage("BTC/USDT:USDT", 1000000000.01)
@pytest.mark.parametrize("exchange_name", ['bittrex', 'binance', 'kraken', 'gate', 'okx', 'bybit'])
@pytest.mark.parametrize("exchange_name", ['binance', 'kraken', 'gate', 'okx', 'bybit'])
def test__get_params(mocker, default_conf, exchange_name):
api_mock = MagicMock()
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
+4 -4
View File
@@ -18,7 +18,7 @@ from tests.conftest import log_has_re
def test_check_exchange(default_conf, caplog) -> None:
# Test an officially supported by Freqtrade team exchange
default_conf['runmode'] = RunMode.DRY_RUN
default_conf.get('exchange').update({'name': 'BITTREX'})
default_conf.get('exchange').update({'name': 'BINANCE'})
assert check_exchange(default_conf)
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
caplog)
@@ -41,14 +41,14 @@ def test_check_exchange(default_conf, caplog) -> None:
caplog.clear()
# Test an officially supported by Freqtrade team exchange - with remapping
default_conf.get('exchange').update({'name': 'okex'})
default_conf.get('exchange').update({'name': 'okx'})
assert check_exchange(default_conf)
assert log_has_re(
r"Exchange \"okex\" is officially supported by the Freqtrade development team\.",
r"Exchange \"okx\" is officially supported by the Freqtrade development team\.",
caplog)
caplog.clear()
# Test an available exchange, supported by ccxt
default_conf.get('exchange').update({'name': 'huobipro'})
default_conf.get('exchange').update({'name': 'huobijp'})
assert check_exchange(default_conf)
assert log_has_re(r"Exchange .* is known to the the ccxt library, available for the bot, "
r"but not officially supported "

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