Compare commits

..

444 Commits

Author SHA1 Message Date
Matthias 0654186400 Merge pull request #9486 from freqtrade/new_release
New release 2023.11
2023-11-30 17:25:25 +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
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
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 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
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
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 f142abfb76 Merge pull request #9348 from freqtrade/new_release
New release 2023.10
2023-10-31 06:42:58 +01:00
Matthias c98c6c38dc update binance leverage tiers 2023-10-30 20:10:07 +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 9a73f7a7b8 Bump version to 2023.10 2023-10-29 13:51:19 +01:00
Matthias 7813d1acd6 Merge branch 'stable' into new_release 2023-10-29 13:51:10 +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 2c20464983 Reinit orders list on "local" objects to instance variable 2023-10-29 09:18:00 +01:00
Matthias e97d9013d5 Avoid having orders leak after multiple "from_json" calls 2023-10-29 09:17:07 +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
Matthias 1e18b35f22 Change box type to tip 2023-10-27 07:08:38 +02:00
Matthias bb78285661 Add hint about helper commands to common mistakes section 2023-10-27 06:38:35 +02:00
Matthias b47ba8cfd3 Merge pull request #9339 from freqtrade/fix/returndf-bug
fix: bug in startup candle offset
2023-10-26 19:49:44 +02:00
Matthias 1dccdf0594 bump ruff in pre-commit 2023-10-26 19:49:25 +02:00
robcaulk 5da48d8ffc chore: fix tests 2023-10-25 18:38:30 +02:00
robcaulk 4f4b7c5625 fix: bug in startup candle offset 2023-10-23 20:31:51 +02:00
Matthias 9dcf236387 Align flake and ruff configs further 2023-10-23 18:06:31 +02:00
Matthias 97bc5804fd Merge pull request #9334 from freqtrade/dependabot/pip/develop/tensorboard-2.15.0
Bump tensorboard from 2.14.1 to 2.15.0
2023-10-23 09:00:42 +02:00
Matthias beab966851 Merge pull request #9328 from freqtrade/dependabot/pip/develop/websockets-12.0
Bump websockets from 11.0.3 to 12.0
2023-10-23 09:00:17 +02:00
Matthias 00a7e8f9a2 Merge pull request #9338 from freqtrade/dependabot/pip/develop/ccxt-4.1.22
Bump ccxt from 4.1.13 to 4.1.22
2023-10-23 08:57:12 +02:00
Matthias 59dc526683 Merge pull request #9335 from freqtrade/dependabot/pip/develop/types-requests-2.31.0.10
Bump types-requests from 2.31.0.9 to 2.31.0.10
2023-10-23 08:56:50 +02:00
Matthias aef7f9dc03 Merge pull request #9337 from freqtrade/dependabot/pip/develop/pytest-mock-3.12.0
Bump pytest-mock from 3.11.1 to 3.12.0
2023-10-23 08:56:36 +02:00
Matthias abc6a08397 Merge pull request #9336 from freqtrade/dependabot/pip/develop/fastapi-0.104.0
Bump fastapi from 0.103.2 to 0.104.0
2023-10-23 08:56:20 +02:00
Matthias eb4da8a6f6 Merge pull request #9332 from freqtrade/dependabot/pip/develop/ruff-0.1.1
Bump ruff from 0.0.292 to 0.1.1
2023-10-23 08:56:00 +02:00
dependabot[bot] 494fd734bc Bump ruff from 0.0.292 to 0.1.1
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.0.292 to 0.1.1.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.0.292...v0.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 04:47:44 +00:00
Matthias 9174f60b1d Merge pull request #9330 from freqtrade/dependabot/pip/develop/mypy-1.6.1
Bump mypy from 1.6.0 to 1.6.1
2023-10-23 06:46:57 +02:00
Matthias c2905a4522 use --output-format in ruff CI 2023-10-23 06:43:50 +02:00
Matthias adf03e2ee3 Merge pull request #9329 from freqtrade/dependabot/pip/develop/pymdown-extensions-10.3.1
Bump pymdown-extensions from 10.3 to 10.3.1
2023-10-23 06:32:13 +02:00
Matthias fe5f085ec1 types-requests pre-commit 2023-10-23 06:31:22 +02:00
dependabot[bot] 748ac50d83 Bump ccxt from 4.1.13 to 4.1.22
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.13 to 4.1.22.
- [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.13...4.1.22)

---
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-23 03:47:08 +00:00
dependabot[bot] d2069c1729 Bump pytest-mock from 3.11.1 to 3.12.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.11.1 to 3.12.0.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.11.1...v3.12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 03:47:01 +00:00
dependabot[bot] 38cf50830a Bump fastapi from 0.103.2 to 0.104.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.103.2 to 0.104.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.103.2...0.104.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-10-23 03:46:55 +00:00
dependabot[bot] bf96a43efb Bump types-requests from 2.31.0.9 to 2.31.0.10
Bumps [types-requests](https://github.com/python/typeshed) from 2.31.0.9 to 2.31.0.10.
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 03:46:50 +00:00
dependabot[bot] 22b4555926 Bump tensorboard from 2.14.1 to 2.15.0
Bumps [tensorboard](https://github.com/tensorflow/tensorboard) from 2.14.1 to 2.15.0.
- [Release notes](https://github.com/tensorflow/tensorboard/releases)
- [Changelog](https://github.com/tensorflow/tensorboard/blob/2.15.0/RELEASE.md)
- [Commits](https://github.com/tensorflow/tensorboard/compare/2.14.1...2.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 03:46:46 +00:00
dependabot[bot] 7fb3632e7b Bump mypy from 1.6.0 to 1.6.1
Bumps [mypy](https://github.com/python/mypy) from 1.6.0 to 1.6.1.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.6.0...v1.6.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-10-23 03:46:11 +00:00
dependabot[bot] e5f0fe288a Bump pymdown-extensions from 10.3 to 10.3.1
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 10.3 to 10.3.1.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/10.3...10.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 03:46:06 +00:00
dependabot[bot] 58aaaffe2b Bump websockets from 11.0.3 to 12.0
Bumps [websockets](https://github.com/python-websockets/websockets) from 11.0.3 to 12.0.
- [Release notes](https://github.com/python-websockets/websockets/releases)
- [Commits](https://github.com/python-websockets/websockets/compare/11.0.3...12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 03:46:02 +00:00
Matthias c62aefbfde Merge pull request #9327 from amargedon/mapping-fiat-usdc
Add FIAT mapping for USDC
2023-10-22 20:12:42 +02:00
amargedon 16dfde22fc Add FIAT mapping for USDC 2023-10-22 18:43:35 +02:00
Matthias bbbc8a760c Fix stop evaluation sequence to have stop before liquidation
Adjust test to have liquidation above stop
closes #9296
2023-10-22 09:24:28 +02:00
Matthias 9b45bb2e24 Merge pull request #9325 from freqtrade/revert-9281-dependabot/pip/develop/torch-2.1.0
Revert "Bump torch from 2.0.1 to 2.1.0"
2023-10-22 09:23:58 +02:00
Matthias e69c21c9f5 Revert "Bump torch from 2.0.1 to 2.1.0" 2023-10-22 08:59:23 +02:00
Robert Caulk 72933859cf Merge pull request #9281 from freqtrade/dependabot/pip/develop/torch-2.1.0
Bump torch from 2.0.1 to 2.1.0
2023-10-22 08:01:16 +02:00
Matthias 0a5cee6a73 Ensure we're not erroring on invalid custom_entry / exit prices
closes #9323
2023-10-19 22:06:21 +02:00
Matthias a80c979482 Improve behavior when downloading trades data on time-based pagination
closes #9307
2023-10-18 20:26:51 +02:00
Matthias 4a4b695b94 Merge pull request #9321 from freqtrade/dependabot/pip/urllib3-2.0.7
Bump urllib3 from 2.0.6 to 2.0.7
2023-10-18 06:26:10 +02:00
dependabot[bot] a8c246ce0d Bump urllib3 from 2.0.6 to 2.0.7
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.6 to 2.0.7.
- [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.6...2.0.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 21:02:44 +00:00
Matthias c6e979ddda Merge pull request #9303 from freqtrade/fix/progressbarCallback
Improve freqAI RL (error) behavior
2023-10-17 18:01:31 +02:00
Matthias 1a78346cf1 Add further ebug log message for stopping clarity for --dl-data 2023-10-17 07:11:06 +02:00
Matthias e6d0d53e47 Add further ebug log message for stopping clarity 2023-10-17 07:03:03 +02:00
Matthias 68680bb2c6 Merge pull request #9314 from freqtrade/dependabot/pip/develop/numpy-1.26.1
Bump numpy from 1.25.2 to 1.26.1
2023-10-16 19:33:07 +02:00
Matthias 7de415a6a4 Don't bump numpy for armhf just yet 2023-10-16 18:28:00 +02:00
dependabot[bot] f46fa440f0 Bump numpy from 1.25.2 to 1.26.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.25.2 to 1.26.1.
- [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.25.2...v1.26.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-16 16:27:50 +00:00
Matthias 56177d7e92 Merge pull request #9317 from freqtrade/dependabot/pip/develop/ccxt-4.1.13
Bump ccxt from 4.1.8 to 4.1.13
2023-10-16 18:27:02 +02:00
Matthias 41584317e4 Merge pull request #9311 from freqtrade/dependabot/pip/develop/types-requests-2.31.0.9
Bump types-requests from 2.31.0.8 to 2.31.0.9
2023-10-16 14:52:35 +02:00
Matthias 3264e2c31d pre-commit requests bump 2023-10-16 13:38:01 +02:00
dependabot[bot] fadc7a2051 Bump types-requests from 2.31.0.8 to 2.31.0.9
Bumps [types-requests](https://github.com/python/typeshed) from 2.31.0.8 to 2.31.0.9.
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-16 09:59:18 +00:00
Matthias cebc55687b Merge pull request #9316 from freqtrade/dependabot/pip/develop/mypy-1.6.0
Bump mypy from 1.5.1 to 1.6.0
2023-10-16 11:58:20 +02:00
dependabot[bot] 5940279f7b Bump mypy from 1.5.1 to 1.6.0
Bumps [mypy](https://github.com/python/mypy) from 1.5.1 to 1.6.0.
- [Commits](https://github.com/python/mypy/compare/v1.5.1...v1.6.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-10-16 07:01:34 +00:00
dependabot[bot] 35f6333b67 Bump ccxt from 4.1.8 to 4.1.13
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.1.8 to 4.1.13.
- [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.8...4.1.13)

---
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-16 07:01:30 +00:00
Matthias 262b044969 Merge pull request #9312 from freqtrade/dependabot/pip/develop/sqlalchemy-2.0.22
Bump sqlalchemy from 2.0.21 to 2.0.22
2023-10-16 09:00:55 +02:00
Matthias a571df784c Merge pull request #9318 from freqtrade/dependabot/pip/develop/pre-commit-3.5.0
Bump pre-commit from 3.4.0 to 3.5.0
2023-10-16 09:00:36 +02:00
Matthias 078aa8327b Merge pull request #9315 from freqtrade/dependabot/pip/develop/ast-comments-1.1.2
Bump ast-comments from 1.1.0 to 1.1.2
2023-10-16 07:25:41 +02:00
Matthias 10945edbe6 Merge pull request #9313 from freqtrade/dependabot/pip/develop/mkdocs-material-9.4.6
Bump mkdocs-material from 9.4.4 to 9.4.6
2023-10-16 07:03:05 +02:00
Matthias 5d9b69cbfe sqlalchemy - precommit 2023-10-16 06:33:53 +02:00
Matthias 89117dd53f Merge pull request #9310 from freqtrade/dependabot/pip/develop/psutil-5.9.6
Bump psutil from 5.9.5 to 5.9.6
2023-10-16 06:33:03 +02:00
Matthias 4af9654696 Merge pull request #9308 from freqtrade/dependabot/pip/develop/orjson-3.9.9
Bump orjson from 3.9.7 to 3.9.9
2023-10-16 06:32:33 +02:00
dependabot[bot] 1e0ce7d47a Bump pre-commit from 3.4.0 to 3.5.0
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.4.0 to 3.5.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.4.0...v3.5.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-10-16 03:49:38 +00:00
dependabot[bot] 27cd54b42c Bump ast-comments from 1.1.0 to 1.1.2
Bumps [ast-comments](https://github.com/t3rn0/ast-comments) from 1.1.0 to 1.1.2.
- [Release notes](https://github.com/t3rn0/ast-comments/releases)
- [Commits](https://github.com/t3rn0/ast-comments/compare/1.1.0...1.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-16 03:49:12 +00:00
dependabot[bot] ec64a182f9 Bump mkdocs-material from 9.4.4 to 9.4.6
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.4 to 9.4.6.
- [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.4...9.4.6)

---
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-16 03:48:51 +00:00
dependabot[bot] dd30df7057 Bump sqlalchemy from 2.0.21 to 2.0.22
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.21 to 2.0.22.
- [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-10-16 03:48:44 +00:00
dependabot[bot] 4c6e33aa82 Bump psutil from 5.9.5 to 5.9.6
Bumps [psutil](https://github.com/giampaolo/psutil) from 5.9.5 to 5.9.6.
- [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst)
- [Commits](https://github.com/giampaolo/psutil/compare/release-5.9.5...release-5.9.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-16 03:48:10 +00:00
dependabot[bot] 8cb934849a Bump orjson from 3.9.7 to 3.9.9
Bumps [orjson](https://github.com/ijl/orjson) from 3.9.7 to 3.9.9.
- [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.7...3.9.9)

---
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-16 03:47:58 +00:00
Matthias c627aee096 Merge pull request #9304 from stash86/bt-metrics
have to use bitwise operator on series comparison, otherwise ambiguous error is thrown
2023-10-15 13:07:54 +02:00
Stefano Ariestasia 9d552d45c2 have to use bitwise operator, otherwise ambiguous error is thrown 2023-10-15 19:32:03 +09:00
Matthias 1e1b8dbe53 Handle multiproc calls for now 2023-10-15 12:03:18 +02:00
Matthias 2d9d8dc976 Improve logic for progressbarcallback handling 2023-10-15 11:20:25 +02:00
Matthias ba674fc796 Type-ignore training-envs 2023-10-15 11:20:11 +02:00
Matthias 58550515ad Fix deprecation warning from tensorboard-callback 2023-10-15 11:04:05 +02:00
Matthias 27bae60b68 Fix typo 2023-10-15 10:51:36 +02:00
Matthias 646dd63faf Properly close out progressbarCallback
based on suggestions provided in https://github.com/DLR-RM/stable-baselines3/issues/1645
2023-10-15 10:41:07 +02:00
Matthias 8d2b389e27 Fix wording in log msg 2023-10-15 10:40:45 +02:00
Matthias fa174a392a Merge pull request #9298 from freqtrade/funding_fees
improve Funding fee behavior
2023-10-13 16:38:16 +02:00
Matthias 042e35e8d3 Improve funding fee startup behavior 2023-10-13 06:45:00 +02:00
Matthias b76513ce33 Fix typo in trade_model 2023-10-12 10:18:57 +00:00
Matthias 368bfcf476 Add comment for funding fees running 2023-10-12 07:25:46 +02:00
Matthias fee3c598d0 Move schedule to 1 minute after the hour
This will avoid congestion at :00, and make sure that the dry-run funding fees are actually already available
2023-10-12 07:16:56 +02:00
Matthias 69264cc164 Reduce funding fee update calls
Funding fees update every 4-8 hours - calling this every 15 minutes is way overboard.
2023-10-12 07:13:30 +02:00
Matthias e81929bc55 Have test use funding_fee_running 2023-10-12 07:01:43 +02:00
Matthias 0843b19b6c Implement logic around funding_fees runnign 2023-10-12 06:53:46 +02:00
Matthias 813b472c6c Add funding_fee_running column 2023-10-12 06:48:35 +02:00
Matthias 2f079711ec Add explicit test for get_funding_fees logic 2023-10-12 06:27:57 +02:00
Matthias 97e9d2dc42 Remove get_funding_fee error handling - it's no longer raising this error. 2023-10-12 06:27:35 +02:00
Matthias 7344f20803 Handle funding_fee error in exchange class 2023-10-12 06:27:29 +02:00
Matthias bfe04464b4 Handle funding fee errors for regular trades per trade 2023-10-11 20:27:54 +02:00
Matthias 2225f5661b Additional funding fee update after additional entry orders 2023-10-11 20:27:03 +02:00
Matthias 9e77c93a54 Tighten funding-fee variance for backtest 2023-10-11 19:49:33 +02:00
Matthias b65fa98cee Simplify backtesting by using current_time more consequently 2023-10-11 19:45:00 +02:00
Matthias b57821b273 Add set_funding_fees to backtesting 2023-10-11 19:38:58 +02:00
Matthias db7f9598b0 add set_funding_fees method 2023-10-11 19:38:46 +02:00
Matthias e547da10de Move funding fee assignment to update_trade 2023-10-11 18:28:15 +02:00
Matthias 5a0c15f377 Update Idem test 2023-10-10 18:21:52 +02:00
Matthias 0f5b69b4f2 Move from_json to LocalTrade class 2023-10-10 07:13:32 +02:00
Matthias 86d4497aaf Add additional test for from_json 2023-10-09 20:01:41 +02:00
Matthias 4b80961c65 Merge pull request #9276 from freqtrade/cancel_behavior
Improve Cancel order messaging behavior
2023-10-09 18:13:04 +02:00
Matthias 785cc9df85 Merge pull request #9293 from freqtrade/revert-9285-dependabot/pip/develop/tables-3.9.1
Revert "Bump tables from 3.8.0 to 3.9.1"
2023-10-09 18:11:16 +02:00
Matthias 1bfecb0313 Revert "Bump tables from 3.8.0 to 3.9.1" 2023-10-09 18:11:01 +02:00
Matthias b88a561eb5 Merge pull request #9283 from freqtrade/dependabot/pip/develop/types-requests-2.31.0.8
Bump types-requests from 2.31.0.7 to 2.31.0.8
2023-10-09 09:42:26 +02:00
Matthias 4bf026605e Merge pull request #9289 from freqtrade/dependabot/pip/develop/markdown-3.5
Bump markdown from 3.4.4 to 3.5
2023-10-09 09:42:13 +02:00
Matthias db6933856f Merge pull request #9288 from freqtrade/dependabot/pip/develop/aiohttp-3.8.6
Bump aiohttp from 3.8.5 to 3.8.6
2023-10-09 09:41:49 +02:00
Matthias 01107ffa59 Merge pull request #9282 from freqtrade/dependabot/pip/develop/python-telegram-bot-20.6
Bump python-telegram-bot from 20.5 to 20.6
2023-10-09 09:41:32 +02:00
dependabot[bot] 74f678a26f Bump markdown from 3.4.4 to 3.5
Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.4.4 to 3.5.
- [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md)
- [Commits](https://github.com/Python-Markdown/markdown/compare/3.4.4...3.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 06:13:16 +00:00
Matthias bf93648198 Merge pull request #9287 from freqtrade/dependabot/pip/develop/nbconvert-7.9.2
Bump nbconvert from 7.8.0 to 7.9.2
2023-10-09 08:12:34 +02:00
Matthias 51dccaeb4c Merge pull request #9280 from freqtrade/dependabot/pip/develop/mkdocs-material-9.4.4
Bump mkdocs-material from 9.4.2 to 9.4.4
2023-10-09 08:11:04 +02:00
Matthias ed4252af53 Merge pull request #9285 from freqtrade/dependabot/pip/develop/tables-3.9.1
Bump tables from 3.8.0 to 3.9.1
2023-10-09 08:09:33 +02:00
Matthias 2fde902c82 Merge pull request #9284 from freqtrade/dependabot/pip/develop/python-rapidjson-1.12
Bump python-rapidjson from 1.11 to 1.12
2023-10-09 08:07:24 +02:00
Matthias 4ea75af2d9 Merge pull request #9286 from freqtrade/dependabot/pip/develop/ruff-0.0.292
Bump ruff from 0.0.291 to 0.0.292
2023-10-09 08:07:00 +02:00
Matthias 1bba0cf7fc Bump pre-commit types-requests 2023-10-09 07:06:33 +02:00
Matthias b1fd0c73c7 Add additional test case for funding-fee calculation 2023-10-09 07:05:39 +02:00
Matthias 29eb6d938b Update test for fixed funding_fee logic 2023-10-09 07:04:13 +02:00
Matthias 19620470bd Improve funding fee cutof logic 2023-10-09 07:04:13 +02:00
Matthias 7a69b01b9b avoid edge-case in test 2023-10-09 07:04:13 +02:00
Matthias bc531cf846 Improve variable naming 2023-10-09 07:04:13 +02:00
Matthias 14908e52e2 Improv variable naming 2023-10-09 07:04:13 +02:00
dependabot[bot] a86bf8d6d7 Bump aiohttp from 3.8.5 to 3.8.6
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.5 to 3.8.6.
- [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.5...v3.8.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 05:02:10 +00:00
Matthias 3662ca3ca6 Merge pull request #9279 from freqtrade/dependabot/pip/develop/ccxt-4.1.8
Bump ccxt from 4.0.112 to 4.1.8
2023-10-09 07:01:04 +02:00
dependabot[bot] 5fae03f7be Bump nbconvert from 7.8.0 to 7.9.2
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.8.0 to 7.9.2.
- [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.8.0...v7.9.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 03:54:23 +00:00
dependabot[bot] f7f0f3bebb Bump ruff from 0.0.291 to 0.0.292
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.0.291 to 0.0.292.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.0.291...v0.0.292)

---
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-09 03:54:13 +00:00
dependabot[bot] ccbab6ee6f 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-10-09 03:53:53 +00:00
dependabot[bot] ef12dafea8 Bump python-rapidjson from 1.11 to 1.12
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 1.11 to 1.12.
- [Changelog](https://github.com/python-rapidjson/python-rapidjson/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-rapidjson/python-rapidjson/compare/v1.11...v1.12)

---
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-09 03:53:42 +00:00
dependabot[bot] 08a65b50aa Bump types-requests from 2.31.0.7 to 2.31.0.8
Bumps [types-requests](https://github.com/python/typeshed) from 2.31.0.7 to 2.31.0.8.
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 03:53:37 +00:00
dependabot[bot] d28d6cbdb4 Bump python-telegram-bot from 20.5 to 20.6
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 20.5 to 20.6.
- [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.5...v20.6)

---
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-10-09 03:53:34 +00:00
dependabot[bot] 41a6709ece Bump torch from 2.0.1 to 2.1.0
Bumps [torch](https://github.com/pytorch/pytorch) from 2.0.1 to 2.1.0.
- [Release notes](https://github.com/pytorch/pytorch/releases)
- [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md)
- [Commits](https://github.com/pytorch/pytorch/compare/v2.0.1...v2.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 03:53:23 +00:00
dependabot[bot] 756f5d5408 Bump mkdocs-material from 9.4.2 to 9.4.4
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.2 to 9.4.4.
- [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.2...9.4.4)

---
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-09 03:53:10 +00:00
dependabot[bot] 422b9c8fbc Bump ccxt from 4.0.112 to 4.1.8
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.0.112 to 4.1.8.
- [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.0.112...4.1.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-09 03:53:01 +00:00
Matthias 40ec2c4921 Improve messaging in case of delayed exchange cancel 2023-10-08 11:17:29 +02:00
Matthias 5cf7ad85a0 Adjust tests for new interface to handle_cancel_* methods 2023-10-08 10:44:37 +02:00
Matthias f02c9f0435 Pass order object to handle_cancel* methods 2023-10-08 10:26:27 +02:00
Matthias c59b5e7781 Improve type hinting 2023-10-08 09:58:06 +02:00
Matthias e525c6694b Add ft_cancel_reason column to order object 2023-10-08 09:46:12 +02:00
Matthias 897c14e2e5 Don't check for "open orders" in handle_cancel_enter
it's actually irrelenant (closes #9273).
2023-10-08 09:40:46 +02:00
Matthias 6c00bf423b Fix comment 2023-10-08 08:59:18 +02:00
Matthias 094984eb2f Fix wrong typehint 2023-10-07 15:09:44 +02:00
Matthias 081411fba4 Improve bot typehints 2023-10-07 15:09:34 +02:00
Matthias 178c0972ff Read funding_fee on order objects in "from_json" 2023-10-07 08:43:06 +02:00
Matthias 910e317a45 Fix unhandled exception
closes #9270
2023-10-06 20:13:37 +02:00
Matthias 1ef5adbb0e Test for #9270 2023-10-06 20:13:11 +02:00
Matthias f5db856a75 re-align adjust_entry_price between backtest and live 2023-10-05 18:11:35 +02:00
Matthias b2ad40253f Hide most non-freqtrade logs in -v mode 2023-10-05 07:03:29 +02:00
Matthias 1e0d622d80 Don't run "recovery" when stop-orders are open 2023-10-05 06:45:00 +02:00
Matthias 1d941249ed Revert "Remove numpy armv7l lock since wheels are now available"
This reverts commit 04409602a6.
2023-10-04 19:57:26 +02:00
Matthias 5bfd3fdc33 Add openblas to armhf image 2023-10-04 17:55:15 +02:00
Matthias 753b807a45 Merge pull request #9211 from freqtrade/dependabot/pip/cryptography-41.0.4
Bump cryptography from 41.0.3 to 41.0.4
2023-10-04 07:12:01 +02:00
Matthias 04409602a6 Remove numpy armv7l lock since wheels are now available 2023-10-04 07:10:51 +02:00
Matthias b2796b850b Add funding_fee export to order object
Helps debugging #9163
2023-10-04 06:36:39 +02:00
Matthias 8c633aab19 Merge pull request #9261 from stash86/bt-metrics
Fix visual issues and docs
2023-10-03 07:06:03 +02:00
Stefano Ariestasia f14b4133c3 fix wording 2023-10-03 13:36:31 +09:00
Matthias 8f2e4aa4fd Merge pull request #9262 from freqtrade/dependabot/pip/urllib3-2.0.6
Bump urllib3 from 2.0.5 to 2.0.6
2023-10-03 06:17:44 +02:00
dependabot[bot] 3c2e043e82 Bump urllib3 from 2.0.5 to 2.0.6
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.5 to 2.0.6.
- [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/v2.0.5...2.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-03 00:22:39 +00:00
Stefano 609ed2d7b3 fix return values 2023-10-03 08:41:05 +09:00
Stefano Ariestasia 183166b3fb fix output if no variance, and fix docs 2023-10-03 08:27:28 +09:00
Matthias 12dc91719e Merge pull request #9247 from freqtrade/dependabot/pip/develop/pydantic-2.4.2
Bump pydantic from 2.3.0 to 2.4.2
2023-10-02 19:26:33 +02:00
dependabot[bot] cd071c3bdc Bump cryptography from 41.0.3 to 41.0.4
Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.3 to 41.0.4.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/41.0.3...41.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 17:21:57 +00:00
Matthias 0618ecce47 Merge pull request #9249 from freqtrade/dependabot/pip/develop/ccxt-4.0.112
Bump ccxt from 4.0.105 to 4.0.112
2023-10-02 19:21:00 +02:00
Matthias 13438ad8de Merge pull request #9260 from freqtrade/revert-9250-dependabot/pip/develop/ast-comments-1.1.1
Revert "Bump ast-comments from 1.1.0 to 1.1.1"
2023-10-02 18:30:22 +02:00
Matthias 60c2b1d6ca Revert "Bump ast-comments from 1.1.0 to 1.1.1" 2023-10-02 18:02:36 +02:00
Matthias eaf4ffcbaf Merge pull request #9253 from freqtrade/dependabot/pip/develop/types-requests-2.31.0.7
Bump types-requests from 2.31.0.4 to 2.31.0.7
2023-10-02 16:11:00 +02:00
Matthias 79e59bdda0 Bump types-requests pre-commit 2023-10-02 13:37:49 +02:00
dependabot[bot] b409ab5ead Bump pydantic from 2.3.0 to 2.4.2
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.3.0 to 2.4.2.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.3.0...v2.4.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 07:59:35 +00:00
Matthias 790c7036a1 Merge pull request #9258 from freqtrade/dependabot/pip/develop/fastapi-0.103.2
Bump fastapi from 0.103.1 to 0.103.2
2023-10-02 09:58:33 +02:00
Matthias 73902f507a Merge pull request #9250 from freqtrade/dependabot/pip/develop/ast-comments-1.1.1
Bump ast-comments from 1.1.0 to 1.1.1
2023-10-02 09:43:39 +02:00
Matthias 1a80f6bc4e Merge pull request #9257 from freqtrade/dependabot/pip/develop/arrow-1.3.0
Bump arrow from 1.2.3 to 1.3.0
2023-10-02 09:43:18 +02:00
dependabot[bot] 5feb7fe654 Bump ast-comments from 1.1.0 to 1.1.1
Bumps [ast-comments](https://github.com/t3rn0/ast-comments) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/t3rn0/ast-comments/releases)
- [Commits](https://github.com/t3rn0/ast-comments/compare/1.1.0...1.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 06:19:59 +00:00
dependabot[bot] 980960bc6a Bump arrow from 1.2.3 to 1.3.0
Bumps [arrow](https://github.com/arrow-py/arrow) from 1.2.3 to 1.3.0.
- [Release notes](https://github.com/arrow-py/arrow/releases)
- [Changelog](https://github.com/arrow-py/arrow/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/arrow-py/arrow/compare/1.2.3...1.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 06:18:56 +00:00
Matthias 52c614733f Merge pull request #9255 from freqtrade/dependabot/pip/develop/tensorboard-2.14.1
Bump tensorboard from 2.14.0 to 2.14.1
2023-10-02 08:18:48 +02:00
Matthias e913d12c71 Merge pull request #9252 from freqtrade/dependabot/pip/develop/mkdocs-material-9.4.2
Bump mkdocs-material from 9.4.1 to 9.4.2
2023-10-02 08:18:08 +02:00
Matthias 5dc24232ca Merge pull request #9254 from freqtrade/dependabot/pip/develop/packaging-23.2
Bump packaging from 23.1 to 23.2
2023-10-02 08:17:53 +02:00
Matthias ef2115d667 Merge pull request #9256 from freqtrade/dependabot/pip/develop/rich-13.6.0
Bump rich from 13.5.3 to 13.6.0
2023-10-02 08:17:31 +02:00
Matthias 74476eae43 Merge pull request #9251 from freqtrade/dependabot/pip/develop/scipy-1.11.3
Bump scipy from 1.11.2 to 1.11.3
2023-10-02 08:17:14 +02:00
Matthias 84335d58b3 Greatly speed up recursive by caching exchange 2023-10-02 06:34:35 +02:00
Matthias f175fc6e9b Merge pull request #9248 from freqtrade/dependabot/pip/develop/schedule-1.2.1
Bump schedule from 1.2.0 to 1.2.1
2023-10-02 06:20:44 +02:00
dependabot[bot] 9edd7e6bc8 Bump fastapi from 0.103.1 to 0.103.2
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.103.1 to 0.103.2.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.103.1...0.103.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 03:41:42 +00:00
dependabot[bot] 7478c56ca5 Bump rich from 13.5.3 to 13.6.0
Bumps [rich](https://github.com/Textualize/rich) from 13.5.3 to 13.6.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.5.3...v13.6.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-10-02 03:41:29 +00:00
dependabot[bot] 1f36f4802a Bump tensorboard from 2.14.0 to 2.14.1
Bumps [tensorboard](https://github.com/tensorflow/tensorboard) from 2.14.0 to 2.14.1.
- [Release notes](https://github.com/tensorflow/tensorboard/releases)
- [Changelog](https://github.com/tensorflow/tensorboard/blob/master/RELEASE.md)
- [Commits](https://github.com/tensorflow/tensorboard/compare/2.14.0...2.14.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-10-02 03:41:23 +00:00
dependabot[bot] 4d920d7866 Bump packaging from 23.1 to 23.2
Bumps [packaging](https://github.com/pypa/packaging) from 23.1 to 23.2.
- [Release notes](https://github.com/pypa/packaging/releases)
- [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/packaging/compare/23.1...23.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 03:41:09 +00:00
dependabot[bot] 19fb3f9b54 Bump types-requests from 2.31.0.4 to 2.31.0.7
Bumps [types-requests](https://github.com/python/typeshed) from 2.31.0.4 to 2.31.0.7.
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 03:40:59 +00:00
dependabot[bot] fafc102573 Bump mkdocs-material from 9.4.1 to 9.4.2
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.4.1 to 9.4.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.4.1...9.4.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-10-02 03:40:52 +00:00
dependabot[bot] 3868f9c698 Bump scipy from 1.11.2 to 1.11.3
Bumps [scipy](https://github.com/scipy/scipy) from 1.11.2 to 1.11.3.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.11.2...v1.11.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 03:40:40 +00:00
dependabot[bot] 0204f666b3 Bump ccxt from 4.0.105 to 4.0.112
Bumps [ccxt](https://github.com/ccxt/ccxt) from 4.0.105 to 4.0.112.
- [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.0.105...4.0.112)

---
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-02 03:40:23 +00:00
dependabot[bot] f32a13bfb0 Bump schedule from 1.2.0 to 1.2.1
Bumps [schedule](https://github.com/dbader/schedule) from 1.2.0 to 1.2.1.
- [Changelog](https://github.com/dbader/schedule/blob/master/HISTORY.rst)
- [Commits](https://github.com/dbader/schedule/compare/1.2.0...1.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 03:40:10 +00:00
Matthias 4809c9f07a Adjust tests for new naming 2023-10-01 08:00:09 +02:00
Matthias 19af144b33 Improve of analysis files further 2023-10-01 07:58:46 +02:00
Matthias 4db7962048 Update tests to new structure 2023-10-01 07:55:03 +02:00
Matthias 7e6f2cba53 Move analysis command into their own subspace 2023-10-01 07:54:09 +02:00
Matthias c6199e5ca6 Merge pull request #9232 from freqtrade/kraken/dldata
Kraken - dataimport
2023-10-01 07:13:54 +02:00
Matthias f7ff1dc610 Bump develop version to 2023.10-dev 2023-09-30 13:13:18 +02:00
Matthias 8ad6eb9896 Update parameter value to be clearer 2023-09-25 19:55:58 +02:00
Matthias 74709461e3 Improve exception wording 2023-09-25 19:48:09 +02:00
Matthias 9e6cc5ebbd Improve comment on special handling 2023-09-25 19:46:27 +02:00
Matthias a2d8f92e05 Add rudimentary test for test_trade_converter 2023-09-25 19:46:15 +02:00
Matthias a7d90e2a25 Minor adjustments to conversions 2023-09-25 19:45:03 +02:00
Matthias 83b37e2f78 Add documentation for kraken data mode 2023-09-25 18:23:20 +02:00
Matthias 488629096b Improve logging in kraken-converter 2023-09-25 18:23:20 +02:00
Matthias a3f167f6df Split format-from for trades to allow for trades special case 2023-09-25 18:23:20 +02:00
Matthias 1e8814b43e Improve handling of kraken dataconvert 2023-09-25 18:23:20 +02:00
Matthias 2e430519e3 Call kraken-convert in special cases 2023-09-25 18:23:20 +02:00
Matthias 2164b02c66 Add initial code for trade_kraken import 2023-09-25 18:23:20 +02:00
127 changed files with 5453 additions and 1802 deletions
+9 -9
View File
@@ -90,7 +90,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 +98,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
@@ -108,7 +108,7 @@ jobs:
- name: Run Ruff
run: |
ruff check --format=github .
ruff check --output-format=github .
- name: Mypy
run: |
@@ -200,14 +200,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
@@ -217,7 +217,7 @@ jobs:
- name: Run Ruff
run: |
ruff check --format=github .
ruff check --output-format=github .
- name: Mypy
run: |
@@ -275,19 +275,19 @@ 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
- name: Run Ruff
run: |
ruff check --format=github .
ruff check --output-format=github .
- name: Mypy
run: |
+5 -5
View File
@@ -8,17 +8,17 @@ repos:
# stages: [push]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.5.1"
rev: "v1.7.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.4
- types-requests==2.31.0.10
- types-tabulate==0.9.0.3
- types-python-dateutil==2.8.19.14
- SQLAlchemy==2.0.21
- SQLAlchemy==2.0.23
# stages: [push]
- repo: https://github.com/pycqa/isort
@@ -30,7 +30,7 @@ repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
# Ruff version.
rev: 'v0.0.270'
rev: 'v0.1.1'
hooks:
- id: ruff
+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
+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/.*"
+6 -9
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,12 +11,13 @@ 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
@@ -25,20 +26,16 @@ FROM base as python-deps
RUN apt-get update \
&& 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
@@ -31,9 +31,9 @@ optional arguments:
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--data-format-ohlcv {json,jsongz,hdf5}
--data-format-ohlcv {json,jsongz,hdf5,feather,parquet}
Storage format for downloaded candle (OHLCV) data.
(default: `json`).
(default: `feather`).
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
@@ -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
```
---
+2 -2
View File
@@ -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)
+1
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)
+55
View File
@@ -136,6 +136,43 @@ Freqtrade will not attempt to change these settings.
The Kraken API does only provide 720 historic candles, which is sufficient for Freqtrade dry-run and live trade modes, but is a problem for backtesting.
To download data for the Kraken exchange, using `--dl-trades` is mandatory, otherwise the bot will download the same 720 candles over and over, and you'll not have enough backtest data.
To speed up downloading, you can download the [trades zip files](https://support.kraken.com/hc/en-us/articles/360047543791-Downloadable-historical-market-data-time-and-sales-) kraken provides.
These are usually updated once per quarter. Freqtrade expects these files to be placed in `user_data/data/kraken/trades_csv`.
A structure as follows can make sense if using incremental files, with the "full" history in one directory, and incremental files in different directories.
The assumption for this mode is that the data is downloaded and unzipped keeping filenames as they are.
Duplicate content will be ignored (based on timestamp) - though the assumption is that there is no gap in the data.
This means, if your "full" history ends in Q4 2022 - then both incremental updates Q1 2023 and Q2 2023 are available.
Not having this will lead to incomplete data, and therefore invalid results while using the data.
```
└── trades_csv
    ├── Kraken_full_history
   │   ├── BCHEUR.csv
   │   └── XBTEUR.csv
   ├── Kraken_Trading_History_Q1_2023
   │   ├── BCHEUR.csv
   │   └── XBTEUR.csv
   └── Kraken_Trading_History_Q2_2023
      ├── BCHEUR.csv
      └── XBTEUR.csv
```
You can convert these files into freqtrade files:
``` bash
freqtrade convert-trade-data --exchange kraken --format-from kraken_csv --format-to feather
# Convert trade data to different ohlcv timeframes
freqtrade trades-to-ohlcv -p BTC/EUR BCH/EUR --exchange kraken -t 1m 5m 15m 1h
```
The converted data also makes downloading data possible, and will start the download after the latest loaded trade.
``` bash
freqtrade download-data --exchange kraken --dl-trades -p BTC/EUR BCH/EUR
```
!!! Warning "Downloading data from kraken"
Downloading kraken data will require significantly more memory (RAM) than any other exchange, as the trades-data needs to be converted into candles on your machine.
It will also take a long time, as freqtrade will need to download every single trade that happened on the exchange for the pair / timerange combination, therefore please be patient.
@@ -265,6 +302,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 -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.
+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/)
+32 -2
View File
@@ -40,11 +40,41 @@ usage: freqtrade recursive-analysis [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[--startup-candle STARTUP_CANDLES [STARTUP_CANDLES ...]]
optional arguments:
-p PAIR, --pairs PAIR
-h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
--data-format-ohlcv {json,jsongz,hdf5,feather,parquet}
Storage format for downloaded candle (OHLCV) data.
(default: `feather`).
-p PAIR, --pairs PAIR
Limit command to this pair.
--startup-candle STARTUP_CANDLE [STARTUP_CANDLE ...]
--startup-candle STARTUP_CANDLE [STARTUP_CANDLE ...]
Provide a space-separated list of startup_candle_count to
be checked. Default : `199 399 499 999 1999`.
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.
-V, --version show program's version number and exit
-c PATH, --config 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
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
--timerange TIMERANGE
Specify what timerange of data to use.
```
### Why are odd-numbered default startup candles used?
+3 -3
View File
@@ -1,6 +1,6 @@
markdown==3.4.4
markdown==3.5.1
mkdocs==1.5.3
mkdocs-material==9.4.1
mkdocs-material==9.4.14
mdx_truly_sane_lists==1.3
pymdown-extensions==10.3
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.
+6 -4
View File
@@ -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.
+10 -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.
@@ -1008,6 +1009,10 @@ The following lists some common patterns which should be avoided to prevent frus
- don't use `dataframe['volume'].mean()`. This uses the full DataFrame for backtesting, including data from the future. Use `dataframe['volume'].rolling(<window>).mean()` instead
- don't use `.resample('1h')`. This uses the left border of the interval, so moves data from an hour to the start of the hour. Use `.resample('1h', label='right')` instead.
!!! Tip "Identifying problems"
You may also want to check the 2 helper commands [lookahead-analysis](lookahead-analysis.md) and [recursive-analysis](recursive-analysis.md), which can each help you figure out problems with your strategy in different ways.
Please treat them as what they are - helpers to identify most common problems. A negative result of each does not guarantee that there's none of the above errors included.
### Colliding signals
When conflicting signals collide (e.g. both `'enter_long'` and `'exit_long'` are 1), freqtrade will do nothing and ignore the entry signal. This will avoid trades that enter, and exit immediately. Obviously, this can potentially lead to missed entries.
+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 -24
View File
@@ -427,25 +427,33 @@ zb True missing opt: fetchMyTrades
Use the `list-timeframes` subcommand to see the list of timeframes available for the exchange.
```
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 +487,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 +509,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 +539,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 +571,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 +585,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.9'
__version__ = '2023.11'
if 'dev' in __version__:
from pathlib import Path
+2 -2
View File
@@ -65,8 +65,8 @@ ARGS_BUILD_CONFIG = ["config"]
ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"]
ARGS_CONVERT_DATA_TRADES = ["pairs", "format_from_trades", "format_to", "erase", "exchange"]
ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to", "erase", "exchange"]
ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes", "trading_mode", "candle_types"]
ARGS_CONVERT_TRADES = ["pairs", "timeframes", "exchange", "dataformat_ohlcv", "dataformat_trades"]
@@ -268,7 +268,7 @@ class Arguments:
parents=[_common_parser],
)
convert_trade_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=False))
self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_trade_data_cmd)
self._build_args(optionlist=ARGS_CONVERT_DATA_TRADES, parser=convert_trade_data_cmd)
# Add trades-to-ohlcv subcommand
convert_trade_data_cmd = subparsers.add_parser(
@@ -108,7 +108,6 @@ def ask_user_config() -> Dict[str, Any]:
"choices": [
"binance",
"binanceus",
"bittrex",
"gate",
"huobi",
"kraken",
+6
View File
@@ -421,6 +421,12 @@ AVAILABLE_CLI_OPTIONS = {
'desired timeframe as specified as --timeframes/-t.',
action='store_true',
),
"format_from_trades": Arg(
'--format-from',
help='Source format for data conversion.',
choices=constants.AVAILABLE_DATAHANDLERS + ['kraken_csv'],
required=True,
),
"format_from": Arg(
'--format-from',
help='Source format for data conversion.',
+1 -1
View File
@@ -85,7 +85,7 @@ def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None:
erase=args['erase'])
else:
convert_trades_format(config,
convert_from=args['format_from'], convert_to=args['format_to'],
convert_from=args['format_from_trades'], convert_to=args['format_to'],
erase=args['erase'])
+2 -2
View File
@@ -140,7 +140,7 @@ def start_lookahead_analysis(args: Dict[str, Any]) -> None:
:param args: Cli args from Arguments()
:return: None
"""
from freqtrade.optimize.lookahead_analysis_helpers import LookaheadAnalysisSubFunctions
from freqtrade.optimize.analysis.lookahead_helpers import LookaheadAnalysisSubFunctions
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
LookaheadAnalysisSubFunctions.start(config)
@@ -152,7 +152,7 @@ def start_recursive_analysis(args: Dict[str, Any]) -> None:
:param args: Cli args from Arguments()
:return: None
"""
from freqtrade.optimize.recursive_analysis_helpers import RecursiveAnalysisSubFunctions
from freqtrade.optimize.analysis.recursive_helpers import RecursiveAnalysisSubFunctions
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
RecursiveAnalysisSubFunctions.start(config)
@@ -12,6 +12,7 @@ from freqtrade.configuration import TimeRange
from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TRADES_DTYPES,
Config, TradeList)
from freqtrade.enums import CandleType
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
@@ -127,6 +128,16 @@ def convert_trades_format(config: Config, convert_from: str, convert_to: str, er
:param convert_to: Target format
:param erase: Erase source data (does not apply if source and target format are identical)
"""
if convert_from == 'kraken_csv':
if config['exchange']['name'] != 'kraken':
raise OperationalException(
'Converting from csv is only supported for kraken.'
'Please refer to the documentation for details about this special mode.'
)
from freqtrade.data.converter.trade_converter_kraken import import_kraken_trades_from_csv
import_kraken_trades_from_csv(config, convert_to)
return
from freqtrade.data.history.idatahandler import get_datahandler
src = get_datahandler(config['datadir'], convert_from)
trg = get_datahandler(config['datadir'], convert_to)
@@ -0,0 +1,70 @@
import logging
from pathlib import Path
import pandas as pd
from freqtrade.constants import DATETIME_PRINT_FORMAT, DEFAULT_TRADES_COLUMNS, Config
from freqtrade.data.converter.trade_converter import (trades_convert_types,
trades_df_remove_duplicates)
from freqtrade.data.history.idatahandler import get_datahandler
from freqtrade.exceptions import OperationalException
from freqtrade.resolvers import ExchangeResolver
logger = logging.getLogger(__name__)
KRAKEN_CSV_TRADE_COLUMNS = ['timestamp', 'price', 'amount']
def import_kraken_trades_from_csv(config: Config, convert_to: str):
"""
Import kraken trades from csv
"""
if config['exchange']['name'] != 'kraken':
raise OperationalException('This function is only for the kraken exchange.')
datadir: Path = config['datadir']
data_handler = get_datahandler(datadir, data_format=convert_to)
tradesdir: Path = config['datadir'] / 'trades_csv'
exchange = ExchangeResolver.load_exchange(config, validate=False)
# iterate through directories in this directory
data_symbols = {p.stem for p in tradesdir.rglob('*.csv')}
# create pair/filename mapping
markets = {
(m['symbol'], m['altname']) for m in exchange.markets.values()
if m.get('altname') in data_symbols
}
logger.info(f"Found csv files for {', '.join(data_symbols)}.")
for pair, name in markets:
dfs = []
# Load and combine all csv files for this pair
for f in tradesdir.rglob(f"{name}.csv"):
df = pd.read_csv(f, names=KRAKEN_CSV_TRADE_COLUMNS)
dfs.append(df)
# Load existing trades data
if not dfs:
# edgecase, can only happen if the file was deleted between the above glob and here
logger.info(f"No data found for pair {pair}")
continue
trades = pd.concat(dfs, ignore_index=True)
trades.loc[:, 'timestamp'] = trades['timestamp'] * 1e3
trades.loc[:, 'cost'] = trades['price'] * trades['amount']
for col in DEFAULT_TRADES_COLUMNS:
if col not in trades.columns:
trades[col] = ''
trades = trades[DEFAULT_TRADES_COLUMNS]
trades = trades_convert_types(trades)
trades_df = trades_df_remove_duplicates(trades)
logger.info(f"{pair}: {len(trades_df)} trades, from "
f"{trades_df['date'].min():{DATETIME_PRINT_FORMAT}} to "
f"{trades_df['date'].max():{DATETIME_PRINT_FORMAT}}")
data_handler.trades_store(pair, trades_df)
+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
View File
@@ -4,6 +4,7 @@ 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
+6 -2
View File
@@ -123,10 +123,14 @@ class Binance(Exchange):
def funding_fee_cutoff(self, open_date: datetime):
"""
Funding fees are only charged at full hours (usually every 4-8h).
Therefore a trade opening at 10:00:01 will not be charged a funding fee until the next hour.
On binance, this cutoff is 15s.
https://github.com/freqtrade/freqtrade/pull/5779#discussion_r740175931
:param open_date: The open date for a trade
:return: The cutoff open time for when a funding fee is charged
:return: True if the date falls on a full hour, False otherwise
"""
return open_date.minute > 0 or (open_date.minute == 0 and open_date.second > 15)
return open_date.minute == 0 and open_date.second < 15
def dry_run_liquidation_price(
self,
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,
}
+6 -3
View File
@@ -7,7 +7,7 @@ import ccxt
from freqtrade.constants import BuySell
from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
from freqtrade.exceptions import DDosProtection, ExchangeError, OperationalException, TemporaryError
from freqtrade.exchange import Exchange
from freqtrade.exchange.common import retrier
from freqtrade.util.datetime_helpers import dt_now, dt_ts
@@ -202,8 +202,11 @@ class Bybit(Exchange):
"""
# Bybit does not provide "applied" funding fees per position.
if self.trading_mode == TradingMode.FUTURES:
return self._fetch_and_calculate_funding_fees(
pair, amount, is_short, open_date)
try:
return self._fetch_and_calculate_funding_fees(
pair, amount, is_short, open_date)
except ExchangeError:
logger.warning(f"Could not update funding fees for {pair}.")
return 0.0
def fetch_orders(self, pair: str, since: datetime, params: Optional[Dict] = None) -> List[Dict]:
+1 -1
View File
@@ -52,7 +52,7 @@ MAP_EXCHANGE_CHILDCLASS = {
SUPPORTED_EXCHANGES = [
'binance',
'bittrex',
'bitmart',
'gate',
'huobi',
'kraken',
+54 -33
View File
@@ -486,11 +486,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 +1231,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 +1499,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 +1550,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 +1964,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
@@ -2279,6 +2289,7 @@ class Exchange:
from_id = t[-1][1]
else:
logger.debug("Stopping as no more trades were returned.")
break
except asyncio.CancelledError:
logger.debug("Async operation Interrupted, breaking trades DL loop.")
@@ -2304,6 +2315,11 @@ class Exchange:
try:
t = await self._async_fetch_trades(pair, since=since)
if t:
# No more trades to download available at the exchange,
# So we repeatedly get the same trade over and over again.
if since == t[-1][0] and len(t) == 1:
logger.debug("Stopping because no more trades are available.")
break
since = t[-1][0]
trades.extend(t)
# Reached the end of the defined-download period
@@ -2312,6 +2328,7 @@ class Exchange:
f"Stopping because until was reached. {t[-1][0]} > {until}")
break
else:
logger.debug("Stopping as no more trades were returned.")
break
except asyncio.CancelledError:
logger.debug("Async operation Interrupted, breaking trades DL loop.")
@@ -2653,12 +2670,14 @@ class Exchange:
"""
return 0.0
def funding_fee_cutoff(self, open_date: datetime):
def funding_fee_cutoff(self, open_date: datetime) -> bool:
"""
Funding fees are only charged at full hours (usually every 4-8h).
Therefore a trade opening at 10:00:01 will not be charged a funding fee until the next hour.
:param open_date: The open date for a trade
:return: The cutoff open time for when a funding fee is charged
:return: True if the date falls on a full hour, False otherwise
"""
return open_date.minute > 0 or open_date.second > 0
return open_date.minute == 0 and open_date.second == 0
@retrier
def set_margin_mode(self, pair: str, margin_mode: MarginMode, accept_fail: bool = False,
@@ -2706,15 +2725,16 @@ class Exchange:
"""
if self.funding_fee_cutoff(open_date):
open_date += timedelta(hours=1)
# Shift back to 1h candle to avoid missing funding fees
# Only really relevant for trades very close to the full hour
open_date = timeframe_to_prev_date('1h', open_date)
timeframe = self._ft_has['mark_ohlcv_timeframe']
timeframe_ff = self._ft_has.get('funding_fee_timeframe',
self._ft_has['mark_ohlcv_timeframe'])
if not close_date:
close_date = datetime.now(timezone.utc)
open_timestamp = int(timeframe_to_prev_date(timeframe, open_date).timestamp()) * 1000
# close_timestamp = int(close_date.timestamp()) * 1000
since_ms = int(timeframe_to_prev_date(timeframe, open_date).timestamp()) * 1000
mark_comb: PairWithTimeframe = (
pair, timeframe, CandleType.from_string(self._ft_has["mark_ohlcv_price"]))
@@ -2722,7 +2742,7 @@ class Exchange:
funding_comb: PairWithTimeframe = (pair, timeframe_ff, CandleType.FUNDING_RATE)
candle_histories = self.refresh_latest_ohlcv(
[mark_comb, funding_comb],
since_ms=open_timestamp,
since_ms=since_ms,
cache=False,
drop_incomplete=False,
)
@@ -2733,8 +2753,7 @@ class Exchange:
except KeyError:
raise ExchangeError("Could not find funding rates.") from None
funding_mark_rates = self.combine_funding_and_mark(
funding_rates=funding_rates, mark_rates=mark_rates)
funding_mark_rates = self.combine_funding_and_mark(funding_rates, mark_rates)
return self.calculate_funding_fees(
funding_mark_rates,
@@ -2781,7 +2800,7 @@ class Exchange:
amount: float,
is_short: bool,
open_date: datetime,
close_date: Optional[datetime] = None,
close_date: datetime,
time_in_ratio: Optional[float] = None
) -> float:
"""
@@ -2797,8 +2816,8 @@ class Exchange:
fees: float = 0
if not df.empty:
df = df[(df['date'] >= open_date) & (df['date'] <= close_date)]
fees = sum(df['open_fund'] * df['open_mark'] * amount)
df1 = df[(df['date'] >= open_date) & (df['date'] <= close_date)]
fees = sum(df1['open_fund'] * df1['open_mark'] * amount)
# Negate fees for longs as funding_fees expects it this way based on live endpoints.
return fees if is_short else -fees
@@ -2813,17 +2832,19 @@ class Exchange:
:param amount: Trade amount
:param open_date: Open date of the trade
:return: funding fee since open_date
:raises: ExchangeError if something goes wrong.
"""
if self.trading_mode == TradingMode.FUTURES:
if self._config['dry_run']:
funding_fees = self._fetch_and_calculate_funding_fees(
pair, amount, is_short, open_date)
else:
funding_fees = self._get_funding_fees_from_exchange(pair, open_date)
return funding_fees
else:
return 0.0
try:
if self._config['dry_run']:
funding_fees = self._fetch_and_calculate_funding_fees(
pair, amount, is_short, open_date)
else:
funding_fees = self._get_funding_fees_from_exchange(pair, open_date)
return funding_fees
except ExchangeError:
logger.warning(f"Could not update funding fees for {pair}.")
return 0.0
def get_liquidation_price(
self,
+1 -1
View File
@@ -195,7 +195,7 @@ class Kraken(Exchange):
amount: float,
is_short: bool,
open_date: datetime,
close_date: Optional[datetime] = None,
close_date: datetime,
time_in_ratio: Optional[float] = None
) -> float:
"""
+1 -1
View File
@@ -159,7 +159,7 @@ class BaseEnvironment(gym.Env):
function is designed for tracking incremented objects,
events, actions inside the training environment.
For example, a user can call this to track the
frequency of occurence of an `is_valid` call in
frequency of occurrence of an `is_valid` call in
their `calculate_reward()`:
def calculate_reward(self, action: int) -> float:
+1 -2
View File
@@ -296,8 +296,7 @@ class FreqaiDataDrawer:
f"for more than {len(dataframe.index)} candles.")
df_concat = pd.concat([hist_preds, new_pred], ignore_index=True, keys=hist_preds.keys())
# remove last row because we will append that later in append_model_predictions()
df_concat = df_concat.iloc[:-1]
# any missing values will get zeroed out so users can see the exact
# downtime in FreqUI
df_concat = df_concat.fillna(0)
@@ -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)
@@ -1,8 +1,9 @@
import logging
from pathlib import Path
from typing import Any, Dict, Type
from typing import Any, Dict, List, Optional, Type
import torch as th
from stable_baselines3.common.callbacks import ProgressBarCallback
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from freqtrade.freqai.RL.Base5ActionRLEnv import Actions, Base5ActionRLEnv, Positions
@@ -73,19 +74,27 @@ class ReinforcementLearner(BaseReinforcementLearningModel):
'trained agent.')
model = self.dd.model_dictionary[dk.pair]
model.set_env(self.train_env)
callbacks: List[Any] = [self.eval_callback, self.tensorboard_callback]
progressbar_callback: Optional[ProgressBarCallback] = None
if self.rl_config.get('progress_bar', False):
progressbar_callback = ProgressBarCallback()
callbacks.insert(0, progressbar_callback)
model.learn(
total_timesteps=int(total_timesteps),
callback=[self.eval_callback, self.tensorboard_callback],
progress_bar=self.rl_config.get('progress_bar', False)
)
try:
model.learn(
total_timesteps=int(total_timesteps),
callback=callbacks,
)
finally:
if progressbar_callback:
progressbar_callback.on_training_end()
if Path(dk.data_path / "best_model.zip").is_file():
logger.info('Callback found a best model.')
best_model = self.MODELCLASS.load(dk.data_path / "best_model")
return best_model
logger.info('Couldnt find best model, using final model instead.')
logger.info("Couldn't find best model, using final model instead.")
return model
@@ -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,9 +42,13 @@ class TensorboardCallback(BaseCallback):
def _on_step(self) -> bool:
local_info = self.locals["infos"][0]
if self.training_env is None:
return True
tensorboard_metrics = self.training_env.get_attr("tensorboard_metrics")[0]
if hasattr(self.training_env, 'envs'):
tensorboard_metrics = self.training_env.envs[0].unwrapped.tensorboard_metrics
else:
# For RL-multiproc - usage of [0] might need to be evaluated
tensorboard_metrics = self.training_env.get_attr("tensorboard_metrics")[0]
for metric in local_info:
if metric not in ["episode", "terminal_observation"]:
+75 -65
View File
@@ -132,7 +132,7 @@ class FreqtradeBot(LoggingMixin):
# TODO: This would be more efficient if scheduled in utc time, and performed at each
# TODO: funding interval, specified by funding_fee_times on the exchange classes
for time_slot in range(0, 24):
for minutes in [0, 15, 30, 45]:
for minutes in [1, 31]:
t = str(time(time_slot, minutes, 2))
self._schedule.every().day.at(t).do(update)
self.last_process: Optional[datetime] = None
@@ -199,6 +199,7 @@ class FreqtradeBot(LoggingMixin):
# Only update open orders on startup
# This will update the database after the initial migration
self.startup_update_open_orders()
self.update_funding_fees()
def process(self) -> None:
"""
@@ -312,22 +313,19 @@ class FreqtradeBot(LoggingMixin):
open_trades = Trade.get_open_trade_count()
return max(0, self.config['max_open_trades'] - open_trades)
def update_funding_fees(self):
def update_funding_fees(self) -> None:
if self.trading_mode == TradingMode.FUTURES:
trades = Trade.get_open_trades()
try:
for trade in trades:
funding_fees = self.exchange.get_funding_fees(
trades: List[Trade] = Trade.get_open_trades()
for trade in trades:
trade.set_funding_fees(
self.exchange.get_funding_fees(
pair=trade.pair,
amount=trade.amount,
is_short=trade.is_short,
open_date=trade.date_last_filled_utc
)
trade.funding_fees = funding_fees
except ExchangeError:
logger.warning("Could not update funding fees for open trades.")
open_date=trade.date_last_filled_utc)
)
def startup_backpopulate_precision(self):
def startup_backpopulate_precision(self) -> None:
trades = Trade.get_trades([Trade.contract_size.is_(None)])
for trade in trades:
@@ -374,17 +372,13 @@ class FreqtradeBot(LoggingMixin):
fo = order.to_ccxt_object()
fo['status'] = 'canceled'
self.handle_cancel_order(
fo, order.order_id, order.trade,
constants.CANCEL_REASON['TIMEOUT']
fo, order, order.trade, constants.CANCEL_REASON['TIMEOUT']
)
except ExchangeError as e:
logger.warning(f"Error updating Order {order.order_id} due to {e}")
if self.trading_mode == TradingMode.FUTURES:
self._schedule.run_pending()
def update_trades_without_assigned_fees(self) -> None:
"""
Update closed trades without close fees assigned.
@@ -749,6 +743,7 @@ class FreqtradeBot(LoggingMixin):
:param pair: pair for which we want to create a LIMIT_BUY
:param stake_amount: amount of stake-currency for the pair
:return: True if a buy order is created, false if it fails.
:raise: DependencyException or it's subclasses like ExchangeError.
"""
time_in_force = self.strategy.order_time_in_force['entry']
@@ -835,14 +830,15 @@ class FreqtradeBot(LoggingMixin):
base_currency = self.exchange.get_pair_base_currency(pair)
open_date = datetime.now(timezone.utc)
funding_fees = self.exchange.get_funding_fees(
pair=pair,
amount=amount + trade.amount if trade else amount,
is_short=is_short,
open_date=trade.date_last_filled_utc if trade else open_date
)
# This is a new trade
if trade is None:
funding_fees = 0.0
try:
funding_fees = self.exchange.get_funding_fees(
pair=pair, amount=amount, is_short=is_short, open_date=open_date)
except ExchangeError:
logger.warning("Could not find funding fee.")
trade = Trade(
pair=pair,
@@ -878,6 +874,7 @@ class FreqtradeBot(LoggingMixin):
trade.is_open = True
trade.fee_open_currency = None
trade.open_rate_requested = enter_limit_requested
trade.set_funding_fees(funding_fees)
trade.orders.append(order_obj)
trade.recalc_trade_from_orders()
@@ -1087,7 +1084,11 @@ class FreqtradeBot(LoggingMixin):
trades_closed = 0
for trade in trades:
if not trade.has_open_orders and not self.wallets.check_exit_amount(trade):
if (
not trade.has_open_orders
and not trade.stoploss_order_id
and not self.wallets.check_exit_amount(trade)
):
logger.warning(
f'Not enough {trade.safe_base_currency} in wallet to exit {trade}. '
'Trying to recover.')
@@ -1331,6 +1332,7 @@ class FreqtradeBot(LoggingMixin):
:return: None
"""
for trade in Trade.get_open_trades():
open_order: Order
for open_order in trade.open_orders:
try:
order = self.exchange.fetch_order(open_order.order_id, trade.pair)
@@ -1351,22 +1353,23 @@ class FreqtradeBot(LoggingMixin):
)
):
self.handle_cancel_order(
order, open_order.order_id, trade, constants.CANCEL_REASON['TIMEOUT']
order, open_order, trade, constants.CANCEL_REASON['TIMEOUT']
)
else:
self.replace_order(order, open_order, trade)
def handle_cancel_order(self, order: Dict, order_id: str, trade: Trade, reason: str) -> None:
def handle_cancel_order(self, order: Dict, order_obj: Order, trade: Trade, reason: str) -> None:
"""
Check if current analyzed order timed out and cancel if necessary.
:param order: Order dict grabbed with exchange.fetch_order()
:param order_obj: Order object from the database.
:param trade: Trade object.
:return: None
"""
if order['side'] == trade.entry_side:
self.handle_cancel_enter(trade, order, order_id, reason)
self.handle_cancel_enter(trade, order, order_obj, reason)
else:
canceled = self.handle_cancel_exit(trade, order, order_id, reason)
canceled = self.handle_cancel_exit(trade, order, order_obj, reason)
canceled_count = trade.get_canceled_exit_order_count()
max_timeouts = self.config.get('unfilledtimeout', {}).get('exit_timeout_count', 0)
if (canceled and max_timeouts > 0 and canceled_count >= max_timeouts):
@@ -1431,7 +1434,7 @@ class FreqtradeBot(LoggingMixin):
trade=trade, order=order_obj, pair=trade.pair,
current_time=datetime.now(timezone.utc), proposed_rate=proposed_rate,
current_order_rate=order_obj.safe_price, entry_tag=trade.enter_tag,
side=trade.entry_side)
side=trade.trade_direction)
replacing = True
cancel_reason = constants.CANCEL_REASON['REPLACE']
@@ -1440,7 +1443,7 @@ class FreqtradeBot(LoggingMixin):
cancel_reason = constants.CANCEL_REASON['USER_CANCEL']
if order_obj.price != adjusted_entry_price:
# cancel existing order if new price is supplied or None
res = self.handle_cancel_enter(trade, order, order_obj.order_id, cancel_reason,
res = self.handle_cancel_enter(trade, order, order_obj, cancel_reason,
replacing=replacing)
if not res:
self.replace_order_failed(
@@ -1448,15 +1451,21 @@ class FreqtradeBot(LoggingMixin):
return
if adjusted_entry_price:
# place new order only if new price is supplied
if not self.execute_entry(
pair=trade.pair,
stake_amount=(
order_obj.safe_remaining * order_obj.safe_price / trade.leverage),
price=adjusted_entry_price,
trade=trade,
is_short=trade.is_short,
mode='replace',
):
try:
if not self.execute_entry(
pair=trade.pair,
stake_amount=(
order_obj.safe_remaining * order_obj.safe_price / trade.leverage),
price=adjusted_entry_price,
trade=trade,
is_short=trade.is_short,
mode='replace',
):
self.replace_order_failed(
trade, f"Could not replace order for {trade}.")
except DependencyException as exception:
logger.warning(
f'Unable to replace order for {trade.pair}: {exception}')
self.replace_order_failed(trade, f"Could not replace order for {trade}.")
def cancel_all_open_orders(self) -> None:
@@ -1475,29 +1484,28 @@ class FreqtradeBot(LoggingMixin):
if order['side'] == trade.entry_side:
self.handle_cancel_enter(
trade, order, open_order.order_id, constants.CANCEL_REASON['ALL_CANCELLED']
trade, order, open_order, constants.CANCEL_REASON['ALL_CANCELLED']
)
elif order['side'] == trade.exit_side:
self.handle_cancel_exit(
trade, order, open_order.order_id, constants.CANCEL_REASON['ALL_CANCELLED']
trade, order, open_order, constants.CANCEL_REASON['ALL_CANCELLED']
)
Trade.commit()
def handle_cancel_enter(
self, trade: Trade, order: Dict, order_id: str,
self, trade: Trade, order: Dict, order_obj: Order,
reason: str, replacing: Optional[bool] = False
) -> bool:
"""
entry cancel - cancel order
:param order_obj: Order object from the database.
:param replacing: Replacing order - prevent trade deletion.
:return: True if trade was fully cancelled
"""
was_trade_fully_canceled = False
order_id = order_obj.order_id
side = trade.entry_side.capitalize()
if not trade.has_open_orders:
logger.warning(f"No open order for {trade}.")
return False
if order['status'] not in constants.NON_OPEN_EXCHANGE_STATES:
filled_val: float = order.get('filled', 0.0) or 0.0
@@ -1510,8 +1518,8 @@ class FreqtradeBot(LoggingMixin):
f"Order {order_id} for {trade.pair} not cancelled, "
f"as the filled amount of {filled_val} would result in an unexitable trade.")
return False
corder = self.exchange.cancel_order_with_result(order_id, trade.pair,
trade.amount)
corder = self.exchange.cancel_order_with_result(order_id, trade.pair, trade.amount)
order_obj.ft_cancel_reason = reason
# if replacing, retry fetching the order 3 times if the status is not what we need
if replacing:
retry_count = 0
@@ -1532,9 +1540,10 @@ class FreqtradeBot(LoggingMixin):
else:
# Order was cancelled already, so we can reuse the existing dict
corder = order
reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE']
if order_obj.ft_cancel_reason is None:
order_obj.ft_cancel_reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE']
logger.info(f'{side} order {reason} for {trade}.')
logger.info(f'{side} order {order_obj.ft_cancel_reason} for {trade}.')
# Using filled to determine the filled amount
filled_amount = safe_value_fallback2(corder, order, 'filled', 'filled')
@@ -1547,7 +1556,7 @@ class FreqtradeBot(LoggingMixin):
if open_order_count < 1 and trade.nr_of_successful_entries == 0 and not replacing:
logger.info(f'{side} order fully cancelled. Removing {trade} from database.')
trade.delete()
reason += f", {constants.CANCEL_REASON['FULLY_CANCELLED']}"
order_obj.ft_cancel_reason += f", {constants.CANCEL_REASON['FULLY_CANCELLED']}"
else:
self.update_trade_state(trade, order_id, corder)
logger.info(f'{side} Order timeout for {trade}.')
@@ -1557,21 +1566,21 @@ class FreqtradeBot(LoggingMixin):
self.update_trade_state(trade, order_id, corder)
logger.info(f'Partial {trade.entry_side} order timeout for {trade}.')
reason += f", {constants.CANCEL_REASON['PARTIALLY_FILLED']}"
order_obj.ft_cancel_reason += f", {constants.CANCEL_REASON['PARTIALLY_FILLED']}"
self.wallets.update()
self._notify_enter_cancel(trade, order_type=self.strategy.order_types['entry'],
reason=reason)
reason=order_obj.ft_cancel_reason)
return was_trade_fully_canceled
def handle_cancel_exit(
self, trade: Trade, order: Dict, order_id: str,
reason: str
self, trade: Trade, order: Dict, order_obj: Order, reason: str
) -> bool:
"""
exit order cancel - cancel order and update trade
:return: True if exit order was cancelled, false otherwise
"""
order_id = order_obj.order_id
cancelled = False
# Cancelled orders may have the status of 'canceled' or 'closed'
if order['status'] not in constants.NON_OPEN_EXCHANGE_STATES:
@@ -1596,7 +1605,7 @@ class FreqtradeBot(LoggingMixin):
sub_trade=trade.amount != order['amount']
)
return False
order_obj.ft_cancel_reason = reason
try:
order = self.exchange.cancel_order_with_result(
order['id'], trade.pair, trade.amount)
@@ -1615,19 +1624,22 @@ class FreqtradeBot(LoggingMixin):
trade.exit_reason = exit_reason_prev
cancelled = True
else:
reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE']
if order_obj.ft_cancel_reason is None:
order_obj.ft_cancel_reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE']
trade.exit_reason = None
self.update_trade_state(trade, order['id'], order)
logger.info(f'{trade.exit_side.capitalize()} order {reason} for {trade}.')
logger.info(
f'{trade.exit_side.capitalize()} order {order_obj.ft_cancel_reason} for {trade}.')
trade.close_rate = None
trade.close_rate_requested = None
self._notify_exit_cancel(
trade,
order_type=self.strategy.order_types['exit'],
reason=reason, order_id=order['id'], sub_trade=trade.amount != order['amount']
reason=order_obj.ft_cancel_reason, order_id=order['id'],
sub_trade=trade.amount != order['amount']
)
return cancelled
@@ -1679,15 +1691,13 @@ class FreqtradeBot(LoggingMixin):
:param exit_check: CheckTuple with signal and reason
:return: True if it succeeds False
"""
try:
trade.funding_fees = self.exchange.get_funding_fees(
trade.set_funding_fees(
self.exchange.get_funding_fees(
pair=trade.pair,
amount=trade.amount,
is_short=trade.is_short,
open_date=trade.date_last_filled_utc,
)
except ExchangeError:
logger.warning("Could not update funding fee.")
open_date=trade.date_last_filled_utc)
)
exit_type = 'exit'
exit_reason = exit_tag or exit_check.exit_reason
@@ -1910,7 +1920,7 @@ class FreqtradeBot(LoggingMixin):
if self.exchange.check_order_canceled_empty(order):
# Trade has been cancelled on exchange
# Handling of this will happen in check_handle_timedout.
# Handling of this will happen in handle_cancel_order.
return True
order_obj_or_none = trade.select_order_by_order_id(order_id)
+5 -7
View File
@@ -8,15 +8,13 @@ logger = logging.getLogger(__name__)
def set_loggers(verbosity: int = 0, api_verbosity: str = 'info') -> None:
"""
Set the logging level for third party libraries
:param verbosity: Verbosity level. amount of `-v` passed to the command line
:return: None
"""
logging.getLogger('requests').setLevel(
logging.INFO if verbosity <= 1 else logging.DEBUG
)
logging.getLogger("urllib3").setLevel(
logging.INFO if verbosity <= 1 else logging.DEBUG
)
for logger_name in ('requests', 'urllib3', 'httpcore'):
logging.getLogger(logger_name).setLevel(
logging.INFO if verbosity <= 1 else logging.DEBUG
)
logging.getLogger('ccxt.base.exchange').setLevel(
logging.INFO if verbosity <= 2 else logging.DEBUG
)
+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)
@@ -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:
@@ -7,7 +7,7 @@ import pandas as pd
from freqtrade.constants import Config
from freqtrade.exceptions import OperationalException
from freqtrade.optimize.lookahead_analysis import LookaheadAnalysis
from freqtrade.optimize.analysis.lookahead import LookaheadAnalysis
from freqtrade.resolvers import StrategyResolver
@@ -64,7 +64,7 @@ class RecursiveAnalysis(BaseAnalysis):
self.dict_recursive[indicator][part.startup_candle] = f"{diff:.3f}%"
else:
logger.info("No difference found. Stop the process.")
logger.info("No variance on indicator(s) found due to recursive formula.")
break
# For lookahead bias check
@@ -100,7 +100,7 @@ class RecursiveAnalysis(BaseAnalysis):
# logger.info("part value {:.5f}".format(values_diff_other))
else:
logger.info("No lookahead bias on indicators found. Stop the process.")
logger.info("No lookahead bias on indicators found.")
def prepare_data(self, varholder: VarHolder, pairs_to_load: List[DataFrame]):
@@ -120,6 +120,7 @@ class RecursiveAnalysis(BaseAnalysis):
prepare_data_config['exchange']['pair_whitelist'] = pairs_to_load
backtesting = Backtesting(prepare_data_config, self.exchange)
self.exchange = backtesting.exchange
backtesting._set_strategy(backtesting.strategylist[0])
varholder.data, varholder.timerange = backtesting.load_bt_data()
@@ -5,7 +5,7 @@ from typing import Any, Dict, List
from freqtrade.constants import Config
from freqtrade.exceptions import OperationalException
from freqtrade.optimize.recursive_analysis import RecursiveAnalysis
from freqtrade.optimize.analysis.recursive import RecursiveAnalysis
from freqtrade.resolvers import StrategyResolver
@@ -31,10 +31,13 @@ class RecursiveAnalysisSubFunctions:
temp_data.append(values.get(int(candle), '-'))
data.append(temp_data)
from tabulate import tabulate
table = tabulate(data, headers=headers, tablefmt="orgtbl")
print(table)
return table, headers, data
if len(data) > 0:
from tabulate import tabulate
table = tabulate(data, headers=headers, tablefmt="orgtbl")
print(table)
return table, headers, data
return None, None, data
@staticmethod
def calculate_config_overrides(config: Config):
@@ -81,8 +84,7 @@ class RecursiveAnalysisSubFunctions:
if not (strategy_list := config.get('strategy_list', [])):
if config.get('strategy') is None:
raise OperationalException(
"No Strategy specified. Please specify a strategy via --strategy or "
"--strategy-list"
"No Strategy specified. Please specify a strategy via --strategy"
)
strategy_list = [config['strategy']]
@@ -100,7 +102,5 @@ class RecursiveAnalysisSubFunctions:
RecursiveAnalysisSubFunctions.text_table_recursive_analysis_instances(
RecursiveAnalysis_instances)
else:
logger.error("There were no strategies specified neither through "
"--strategy nor through "
"--strategy-list "
logger.error("There was no strategy specified through --strategy "
"or timeframe was not specified.")
+26 -23
View File
@@ -525,10 +525,10 @@ class Backtesting:
# This should not be reached...
return row[OPEN_IDX]
def _get_adjust_trade_entry_for_candle(self, trade: LocalTrade, row: Tuple
) -> LocalTrade:
def _get_adjust_trade_entry_for_candle(
self, trade: LocalTrade, row: Tuple, current_time: datetime
) -> LocalTrade:
current_rate = row[OPEN_IDX]
current_date = row[DATE_IDX].to_pydatetime()
current_profit = trade.calc_profit_ratio(current_rate)
min_stake = self.exchange.get_min_pair_stake_amount(trade.pair, current_rate, -0.1)
max_stake = self.exchange.get_max_pair_stake_amount(trade.pair, current_rate)
@@ -536,7 +536,7 @@ class Backtesting:
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
default_retval=None, supress_error=True)(
trade=trade, # type: ignore[arg-type]
current_time=current_date, current_rate=current_rate,
current_time=current_time, current_rate=current_rate,
current_profit=current_profit, min_stake=min_stake,
max_stake=min(max_stake, stake_available),
current_entry_rate=current_rate, current_exit_rate=current_rate,
@@ -569,10 +569,10 @@ class Backtesting:
# Remaining stake is too low to be sold.
return trade
exit_ = ExitCheckTuple(ExitType.PARTIAL_EXIT)
pos_trade = self._get_exit_for_signal(trade, row, exit_, amount)
pos_trade = self._get_exit_for_signal(trade, row, exit_, current_time, amount)
if pos_trade is not None:
order = pos_trade.orders[-1]
if self._try_close_open_order(order, trade, current_date, row):
if self._try_close_open_order(order, trade, current_time, row):
trade.recalc_trade_from_orders()
self.wallets.update()
return pos_trade
@@ -615,11 +615,11 @@ class Backtesting:
def _get_exit_for_signal(
self, trade: LocalTrade, row: Tuple, exit_: ExitCheckTuple,
current_time: datetime,
amount: Optional[float] = None) -> Optional[LocalTrade]:
exit_candle_time: datetime = row[DATE_IDX].to_pydatetime()
if exit_.exit_flag:
trade.close_date = exit_candle_time
trade.close_date = current_time
exit_reason = exit_.exit_reason
amount_ = amount if amount is not None else trade.amount
trade_dur = int((trade.close_date_utc - trade.open_date_utc).total_seconds() // 60)
@@ -647,10 +647,10 @@ class Backtesting:
default_retval=close_rate)(
pair=trade.pair,
trade=trade, # type: ignore[arg-type]
current_time=exit_candle_time,
current_time=current_time,
proposed_rate=close_rate, current_profit=current_profit,
exit_tag=exit_reason)
if rate != close_rate:
if rate is not None and rate != close_rate:
close_rate = price_to_precision(rate, trade.price_precision,
self.precision_mode)
# We can't place orders lower than current low.
@@ -673,7 +673,7 @@ class Backtesting:
time_in_force=time_in_force,
sell_reason=exit_reason, # deprecated
exit_reason=exit_reason,
current_time=exit_candle_time)):
current_time=current_time)):
return None
trade.exit_reason = exit_reason
@@ -714,21 +714,24 @@ class Backtesting:
trade.orders.append(order)
return trade
def _check_trade_exit(self, trade: LocalTrade, row: Tuple) -> Optional[LocalTrade]:
exit_candle_time: datetime = row[DATE_IDX].to_pydatetime()
def _check_trade_exit(
self, trade: LocalTrade, row: Tuple, current_time: datetime
) -> Optional[LocalTrade]:
if self.trading_mode == TradingMode.FUTURES:
trade.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=exit_candle_time,
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
)
)
# Check if we need to adjust our current positions
if self.strategy.position_adjustment_enable:
trade = self._get_adjust_trade_entry_for_candle(trade, row)
trade = self._get_adjust_trade_entry_for_candle(trade, row, current_time)
enter = row[SHORT_IDX] if trade.is_short else row[LONG_IDX]
exit_sig = row[ESHORT_IDX] if trade.is_short else row[ELONG_IDX]
@@ -738,7 +741,7 @@ class Backtesting:
low=row[LOW_IDX], high=row[HIGH_IDX]
)
for exit_ in exits:
t = self._get_exit_for_signal(trade, row, exit_)
t = self._get_exit_for_signal(trade, row, exit_, current_time)
if t:
return t
return None
@@ -760,7 +763,7 @@ class Backtesting:
) # default value is the open rate
# We can't place orders higher than current high (otherwise it'd be a stop limit entry)
# which freqtrade does not support in live.
if new_rate != propose_rate:
if new_rate is not None and new_rate != propose_rate:
propose_rate = price_to_precision(new_rate, price_precision,
self.precision_mode)
if direction == "short":
@@ -1145,7 +1148,7 @@ class Backtesting:
# 4. Create exit orders (if any)
if not trade.has_open_orders:
self._check_trade_exit(trade, row) # Place exit order if necessary
self._check_trade_exit(trade, row, current_time) # Place exit order if necessary
# 5. Process exit orders.
order = trade.select_order(trade.exit_side, is_open=True)
+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)
+9 -6
View File
@@ -115,6 +115,7 @@ def migrate_trades_and_orders_table(
# Futures Properties
interest_rate = get_column_def(cols, 'interest_rate', '0.0')
funding_fees = get_column_def(cols, 'funding_fees', '0.0')
funding_fee_running = get_column_def(cols, 'funding_fee_running', 'null')
max_stake_amount = get_column_def(cols, 'max_stake_amount', 'stake_amount')
# If ticker-interval existed use that, else null.
@@ -163,7 +164,7 @@ def migrate_trades_and_orders_table(
max_rate, min_rate, exit_reason, exit_order_status, strategy, enter_tag,
timeframe, open_trade_value, close_profit_abs,
trading_mode, leverage, liquidation_price, is_short,
interest_rate, funding_fees, realized_profit,
interest_rate, funding_fees, funding_fee_running, realized_profit,
amount_precision, price_precision, precision_mode, contract_size,
max_stake_amount
)
@@ -192,7 +193,8 @@ def migrate_trades_and_orders_table(
{open_trade_value} open_trade_value, {close_profit_abs} close_profit_abs,
{trading_mode} trading_mode, {leverage} leverage, {liquidation_price} liquidation_price,
{is_short} is_short, {interest_rate} interest_rate,
{funding_fees} funding_fees, {realized_profit} realized_profit,
{funding_fees} funding_fees, {funding_fee_running} funding_fee_running,
{realized_profit} realized_profit,
{amount_precision} amount_precision, {price_precision} price_precision,
{precision_mode} precision_mode, {contract_size} contract_size,
{max_stake_amount} max_stake_amount
@@ -220,6 +222,7 @@ def migrate_orders_table(engine, table_back_name: str, cols_order: List):
funding_fee = get_column_def(cols_order, 'funding_fee', '0.0')
ft_amount = get_column_def(cols_order, 'ft_amount', 'coalesce(amount, 0.0)')
ft_price = get_column_def(cols_order, 'ft_price', 'coalesce(price, 0.0)')
ft_cancel_reason = get_column_def(cols_order, 'ft_cancel_reason', 'null')
# sqlite does not support literals for booleans
with engine.begin() as connection:
@@ -227,13 +230,13 @@ def migrate_orders_table(engine, table_back_name: str, cols_order: List):
insert into orders (id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id,
status, symbol, order_type, side, price, amount, filled, average, remaining, cost,
stop_price, order_date, order_filled_date, order_update_date, ft_fee_base, funding_fee,
ft_amount, ft_price
ft_amount, ft_price, ft_cancel_reason
)
select id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id,
status, symbol, order_type, side, price, amount, filled, {average} average, remaining,
cost, {stop_price} stop_price, order_date, order_filled_date,
order_update_date, {ft_fee_base} ft_fee_base, {funding_fee} funding_fee,
{ft_amount} ft_amount, {ft_price} ft_price
{ft_amount} ft_amount, {ft_price} ft_price, {ft_cancel_reason} ft_cancel_reason
from {table_back_name}
"""))
@@ -328,8 +331,8 @@ def check_migrate(engine, decl_base, previous_tables) -> None:
# if ('orders' not in previous_tables
# or not has_column(cols_orders, 'funding_fee')):
migrating = False
# if not has_column(cols_orders, 'ft_price'):
if not has_column(cols_trades, 'is_stop_loss_trailing'):
# if not has_column(cols_orders, 'ft_cancel_reason'):
if not has_column(cols_trades, 'funding_fee_running'):
migrating = True
logger.info(f"Running database migration for trades - "
f"backup: {table_back_name}, {order_table_bak_name}")
+138 -114
View File
@@ -68,6 +68,7 @@ class Order(ModelBase):
ft_is_open: Mapped[bool] = mapped_column(nullable=False, default=True, index=True)
ft_amount: Mapped[float] = mapped_column(Float(), nullable=False)
ft_price: Mapped[float] = mapped_column(Float(), nullable=False)
ft_cancel_reason: Mapped[str] = mapped_column(String(CUSTOM_TAG_MAX_LENGTH), nullable=True)
order_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
status: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
@@ -173,10 +174,6 @@ class Order(ModelBase):
self.ft_is_open = True
if self.status in NON_OPEN_EXCHANGE_STATES:
self.ft_is_open = False
if self.trade:
# Assign funding fee up to this point
# (represents the funding fee since the last order)
self.funding_fee = self.trade.funding_fees
if (order.get('filled', 0.0) or 0.0) > 0 and not self.order_filled_date:
self.order_filled_date = dt_from_ts(
safe_value_fallback(order, 'lastTradeTimestamp', default_value=dt_ts())
@@ -237,6 +234,7 @@ class Order(ModelBase):
'price': self.price,
'remaining': self.remaining,
'ft_fee_base': self.ft_fee_base,
'funding_fee': self.funding_fee,
})
return resp
@@ -248,7 +246,8 @@ class Order(ModelBase):
self.ft_is_open = False
# Assign funding fees to Order.
# Assumes backtesting will use date_last_filled_utc to calculate future funding fees.
self.funding_fee = trade.funding_fees
self.funding_fee = trade.funding_fee_running
trade.funding_fee_running = 0.0
if (self.ft_order_side == trade.entry_side and self.price):
trade.open_rate = self.price
@@ -395,6 +394,9 @@ class LocalTrade:
# Futures properties
funding_fees: Optional[float] = None
# Used to keep running funding fees - between the last filled order and now
# Shall not be used for calculations!
funding_fee_running: Optional[float] = None
@property
def stoploss_or_liquidation(self) -> float:
@@ -534,6 +536,7 @@ class LocalTrade:
for key in kwargs:
setattr(self, key, kwargs[key])
self.recalc_open_trade_value()
self.orders = []
if self.trading_mode == TradingMode.MARGIN and self.interest_rate is None:
raise OperationalException(
f"{self.trading_mode.value} trading requires param interest_rate on trades")
@@ -660,6 +663,16 @@ class LocalTrade:
return
self.liquidation_price = liquidation_price
def set_funding_fees(self, funding_fee: float) -> None:
"""
Assign funding fees to Trade.
"""
if funding_fee is None:
return
self.funding_fee_running = funding_fee
prior_funding_fees = sum([o.funding_fee for o in self.orders if o.funding_fee])
self.funding_fees = prior_funding_fees + funding_fee
def __set_stop_loss(self, stop_loss: float, percent: float):
"""
Method used internally to set self.stop_loss.
@@ -740,6 +753,10 @@ class LocalTrade:
return
logger.info(f'Updating trade (id={self.id}) ...')
if order.ft_order_side != 'stoploss':
order.funding_fee = self.funding_fee_running
# Reset running funding fees
self.funding_fee_running = 0.0
if order.ft_order_side == self.entry_side:
# Update open rate and actual amount
@@ -1036,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:
@@ -1049,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)
@@ -1285,6 +1305,99 @@ class LocalTrade:
trade.adjust_stop_loss(trade.open_rate, desired_stoploss)
logger.info(f"New stoploss: {trade.stop_loss}.")
@classmethod
def from_json(cls, json_str: str) -> Self:
"""
Create a Trade instance from a json string.
Used for debugging purposes - please keep.
:param json_str: json string to parse
:return: Trade instance
"""
import rapidjson
data = rapidjson.loads(json_str)
trade = cls(
__FROM_JSON=True,
id=data["trade_id"],
pair=data["pair"],
base_currency=data["base_currency"],
stake_currency=data["quote_currency"],
is_open=data["is_open"],
exchange=data["exchange"],
amount=data["amount"],
amount_requested=data["amount_requested"],
stake_amount=data["stake_amount"],
strategy=data["strategy"],
enter_tag=data["enter_tag"],
timeframe=data["timeframe"],
fee_open=data["fee_open"],
fee_open_cost=data["fee_open_cost"],
fee_open_currency=data["fee_open_currency"],
fee_close=data["fee_close"],
fee_close_cost=data["fee_close_cost"],
fee_close_currency=data["fee_close_currency"],
open_date=datetime.fromtimestamp(data["open_timestamp"] // 1000, tz=timezone.utc),
open_rate=data["open_rate"],
open_rate_requested=data["open_rate_requested"],
open_trade_value=data["open_trade_value"],
close_date=(datetime.fromtimestamp(data["close_timestamp"] // 1000, tz=timezone.utc)
if data["close_timestamp"] else None),
realized_profit=data["realized_profit"],
close_rate=data["close_rate"],
close_rate_requested=data["close_rate_requested"],
close_profit=data["close_profit"],
close_profit_abs=data["close_profit_abs"],
exit_reason=data["exit_reason"],
exit_order_status=data["exit_order_status"],
stop_loss=data["stop_loss_abs"],
stop_loss_pct=data["stop_loss_ratio"],
stoploss_order_id=data["stoploss_order_id"],
stoploss_last_update=(
datetime.fromtimestamp(data["stoploss_last_update_timestamp"] // 1000,
tz=timezone.utc)
if data["stoploss_last_update_timestamp"] else None),
initial_stop_loss=data["initial_stop_loss_abs"],
initial_stop_loss_pct=data["initial_stop_loss_ratio"],
min_rate=data["min_rate"],
max_rate=data["max_rate"],
leverage=data["leverage"],
interest_rate=data["interest_rate"],
liquidation_price=data["liquidation_price"],
is_short=data["is_short"],
trading_mode=data["trading_mode"],
funding_fees=data["funding_fees"],
amount_precision=data.get('amount_precision', None),
price_precision=data.get('price_precision', None),
precision_mode=data.get('precision_mode', None),
contract_size=data.get('contract_size', None),
)
for order in data["orders"]:
order_obj = Order(
amount=order["amount"],
ft_amount=order["amount"],
ft_order_side=order["ft_order_side"],
ft_pair=order["pair"],
ft_is_open=order["is_open"],
order_id=order["order_id"],
status=order["status"],
average=order["average"],
cost=order["cost"],
filled=order["filled"],
order_date=datetime.strptime(order["order_date"], DATETIME_PRINT_FORMAT),
order_filled_date=(datetime.fromtimestamp(
order["order_filled_timestamp"] // 1000, tz=timezone.utc)
if order["order_filled_timestamp"] else None),
order_type=order["order_type"],
price=order["price"],
ft_price=order["price"],
remaining=order["remaining"],
funding_fee=order.get("funding_fee", None),
)
trade.orders.append(order_obj)
return trade
class Trade(ModelBase, LocalTrade):
"""
@@ -1388,6 +1501,8 @@ class Trade(ModelBase, LocalTrade):
# Futures properties
funding_fees: Mapped[Optional[float]] = mapped_column(
Float(), nullable=True, default=None) # type: ignore
funding_fee_running: Mapped[Optional[float]] = mapped_column(
Float(), nullable=True, default=None) # type: ignore
def __init__(self, **kwargs):
from_json = kwargs.pop('__FROM_JSON', None)
@@ -1668,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"
@@ -1676,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)):
@@ -1728,95 +1844,3 @@ class Trade(ModelBase, LocalTrade):
Order.status == 'closed'
)).scalar_one()
return trading_volume
@classmethod
def from_json(cls, json_str: str) -> Self:
"""
Create a Trade instance from a json string.
Used for debugging purposes - please keep.
:param json_str: json string to parse
:return: Trade instance
"""
import rapidjson
data = rapidjson.loads(json_str)
trade = cls(
__FROM_JSON=True,
id=data["trade_id"],
pair=data["pair"],
base_currency=data["base_currency"],
stake_currency=data["quote_currency"],
is_open=data["is_open"],
exchange=data["exchange"],
amount=data["amount"],
amount_requested=data["amount_requested"],
stake_amount=data["stake_amount"],
strategy=data["strategy"],
enter_tag=data["enter_tag"],
timeframe=data["timeframe"],
fee_open=data["fee_open"],
fee_open_cost=data["fee_open_cost"],
fee_open_currency=data["fee_open_currency"],
fee_close=data["fee_close"],
fee_close_cost=data["fee_close_cost"],
fee_close_currency=data["fee_close_currency"],
open_date=datetime.fromtimestamp(data["open_timestamp"] // 1000, tz=timezone.utc),
open_rate=data["open_rate"],
open_rate_requested=data["open_rate_requested"],
open_trade_value=data["open_trade_value"],
close_date=(datetime.fromtimestamp(data["close_timestamp"] // 1000, tz=timezone.utc)
if data["close_timestamp"] else None),
realized_profit=data["realized_profit"],
close_rate=data["close_rate"],
close_rate_requested=data["close_rate_requested"],
close_profit=data["close_profit"],
close_profit_abs=data["close_profit_abs"],
exit_reason=data["exit_reason"],
exit_order_status=data["exit_order_status"],
stop_loss=data["stop_loss_abs"],
stop_loss_pct=data["stop_loss_ratio"],
stoploss_order_id=data["stoploss_order_id"],
stoploss_last_update=(
datetime.fromtimestamp(data["stoploss_last_update_timestamp"] // 1000,
tz=timezone.utc)
if data["stoploss_last_update_timestamp"] else None),
initial_stop_loss=data["initial_stop_loss_abs"],
initial_stop_loss_pct=data["initial_stop_loss_ratio"],
min_rate=data["min_rate"],
max_rate=data["max_rate"],
leverage=data["leverage"],
interest_rate=data["interest_rate"],
liquidation_price=data["liquidation_price"],
is_short=data["is_short"],
trading_mode=data["trading_mode"],
funding_fees=data["funding_fees"],
amount_precision=data.get('amount_precision', None),
price_precision=data.get('price_precision', None),
precision_mode=data.get('precision_mode', None),
contract_size=data.get('contract_size', None),
)
for order in data["orders"]:
order_obj = Order(
amount=order["amount"],
ft_amount=order["amount"],
ft_order_side=order["ft_order_side"],
ft_pair=order["pair"],
ft_is_open=order["is_open"],
order_id=order["order_id"],
status=order["status"],
average=order["average"],
cost=order["cost"],
filled=order["filled"],
order_date=datetime.strptime(order["order_date"], DATETIME_PRINT_FORMAT),
order_filled_date=(datetime.fromtimestamp(
order["order_filled_timestamp"] // 1000, tz=timezone.utc)
if order["order_filled_timestamp"] else None),
order_type=order["order_type"],
price=order["price"],
ft_price=order["price"],
remaining=order["remaining"],
)
trade.orders.append(order_obj)
return trade
+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']
+20 -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
@@ -484,11 +499,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):
+24 -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()
+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
+1 -2
View File
@@ -31,12 +31,11 @@ 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)
color = 0x0000FF
if msg['type'] in (RPCMessageType.EXIT, RPCMessageType.EXIT_FILL):
profit_ratio = msg.get('profit_ratio')
+1
View File
@@ -27,6 +27,7 @@ coingecko_mapping = {
'usdt': 'tether',
'busd': 'binance-usd',
'tusd': 'true-usd',
'usdc': 'usd-coin',
}
+3 -3
View File
@@ -795,14 +795,14 @@ class RPC:
if order['side'] == trade.entry_side:
fully_canceled = self._freqtrade.handle_cancel_enter(
trade, order, oo.order_id, CANCEL_REASON['FORCE_EXIT'])
trade, order, oo, CANCEL_REASON['FORCE_EXIT'])
trade_entry_cancelation_res['cancel_state'] = fully_canceled
trade_entry_cancelation_registry.append(trade_entry_cancelation_res)
if order['side'] == trade.exit_side:
# Cancel order - so it is placed anew with a fresh price.
self._freqtrade.handle_cancel_exit(
trade, order, oo.order_id, CANCEL_REASON['FORCE_EXIT'])
trade, order, oo, CANCEL_REASON['FORCE_EXIT'])
if all(tocr['cancel_state'] is False for tocr in trade_entry_cancelation_registry):
if trade.has_open_orders:
@@ -955,7 +955,7 @@ class RPC:
logger.info(f"Cannot query order for {trade} due to {e}.", exc_info=True)
raise RPCException("Order not found.")
self._freqtrade.handle_cancel_order(
order, open_order.order_id, trade, CANCEL_REASON['USER_CANCEL'])
order, open_order, trade, CANCEL_REASON['USER_CANCEL'])
Trade.commit()
def _rpc_delete(self, trade_id: int) -> Dict[str, Union[str, int]]:
+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:
+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,
}
+29 -18
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,
@@ -1244,10 +1255,6 @@ class IStrategy(ABC, HyperStrategyMixin):
and trade.liquidation_price <= (high or current_rate)
and trade.is_short)
if (liq_higher_long or liq_lower_short):
logger.debug(f"{trade.pair} - Liquidation price hit. exit_type=ExitType.LIQUIDATION")
return ExitCheckTuple(exit_type=ExitType.LIQUIDATION)
# evaluate if the stoploss was hit if stoploss is not on exchange
# in Dry-Run, this handles stoploss logic as well, as the logic will not be different to
# regular stoploss handling.
@@ -1268,6 +1275,10 @@ class IStrategy(ABC, HyperStrategyMixin):
return ExitCheckTuple(exit_type=exit_type)
if (liq_higher_long or liq_lower_short):
logger.debug(f"{trade.pair} - Liquidation price hit. exit_type=ExitType.LIQUIDATION")
return ExitCheckTuple(exit_type=ExitType.LIQUIDATION)
return ExitCheckTuple(exit_type=ExitType.NONE)
def min_roi_reached_entry(self, trade_dur: int) -> Tuple[Optional[int], Optional[float]]:
@@ -290,9 +290,6 @@ class FreqaiExampleStrategy(IStrategy):
return df
def get_ticker_indicator(self):
return int(self.config["timeframe"][:-1])
def confirm_trade_entry(
self,
pair: str,
+1 -1
View File
@@ -226,7 +226,7 @@ def crossed(series1, series2, direction=None):
series1.shift(1) >= series2.shift(1)))
if direction is None:
return above or below
return above | below
return above if direction == "above" else below
+5
View File
@@ -82,6 +82,11 @@ extend-select = [
# "TCH", # flake8-type-checking
"PTH", # flake8-use-pathlib
]
extend-ignore = [
"E241", # Multiple spaces after comma
"E272", # Multiple spaces before keyword
"E221", # Multiple spaces before operator
]
[tool.ruff.mccabe]
max-complexity = 12
+8 -8
View File
@@ -7,24 +7,24 @@
-r docs/requirements-docs.txt
coveralls==3.3.1
ruff==0.0.291
mypy==1.5.1
pre-commit==3.4.0
pytest==7.4.2
ruff==0.1.6
mypy==1.7.1
pre-commit==3.5.0
pytest==7.4.3
pytest-asyncio==0.21.1
pytest-cov==4.1.0
pytest-mock==3.11.1
pytest-mock==3.12.0
pytest-random-order==1.1.0
isort==5.12.0
# For datetime mocking
time-machine==2.13.0
# Convert jupyter notebooks to markdown documents
nbconvert==7.8.0
nbconvert==7.11.0
# mypy types
types-cachetools==5.3.0.6
types-cachetools==5.3.0.7
types-filelock==3.2.7
types-requests==2.31.0.4
types-requests==2.31.0.10
types-tabulate==0.9.0.3
types-python-dateutil==2.8.19.14
+1 -1
View File
@@ -5,7 +5,7 @@
torch==2.0.1
#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
+2 -2
View File
@@ -7,6 +7,6 @@ scikit-learn==1.1.3
joblib==1.3.2
catboost==1.2.2; 'arm' not in platform_machine
lightgbm==4.1.0
xgboost==2.0.0
tensorboard==2.14.0
xgboost==2.0.2
tensorboard==2.15.1
datasieve==0.1.7
+2 -2
View File
@@ -2,7 +2,7 @@
-r requirements.txt
# Required for hyperopt
scipy==1.11.2
scipy==1.11.4
scikit-learn==1.1.3
scikit-optimize==0.9.0
filelock==3.12.4
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
+25 -27
View File
@@ -1,49 +1,47 @@
numpy==1.26.0; platform_machine != 'armv7l'
numpy==1.25.2; platform_machine == 'armv7l'
pandas==2.0.3
numpy==1.26.2
pandas==2.1.3
pandas-ta==0.3.14b
ccxt==4.0.105
cryptography==41.0.3
aiohttp==3.8.5
SQLAlchemy==2.0.21
python-telegram-bot==20.5
ccxt==4.1.66
cryptography==41.0.7
aiohttp==3.9.1
SQLAlchemy==2.0.23
python-telegram-bot==20.6
# can't be hard-pinned due to telegram-bot pinning httpx with ~
httpx>=0.24.1
arrow==1.2.3
cachetools==5.3.1
arrow==1.3.0
cachetools==5.3.2
requests==2.31.0
urllib3==2.0.5
jsonschema==4.19.1
urllib3==2.1.0
jsonschema==4.20.0
TA-Lib==0.4.28
technical==1.4.0
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.5.3
pyarrow==13.0.0; platform_machine != 'armv7l'
rich==13.7.0
pyarrow==14.0.1; 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.11
python-rapidjson==1.13
# Properly format api responses
orjson==3.9.7
orjson==3.9.10
# Notify systemd
sdnotify==0.3.2
# API Server
fastapi==0.103.1
pydantic==2.3.0
uvicorn==0.23.2
fastapi==0.104.1
pydantic==2.5.2
uvicorn==0.24.0.post1
pyjwt==2.8.0
aiofiles==23.2.1
psutil==5.9.5
psutil==5.9.6
# Support for colorized terminal output
colorama==0.4.6
@@ -54,11 +52,11 @@ prompt-toolkit==3.0.36
python-dateutil==2.8.2
#Futures
schedule==1.2.0
schedule==1.2.1
#WS Messages
websockets==11.0.3
websockets==12.0
janus==1.0.0
ast-comments==1.1.0
packaging==23.1
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
+12 -12
View File
@@ -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
@@ -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",
+2 -2
View File
@@ -413,8 +413,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
+22 -26
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):
@@ -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)
+11 -14
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')
+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()
+50
View File
@@ -0,0 +1,50 @@
from datetime import datetime, timezone
from shutil import copytree
from unittest.mock import PropertyMock
import pytest
from freqtrade.data.converter.trade_converter_kraken import import_kraken_trades_from_csv
from freqtrade.data.history.idatahandler import get_datahandler
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, 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')
default_conf_usdt['exchange']['name'] = 'kraken'
patch_exchange(mocker, id='kraken')
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={
'BCH/EUR': {'symbol': 'BCH/EUR', 'id': 'BCHEUR', 'altname': 'BCHEUR'},
}))
dstfile = tmp_path / 'BCH_EUR-trades.feather'
assert not dstfile.is_file()
default_conf_usdt['datadir'] = tmp_path
# There's 2 files in this tree, containing a total of 2 days.
# tests/testdata/kraken/
# └── trades_csv
# ├── BCHEUR.csv <-- 2023-01-01
# └── incremental_q2
# └── BCHEUR.csv <-- 2023-01-02
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)
assert log_has_re(r"BCH/EUR: 340 trades.* 2023-01-01.* 2023-01-02.*", caplog)
assert dstfile.is_file()
dh = get_datahandler(tmp_path, 'feather')
trades = dh.trades_load('BCH_EUR')
assert len(trades) == 340
assert trades['date'].min().to_pydatetime() == datetime(2023, 1, 1, 0, 3, 56,
tzinfo=timezone.utc)
assert trades['date'].max().to_pydatetime() == datetime(2023, 1, 2, 23, 17, 3,
tzinfo=timezone.utc)
# ID is not filled
assert len(trades.loc[trades['id'] != '']) == 0
+26 -3
View File
@@ -1851,7 +1851,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 +1900,14 @@ def test_get_tickers(default_conf, mocker, exchange_name):
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
exchange.get_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()
@@ -3737,6 +3745,18 @@ def test_calculate_backoff(retrycount, max_retries, expected):
assert calculate_backoff(retrycount, max_retries) == expected
@pytest.mark.parametrize("exchange_name", EXCHANGES)
def test_get_funding_fees(default_conf_usdt, mocker, exchange_name, caplog):
now = datetime.now(timezone.utc)
default_conf_usdt['trading_mode'] = 'futures'
default_conf_usdt['margin_mode'] = 'isolated'
exchange = get_patched_exchange(mocker, default_conf_usdt, id=exchange_name)
exchange._fetch_and_calculate_funding_fees = MagicMock(side_effect=ExchangeError)
assert exchange.get_funding_fees('BTC/USDT:USDT', 1, False, now) == 0.0
assert exchange._fetch_and_calculate_funding_fees.call_count == 1
assert log_has("Could not update funding fees for BTC/USDT:USDT.", caplog)
@pytest.mark.parametrize("exchange_name", ['binance'])
def test__get_funding_fees_from_exchange(default_conf, mocker, exchange_name):
api_mock = MagicMock()
@@ -4075,7 +4095,10 @@ def test_combine_funding_and_mark(
('binance', 1, 2, "2021-09-01 00:00:16", "2021-09-01 08:00:00", 30.0, -0.0002493),
('binance', 0, 1, "2021-09-01 00:00:00", "2021-09-01 07:59:59", 30.0, -0.00066479999),
('binance', 0, 2, "2021-09-01 00:00:00", "2021-09-01 12:00:00", 30.0, -0.00091409999),
('binance', 0, 2, "2021-09-01 00:00:01", "2021-09-01 08:00:00", 30.0, -0.0002493),
# :01 must be rounded down.
('binance', 0, 2, "2021-09-01 00:00:01", "2021-09-01 08:00:00", 30.0, -0.00091409999),
('binance', 0, 2, "2021-08-31 23:58:00", "2021-09-01 08:00:00", 30.0, -0.00091409999),
('binance', 0, 2, "2021-09-01 00:10:01", "2021-09-01 08:00:00", 30.0, -0.0002493),
# TODO: Uncoment once _calculate_funding_fees can pas time_in_ratio to exchange._get_funding_fee
# ('kraken', "2021-09-01 00:00:00", "2021-09-01 08:00:00", 30.0, -0.0014937),
# ('kraken', "2021-09-01 00:00:15", "2021-09-01 08:00:00", 30.0, -0.0008289),
@@ -4191,7 +4214,7 @@ def test__fetch_and_calculate_funding_fees_datetime_called(
type(api_mock).has = PropertyMock(return_value={'fetchFundingRateHistory': True})
mocker.patch(f'{EXMS}.timeframes', PropertyMock(return_value=['4h', '8h']))
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange)
d1 = datetime.strptime("2021-09-01 00:00:00 +0000", '%Y-%m-%d %H:%M:%S %z')
d1 = datetime.strptime("2021-08-31 23:00:01 +0000", '%Y-%m-%d %H:%M:%S %z')
time_machine.move_to("2021-09-01 08:00:00 +00:00")
funding_fees = exchange._fetch_and_calculate_funding_fees('ADA/USDT', 30.0, True, d1)
+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 "
+2 -3
View File
@@ -1,5 +1,4 @@
from datetime import datetime, timedelta, timezone
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, PropertyMock
import ccxt
@@ -269,9 +268,9 @@ def test_additional_exchange_init_okx(default_conf, mocker):
"additional_exchange_init", "fetch_accounts")
def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmpdir, caplog, time_machine):
def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmp_path, caplog, time_machine):
default_conf['datadir'] = Path(tmpdir)
default_conf['datadir'] = tmp_path
# fd_mock = mocker.patch('freqtrade.exchange.exchange.file_dump_json')
api_mock = MagicMock()
type(api_mock).has = PropertyMock(return_value={
+8
View File
@@ -227,6 +227,7 @@ EXCHANGES = {
'timeframe': '1h',
'futures_pair': 'BTC/USDT:USDT',
'futures': True,
'orderbook_max_entries': 50,
'leverage_tiers_public': True,
'leverage_in_spot_market': True,
'sample_order': [
@@ -247,6 +248,13 @@ EXCHANGES = {
}
]
},
'bitmart': {
'pair': 'BTC/USDT',
'stake_currency': 'USDT',
'hasQuoteVolume': True,
'timeframe': '1h',
'orderbook_max_entries': 50,
},
'huobi': {
'pair': 'ETH/BTC',
'stake_currency': 'BTC',
+2 -1
View File
@@ -133,6 +133,7 @@ class TestCCXTExchange:
exch, exchangename = exchange
pair = EXCHANGES[exchangename]['pair']
l2 = exch.fetch_l2_order_book(pair)
orderbook_max_entries = EXCHANGES[exchangename].get('orderbook_max_entries')
assert 'asks' in l2
assert 'bids' in l2
assert len(l2['asks']) >= 1
@@ -143,7 +144,7 @@ class TestCCXTExchange:
# TODO: Gate is unstable here at the moment, ignoring the limit partially.
return
for val in [1, 2, 5, 25, 50, 100]:
if val > 50 and exchangename == 'bybit':
if orderbook_max_entries and val > orderbook_max_entries:
continue
l2 = exch.fetch_l2_order_book(pair, val)
if not l2_limit_range or val in l2_limit_range:
+2 -2
View File
@@ -21,13 +21,13 @@ def is_mac() -> bool:
@pytest.fixture(scope="function")
def freqai_conf(default_conf, tmpdir):
def freqai_conf(default_conf, tmp_path):
freqaiconf = deepcopy(default_conf)
freqaiconf.update(
{
"datadir": Path(default_conf["datadir"]),
"strategy": "freqai_test_strat",
"user_data_dir": Path(tmpdir),
"user_data_dir": tmp_path,
"strategy-path": "freqtrade/tests/strategy/strats",
"freqaimodel": "LightGBMRegressor",
"freqaimodel_path": "freqai/prediction_models",
+4 -5
View File
@@ -179,10 +179,9 @@ def test_set_initial_return_values(mocker, freqai_conf):
hist_pred_df = freqai.dd.historic_predictions[pair]
model_return_df = freqai.dd.model_return_values[pair]
assert (hist_pred_df['date_pred'].iloc[-1] ==
pd.Timestamp(end_x_plus_5) - pd.Timedelta(days=1))
assert hist_pred_df['date_pred'].iloc[-1] == pd.Timestamp(end_x_plus_5)
assert 'date_pred' in hist_pred_df.columns
assert hist_pred_df.shape[0] == 7 # Total rows: 5 from historic and 2 new zeros
assert hist_pred_df.shape[0] == 8
# compare values in model_return_df with hist_pred_df
assert (model_return_df["value"].values ==
@@ -234,9 +233,9 @@ def test_set_initial_return_values_warning(mocker, freqai_conf):
hist_pred_df = freqai.dd.historic_predictions[pair]
model_return_df = freqai.dd.model_return_values[pair]
assert hist_pred_df['date_pred'].iloc[-1] == pd.Timestamp(end_x_plus_5) - pd.Timedelta(days=1)
assert hist_pred_df['date_pred'].iloc[-1] == pd.Timestamp(end_x_plus_5)
assert 'date_pred' in hist_pred_df.columns
assert hist_pred_df.shape[0] == 9 # Total rows: 5 from historic and 4 new zeros
assert hist_pred_df.shape[0] == 10
# compare values in model_return_df with hist_pred_df
assert (model_return_df["value"].values == hist_pred_df.tail(
+2 -2
View File
@@ -500,14 +500,14 @@ def test_get_required_data_timerange(mocker, freqai_conf):
assert (time_range.stopts - time_range.startts) == 177300
def test_download_all_data_for_training(mocker, freqai_conf, caplog, tmpdir):
def test_download_all_data_for_training(mocker, freqai_conf, caplog, tmp_path):
caplog.set_level(logging.DEBUG)
strategy = get_patched_freqai_strategy(mocker, freqai_conf)
exchange = get_patched_exchange(mocker, freqai_conf)
pairlist = PairListManager(exchange, freqai_conf)
strategy.dp = DataProvider(freqai_conf, exchange, pairlist)
freqai_conf['pairs'] = freqai_conf['exchange']['pair_whitelist']
freqai_conf['datadir'] = Path(tmpdir)
freqai_conf['datadir'] = tmp_path
download_all_data_for_training(strategy.dp, freqai_conf)
assert log_has_re(

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