Compare commits

...

1357 Commits

Author SHA1 Message Date
Matthias
0afd5a7385 Improve stoploss documentation
closes #8492
2023-04-12 18:13:16 +02:00
Matthias
2131205db6 Bump tag length to 255 2023-04-12 07:19:36 +02:00
Matthias
b2b19915e6 Limit enter_tag and exit_reason to their actual field lenght
closes #8486
2023-04-12 07:19:36 +02:00
Matthias
bba6f8e133 Use length constant for tests 2023-04-12 07:19:36 +02:00
Matthias
a6d2233b95 Use constant for custom field lengths 2023-04-11 21:05:14 +02:00
Matthias
9857675a5e Update torch import 2023-04-11 19:38:24 +02:00
Robert Caulk
4ab047dfa7
Merge pull request #8297 from Yinon-Polak/feat/add-pytorch-model-support
Feat/add pytorch model support
2023-04-11 15:40:12 +02:00
Matthias
476ed938f5 Extract custom_tag limit from interface file 2023-04-11 07:26:38 +02:00
Matthias
40ffac9de0 Prevent random test failures by freezing time for certain tests 2023-04-10 19:45:24 +02:00
Matthias
b892d373cd Improve timerange parsing when accepting values from API 2023-04-10 19:45:24 +02:00
Matthias
c3647e49ad
Merge pull request #8484 from freqtrade/dependabot/pip/develop/nbconvert-7.3.1
Bump nbconvert from 7.2.10 to 7.3.1
2023-04-10 19:38:12 +02:00
Matthias
37ed37dc76
Merge pull request #8485 from freqtrade/dependabot/pip/develop/mkdocs-material-9.1.6
Bump mkdocs-material from 9.1.5 to 9.1.6
2023-04-10 19:37:54 +02:00
Matthias
5cb688c112
Merge pull request #8482 from freqtrade/dependabot/pip/develop/websockets-11.0.1
Bump websockets from 11.0 to 11.0.1
2023-04-10 19:37:37 +02:00
Matthias
3e394d0612
Merge pull request #8480 from freqtrade/dependabot/pip/develop/sqlalchemy-2.0.9
Bump sqlalchemy from 2.0.8 to 2.0.9
2023-04-10 19:37:17 +02:00
dependabot[bot]
c4c2298686
Bump mkdocs-material from 9.1.5 to 9.1.6
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.1.5 to 9.1.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.1.5...9.1.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-04-10 16:17:10 +00:00
dependabot[bot]
8564dc10b2
Bump nbconvert from 7.2.10 to 7.3.1
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.2.10 to 7.3.1.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.2.10...v7.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 16:16:42 +00:00
Matthias
3fb892fcb8
Merge pull request #8483 from freqtrade/dependabot/pip/develop/ruff-0.0.261
Bump ruff from 0.0.260 to 0.0.261
2023-04-10 18:16:24 +02:00
Matthias
9968348324
Merge pull request #8481 from freqtrade/dependabot/pip/develop/ccxt-3.0.59
Bump ccxt from 3.0.58 to 3.0.59
2023-04-10 18:15:44 +02:00
dependabot[bot]
fa293c54f8
Bump websockets from 11.0 to 11.0.1
Bumps [websockets](https://github.com/aaugustin/websockets) from 11.0 to 11.0.1.
- [Release notes](https://github.com/aaugustin/websockets/releases)
- [Commits](https://github.com/aaugustin/websockets/compare/11.0...11.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 15:46:40 +00:00
Matthias
95449ca886
Merge pull request #8478 from freqtrade/dependabot/pip/develop/schedule-1.2.0
Bump schedule from 1.1.0 to 1.2.0
2023-04-10 17:45:44 +02:00
Matthias
70fa4a53cd
pre-commit - bump sqlalchemy 2023-04-10 17:45:23 +02:00
dependabot[bot]
467c63ff01
Bump ruff from 0.0.260 to 0.0.261
Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.260 to 0.0.261.
- [Release notes](https://github.com/charliermarsh/ruff/releases)
- [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.260...v0.0.261)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 15:25:04 +00:00
Matthias
b8a9c200fe
Merge pull request #8479 from freqtrade/dependabot/pip/develop/pre-commit-3.2.2
Bump pre-commit from 3.2.1 to 3.2.2
2023-04-10 17:24:02 +02:00
Matthias
7c10af65a1
Merge pull request #8477 from freqtrade/dependabot/pip/develop/plotly-5.14.1
Bump plotly from 5.14.0 to 5.14.1
2023-04-10 16:44:35 +02:00
Matthias
e2cd23b1d2 Remove deprecated pandas option 2023-04-10 16:33:56 +02:00
dependabot[bot]
0d408d3d43
Bump ccxt from 3.0.58 to 3.0.59
Bumps [ccxt](https://github.com/ccxt/ccxt) from 3.0.58 to 3.0.59.
- [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/3.0.58...3.0.59)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 14:20:19 +00:00
dependabot[bot]
2309197771
Bump sqlalchemy from 2.0.8 to 2.0.9
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.8 to 2.0.9.
- [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-04-10 14:20:14 +00:00
dependabot[bot]
66fe9abce0
Bump pre-commit from 3.2.1 to 3.2.2
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.2.1 to 3.2.2.
- [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.2.1...v3.2.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 14:20:03 +00:00
dependabot[bot]
200c18f3e4
Bump schedule from 1.1.0 to 1.2.0
Bumps [schedule](https://github.com/dbader/schedule) from 1.1.0 to 1.2.0.
- [Release notes](https://github.com/dbader/schedule/releases)
- [Changelog](https://github.com/dbader/schedule/blob/master/HISTORY.rst)
- [Commits](https://github.com/dbader/schedule/compare/1.1.0...1.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 14:19:59 +00:00
dependabot[bot]
351b5f6e65
Bump plotly from 5.14.0 to 5.14.1
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.14.0 to 5.14.1.
- [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.14.0...v5.14.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 14:19:56 +00:00
Matthias
605cc20a21
Merge pull request #8459 from freqtrade/feat/kvstore
Add initial bot start time to /profit endpoint
2023-04-10 14:49:01 +02:00
Matthias
f73d2a5371 Ensure bot_start is called when visualizing results 2023-04-10 14:48:02 +02:00
Matthias
485a074674
Merge pull request #8472 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19.12
Bump types-python-dateutil from 2.8.19.11 to 2.8.19.12
2023-04-10 14:42:53 +02:00
Matthias
865cf5232b
Merge pull request #8471 from freqtrade/dependabot/pip/develop/mypy-1.2.0
Bump mypy from 1.1.1 to 1.2.0
2023-04-10 14:42:35 +02:00
Matthias
95a24c3133
Merge pull request #8467 from freqtrade/dependabot/pip/develop/orjson-3.8.10
Bump orjson from 3.8.9 to 3.8.10
2023-04-10 14:41:25 +02:00
Matthias
6833059c70
Merge pull request #8474 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.8.5
Bump pypa/gh-action-pypi-publish from 1.8.4 to 1.8.5
2023-04-10 08:03:55 +02:00
Matthias
3833dc0b78
pre-commit - bump dateutil 2023-04-10 07:54:01 +02:00
Matthias
e0d3c771db
Merge pull request #8465 from freqtrade/dependabot/pip/develop/ccxt-3.0.58
Bump ccxt from 3.0.50 to 3.0.58
2023-04-10 07:53:21 +02:00
dependabot[bot]
5a18ab0784
Bump mypy from 1.1.1 to 1.2.0
Bumps [mypy](https://github.com/python/mypy) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v1.1.1...v1.2.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-04-10 05:51:33 +00:00
Matthias
1d66f82b1d
Merge pull request #8469 from freqtrade/dependabot/pip/develop/filelock-3.11.0
Bump filelock from 3.10.6 to 3.11.0
2023-04-10 07:50:48 +02:00
Matthias
2e765fe6d1
Merge pull request #8470 from freqtrade/dependabot/pip/develop/pymdown-extensions-9.11
Bump pymdown-extensions from 9.10 to 9.11
2023-04-10 07:50:25 +02:00
Matthias
21ea02bbcf
Merge pull request #8466 from freqtrade/dependabot/pip/develop/pytest-7.3.0
Bump pytest from 7.2.2 to 7.3.0
2023-04-10 07:49:57 +02:00
dependabot[bot]
2ea0157197
Bump pypa/gh-action-pypi-publish from 1.8.4 to 1.8.5
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.4 to 1.8.5.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.4...v1.8.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 03:57:51 +00:00
dependabot[bot]
03352f3b62
Bump types-python-dateutil from 2.8.19.11 to 2.8.19.12
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.19.11 to 2.8.19.12.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 03:57:04 +00:00
dependabot[bot]
26eb4f7fe6
Bump pymdown-extensions from 9.10 to 9.11
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.10 to 9.11.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.10...9.11)

---
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-04-10 03:56:57 +00:00
dependabot[bot]
7e1f3aa545
Bump filelock from 3.10.6 to 3.11.0
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.6 to 3.11.0.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.6...3.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 03:56:51 +00:00
dependabot[bot]
14532e3a56
Bump orjson from 3.8.9 to 3.8.10
Bumps [orjson](https://github.com/ijl/orjson) from 3.8.9 to 3.8.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.8.9...3.8.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-04-10 03:56:42 +00:00
dependabot[bot]
a449f7c78c
Bump pytest from 7.2.2 to 7.3.0
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.2 to 7.3.0.
- [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.2.2...7.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 03:56:38 +00:00
dependabot[bot]
8854ef8cba
Bump ccxt from 3.0.50 to 3.0.58
Bumps [ccxt](https://github.com/ccxt/ccxt) from 3.0.50 to 3.0.58.
- [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/3.0.50...3.0.58)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 03:56:33 +00:00
Matthias
526943f29e Remove freqUI alpha warning 2023-04-09 19:44:38 +02:00
Matthias
df51111c33 Always show strategy summary 2023-04-09 08:53:36 +02:00
Matthias
dd8900a1c6 Improve ordering of backtest output 2023-04-09 08:53:36 +02:00
Matthias
5404905d28 Fix typos in docs 2023-04-08 17:13:51 +02:00
Matthias
bed51fa790 Properly build specific Torch image 2023-04-08 17:00:25 +02:00
Matthias
f5a5c2d6b9 Improve imports 2023-04-08 16:44:33 +02:00
Matthias
a102cfdfc9 Add new /profit fields to API 2023-04-08 16:41:25 +02:00
Matthias
be72670ca2 Add documentation about /profit change 2023-04-08 16:40:14 +02:00
Matthias
cf2cb94f8d Add bot start date to /profit output 2023-04-08 16:38:44 +02:00
Matthias
fa3a81b022 convert Keys to enum 2023-04-08 16:28:50 +02:00
Matthias
7ff30c6df8 Add additional, typesafe getters 2023-04-08 16:24:38 +02:00
Matthias
7751768b2e Store initial_time value 2023-04-08 16:13:16 +02:00
Matthias
9c2cdd4fb9
Merge pull request #8388 from freqtrade/patch-pair-colon-bug
Bug fix: FreqAI backtest target setting
2023-04-08 14:16:41 +02:00
robcaulk
69b9b35a08 Merge remote-tracking branch 'origin/develop' into feat/add-pytorch-model-support 2023-04-08 13:22:25 +02:00
robcaulk
c2c97d9f78 make a fake pair_dict instead of MagicMocking it 2023-04-08 13:20:29 +02:00
robcaulk
48d3c8e62e fix model loading from disk bug, improve doc, clarify installation/docker instructions, add a torch tag to the freqairl docker image. Fix seriously outdated prediction_model docstrings 2023-04-08 12:09:53 +02:00
Matthias
ac817b7808 Improve docstrings for key-value store 2023-04-08 10:09:31 +02:00
Matthias
4d4f4bf23e Add test for key_value_store 2023-04-08 10:07:21 +02:00
Matthias
c083723698 Add initial version of key value store 2023-04-08 10:07:03 +02:00
Matthias
f8d89c46e5 Don't reset open_order_id if the order didn't cancel 2023-04-07 19:49:13 +02:00
Matthias
1952e453bb Improved formatting for fetch order_or_stop calls 2023-04-07 17:35:11 +02:00
Matthias
77985fa591 Update thread name for uvicorn worker 2023-04-07 14:49:53 +02:00
Matthias
a75d891007 Ensure minimum sqlalchemy version is respected 2023-04-07 14:45:06 +02:00
Matthias
dae3f72be7 Bump Dockerfile to latest 3.10 2023-04-07 14:11:31 +02:00
Matthias
f03a99918a Ensure hyper param file can be loaded
closes #8452
2023-04-04 20:04:28 +02:00
Yinon Polak
a655524221 pytorch mlp rename input to fix mypy error 2023-04-04 12:24:29 +03:00
Yinon Polak
26738370c7 pytorch mlp add explicit annotation to fix mypy error 2023-04-04 12:12:02 +03:00
Matthias
fe02f611fb Fix typo in reinforcement learning
closes #8431
2023-04-04 06:46:35 +02:00
Matthias
1b10a3a2bf Merge branch 'develop' of github.com:freqtrade/freqtrade into develop 2023-04-03 20:24:58 +02:00
Matthias
92a060c5b4 Make stop_price_parameter configurable by exchange 2023-04-03 20:18:57 +02:00
Matthias
096fd1916c
Merge pull request #8445 from freqtrade/dependabot/pip/develop/tensorboard-2.12.1
Bump tensorboard from 2.12.0 to 2.12.1
2023-04-03 19:14:29 +02:00
Matthias
fb09a16127
Merge pull request #8438 from freqtrade/dependabot/pip/develop/types-tabulate-0.9.0.2
Bump types-tabulate from 0.9.0.1 to 0.9.0.2
2023-04-03 18:12:30 +02:00
Yinon Polak
6b204c97ed fix pytorch data convertor type hints 2023-04-03 19:02:07 +03:00
Yinon Polak
0c4574b3b7 prevent mypy error, explicitly unpack input list of pytorch mlp model, 2023-04-03 18:10:47 +03:00
Yinon Polak
d9d9993179 add documentation 2023-04-03 17:06:39 +03:00
Yinon Polak
7b494c8333 add documentation to pytorch data convertor 2023-04-03 16:39:49 +03:00
Yinon Polak
bc9454e0f9 add device to data convertor class doc 2023-04-03 16:36:38 +03:00
Yinon Polak
36a0a14a23 clean code 2023-04-03 16:26:42 +03:00
Yinon Polak
c137666230 fix imports 2023-04-03 16:03:15 +03:00
Matthias
7fed0782d5
pre-commit types-tabulate 2023-04-03 14:19:11 +02:00
Yinon Polak
bd3b70293f add pytorch data convertor 2023-04-03 15:19:10 +03:00
dependabot[bot]
30fc24bd8c
Bump types-tabulate from 0.9.0.1 to 0.9.0.2
Bumps [types-tabulate](https://github.com/python/typeshed) from 0.9.0.1 to 0.9.0.2.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 12:18:15 +00:00
Matthias
7e3de178e1
Merge pull request #8447 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19.11
Bump types-python-dateutil from 2.8.19.10 to 2.8.19.11
2023-04-03 14:17:24 +02:00
Matthias
0c9c9fff0e
Merge branch 'develop' into dependabot/pip/develop/types-python-dateutil-2.8.19.11 2023-04-03 13:41:10 +02:00
Matthias
b96f6670e3
pre-commit dateutil 2023-04-03 13:28:17 +02:00
Matthias
6e02743256
Merge pull request #8446 from freqtrade/dependabot/pip/develop/types-requests-2.28.11.17
Bump types-requests from 2.28.11.16 to 2.28.11.17
2023-04-03 13:27:31 +02:00
Matthias
2b4fa92d09
Merge pull request #8444 from freqtrade/dependabot/pip/develop/ruff-0.0.260
Bump ruff from 0.0.259 to 0.0.260
2023-04-03 11:40:07 +02:00
Matthias
be250230b6
Merge pull request #8443 from freqtrade/dependabot/pip/develop/plotly-5.14.0
Bump plotly from 5.13.1 to 5.14.0
2023-04-03 11:39:42 +02:00
Matthias
5d33ffc015
Merge pull request #8442 from freqtrade/dependabot/pip/develop/orjson-3.8.9
Bump orjson from 3.8.8 to 3.8.9
2023-04-03 11:04:17 +02:00
Matthias
b48498f27f
Types pre-commit 2023-04-03 10:16:56 +02:00
Matthias
e582d8bacb
Merge pull request #8434 from freqtrade/dependabot/pip/develop/sqlalchemy-2.0.8
Bump sqlalchemy from 2.0.7 to 2.0.8
2023-04-03 10:16:00 +02:00
dependabot[bot]
ff40ee655b
Bump types-python-dateutil from 2.8.19.10 to 2.8.19.11
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.19.10 to 2.8.19.11.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 07:49:24 +00:00
dependabot[bot]
57deaad806
Bump types-requests from 2.28.11.16 to 2.28.11.17
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.16 to 2.28.11.17.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-04-03 07:49:21 +00:00
dependabot[bot]
7779b82277
Bump tensorboard from 2.12.0 to 2.12.1
Bumps [tensorboard](https://github.com/tensorflow/tensorboard) from 2.12.0 to 2.12.1.
- [Release notes](https://github.com/tensorflow/tensorboard/releases)
- [Changelog](https://github.com/tensorflow/tensorboard/blob/2.12.1/RELEASE.md)
- [Commits](https://github.com/tensorflow/tensorboard/compare/2.12.0...2.12.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-04-03 07:49:18 +00:00
dependabot[bot]
2bd2058afa
Bump ruff from 0.0.259 to 0.0.260
Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.259 to 0.0.260.
- [Release notes](https://github.com/charliermarsh/ruff/releases)
- [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.259...v0.0.260)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 07:49:12 +00:00
dependabot[bot]
bf7936b0af
Bump plotly from 5.13.1 to 5.14.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.13.1 to 5.14.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.13.1...v5.14.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-04-03 07:48:50 +00:00
dependabot[bot]
8236bbfd48
Bump orjson from 3.8.8 to 3.8.9
Bumps [orjson](https://github.com/ijl/orjson) from 3.8.8 to 3.8.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.8.8...3.8.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-04-03 07:48:43 +00:00
Matthias
4dc13ac16a
Merge pull request #8437 from freqtrade/dependabot/pip/develop/ccxt-3.0.50
Bump ccxt from 3.0.37 to 3.0.50
2023-04-03 09:47:27 +02:00
Matthias
eb5423469a
Merge pull request #8435 from freqtrade/dependabot/pip/develop/xgboost-1.7.5
Bump xgboost from 1.7.4 to 1.7.5
2023-04-03 09:47:09 +02:00
Matthias
43496d7929
bump sqlalchemy pre-commit 2023-04-03 09:46:32 +02:00
Matthias
92c70b6b90
Merge pull request #8441 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.8.4
Bump pypa/gh-action-pypi-publish from 1.8.3 to 1.8.4
2023-04-03 09:45:51 +02:00
Matthias
77897c7d6b
Merge pull request #8439 from freqtrade/dependabot/pip/develop/mkdocs-material-9.1.5
Bump mkdocs-material from 9.1.4 to 9.1.5
2023-04-03 09:45:26 +02:00
Matthias
531861573a
Merge pull request #8436 from freqtrade/dependabot/pip/develop/types-cachetools-5.3.0.5
Bump types-cachetools from 5.3.0.4 to 5.3.0.5
2023-04-03 09:45:10 +02:00
Matthias
c9b904eb0e Fix typos in documentation 2023-04-03 06:49:30 +02:00
Matthias
372f1cb37f Reduce verbosity for stop orders 2023-04-03 06:37:31 +02:00
Matthias
a3acdd5240 apply stop-reserve to minimum limits only when necessary
it's unnecessary for amount - but necessary for Cost / price limits.
2023-04-03 06:37:31 +02:00
Matthias
e6a125719e Slightly refactor _get_stake_amount_limit 2023-04-03 06:37:31 +02:00
Matthias
78a1551798 Reorder get_stake_limit 2023-04-03 06:37:31 +02:00
Matthias
6f79d14c9c
pre-commit - bump cachetools 2023-04-03 06:37:15 +02:00
Matthias
28d8722fa7
Merge pull request #8433 from freqtrade/dependabot/pip/develop/websockets-11.0
Bump websockets from 10.4 to 11.0
2023-04-03 06:36:30 +02:00
dependabot[bot]
2715b2ccf0
Bump pypa/gh-action-pypi-publish from 1.8.3 to 1.8.4
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.3 to 1.8.4.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.3...v1.8.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 03:58:12 +00:00
dependabot[bot]
2ea575cb31
Bump mkdocs-material from 9.1.4 to 9.1.5
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.1.4 to 9.1.5.
- [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.1.4...9.1.5)

---
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-04-03 03:57:30 +00:00
dependabot[bot]
1b31c54162
Bump ccxt from 3.0.37 to 3.0.50
Bumps [ccxt](https://github.com/ccxt/ccxt) from 3.0.37 to 3.0.50.
- [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/3.0.37...3.0.50)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 03:57:19 +00:00
dependabot[bot]
e289c10b6c
Bump types-cachetools from 5.3.0.4 to 5.3.0.5
Bumps [types-cachetools](https://github.com/python/typeshed) from 5.3.0.4 to 5.3.0.5.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-04-03 03:57:10 +00:00
dependabot[bot]
26ed1ca07c
Bump xgboost from 1.7.4 to 1.7.5
Bumps [xgboost](https://github.com/dmlc/xgboost) from 1.7.4 to 1.7.5.
- [Release notes](https://github.com/dmlc/xgboost/releases)
- [Changelog](https://github.com/dmlc/xgboost/blob/master/NEWS.md)
- [Commits](https://github.com/dmlc/xgboost/compare/v1.7.4...v1.7.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 03:57:05 +00:00
dependabot[bot]
b1e20bcd1e
Bump sqlalchemy from 2.0.7 to 2.0.8
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.7 to 2.0.8.
- [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-04-03 03:57:00 +00:00
dependabot[bot]
12a73bc151
Bump websockets from 10.4 to 11.0
Bumps [websockets](https://github.com/aaugustin/websockets) from 10.4 to 11.0.
- [Release notes](https://github.com/aaugustin/websockets/releases)
- [Commits](https://github.com/aaugustin/websockets/compare/10.4...11.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-04-03 03:56:46 +00:00
Matthias
19e112f399
Merge pull request #8427 from initrv/typo-fix-constants
Typo fix constants
2023-04-02 07:42:15 +02:00
initrv
cccf4f305b fix randomize_starting_position typo 2023-04-02 03:42:05 +03:00
Matthias
dc7e834911 Fix some type issues 2023-04-01 20:17:56 +02:00
Matthias
a630799984
Merge pull request #8423 from freqtrade/add-profit-trade-history
make trade_type value more explicit, add profit to trade_history dict
2023-04-01 15:19:54 +02:00
Matthias
916e1bbc7c
Merge pull request #8412 from freqtrade/fix/partial_stops
support partially filled stops
2023-04-01 15:18:42 +02:00
Robert Caulk
631cb44f5c ensure python code block renders 2023-04-01 15:16:48 +02:00
Robert Caulk
367186cc34 Update freqai-feature-engineering.md
The `metadata` section of `freqai-feature-engineering.md` had a misplaced whitespace in front of the title. 

This PR removes the whitespace.
2023-04-01 15:16:43 +02:00
robcaulk
92f34f262e make trade_type value more explicit, add profit to trade_history dict 2023-04-01 10:05:58 +02:00
Matthias
5e13b48648
Merge pull request #8386 from freqtrade/feature/price_to_precision_round
price to precision rounding
2023-03-31 07:20:10 +02:00
Matthias
6dfb1a1d14 Improve docker regular build caching 2023-03-31 06:49:12 +02:00
Matthias
f8330800d1 Improve docker arm builds 2023-03-31 06:49:02 +02:00
Matthias
3ec7c72da1 Bump develop version to 2023.4.dev 2023-03-30 07:06:23 +02:00
robcaulk
355fde3bca revert setting dk to live in test_plot_feature_importances 2023-03-29 22:01:54 +02:00
Matthias
fa7c29fe9f Update producer docs to reflect proper datatype
closes #8419
2023-03-29 20:43:23 +02:00
Matthias
861c577138 Support partially filled stop orders
closes #8374
2023-03-29 07:05:39 +02:00
Matthias
e062a74e70 Add test for partial stop order canceling
part of #8374
2023-03-29 06:57:17 +02:00
Matthias
c330c493d5 test for Handle stop on exchange partial filled
part of #8374
2023-03-29 06:57:17 +02:00
Matthias
8a49d62068 Don't update liquidation price for closed trades 2023-03-29 06:49:22 +02:00
Matthias
a642524928 Improve integration test correctness 2023-03-29 06:48:00 +02:00
Matthias
eb96490c99 Improve some more stoploss tests 2023-03-28 20:28:05 +02:00
Matthias
6282b42741 Remove further Magicmock trade 2023-03-28 19:38:43 +02:00
Matthias
513df4515b Improve stoploss tests 2023-03-28 19:19:55 +02:00
Matthias
411e21f430 Improve stop test 2023-03-28 18:13:26 +02:00
Matthias
f0b5f95fd6 Remove missleading comment 2023-03-28 18:10:26 +02:00
Matthias
736c396d98 Use correct amount for stoploss test 2023-03-28 16:45:54 +02:00
Yinon Polak
5a7ca35c6b declare class names in FreqaiExampleHybridStrategy 2023-03-28 16:24:49 +03:00
Yinon Polak
077a947972 clean code 2023-03-28 15:18:10 +03:00
Yinon Polak
8ac3a94358 add note to pytorch docs - setting class names for classifiers 2023-03-28 15:17:40 +03:00
Yinon Polak
dfbebdea9b improve comment on class_names in freqai interface 2023-03-28 14:44:44 +03:00
Yinon Polak
b795a70102 fix config example in pytorch mlp documentation 2023-03-28 14:44:43 +03:00
Yinon Polak
026b6a39a9 bugfix skip test split when empty 2023-03-28 14:40:23 +03:00
Matthias
2860e817bd Update cached binance leverage Tiers 2023-03-28 07:05:37 +02:00
Matthias
19b78fbc22 Override ccxt's marketOrderRequiresPrice settings for gate 2023-03-28 06:57:18 +02:00
Matthias
cde432fef0 Enable gate market orders
closes #8368
2023-03-28 06:56:11 +02:00
Matthias
8ae44c204e
Merge pull request #8361 from TheJoeSchr/feature/trades-feather
featherdatahandler: implement trades_store/_trades_load
2023-03-27 21:05:30 +02:00
Matthias
ed0e7ead31 Fix wrong import 2023-03-27 20:36:05 +02:00
Matthias
3928051baf Revert unneeded formatting changes 2023-03-27 20:35:26 +02:00
Matthias
e35c85000e Excude raspberry from catboost installs
closes #8404
2023-03-27 20:19:23 +02:00
robcaulk
3cabcabcbd ensure labels are properly defined in backtesting 2023-03-27 15:23:01 +02:00
Matthias
85776db692
Merge pull request #8401 from freqtrade/dependabot/pip/develop/ccxt-3.0.37
Bump ccxt from 3.0.36 to 3.0.37
2023-03-27 11:02:44 +02:00
Matthias
ce81af08d8
Merge pull request #8398 from freqtrade/dependabot/pip/develop/mkdocs-material-9.1.4
Bump mkdocs-material from 9.1.3 to 9.1.4
2023-03-27 11:00:57 +02:00
Matthias
5aa6c1dfae
Merge pull request #8402 from freqtrade/dependabot/pip/develop/pydantic-1.10.7
Bump pydantic from 1.10.6 to 1.10.7
2023-03-27 11:00:40 +02:00
dependabot[bot]
4f4dfa2a59
Bump pydantic from 1.10.6 to 1.10.7
Bumps [pydantic](https://github.com/pydantic/pydantic) from 1.10.6 to 1.10.7.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v1.10.7/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v1.10.6...v1.10.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 07:50:06 +00:00
dependabot[bot]
90669e0ba9
Bump ccxt from 3.0.36 to 3.0.37
Bumps [ccxt](https://github.com/ccxt/ccxt) from 3.0.36 to 3.0.37.
- [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/3.0.36...3.0.37)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 07:49:56 +00:00
Matthias
bc9f6d30c1
Merge pull request #8391 from freqtrade/dependabot/pip/develop/types-requests-2.28.11.16
Bump types-requests from 2.28.11.15 to 2.28.11.16
2023-03-27 09:47:34 +02:00
Matthias
4ae2333306
Merge pull request #8399 from freqtrade/dependabot/pip/develop/filelock-3.10.6
Bump filelock from 3.10.0 to 3.10.6
2023-03-27 09:47:16 +02:00
Matthias
8c63e3dc4f
Merge pull request #8396 from freqtrade/dependabot/pip/develop/cryptography-40.0.1
Bump cryptography from 39.0.2 to 40.0.1
2023-03-27 09:47:02 +02:00
Matthias
b0dddd35ca
Merge pull request #8395 from freqtrade/dependabot/pip/develop/pre-commit-3.2.1
Bump pre-commit from 3.2.0 to 3.2.1
2023-03-27 09:45:57 +02:00
Matthias
96ba75179b
Merge pull request #8400 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.8.3
Bump pypa/gh-action-pypi-publish from 1.8.1 to 1.8.3
2023-03-27 08:28:18 +02:00
Matthias
2589717375
Merge pull request #8397 from freqtrade/dependabot/pip/develop/orjson-3.8.8
Bump orjson from 3.8.7 to 3.8.8
2023-03-27 08:00:46 +02:00
dependabot[bot]
bc0816aa66
Bump cryptography from 39.0.2 to 40.0.1
Bumps [cryptography](https://github.com/pyca/cryptography) from 39.0.2 to 40.0.1.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/39.0.2...40.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 05:15:59 +00:00
dependabot[bot]
1743ad7946
Bump pre-commit from 3.2.0 to 3.2.1
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.2.0 to 3.2.1.
- [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.2.0...v3.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 05:14:04 +00:00
Matthias
9367cbcfd3
Merge pull request #8390 from freqtrade/dependabot/pip/develop/ccxt-3.0.36
Bump ccxt from 3.0.23 to 3.0.36
2023-03-27 07:10:39 +02:00
Matthias
43a7b9236b
Merge pull request #8393 from freqtrade/dependabot/pip/develop/ruff-0.0.259
Bump ruff from 0.0.257 to 0.0.259
2023-03-27 07:00:38 +02:00
Matthias
4891174a71 list-data should sort pairs also in timerange mode 2023-03-27 06:44:36 +02:00
Matthias
8845f765db
pre-commit - bump requests 2023-03-27 06:25:11 +02:00
dependabot[bot]
7e11bce4f4
Bump pypa/gh-action-pypi-publish from 1.8.1 to 1.8.3
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.1 to 1.8.3.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.1...v1.8.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 03:58:02 +00:00
dependabot[bot]
8955e09175
Bump filelock from 3.10.0 to 3.10.6
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.0 to 3.10.6.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.10.0...3.10.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 03:58:00 +00:00
dependabot[bot]
d13ea71a58
Bump mkdocs-material from 9.1.3 to 9.1.4
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.1.3 to 9.1.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.1.3...9.1.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-03-27 03:57:55 +00:00
dependabot[bot]
b72f61080b
Bump orjson from 3.8.7 to 3.8.8
Bumps [orjson](https://github.com/ijl/orjson) from 3.8.7 to 3.8.8.
- [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.8.7...3.8.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 03:57:46 +00:00
dependabot[bot]
75c31cc8cc
Bump ruff from 0.0.257 to 0.0.259
Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.257 to 0.0.259.
- [Release notes](https://github.com/charliermarsh/ruff/releases)
- [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.257...v0.0.259)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 03:57:14 +00:00
dependabot[bot]
1b3d9efedd
Bump types-requests from 2.28.11.15 to 2.28.11.16
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.15 to 2.28.11.16.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-03-27 03:56:55 +00:00
dependabot[bot]
2f8f60373e
Bump ccxt from 3.0.23 to 3.0.36
Bumps [ccxt](https://github.com/ccxt/ccxt) from 3.0.23 to 3.0.36.
- [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/3.0.23...3.0.36)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 03:56:49 +00:00
robcaulk
55781e7f10 fix tests 2023-03-26 19:22:52 +02:00
Matthias
72284317c2 Fix failing backtest test 2023-03-26 18:21:21 +02:00
Matthias
80a27bc0db Fix random uvicorn error 2023-03-26 18:18:52 +02:00
Matthias
1c9abd9e35 Properly respect can_short flag in backtesting
closes  #8387
2023-03-26 17:27:52 +02:00
Matthias
c14ac8a205 Properly handle non-replaced first entry orders 2023-03-26 16:46:41 +02:00
Matthias
b09fb5826f don't use "can_short" in backtesting to determine application of leverage 2023-03-26 16:21:51 +02:00
Matthias
fb1541bdf6 Explicitly close loop in async tests 2023-03-26 16:21:51 +02:00
Matthias
444d18aa39 Revert binance PO fix, since ccxt has fixed this bug. 2023-03-26 16:21:51 +02:00
Matthias
91ab4abba8
Merge pull request #8389 from escanoro/patch-1
typo:  above should be below
2023-03-26 15:45:29 +02:00
escanoro
16057da6cc
typo: above should be below 2023-03-26 14:09:41 +02:00
Matthias
d97500581d
Merge pull request #8379 from xmatthias/type_sendmsg
Type sendmsg
2023-03-26 14:09:01 +02:00
robcaulk
f1e831a7b8 fix bug in backtest target setting 2023-03-26 13:43:59 +02:00
Matthias
31a396bc25
Merge pull request #8272 from paranoidandy/bot-loop-start-every-candle-bt
Make strategy.bot_loop_start run once per candle in backtest
2023-03-26 13:21:08 +02:00
Matthias
7cdcd97c26 Update tests for new logic. 2023-03-26 11:30:44 +02:00
Matthias
73b59df77b Merge branch 'develop' into pr/paranoidandy/8272 2023-03-26 11:22:24 +02:00
Matthias
86aef7cf9d Add current_time to bot_loop_start callbak 2023-03-26 11:22:19 +02:00
Matthias
159090c0e7 Add explicit tests for TRUNCATE mode 2023-03-26 11:14:34 +02:00
Matthias
0cb28f3d82 Use kwarg for rounding_mode, update tests with additional parameter 2023-03-26 11:00:41 +02:00
Matthias
d0d0cbe1d1 Implement price_to_precision logic for stoploss 2023-03-26 10:37:18 +02:00
Matthias
02078456fc Merge branch 'develop' into pr/asuiu/8296 2023-03-26 10:28:02 +02:00
Matthias
01dfb1cba8 Revert having price_rounding_mode as configuration 2023-03-26 10:24:47 +02:00
Matthias
ee205ddc86 Improve trade.from_json when stops are used 2023-03-25 20:26:56 +01:00
Matthias
298f5685ee Reuse existing "cancel_stoploss" call 2023-03-25 20:06:21 +01:00
Matthias
486d8a48a0 Fix docs (buffer_train_data_candles is an integer, not a boolean)
closes #8384
2023-03-25 19:36:28 +01:00
Matthias
d426077445 Merge branch 'develop' of github.com:freqtrade/freqtrade into develop 2023-03-25 16:33:07 +01:00
Matthias
9aa455fcd4
Merge pull request #8364 from freqtrade/robcaulk-patch-1
Update freqai_interface.py
2023-03-25 16:27:25 +01:00
Robert Caulk
d9c8b322ce
Update freqai_interface.py 2023-03-25 13:37:07 +01:00
robcaulk
68154a1f52 document why users cant arbitrarily change parameter spaces... 2023-03-25 11:57:52 +01:00
Matthias
f7c1ee6d3e add precision values to api schema 2023-03-25 11:55:47 +01:00
Matthias
9c6a49436b Export amount/price precisions per trade 2023-03-25 11:42:19 +01:00
Matthias
75464c22f5
Merge pull request #8382 from linquanisaac/develop
docs(protections): fix typo
2023-03-25 11:36:35 +01:00
linquanisaac
cdd44a4005 docs(protections): fix typo 2023-03-25 17:19:58 +08:00
Matthias
34313a7af6 Merge remote-tracking branch 'origin/develop' into type_sendmsg 2023-03-25 09:23:00 +01:00
Matthias
4053ee4581
Merge pull request #8380 from freqtrade/fix/talibinstall
use github to download guess instead of gnu.org
2023-03-25 09:22:43 +01:00
Matthias
56170dba19 use github to download guess instead of gnu.org
gnu.org seems down rn (dns does no longer resolve),
and doesn't have good uptime history
2023-03-25 08:55:36 +01:00
Matthias
79a2de7a64 Reduce impact of short outages 2023-03-25 08:31:35 +01:00
Matthias
c0a57d352f send base_currency with messages that need it. 2023-03-25 08:16:07 +01:00
Matthias
cbdd86d777 Fix test failures due to additional field 2023-03-24 21:05:10 +01:00
Matthias
281dd7785e Fix some remaining type errors 2023-03-24 20:56:18 +01:00
Matthias
ad58bac810 Type WS messagetypes 2023-03-24 20:54:28 +01:00
Matthias
8928d3616a Improve msgtypes 2023-03-24 20:47:53 +01:00
Matthias
e8cffeeffd Update RPCStatusMessage type 2023-03-24 20:36:29 +01:00
Matthias
76d289f0ce Don't overwrite types 2023-03-24 20:35:01 +01:00
Matthias
245ae99273 Further typing ... 2023-03-24 20:33:00 +01:00
Matthias
70ad7b42b1 Improve msg typing 2023-03-24 20:33:00 +01:00
Matthias
0ece73578c Add typedDict for RPC messages
Currently not fully functional.
2023-03-24 20:33:00 +01:00
Matthias
b317524ed7 protect adjust_trade_position from crashing in case of unsafe code 2023-03-24 20:27:45 +01:00
Yinon Polak
8903ba5d89 fix enf of file 2023-03-24 20:35:55 +03:00
Matthias
469166636c Set initial stoploss when creating the order
This ensures that a trade never has "None" as stoploss
2023-03-24 07:27:45 +01:00
Yinon Polak
eabd321281 small docs change 2023-03-23 15:59:57 +02:00
Yinon Polak
45c6ae446f small docs change 2023-03-23 15:04:29 +02:00
Yinon Polak
952e641213 small docs change 2023-03-23 12:43:37 +02:00
Yinon Polak
c44b5b1b3a add pytorch parameters to parameter table docs 2023-03-23 12:41:20 +02:00
Yinon Polak
fc8625c5c5 add pytorch classes uml diagram 2023-03-23 12:13:27 +02:00
Matthias
150c5510c7 Don''t fully fail bot when invalid price value is reached
closes #8300
2023-03-22 19:46:07 +01:00
Yinon Polak
36a005754a add pytorch documentation 2023-03-22 18:15:57 +02:00
Yinon Polak
479aafc331 rename Torch to PyTorch 2023-03-22 17:50:00 +02:00
Robert Caulk
bdf19f1d66
Update freqai_interface.py 2023-03-21 22:44:56 +01:00
Matthias
8cf3e9f91b Accept "insufficient funds" error on set_leverage from stop calls
closes #8341
2023-03-21 19:29:27 +01:00
Matthias
ebebcb886c Move build-system to the top of pyproject.toml 2023-03-21 19:28:26 +01:00
Matthias
36c45fd14f Remove unused argument from set_leverage 2023-03-21 19:14:09 +01:00
Joe Schr
0128b63c1c add 'feather' to AVAILABLE_DATAHANDLERS_TRADES 2023-03-21 19:13:32 +01:00
Joe Schr
e16db814fa featherdatahandler: implement trades_store/_trades_load 2023-03-21 17:56:51 +01:00
Yinon Polak
f81e3d8667 sort imports 2023-03-21 16:42:13 +02:00
Yinon Polak
b9c7d338b3 fix test_start_backtesting 2023-03-21 16:38:05 +02:00
Yinon Polak
4f93106755 Merge remote-tracking branch 'origin/feat/add-pytorch-model-support' into feat/add-pytorch-model-support 2023-03-21 16:26:42 +02:00
Yinon Polak
02bccd0097 add pytorch mlp models to test_start_backtesting 2023-03-21 16:20:35 +02:00
robcaulk
1ba01746a0 organize pytorch files 2023-03-21 15:09:54 +01:00
Yinon Polak
83a7d888bc type hint init in pytorch mlp classes 2023-03-21 15:19:34 +02:00
Yinon Polak
eba82360fa skip pytorch tests on python 3.11 and intel based mac os 2023-03-21 15:18:05 +02:00
Yinon Polak
3fa23860c0 skip pytorch tests on python 3.11 and intel based mac os 2023-03-21 14:34:27 +02:00
Yinon Polak
a80afc8f1b add optional target tensor squeezing to pytorch trainer 2023-03-21 13:20:54 +02:00
Yinon Polak
97339e14cf round up divisions in calc_n_epochs 2023-03-21 12:29:05 +02:00
Yinon Polak
443263803c unsqueeze target tensor when 1 dimensional 2023-03-21 11:42:05 +02:00
Yinon Polak
9906e7d646 clean code 2023-03-21 11:23:45 +02:00
Yinon Polak
e8f040bfbd add class_name attribute to freqai interface 2023-03-20 20:38:43 +02:00
Matthias
97c420b2df Add explicit test for okx lev_prep 2023-03-20 19:27:48 +01:00
Yinon Polak
a4b617e482 type hints fixes 2023-03-20 20:22:28 +02:00
Matthias
7b5e322ef2
Merge pull request #8360 from freqtrade/okx_stop
Okx stoploss on exchange
2023-03-20 19:19:59 +01:00
Yinon Polak
c06cd38951 clean code 2023-03-20 19:55:39 +02:00
Yinon Polak
0a55753faf move default attributes of pytorch classifier to initializer,
to prevent mypy from complaining
2023-03-20 19:40:36 +02:00
Yinon Polak
6b4d9f97c1 clean code 2023-03-20 19:28:30 +02:00
Matthias
639987cbab Prevent parameter reuse 2023-03-20 18:19:17 +01:00
Matthias
56c2aa89bc
Merge pull request #8344 from freqtrade/fix/db_concurrent
Fix db concurrent problem
2023-03-20 18:17:09 +01:00
Yinon Polak
bf4aa91aab Merge remote-tracking branch 'origin/feat/add-pytorch-model-support' into feat/add-pytorch-model-support
# Conflicts:
#	freqtrade/freqai/base_models/PyTorchModelTrainer.py
#	freqtrade/freqai/prediction_models/PyTorchClassifier.py
#	freqtrade/freqai/prediction_models/PyTorchMLPClassifier.py
#	freqtrade/freqai/prediction_models/PyTorchMLPModel.py
#	tests/freqai/test_freqai_interface.py
2023-03-20 18:44:24 +02:00
Yinon Polak
500c401b75 improve pytorch classifier documentation 2023-03-20 18:41:04 +02:00
Yinon Polak
81a2cbb4eb fix tests 2023-03-20 18:41:04 +02:00
Yinon Polak
0510cf4491 add config params to tests 2023-03-20 18:41:04 +02:00
Yinon Polak
68728409aa add pytorch regressor test 2023-03-20 18:41:04 +02:00
Yinon Polak
c00ffcee59 fix pytorch classifier test 2023-03-20 18:41:04 +02:00
Yinon Polak
9aec1ddb17 sort imports 2023-03-20 18:41:04 +02:00
Yinon Polak
d98890f32e sort imports 2023-03-20 18:41:04 +02:00
Yinon Polak
f659f8e309 remove unused imports 2023-03-20 18:41:04 +02:00
Yinon Polak
54db239175 add pytorch regressor example 2023-03-20 18:41:04 +02:00
Yinon Polak
601c37f862 refactor classifiers class names 2023-03-20 18:41:04 +02:00
Yinon Polak
501e746c52 improve mlp documentation 2023-03-20 18:41:04 +02:00
Yinon Polak
d04146d1b1 improve mlp documentation 2023-03-20 18:41:04 +02:00
Yinon Polak
ea08931ab3 add mlp documentation 2023-03-20 18:41:04 +02:00
Yinon Polak
ddd1b5c0ff modify feedforward net, move layer norm to start of thr block 2023-03-20 18:41:04 +02:00
Yinon Polak
e08d8190ae fix test 2023-03-20 18:41:04 +02:00
Yinon Polak
fbf7049ac5 sort imports 2023-03-20 18:41:04 +02:00
Yinon Polak
2a1a8c0e64 fix test 2023-03-20 18:41:04 +02:00
Yinon Polak
833aaf8e10 create children class to PyTorchClassifier to implement the fit method where we initialize the trainer and model objects 2023-03-20 18:41:04 +02:00
Yinon Polak
566346dd87 classifier test - set model file extension 2023-03-20 18:41:03 +02:00
Yinon Polak
d0a33d2ee7 fix tests 2023-03-20 18:41:03 +02:00
robcaulk
fab505be1b cheat flake8 for now until we can refactor save into the model class 2023-03-20 18:41:03 +02:00
Yinon Polak
2f386913ac refactor classifiers class names 2023-03-20 11:54:17 +02:00
Matthias
4f4bfdac4d Adjustments to okx stoploss 2023-03-20 09:00:00 +01:00
Matthias
8b6ea32c4c
Merge pull request #8357 from freqtrade/dependabot/pip/develop/pytest-asyncio-0.21.0
Bump pytest-asyncio from 0.20.3 to 0.21.0
2023-03-20 08:59:19 +01:00
Matthias
ff497d5c90
Merge pull request #8356 from freqtrade/dependabot/pip/develop/fastapi-0.95.0
Bump fastapi from 0.94.0 to 0.95.0
2023-03-20 08:54:49 +01:00
Matthias
c05db6742c
Merge pull request #8351 from freqtrade/dependabot/pip/develop/ccxt-3.0.23
Bump ccxt from 2.9.12 to 3.0.23
2023-03-20 08:52:12 +01:00
Matthias
75f75f3881
Merge pull request #8358 from freqtrade/dependabot/pip/develop/ast-comments-1.0.1
Bump ast-comments from 1.0.0 to 1.0.1
2023-03-20 08:51:56 +01:00
dependabot[bot]
a4e4310d40
Bump pytest-asyncio from 0.20.3 to 0.21.0
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.20.3 to 0.21.0.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.20.3...v0.21.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 07:11:18 +00:00
Matthias
dfc3524334
Merge pull request #8355 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.8.1
Bump pypa/gh-action-pypi-publish from 1.7.1 to 1.8.1
2023-03-20 08:10:17 +01:00
Matthias
a0913588b8
Merge pull request #8353 from freqtrade/dependabot/pip/develop/pre-commit-3.2.0
Bump pre-commit from 3.1.1 to 3.2.0
2023-03-20 08:10:04 +01:00
Matthias
c56b344077
Merge pull request #8354 from freqtrade/dependabot/pip/develop/ruff-0.0.257
Bump ruff from 0.0.255 to 0.0.257
2023-03-20 08:09:08 +01:00
dependabot[bot]
cb1f971d4b
Bump ccxt from 2.9.12 to 3.0.23
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.9.12 to 3.0.23.
- [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/2.9.12...3.0.23)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 06:39:13 +00:00
Matthias
78e64be04e
Merge pull request #8349 from freqtrade/dependabot/pip/develop/sqlalchemy-2.0.7
Bump sqlalchemy from 2.0.5.post1 to 2.0.7
2023-03-20 07:38:07 +01:00
dependabot[bot]
3175121030
Bump ast-comments from 1.0.0 to 1.0.1
Bumps [ast-comments](https://github.com/t3rn0/ast-comments) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/t3rn0/ast-comments/releases)
- [Commits](https://github.com/t3rn0/ast-comments/compare/1.0.0...1.0.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-03-20 05:47:55 +00:00
dependabot[bot]
8d649988ca
Bump fastapi from 0.94.0 to 0.95.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.94.0 to 0.95.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.94.0...0.95.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-03-20 05:47:47 +00:00
Matthias
ec7e7e744b
Merge pull request #8352 from freqtrade/dependabot/pip/develop/uvicorn-0.21.1
Bump uvicorn from 0.21.0 to 0.21.1
2023-03-20 06:46:46 +01:00
Matthias
5c754eb4d3
Merge pull request #8350 from freqtrade/dependabot/pip/develop/mkdocs-material-9.1.3
Bump mkdocs-material from 9.1.2 to 9.1.3
2023-03-20 06:46:25 +01:00
Matthias
54d8aa7782 Test stoploss_adjust okx 2023-03-20 06:46:00 +01:00
Matthias
4690244673 Enable okx stop-price types 2023-03-20 06:40:57 +01:00
Matthias
2de5a59d89 Add test for dry-run fetching 2023-03-20 06:38:42 +01:00
Matthias
98685f1c98
Merge pull request #8348 from freqtrade/dependabot/pip/develop/python-rapidjson-1.10
Bump python-rapidjson from 1.9 to 1.10
2023-03-20 06:29:35 +01:00
Matthias
88e93b4902
Merge pull request #8346 from freqtrade/dependabot/pip/develop/nbconvert-7.2.10
Bump nbconvert from 7.2.9 to 7.2.10
2023-03-20 06:29:02 +01:00
Matthias
dcca51985d
sqlalchemy - pre-commit 2023-03-20 06:27:39 +01:00
Matthias
21f2f67ffa
Merge pull request #8347 from freqtrade/dependabot/pip/develop/filelock-3.10.0
Bump filelock from 3.9.0 to 3.10.0
2023-03-20 06:24:50 +01:00
dependabot[bot]
c78342b194
Bump pypa/gh-action-pypi-publish from 1.7.1 to 1.8.1
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.7.1 to 1.8.1.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.7.1...v1.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:58:15 +00:00
dependabot[bot]
29b9be9bd0
Bump ruff from 0.0.255 to 0.0.257
Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.255 to 0.0.257.
- [Release notes](https://github.com/charliermarsh/ruff/releases)
- [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.255...v0.0.257)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:57:47 +00:00
dependabot[bot]
4543a1fe02
Bump pre-commit from 3.1.1 to 3.2.0
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.1.1 to 3.2.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.1.1...v3.2.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-03-20 03:57:33 +00:00
dependabot[bot]
fc7c8cce3c
Bump uvicorn from 0.21.0 to 0.21.1
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.21.0 to 0.21.1.
- [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.21.0...0.21.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:57:28 +00:00
dependabot[bot]
7d1559f319
Bump mkdocs-material from 9.1.2 to 9.1.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.1.2 to 9.1.3.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.1.2...9.1.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:57:13 +00:00
dependabot[bot]
a43502093d
Bump sqlalchemy from 2.0.5.post1 to 2.0.7
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.5.post1 to 2.0.7.
- [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-03-20 03:57:07 +00:00
dependabot[bot]
47e84ad106
Bump python-rapidjson from 1.9 to 1.10
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 1.9 to 1.10.
- [Release notes](https://github.com/python-rapidjson/python-rapidjson/releases)
- [Changelog](https://github.com/python-rapidjson/python-rapidjson/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-rapidjson/python-rapidjson/compare/v1.9...v1.10)

---
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-03-20 03:56:54 +00:00
dependabot[bot]
5ade5777e8
Bump filelock from 3.9.0 to 3.10.0
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.9.0 to 3.10.0.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.9.0...3.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:56:49 +00:00
dependabot[bot]
fb0e824a83
Bump nbconvert from 7.2.9 to 7.2.10
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.2.9 to 7.2.10.
- [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.2.9...v7.2.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:56:45 +00:00
Matthias
a7c7f720c0 Add test for okx fetch_stop 2023-03-19 20:03:34 +01:00
Matthias
224f289ec8 OKX Stop: Add some more okx specific logic 2023-03-19 19:45:30 +01:00
Matthias
d84ece7258 Use conditional orders for stop orders 2023-03-19 19:44:35 +01:00
Matthias
6c5dc7e0a9 OKX: improve stop order handling 2023-03-19 19:44:35 +01:00
Matthias
df20757d21 OKX stop: implement proper stoploss fetching 2023-03-19 19:44:35 +01:00
Matthias
a2ce288241 Add okx stoploss on exchange (non-working for futures). 2023-03-19 19:44:35 +01:00
Matthias
ce3efa8f00 Remove pointless asserts 2023-03-19 18:05:08 +01:00
Matthias
c92f28bf6f ruff: Activate UP ruleset 2023-03-19 17:57:56 +01:00
Matthias
222ecdecd2 Improve code quality 2023-03-19 17:50:08 +01:00
Yinon Polak
1c11a5f048 improve mlp documentation 2023-03-19 18:10:57 +02:00
Yinon Polak
903a1dc3e5 improve mlp documentation 2023-03-19 18:04:01 +02:00
Yinon Polak
6f9a8a089c add mlp documentation 2023-03-19 17:45:30 +02:00
Yinon Polak
8bee499328 modify feedforward net, move layer norm to start of thr block 2023-03-19 17:03:36 +02:00
Matthias
236499a195 Reorder push logic for ghcr 2023-03-19 15:47:42 +01:00
Matthias
3d91dd8a98 Support post-only orders for Binance spot
closes #8044
2023-03-19 15:36:35 +01:00
Matthias
9ccc3e52ec Simplify time in force code structure 2023-03-19 15:30:27 +01:00
Matthias
f5f151fcc5 Fix typing error 2023-03-19 15:06:56 +01:00
Matthias
7aa56adf15
Merge pull request #7951 from hippocritical/strategy_utils
strategy_updater
2023-03-19 14:28:36 +01:00
Yinon Polak
719faab4b8 fix test 2023-03-19 15:21:34 +02:00
Yinon Polak
9f477aa3c9 sort imports 2023-03-19 15:09:50 +02:00
Yinon Polak
61ac36c576 fix test 2023-03-19 14:49:12 +02:00
Yinon Polak
366c148c10 create children class to PyTorchClassifier to implement the fit method where we initialize the trainer and model objects 2023-03-19 14:38:49 +02:00
Matthias
bf3f2e4de4 Fix failing test 2023-03-19 11:16:54 +01:00
hippocritical
763f4f4a3e
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-18 20:15:12 +01:00
hippocritical
4925d8f580 Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils 2023-03-18 20:07:34 +01:00
hippocritical
b1f88e8861 fixed typo from trades to trade 2023-03-18 20:02:55 +01:00
Yinon Polak
a49f62eecb classifier test - set model file extension 2023-03-18 20:51:30 +02:00
Matthias
62c8dd98d5 Use combination of thread-local and asyncio-aware session context 2023-03-18 19:28:22 +01:00
Matthias
b0a7b64d44 Close sessions after telegram calls 2023-03-18 19:28:22 +01:00
Matthias
d808dd49e8 Fix ruff violation 2023-03-18 19:28:13 +01:00
Matthias
818d2bf92a Fix stoploss on exchange value in /show_config call 2023-03-18 18:02:46 +01:00
Matthias
f98a12c26c
Merge pull request #8343 from freqtrade/freqai/add_pair
Add pair output to "tossed" messages
2023-03-18 18:02:36 +01:00
Matthias
477dc50425 Add pair output to "tossed" messages 2023-03-18 16:32:07 +00:00
Yinon Polak
fab9ff1294 fix tests 2023-03-18 15:27:38 +02:00
Yinon Polak
1c91b4427b Merge remote-tracking branch 'origin/feat/add-pytorch-model-support' into feat/add-pytorch-model-support 2023-03-18 14:14:38 +02:00
Yinon Polak
244662b1a4 set class names attribute in the general classifier testing strategy 2023-03-18 14:12:31 +02:00
Robert Caulk
186fe5933b
Merge pull request #8338 from freqtrade/freqai_exception
Fix exceptions when training fails
2023-03-18 12:56:25 +01:00
Matthias
8ab35bbaf3
Merge pull request #8340 from freqtrade/sqlalchemy2_queyr
remove Sqlalchemy .query usage
2023-03-18 08:10:56 +01:00
Matthias
9044052b4e Fix exceptions when training fails 2023-03-17 18:29:10 +01:00
hippocritical
209811d23a
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-17 08:48:52 +01:00
Matthias
764d5507a3 Fix typo in docker param 2023-03-17 07:05:13 +01:00
Matthias
628f6b8b7c Fix crane docker permissions 2023-03-17 07:05:13 +01:00
Matthias
0d3de07012 use Crane to move images around 2023-03-17 07:05:13 +01:00
Matthias
db0f449d93 Use docker manifest for GHCR builds 2023-03-17 07:05:13 +01:00
Matthias
774eacc561 Attempt push to ghcr.io 2023-03-17 07:05:13 +01:00
Matthias
e3e4fbd5ba Minor test fix 2023-03-16 19:24:37 +01:00
Matthias
b7709126f9 remove .query completely 2023-03-16 18:07:22 +01:00
Matthias
4cfbc55d34 Update remaining tests to get rid of .query 2023-03-16 18:07:06 +01:00
Robert Caulk
00054dcfde
Merge pull request #8307 from initrv/tensorboard-category
Improve tensorboard_log
2023-03-16 11:10:29 +01:00
Matthias
9d6e973e5b remove .query from most tests 2023-03-16 07:25:04 +01:00
Matthias
6ed337faa3 Update several tests to remove .query 2023-03-16 07:04:15 +01:00
Matthias
e579ff9532 Simplify pairlock querying 2023-03-16 06:48:12 +01:00
Matthias
ae361e1d5d Update more .query usages 2023-03-16 06:44:53 +01:00
Matthias
8865af9104 Remove .query from pairlock 2023-03-15 21:21:00 +01:00
Matthias
aa54b77702 Rename _session to sessoin 2023-03-15 21:12:06 +01:00
Matthias
8073989c98 Remove more usages of .query 2023-03-15 21:10:47 +01:00
Matthias
d45599ca3b Fix some type errors 2023-03-15 21:09:25 +01:00
Matthias
b469addffb remove usage of .query from regular models 2023-03-15 21:00:30 +01:00
Matthias
47ab285252 Minor test fix 2023-03-15 20:49:35 +01:00
Matthias
95ff59a21c Improve documentation for get_trades_proxy 2023-03-15 07:23:54 +01:00
Matthias
7e08e3a59a Update example to use get_trades_proxy 2023-03-15 07:22:07 +01:00
robcaulk
4550447409 cheat flake8 for now until we can refactor save into the model class 2023-03-14 21:13:30 +01:00
Matthias
8f29312c9e Minimum re-entry stake should not include stoploss 2023-03-14 08:14:01 +01:00
Matthias
5c280d5649 Improve emergency_exit handling 2023-03-13 20:28:13 +01:00
Matthias
b23cea6e59 Bump ruff to 0.0.255 2023-03-13 20:16:12 +01:00
Matthias
487469680f Use correct exception type for ccxt.InvalidOrder 2023-03-13 20:13:12 +01:00
Matthias
8fd13933c3 Improve variable naming 2023-03-13 19:51:03 +01:00
Matthias
cf70deaf8d Disallow negative liquidation prices
part of #8300
2023-03-13 19:41:39 +01:00
Matthias
3d31eca365 Update Exception to contain more info
part of #8300
2023-03-13 19:40:52 +01:00
Matthias
d723979c42 Move total_trades to explicit variable 2023-03-13 19:21:53 +01:00
Yinon Polak
366740885a reduce mlp number of parameters for testing 2023-03-13 20:18:26 +02:00
Yinon Polak
918889a2bd reduce mlp number of parameters for testing 2023-03-13 20:09:12 +02:00
Matthias
1947fab3d7
Merge pull request #8315 from freqtrade/dependabot/pip/develop/uvicorn-0.21.0
Bump uvicorn from 0.20.0 to 0.21.0
2023-03-13 18:11:13 +01:00
Matthias
cdb97e64ab
Merge pull request #8323 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.7.1
Bump pypa/gh-action-pypi-publish from 1.6.4 to 1.7.1
2023-03-13 18:10:04 +01:00
Matthias
daa59f6248
Merge pull request #8322 from freqtrade/dependabot/pip/develop/mkdocs-material-9.1.2
Bump mkdocs-material from 9.1.1 to 9.1.2
2023-03-13 18:08:08 +01:00
Yinon Polak
9c8c30b0e8 add test 2023-03-13 17:17:00 +02:00
initrv
f3a1177bad bring inc back 2023-03-13 17:53:35 +03:00
dependabot[bot]
ad5afd3047
Bump uvicorn from 0.20.0 to 0.21.0
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.20.0 to 0.21.0.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.20.0...0.21.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 08:08:57 +00:00
Matthias
458bfcc89b
Merge pull request #8324 from freqtrade/dependabot/pip/develop/urllib3-1.26.15
Bump urllib3 from 1.26.14 to 1.26.15
2023-03-13 09:02:17 +01:00
Matthias
d4122c36ac
Merge pull request #8317 from freqtrade/dependabot/pip/develop/fastapi-0.94.0
Bump fastapi from 0.92.0 to 0.94.0
2023-03-13 09:01:59 +01:00
Matthias
0e663a5bf8 Refresh binance cached leverage tiers 2023-03-13 07:06:59 +01:00
Matthias
562efd1841
Merge pull request #8320 from freqtrade/dependabot/pip/develop/pytest-7.2.2
Bump pytest from 7.2.1 to 7.2.2
2023-03-13 06:59:00 +01:00
Matthias
7baa2b9005
Merge pull request #8321 from freqtrade/dependabot/pip/develop/mypy-1.1.1
Bump mypy from 1.0.1 to 1.1.1
2023-03-13 06:58:32 +01:00
dependabot[bot]
10c5adfa50
Bump fastapi from 0.92.0 to 0.94.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.92.0 to 0.94.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.92.0...0.94.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-03-13 05:37:55 +00:00
Matthias
44c4729a9d
Merge pull request #8319 from freqtrade/dependabot/pip/develop/pydantic-1.10.6
Bump pydantic from 1.10.5 to 1.10.6
2023-03-13 06:28:28 +01:00
dependabot[bot]
dc6af9a1a7
Bump urllib3 from 1.26.14 to 1.26.15
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.14 to 1.26.15.
- [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/1.26.14...1.26.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 03:57:54 +00:00
dependabot[bot]
82707be7d0
Bump pypa/gh-action-pypi-publish from 1.6.4 to 1.7.1
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.6.4 to 1.7.1.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.6.4...v1.7.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 03:57:48 +00:00
dependabot[bot]
b800f27092
Bump mkdocs-material from 9.1.1 to 9.1.2
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.1.1 to 9.1.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.1.1...9.1.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-03-13 03:57:46 +00:00
dependabot[bot]
31daf72cc6
Bump mypy from 1.0.1 to 1.1.1
Bumps [mypy](https://github.com/python/mypy) from 1.0.1 to 1.1.1.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v1.0.1...v1.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 03:57:40 +00:00
dependabot[bot]
22ebf04daa
Bump pytest from 7.2.1 to 7.2.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.1 to 7.2.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.2.1...7.2.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 03:57:29 +00:00
dependabot[bot]
52a091e063
Bump pydantic from 1.10.5 to 1.10.6
Bumps [pydantic](https://github.com/pydantic/pydantic) from 1.10.5 to 1.10.6.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v1.10.6/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v1.10.5...v1.10.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-13 03:57:23 +00:00
Yinon Polak
d7ea750823 revert to using model_training_parameters 2023-03-13 00:35:51 +02:00
Yinon Polak
b6096efadd logging change 2023-03-13 00:35:14 +02:00
Yinon Polak
b927c9dc01 remove train loss calculation from estimate_loss 2023-03-13 00:17:34 +02:00
Yinon Polak
523a58d3d6 simplify statement for pytorch file_type extension 2023-03-13 00:16:44 +02:00
Matthias
fbca8e6587 Allow empty pairlock reasons through api
closes #8312
2023-03-12 21:31:08 +01:00
initrv
a10f78e3ef fix increment in case of 0 2023-03-12 23:29:27 +03:00
hippocritical
8987e5f108
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-12 20:14:40 +01:00
Matthias
f584edf809 Improve tests by simply running a full strategy through everything 2023-03-12 16:45:56 +01:00
Matthias
f5848ea891 Add test for successful_buys 2023-03-12 16:29:18 +01:00
Matthias
b5c4f9ebe2 Split updater_tests to be clearer 2023-03-12 16:27:54 +01:00
Matthias
0911cd72a2 Add test for strategy-updater start method 2023-03-12 15:59:14 +01:00
Matthias
d2a412d2c6 Simplify start_strategy_update 2023-03-12 15:47:03 +01:00
Matthias
cb086f79ff Improve doc wording and command parameters 2023-03-12 15:46:44 +01:00
Matthias
d9bff68501
Merge pull request #8311 from froggleston/develop
Fix None limit on pair_candles RPC call
2023-03-12 15:25:30 +01:00
Matthias
5bfee44bba Whitespace fix 2023-03-12 15:24:27 +01:00
Yinon Polak
0012fe36ca sort imports 2023-03-12 16:16:04 +02:00
hippocritical
d186f8f1e1
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-12 14:40:02 +01:00
Yinon Polak
cb17b36981 simplify file_type check comparisons 2023-03-12 14:50:08 +02:00
froggleston
aa283a0447 Fix None limit on pair_candles RPC call 2023-03-12 12:44:12 +00:00
Yinon Polak
f9fdf1c31b generalize mlp model 2023-03-12 14:31:08 +02:00
Yinon Polak
1cf0e7be24 use one iteration on all test and train data for evaluation 2023-03-12 12:48:15 +02:00
initrv
82cb107520 add tensorboard category 2023-03-12 01:32:55 +03:00
Matthias
b23841fbfe Bump ccxt to 2.9.12 2023-03-11 17:35:30 +01:00
Matthias
8726a4645d Don't use deprecated Type construct 2023-03-11 15:15:32 +01:00
Matthias
59d2ff3ffa Simplify handle_cancel_exit 2023-03-11 15:15:10 +01:00
Matthias
39c651e40c Remove pointless reset of close_profit 2023-03-11 15:15:02 +01:00
Matthias
a2336f256b Add profit descriptions
closes #8234
2023-03-11 08:25:45 +01:00
Matthias
a76ca771f8 telegram: Fix sending telegram message with exception 2023-03-10 18:09:05 +01:00
hippocritical
f722823b0d Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils 2023-03-10 09:24:08 +01:00
hippocritical
a3988f56b2 Sorry matthias, did not see that you already committed something and did overwrite you.
Added your version to it instead of mine and pushed again (since it was already overwritten by me).
2023-03-10 09:23:56 +01:00
hippocritical
5a467eb969
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-10 09:18:44 +01:00
hippocritical
5f8202e1b5 Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils
# Conflicts:
#	freqtrade/commands/strategy_utils_commands.py
#	tests/test_strategy_updater.py
2023-03-10 09:00:00 +01:00
hippocritical
bfc7f48f17 added checks for python3.8 or lower since ast_comments.unparse() needs python 3.9 or higher.
testing with python 3.8 would make the build fail tests, skipping it there.
2023-03-10 08:59:07 +01:00
Matthias
5b2a291109
Merge pull request #8273 from freqtrade/stop_from_open_lev
Stop from open lev
2023-03-09 19:44:16 +01:00
Matthias
d3a3ddbc61 Check if exchang provides bid/ask via fetch_tickers - and fail with spread filter if it doesn't.
closes #8286
2023-03-09 19:42:43 +01:00
Yinon Polak
8a9f2aedbb improve documentation 2023-03-09 14:55:52 +02:00
Yinon Polak
e88a0d5248 convert single quotes to double quotes 2023-03-09 13:29:11 +02:00
Yinon Polak
2ef11faba7 reformat documentation 2023-03-09 13:25:20 +02:00
Yinon Polak
c9eee2944b reformat documentation 2023-03-09 13:01:04 +02:00
Yinon Polak
6f962362f2 expand pytorch trainer documentation 2023-03-09 12:45:46 +02:00
Yinon Polak
ba5de0cd00 add documentation 2023-03-09 11:21:10 +02:00
Yinon Polak
3081b9402b add documentation 2023-03-09 11:14:54 +02:00
Matthias
30fd1e742e Add 3.8 block for strategyUpdater 2023-03-09 07:46:58 +00:00
Matthias
4d8e3c25bd Merge branch 'develop' into strategy_utils 2023-03-09 07:12:48 +00:00
ASU
1132fa6093 feat: Added price_rounding modes in config 2023-03-09 02:11:31 +02:00
Matthias
29dfb5c169
Merge pull request #8291 from freqtrade/allow-ohlc-removal
allow user to drop ohlc from features in RL
2023-03-08 21:04:34 +01:00
robcaulk
d10ee0979a ensure training_features_list is updated properly 2023-03-08 19:37:11 +01:00
Matthias
0318486bee Update stoploss_from_open documentation for leverage adjustment 2023-03-08 19:35:26 +01:00
Robert Caulk
85e345fc48
Update BaseReinforcementLearningModel.py 2023-03-08 19:29:39 +01:00
Yinon Polak
1597c3aa89 set class names in IStrategy.set_freqai_targets method, also save class name with model meta data 2023-03-08 18:36:44 +02:00
Yinon Polak
7d26df01b8 fix tensor type hint 2023-03-08 16:17:19 +02:00
Yinon Polak
c8296ccb2d sort imports 2023-03-08 16:13:35 +02:00
Yinon Polak
8d60327d60 add missing import 2023-03-08 16:12:47 +02:00
Yinon Polak
04564dc134 add missing import 2023-03-08 16:11:51 +02:00
Yinon Polak
6161b858c4 sort imports 2023-03-08 16:10:25 +02:00
Yinon Polak
1921a07b89 sort imports 2023-03-08 16:08:04 +02:00
Yinon Polak
b65ade51be revert config_freqai_example changes 2023-03-08 16:05:02 +02:00
Yinon Polak
dfbb2e2b35 sort imports 2023-03-08 16:03:36 +02:00
Yinon Polak
1805db2b07 change documentation and small bugfix 2023-03-08 15:38:22 +02:00
Yinon Polak
76fbec0c17 ad multiclass target names encoder to ints 2023-03-08 14:29:38 +02:00
robcaulk
29d337fa02 ensure ohlc is dropped from both train and predict 2023-03-08 11:26:28 +01:00
Matthias
2c7ae756f5 Improve mock behavior 2023-03-08 07:05:59 +01:00
robcaulk
d9dc831772 allow user to drop ohlc from features in RL 2023-03-07 11:33:54 +01:00
Yinon Polak
4241bff32a type hints fixes 2023-03-06 20:15:36 +02:00
Yinon Polak
5dd60eda36 type hints fixes 2023-03-06 19:37:08 +02:00
Yinon Polak
8acdd0b47c type hints fixes 2023-03-06 19:14:54 +02:00
Yinon Polak
125085fbaf add freqai.model_exists pytorch file type support 2023-03-06 18:10:49 +02:00
Yinon Polak
7eedcb9c14 reformat code 2023-03-06 17:56:07 +02:00
Yinon Polak
e6e747bcd8 reformat code 2023-03-06 17:50:02 +02:00
Yinon Polak
348a08f1c4 add todo - currently assuming class labels are strings ['0.0', '1.0' .. n_classes]. need to resolve it per ClassifierModel 2023-03-06 16:41:47 +02:00
Yinon Polak
b1ac2bf515 use data loader, add evaluation on epoch 2023-03-06 16:16:45 +02:00
Matthias
b710bdaf6c
Merge pull request #8284 from freqtrade/dependabot/pip/develop/ccxt-2.9.4
Bump ccxt from 2.8.98 to 2.9.4
2023-03-06 10:49:10 +01:00
Matthias
27fa297209
Merge pull request #8282 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19.10
Bump types-python-dateutil from 2.8.19.9 to 2.8.19.10
2023-03-06 09:13:42 +01:00
dependabot[bot]
85e64cd121
Bump ccxt from 2.8.98 to 2.9.4
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.8.98 to 2.9.4.
- [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/2.8.98...2.9.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 07:21:23 +00:00
Matthias
0d876d7a89
Merge branch 'develop' into dependabot/pip/develop/types-python-dateutil-2.8.19.10 2023-03-06 08:20:59 +01:00
Matthias
69e5377f3d
Merge pull request #8280 from freqtrade/dependabot/pip/develop/sqlalchemy-2.0.5.post1
Bump sqlalchemy from 2.0.4 to 2.0.5.post1
2023-03-06 08:20:17 +01:00
Matthias
532ecaf2c8
Merge pull request #8276 from freqtrade/dependabot/pip/develop/pymdown-extensions-9.10
Bump pymdown-extensions from 9.9.2 to 9.10
2023-03-06 08:07:20 +01:00
Matthias
d779d60812 Expose total_profit_ratio through API 2023-03-06 07:10:02 +01:00
Matthias
c4a80e33ea Fix missing newline in telegram /status 2023-03-06 07:01:25 +01:00
Matthias
cab1b750b3 Improve test accuracy 2023-03-06 06:39:05 +01:00
Matthias
9d285e3dc0 Add total_profit_ratio to telegram output
part of #8234
2023-03-06 06:39:05 +01:00
Matthias
fff08f737f /status msg - improve formatting further 2023-03-06 06:39:05 +01:00
Matthias
ca789b3282 /status - whitespace 2023-03-06 06:39:05 +01:00
Matthias
11eea9b4e1 Fix formatting for /status Realized profit 2023-03-06 06:39:05 +01:00
Matthias
de015a2d7e Improve telegram message formatting 2023-03-06 06:39:05 +01:00
Matthias
4cfc7e4427
Merge pull request #8275 from freqtrade/dependabot/pip/develop/ruff-0.0.254
Bump ruff from 0.0.253 to 0.0.254
2023-03-06 06:38:57 +01:00
Matthias
0a525c6d32
Merge pull request #8274 from freqtrade/dependabot/pip/develop/orjson-3.8.7
Bump orjson from 3.8.6 to 3.8.7
2023-03-06 06:37:43 +01:00
Matthias
ae8c426025
Merge pull request #8278 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.38
Bump prompt-toolkit from 3.0.37 to 3.0.38
2023-03-06 06:37:21 +01:00
dependabot[bot]
0fe72510d5
Bump pymdown-extensions from 9.9.2 to 9.10
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.9.2 to 9.10.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.9.2...9.10)

---
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-03-06 05:36:16 +00:00
Matthias
fecb9db072
Merge pull request #8277 from freqtrade/dependabot/pip/develop/cryptography-39.0.2
Bump cryptography from 39.0.1 to 39.0.2
2023-03-06 06:36:16 +01:00
Matthias
30ac648539
Merge pull request #8279 from freqtrade/dependabot/pip/develop/mkdocs-material-9.1.1
Bump mkdocs-material from 9.0.15 to 9.1.1
2023-03-06 06:35:31 +01:00
Matthias
25fd4a04d6 Update sqlalchemy QueryPropertyDescriptor to match latest version 2023-03-06 06:34:37 +01:00
Matthias
9750e9ca4e
pre-commit python-dateutil 2023-03-06 06:32:33 +01:00
dependabot[bot]
a57b033745
Bump types-python-dateutil from 2.8.19.9 to 2.8.19.10
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.19.9 to 2.8.19.10.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 03:57:27 +00:00
dependabot[bot]
48e16f6aba
Bump sqlalchemy from 2.0.4 to 2.0.5.post1
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.4 to 2.0.5.post1.
- [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-03-06 03:57:18 +00:00
dependabot[bot]
d1d9e25c2e
Bump mkdocs-material from 9.0.15 to 9.1.1
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.0.15 to 9.1.1.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.0.15...9.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 03:57:03 +00:00
dependabot[bot]
57969f8b01
Bump prompt-toolkit from 3.0.37 to 3.0.38
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.37 to 3.0.38.
- [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases)
- [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG)
- [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.37...3.0.38)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 03:56:58 +00:00
dependabot[bot]
8484427cf8
Bump cryptography from 39.0.1 to 39.0.2
Bumps [cryptography](https://github.com/pyca/cryptography) from 39.0.1 to 39.0.2.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/39.0.1...39.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 03:56:54 +00:00
dependabot[bot]
f4c17be8de
Bump ruff from 0.0.253 to 0.0.254
Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.253 to 0.0.254.
- [Release notes](https://github.com/charliermarsh/ruff/releases)
- [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.253...v0.0.254)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 03:56:44 +00:00
dependabot[bot]
0bdd238d7f
Bump orjson from 3.8.6 to 3.8.7
Bumps [orjson](https://github.com/ijl/orjson) from 3.8.6 to 3.8.7.
- [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.8.6...3.8.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 03:56:37 +00:00
hippocritical
1bb697e58c Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils 2023-03-05 18:48:54 +01:00
hippocritical
b072fae507 added strategy-updater compartment inside utils.md 2023-03-05 18:48:32 +01:00
hippocritical
9fa6bfa655
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-05 16:25:17 +01:00
hippocritical
da44b39423 Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils 2023-03-05 16:20:46 +01:00
hippocritical
d0d6f53dec fixed github formatting errors 2023-03-05 16:19:26 +01:00
Yinon Polak
751b205618 initial commit 2023-03-05 16:59:24 +02:00
Matthias
d80760d20c bump ccxt to 2.8.98 2023-03-05 14:16:53 +01:00
hippocritical
5dd919b7ad
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-05 12:30:26 +01:00
Matthias
108a578772 Update tests to latest rpc changes 2023-03-04 20:17:19 +01:00
Matthias
9444bbb6f3 /maxentries should be in single tics. 2023-03-04 20:09:39 +01:00
Matthias
7c0c98a368 Properly format first entry value, too. 2023-03-04 20:08:20 +01:00
Matthias
c1d395a7d8 Revert "Bump ccxt to 2.8.88"
This reverts commit 51c15d894b.
2023-03-04 20:02:20 +01:00
Matthias
3f6795962f Update bybit orderbook test 2023-03-04 19:49:59 +01:00
Matthias
60e651b481 Updat bybit ohlcv data to v5 2023-03-04 19:49:37 +01:00
Matthias
548db18857 Improve wording on partial exit notifications 2023-03-04 19:27:55 +01:00
Matthias
aec11618ce Telegram improved formatting 2023-03-04 18:28:15 +01:00
Matthias
f0cbb4f949 Expose relative realized profit 2023-03-04 18:20:31 +01:00
Matthias
027e023443 Stop from open with leverage 2023-03-04 18:02:47 +01:00
Matthias
51c15d894b Bump ccxt to 2.8.88
closes #8270
2023-03-04 15:27:01 +01:00
Andy Lawless
b262f0b374 Update docs re: bot_loop_start in backtest 2023-03-03 20:46:43 +00:00
Andy Lawless
a3dee9350f Move bot_loop_start call to run on every candle 2023-03-03 20:37:05 +00:00
Matthias
d0045673fa Add explicit test for stoploss_from_open 2023-03-03 20:32:33 +01:00
hippocritical
d92971cca1
Merge branch 'freqtrade:develop' into strategy_utils 2023-03-03 18:56:00 +01:00
hippocritical
87b7513401 fixed --strategy-list
moved ast comments to requirements.txt >=1.0.0 (since that is the first version that adds the comments unparsing)
2023-03-03 18:53:09 +01:00
Matthias
c03c3a5706 improve order REPR display 2023-03-03 18:12:41 +01:00
Matthias
9573974c47 Update deprecations document 2023-03-03 06:36:35 +01:00
Matthias
6e9ff5fdd8
Merge pull request #8202 from freqtrade/remove-populate-any-indicators
remove populate_any_indicators
2023-03-03 06:33:25 +01:00
Matthias
022f85095e Show Number of exits
part of #8234
2023-03-03 06:31:40 +01:00
Matthias
6a0848a3a9
Merge pull request #8267 from freqtrade/python_3.11
Python 3.11
2023-03-03 06:31:33 +01:00
Matthias
13376fdad8
Merge pull request #8220 from eSAMTrade/remove-redundant-dependencies
removed redundant dependencies from environment.yml
2023-03-03 06:25:22 +01:00
Matthias
5b0c143713 Update some comments about 3.11 2023-03-02 19:39:31 +01:00
Matthias
5d0e14b564 Don't mock full modules 2023-03-02 18:23:49 +01:00
Matthias
38050b5346 Simplify "model-run" conditions 2023-03-02 18:23:49 +01:00
Matthias
b1a5776f14 Skip reinforcement learning for python 3.11 2023-03-02 18:23:49 +01:00
Matthias
7a7f16b658 Skip catboost tests on py3.11 2023-03-02 18:23:49 +01:00
Matthias
684d310ea0 Limit catboost to python <3.11 2023-03-02 18:23:49 +01:00
Matthias
49bfa556bf Update CI to test against python 3.11 2023-03-02 18:23:49 +01:00
Matthias
e228733f1a
Merge pull request #8264 from xmatthias/sqlalchemy_2
Sqlalchemy 2
2023-03-02 18:23:01 +01:00
Matthias
103bd9e2f2 keep Trade.session private 2023-03-02 07:26:50 +01:00
Matthias
ba38a826e9 Update missing mocks 2023-03-02 06:46:17 +01:00
Matthias
8103656ae1 Bump mypy in pre-commit 2023-03-02 06:36:03 +01:00
Matthias
b980f45b2b Fix test mypy errors 2023-03-02 06:23:01 +01:00
Matthias
b4b8dde4fb Add sqlalchemy to pre-commit dependencies 2023-03-01 20:41:49 +01:00
Matthias
59d57d3466 Improve test resiliance 2023-03-01 20:32:56 +01:00
Matthias
f0f72fdd33 Don't define "mapped" on LocalTrade class 2023-03-01 20:32:32 +01:00
Matthias
388dfec50b Remove last type error 2023-03-01 20:32:32 +01:00
Matthias
874413ccc5 Fix some style violations 2023-03-01 20:32:32 +01:00
Matthias
4a35d32b6a Improve trade stop types 2023-03-01 20:32:32 +01:00
Matthias
a1166b1077 allow null fee on calc_base_close 2023-03-01 20:32:32 +01:00
Matthias
e5c9cde36f Update trades_proxy typing 2023-03-01 20:32:32 +01:00
Matthias
b5f55c9b14 Improve type safety in backtesting 2023-03-01 20:32:32 +01:00
Matthias
7c09c01788 Add some more typehints 2023-03-01 20:32:32 +01:00
Matthias
0f914cf2bd Use Mapped for LocalTrade
this won't initialize sqlalchemy, as the base class is not inheriting from sqlalchemy.
2023-03-01 20:32:32 +01:00
Matthias
d175ab495b Move SessionType to base module 2023-03-01 20:32:32 +01:00
Matthias
f2f4158974 Bump sqlalchemy to 2.0.4 2023-03-01 20:32:32 +01:00
Matthias
764001a4c2 Don't reuse variable 2023-03-01 20:32:32 +01:00
Matthias
b65cff0adc Update "Query" type 2023-03-01 20:32:32 +01:00
Matthias
db4f4498dc Experimentally type query property ... 2023-03-01 20:32:32 +01:00
Matthias
c2c039151c Improve typesafety around trade object 2023-03-01 20:32:32 +01:00
Matthias
8765e3a4d6 Fix some Type issues 2023-03-01 20:32:32 +01:00
Matthias
f6b3998bbd Fix backtesting type incompatibilities 2023-03-01 20:32:32 +01:00
Matthias
0691bbaad9 Update some db types 2023-03-01 20:32:32 +01:00
Matthias
101d9ab87f Improvements - tests runnable again 2023-03-01 20:32:32 +01:00
Matthias
65a5cf64df Re-type session 2023-03-01 20:32:32 +01:00
Matthias
608a7c2d38 Add safe_close_rate 2023-03-01 20:32:31 +01:00
Matthias
e59eaf33e0 Update _session to session 2023-03-01 20:32:31 +01:00
Matthias
47b66f3220 More fun with types 2023-03-01 20:32:31 +01:00
Matthias
491f49388c "Mapped" for trade_model 2023-03-01 20:32:31 +01:00
Matthias
bb116456a9 Update Types for Order object 2023-03-01 20:32:31 +01:00
Matthias
13b1a3e737 Properly pairlock columns using mapped 2023-03-01 20:32:31 +01:00
Matthias
98791752a9 Update TradeModels to mapped_column 2023-03-01 20:32:31 +01:00
Matthias
0bd9b00132 Pairlock to mappedColumn 2023-03-01 20:32:31 +01:00
Matthias
39a658eac2 Update DeclarativeBase 2023-03-01 20:32:31 +01:00
Matthias
3c019e0e16 tentative augmented typing of Trade object 2023-03-01 20:32:31 +01:00
Matthias
41e27ba621 Enhance some type info 2023-03-01 20:32:31 +01:00
Matthias
3a9d83f86c Mypy: define sqlalchemy plugin 2023-03-01 20:32:31 +01:00
Matthias
9d455f58b1 Improve some trade model Types 2023-03-01 20:32:31 +01:00
Matthias
829e10ff87 Improve Type for models.py 2023-03-01 20:32:31 +01:00
Matthias
b62830031f Dummy-type query objects 2023-03-01 20:32:31 +01:00
Matthias
a553a9923a Update types for pairlock 2023-03-01 20:32:31 +01:00
dependabot[bot]
a629d455fb Bump sqlalchemy from 1.4.46 to 2.0.3
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.46 to 2.0.3.
- [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-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 20:32:31 +01:00
Matthias
feabed30a3 Update remaining exchange mock occurances 2023-03-01 20:27:15 +01:00
Matthias
2ca8b0b12e Update more exchange mocks to use EXMS 2023-03-01 20:27:15 +01:00
Matthias
bcdf4e0fe8 Use variable for exchange mocks to shorten lines 2023-03-01 20:27:15 +01:00
Matthias
78e5ec13bb Use absolute path for generic mocks 2023-03-01 20:27:15 +01:00
Matthias
8b51f5f563 Lowercase exchange ID 2023-03-01 20:27:15 +01:00
Matthias
756c284ecd
Merge pull request #8225 from freqtrade/ruff2
Ruff - add PTH rule and subsequent changes
2023-03-01 20:27:06 +01:00
Matthias
d1b2e38ae9 if a stoploss order exists, always allow canceling that 2023-02-28 20:39:17 +01:00
Matthias
dd10dec73d Improve variable wording 2023-02-28 20:31:02 +01:00
Matthias
f822f1795a Reduce /status verbosity 2023-02-28 19:54:56 +01:00
Matthias
386915378b Improve /status message (show Total profit) 2023-02-28 19:54:47 +01:00
Matthias
2f1c5cf143 Remove pointless pylint rules 2023-02-28 18:22:17 +01:00
Matthias
3706d28125 use pytest.approx in favor of "prec_satoshi" ... 2023-02-28 18:20:37 +01:00
Matthias
0707e70183 Remove deprecated current_profit from api responses 2023-02-28 18:20:37 +01:00
Matthias
bebee15d10 Improve TradeSchema readability 2023-02-28 18:20:36 +01:00
Matthias
5660036f47
Merge pull request #8245 from eSAMTrade/bugfix-8244
Fix last_process related bug in RPC.health (BUG-#8231)
2023-02-28 18:18:53 +01:00
Matthias
262f03bc92 Add backtest warning for market_direction feature 2023-02-28 17:26:38 +01:00
Matthias
244fd0e731
Merge pull request #8184 from LangLazy/feature
Feature market direction
2023-02-28 17:22:31 +01:00
Matthias
fe6af0ef5d
Merge pull request #8258 from freqtrade/dependabot/pip/develop/xgboost-1.7.4
Bump xgboost from 1.7.3 to 1.7.4
2023-02-28 12:06:17 +01:00
Matthias
fd63f50221
Merge pull request #8257 from freqtrade/dependabot/pip/develop/ccxt-2.8.54
Bump ccxt from 2.8.17 to 2.8.54
2023-02-28 12:05:42 +01:00
Matthias
5c13fbb0b8
Merge pull request #8256 from freqtrade/dependabot/pip/develop/types-cachetools-5.3.0.4
Bump types-cachetools from 5.3.0.0 to 5.3.0.4
2023-02-28 12:02:39 +01:00
Matthias
9a5b090894
pre-commit cachetools 2023-02-28 11:23:11 +01:00
dependabot[bot]
5a3f23f00c
Bump types-cachetools from 5.3.0.0 to 5.3.0.4
Bumps [types-cachetools](https://github.com/python/typeshed) from 5.3.0.0 to 5.3.0.4.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-02-28 09:26:32 +00:00
Matthias
8b347dfdcf
Merge pull request #8259 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19.9
Bump types-python-dateutil from 2.8.19.8 to 2.8.19.9
2023-02-28 10:25:35 +01:00
Matthias
deca5479f0
pre-commit dateutil-types 2023-02-28 10:05:38 +01:00
Matthias
2ea71d466c
Merge pull request #8255 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.37
Bump prompt-toolkit from 3.0.36 to 3.0.37
2023-02-28 09:53:24 +01:00
Matthias
200f5ac157
Merge pull request #8252 from freqtrade/dependabot/pip/develop/ruff-0.0.253
Bump ruff from 0.0.252 to 0.0.253
2023-02-28 09:53:06 +01:00
Matthias
9e77effacb
Merge pull request #8253 from freqtrade/dependabot/pip/develop/pre-commit-3.1.1
Bump pre-commit from 3.1.0 to 3.1.1
2023-02-28 09:52:35 +01:00
Matthias
f5f883202d
Merge pull request #8254 from freqtrade/dependabot/pip/develop/plotly-5.13.1
Bump plotly from 5.13.0 to 5.13.1
2023-02-28 09:52:02 +01:00
dependabot[bot]
594757d27d
Bump types-python-dateutil from 2.8.19.8 to 2.8.19.9
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.19.8 to 2.8.19.9.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 05:52:58 +00:00
dependabot[bot]
fed5d87cfd
Bump xgboost from 1.7.3 to 1.7.4
Bumps [xgboost](https://github.com/dmlc/xgboost) from 1.7.3 to 1.7.4.
- [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/v1.7.3...v1.7.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 05:52:55 +00:00
dependabot[bot]
adf5b7f233
Bump ccxt from 2.8.17 to 2.8.54
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.8.17 to 2.8.54.
- [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/2.8.17...2.8.54)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 05:52:48 +00:00
dependabot[bot]
1b4c831469
Bump prompt-toolkit from 3.0.36 to 3.0.37
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.36 to 3.0.37.
- [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases)
- [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG)
- [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.36...3.0.37)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 05:52:40 +00:00
dependabot[bot]
78e7ab92d8
Bump plotly from 5.13.0 to 5.13.1
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.13.0 to 5.13.1.
- [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.13.0...v5.13.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 05:52:35 +00:00
dependabot[bot]
6e45e998ac
Bump pre-commit from 3.1.0 to 3.1.1
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.1.0 to 3.1.1.
- [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.1.0...v3.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 05:52:29 +00:00
dependabot[bot]
a75e9f193f
Bump ruff from 0.0.252 to 0.0.253
Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.252 to 0.0.253.
- [Release notes](https://github.com/charliermarsh/ruff/releases)
- [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.252...v0.0.253)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 05:52:21 +00:00
Matthias
0899e5cb83 Improve documentation wording 2023-02-28 06:41:18 +01:00
Rahul
39331b59ed Fixed issues raised in PR 2023-02-27 22:51:22 +00:00
Matthias
65d1598a90 Show absolute profit in /status command 2023-02-27 21:17:02 +01:00
Matthias
46b987042b Include realized_profit in api output 2023-02-27 20:47:07 +01:00
Matthias
75d1dd2793 Properly round Stake currencies in telegram message 2023-02-27 20:47:07 +01:00
Matthias
e5c68661fe Simplify code line wrapping 2023-02-27 19:57:28 +01:00
Matthias
e482feed7d Further improve behavior for telegram /status with stop on exchange 2023-02-27 19:40:02 +01:00
Matthias
87fe4108a2 Fix order numeration to also work with stoploss on exchange 2023-02-27 18:24:19 +01:00
Matthias
02c831a4e7 Improve Note wording
closes #8235
2023-02-27 18:04:21 +01:00
ASU
bcd416c83d Removed unresolved FreqTrade typehint 2023-02-27 16:18:24 +02:00
ASU
1d5608d627 Fix last_process related bug in RPC.health 2023-02-27 12:14:38 +02:00
Matthias
79a14bcbe7
Merge pull request #8237 from freqtrade/dependabot/pip/develop/types-tabulate-0.9.0.1
Bump types-tabulate from 0.9.0.0 to 0.9.0.1
2023-02-27 10:44:54 +01:00
Matthias
81bc515e5d
Bump tabulate types for pre-commit 2023-02-27 10:00:41 +01:00
dependabot[bot]
201522f1b1
Bump types-tabulate from 0.9.0.0 to 0.9.0.1
Bumps [types-tabulate](https://github.com/python/typeshed) from 0.9.0.0 to 0.9.0.1.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 07:10:51 +00:00
Matthias
44b1005077
Merge pull request #8240 from freqtrade/dependabot/pip/develop/types-requests-2.28.11.15
Bump types-requests from 2.28.11.13 to 2.28.11.15
2023-02-27 08:02:57 +01:00
Matthias
48b21d00d2
bump pre-commit requests 2023-02-27 07:12:12 +01:00
dependabot[bot]
e83eefb71d
Bump types-requests from 2.28.11.13 to 2.28.11.15
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.13 to 2.28.11.15.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-02-27 06:10:08 +00:00
Matthias
345a47ede7
Merge pull request #8238 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19.8
Bump types-python-dateutil from 2.8.19.6 to 2.8.19.8
2023-02-27 07:06:51 +01:00
Matthias
03d41bdf46
Merge pull request #8243 from freqtrade/dependabot/pip/develop/mkdocs-material-9.0.15
Bump mkdocs-material from 9.0.13 to 9.0.15
2023-02-27 06:32:31 +01:00
Matthias
05f3884722
bump pre-commit dateutil 2023-02-27 06:25:13 +01:00
Matthias
aaa0f49f31
Merge pull request #8241 from freqtrade/dependabot/pip/develop/ruff-0.0.252
Bump ruff from 0.0.251 to 0.0.252
2023-02-27 06:24:24 +01:00
Matthias
303c628998
Merge pull request #8239 from freqtrade/dependabot/pip/develop/pre-commit-3.1.0
Bump pre-commit from 3.0.4 to 3.1.0
2023-02-27 06:23:26 +01:00
Matthias
8cab2e85be
Merge pull request #8236 from freqtrade/dependabot/pip/develop/pydantic-1.10.5
Bump pydantic from 1.10.4 to 1.10.5
2023-02-27 06:23:04 +01:00
dependabot[bot]
a4423778d5
Bump mkdocs-material from 9.0.13 to 9.0.15
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.0.13 to 9.0.15.
- [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.0.13...9.0.15)

---
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-02-27 03:58:01 +00:00
dependabot[bot]
2a7f86bfb4
Bump ruff from 0.0.251 to 0.0.252
Bumps [ruff](https://github.com/charliermarsh/ruff) from 0.0.251 to 0.0.252.
- [Release notes](https://github.com/charliermarsh/ruff/releases)
- [Changelog](https://github.com/charliermarsh/ruff/blob/main/BREAKING_CHANGES.md)
- [Commits](https://github.com/charliermarsh/ruff/compare/v0.0.251...v0.0.252)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 03:57:22 +00:00
dependabot[bot]
7add902bc7
Bump pre-commit from 3.0.4 to 3.1.0
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.0.4 to 3.1.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.0.4...v3.1.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-02-27 03:57:04 +00:00
dependabot[bot]
cc78054b8c
Bump types-python-dateutil from 2.8.19.6 to 2.8.19.8
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.19.6 to 2.8.19.8.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 03:56:57 +00:00
dependabot[bot]
533f97f080
Bump pydantic from 1.10.4 to 1.10.5
Bumps [pydantic](https://github.com/pydantic/pydantic) from 1.10.4 to 1.10.5.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v1.10.5/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v1.10.4...v1.10.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 03:56:50 +00:00
Matthias
5b0bc5bbc5 Don't "fix" dry-run kucoin orders
closes #8229
2023-02-26 16:17:41 +01:00
Matthias
6f7ab97fc3 Improve bybit test coverage 2023-02-26 16:17:41 +01:00
Matthias
27676f4aa2 Add explicit bybit test 2023-02-26 16:17:41 +01:00
Matthias
79dc972e5a Add explicit test for kucoin 2023-02-26 16:17:41 +01:00
Matthias
66c2e145cb
Merge pull request #7975 from freqtrade/improve-freqai-gap-handling
handle data gaps between FreqAI and DP better
2023-02-26 15:26:46 +01:00
Matthias
d3d7cb1b14
Merge pull request #8216 from freqtrade/close-rl-env
Close training and eval environments in ReinforcementLearner_multiproc
2023-02-26 15:20:32 +01:00
Matthias
e88bb4e05c Revert small change - otherwise the data is never updated. 2023-02-26 15:09:25 +01:00
ASU
7e7ae144a9 Merge branch 'develop' into remove-redundant-dependencies 2023-02-26 04:29:30 +02:00
Matthias
305eda74e2 Enable Complexity for ruff 2023-02-25 20:50:26 +01:00
Matthias
84d905a648 Fix missed test 2023-02-25 17:39:18 +01:00
ASU
32ce819889 Removed environment.yml and updated documentation 2023-02-25 18:23:07 +02:00
Matthias
26315b6bc2 add PTH ruff selection 2023-02-25 17:17:05 +01:00
Matthias
d014e4590e use Path.open() instead of open 2023-02-25 17:15:54 +01:00
Matthias
c8a4a773ee Fix _pairs_last_refresh_time storing the wrong date
Depending on the drop_incomplete settings, this can lead to implicit bugs
2023-02-25 16:18:46 +01:00
Matthias
ff3aa7c1a9 Bump Version to 2023.3.dev 2023-02-25 16:18:33 +01:00
Matthias
84b8cee004 Merge branch 'stable' into develop 2023-02-25 16:18:25 +01:00
Matthias
6d9e50d60c
Merge pull request #8209 from freqtrade/ruff
Ruff
2023-02-25 16:14:26 +01:00
Matthias
be352ae014 Update more enums 2023-02-25 15:49:45 +01:00
Matthias
563742f13c Fix enum behavior for python 3.11
closes #8221
closes #8217
2023-02-25 15:49:45 +01:00
Matthias
dc2cfee056 Don't request sorted candles from HitBTC.
Apparently hitBTC cannot properly handle this anymore.

closes #8214
2023-02-25 13:49:16 +01:00
Matthias
c6455c4131 Pin scikit-learn to <1.2.0 for conda as well
closes #8223
2023-02-25 13:39:48 +01:00
ASU
7bcae7b665 removed redundant dependencies from environment.yml 2023-02-25 00:26:20 +02:00
Matthias
3471f5204b Don't reuse variable 2023-02-24 14:34:41 +01:00
Matthias
521025037d
Merge pull request #8203 from freqtrade/add-bufer-train-data-candles
Add buffer_train_data_candles feature
2023-02-24 13:25:18 +01:00
Matthias
ac2a2512ef
Merge pull request #8210 from freqtrade/clean-data-drawer
Allow user to control number of historical model files
2023-02-24 13:19:38 +01:00
Robert Caulk
607d90ca5d
Merge pull request #8215 from freqtrade/fix-freqai-index
fix link in freqai index.md
2023-02-24 12:38:56 +01:00
robcaulk
cb80d7c26f close the multi_proc env before creating new ones in an attempt to avoid increasing processes 2023-02-24 11:19:54 +01:00
robcaulk
c283e22325 fix purge_old_models description in parameter table 2023-02-24 10:54:43 +01:00
robcaulk
5ac4b81a5d fix link in freqai index.md 2023-02-24 10:50:39 +01:00
Matthias
34c42be74f Fix minor stylistic errors 2023-02-23 20:06:10 +01:00
Matthias
659140e190 Add bt-error to UI backtest method. 2023-02-23 20:06:10 +01:00
Matthias
63e5d33028 Better handle backtest errors 2023-02-23 20:06:10 +01:00
Matthias
2fed924a0d
Merge pull request #8211 from TheJoeSchr/refactor-1
refactor(if-gate): use temp variable instead of if-gate
2023-02-23 18:14:21 +01:00
Joe Schr
7d906fd4c2 refactor(if-gate): use temp variable instead of if-gate 2023-02-23 10:58:43 +01:00
Matthias
6b829d839b Improve ruff config 2023-02-23 07:12:54 +01:00
Matthias
bf968a9fd8 Use actions as documented 2023-02-23 06:51:03 +01:00
Matthias
cdc96136bc
Merge pull request #8207 from freqtrade/add-freqai-disclaimer
add imposter disclaimer to FreqAI front page
2023-02-23 06:49:18 +01:00
Matthias
23a71680de
Update Doc-box typo 2023-02-23 06:29:58 +01:00
robcaulk
150b7f9c87 lighten the disclaimer message 2023-02-22 22:33:41 +01:00
robcaulk
b8f011a2ab give users ability to decide how many models to keep in dry/live 2023-02-22 22:27:56 +01:00
robcaulk
9633081c31 remove remnants of follower, clean data-drawer, improve doc 2023-02-22 22:01:41 +01:00
Matthias
b4ea37d598 Remove flake8 in favor of ruff 2023-02-22 21:08:17 +01:00
Matthias
549a0e1c44 Add ruff linting - initial configuration 2023-02-22 21:06:11 +01:00
Matthias
2bc9413be1 Fix minor stylistic errors 2023-02-22 20:58:24 +01:00
Matthias
e6766b9b82 Add bt-error to UI backtest method. 2023-02-22 20:22:59 +01:00
Matthias
75bc5809a9 Better handle backtest errors 2023-02-22 20:02:51 +01:00
Matthias
0f878daa98 Remove some too generic noqa statements 2023-02-22 19:56:32 +01:00
Matthias
01d51aa979 Add necesary noqa statements 2023-02-22 19:56:32 +01:00
Matthias
f8fa5bd969 Fix gone wrong noqa ... 2023-02-22 19:56:32 +01:00
Matthias
18bbfa10e5 Reduce amount of variables for API backtesting 2023-02-22 19:56:32 +01:00
Matthias
ff1258fd20 Better handle random UI backtest errors 2023-02-22 19:56:32 +01:00
Matthias
e56bf067c4
Merge pull request #8205 from amalysh/develop
* fixed filename in model_exists
2023-02-22 17:43:57 +01:00
robcaulk
3fbbc57a37 add imposter disclaimer to FreqAI front page 2023-02-22 17:08:30 +01:00
Alexander Malysh
070a7efd73
* fixed filename in model_exists 2023-02-22 14:52:20 +01:00
robcaulk
986bc63e54 raise OperationalException if latest historical data candle is older than earliest dataprovider candle 2023-02-21 21:23:58 +01:00
robcaulk
2b5c11c7b4 allow users to buffer train data with buffer_train_data_candles parameter 2023-02-21 21:08:34 +01:00
Matthias
62e120a602 Remove special treatment of cryptography for raspberries 2023-02-21 20:34:55 +01:00
Matthias
48ecc7f6dc Update freqai-reinforcement-learning docs
closes #8199
2023-02-21 19:55:32 +01:00
Matthias
43962476aa Remove non-working links, update links to https 2023-02-21 19:53:09 +01:00
Matthias
a4a3d27ac6 Improve FAQ page 2023-02-21 19:52:22 +01:00
Matthias
f4bd424226 Remove deprecated ubuntu image
Follows anouncement in https://github.blog/changelog/2022-08-09-github-actions-the-ubuntu-18-04-actions-runner-image-is-being-deprecated-and-will-be-removed-by-12-1-22/
2023-02-21 18:29:00 +01:00
Matthias
af137188f4 Update wrong FAQ entry 2023-02-21 18:05:20 +01:00
robcaulk
fd4e27d889 remove populate_any_indicators 2023-02-21 14:22:40 +01:00
Rahul Gudise
2261cbd92e fixed command regex and updated documentation 2023-02-20 16:22:17 -05:00
Rahul Gudise
3033e27466 Added documentation for new telegram command 2023-02-20 15:53:29 -05:00
Matthias
352f4962da
Merge pull request #8198 from AchmadFathoni/develop
Fix outdated systemd related exception text.
2023-02-20 11:05:42 +01:00
Achmad Fathoni
789c867c8f Fix outdated systemd related exception text. 2023-02-20 16:30:23 +07:00
Matthias
4f794aae61
Merge pull request #8191 from freqtrade/dependabot/pip/develop/mkdocs-material-9.0.13
Bump mkdocs-material from 9.0.12 to 9.0.13
2023-02-20 08:06:53 +01:00
Matthias
bf6560e45b
Merge pull request #8194 from freqtrade/dependabot/pip/develop/types-requests-2.28.11.13
Bump types-requests from 2.28.11.12 to 2.28.11.13
2023-02-20 08:06:37 +01:00
Matthias
ccf4fbed60
Merge pull request #8192 from freqtrade/dependabot/pip/develop/ccxt-2.8.17
Bump ccxt from 2.7.93 to 2.8.17
2023-02-20 07:11:49 +01:00
Matthias
250faf012d
Bump types-requests for pre-commit 2023-02-20 06:55:58 +01:00
Matthias
3a9ffdf135
Merge pull request #8190 from freqtrade/dependabot/pip/develop/fastapi-0.92.0
Bump fastapi from 0.91.0 to 0.92.0
2023-02-20 06:55:17 +01:00
Matthias
ec1991d165
Merge pull request #8189 from freqtrade/dependabot/pip/develop/scipy-1.10.1
Bump scipy from 1.10.0 to 1.10.1
2023-02-20 06:54:16 +01:00
Matthias
4e1f5354fe
Merge pull request #8196 from freqtrade/dependabot/pip/develop/mypy-1.0.1
Bump mypy from 1.0.0 to 1.0.1
2023-02-20 06:53:28 +01:00
dependabot[bot]
0cd28e2cab
Bump mypy from 1.0.0 to 1.0.1
Bumps [mypy](https://github.com/python/mypy) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v1.0.0...v1.0.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-02-20 03:58:03 +00:00
dependabot[bot]
eb08ef6ced
Bump types-requests from 2.28.11.12 to 2.28.11.13
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.12 to 2.28.11.13.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-02-20 03:57:41 +00:00
dependabot[bot]
a4e69574d3
Bump ccxt from 2.7.93 to 2.8.17
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.7.93 to 2.8.17.
- [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/2.7.93...2.8.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-20 03:57:17 +00:00
dependabot[bot]
c85fc6c8ca
Bump mkdocs-material from 9.0.12 to 9.0.13
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.0.12 to 9.0.13.
- [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.0.12...9.0.13)

---
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-02-20 03:57:10 +00:00
dependabot[bot]
f19128ad21
Bump fastapi from 0.91.0 to 0.92.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.91.0 to 0.92.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.91.0...0.92.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-02-20 03:56:55 +00:00
dependabot[bot]
2ef656fac0
Bump scipy from 1.10.0 to 1.10.1
Bumps [scipy](https://github.com/scipy/scipy) from 1.10.0 to 1.10.1.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.10.0...v1.10.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-20 03:56:50 +00:00
Matthias
e9c64c5839 Update dependency to cysystemd
closes #8187
2023-02-19 19:30:27 +01:00
Rahul
8927a92eaf fixed lint issue 2023-02-19 16:11:21 +00:00
Matthias
b0ec35d526
Merge pull request #7904 from freqtrade/feat/shuffle_after_split
add shuffle_after_split option
2023-02-19 15:03:04 +01:00
Rahul
5fb539190d addressed some issues mentioned in PR 2023-02-18 23:50:02 +00:00
Matthias
f89b63b0c5 Fix dry-run stoploss orders filling "in place" after restart. 2023-02-18 19:25:11 +01:00
Matthias
2c0fbd8500 Simplify test slightly 2023-02-18 18:07:35 +01:00
Rahul Gudise
ade64f25d3 fixed formatting 2023-02-17 17:08:39 -05:00
Rahul
72af1912ca added new text 2023-02-17 22:01:00 +00:00
hippocritical
08ca0f7c0f
Merge branch 'freqtrade:develop' into strategy_utils 2023-02-17 21:07:23 +01:00
hippocritical
bcef00edee changed to ast_comments, added tests for comments. 2023-02-17 21:04:26 +01:00
hippocritical
06edc5c044 changed to ast_comments, added tests for comments. 2023-02-17 21:01:09 +01:00
Matthias
c4ec4db050
Merge pull request #8183 from th0rntwig/improve-freqai-docs
fix minor typos
2023-02-17 07:14:39 +01:00
Matthias
31c7b3e136 Update binance leverage tiers 2023-02-17 06:37:03 +01:00
Matthias
22700527ac Convert limit orders to market orders if they cross a threshold
closes #7786
2023-02-17 06:37:03 +01:00
Matthias
9600039686 Update dry-run fill method naming 2023-02-17 06:37:03 +01:00
Rahul
1a74ede126 Merge branch 'feature' of github.com:LangLazy/freqtrade into feature 2023-02-16 17:54:20 -05:00
Rahul Gudise
07c886a2b1
Merge branch 'freqtrade:develop' into feature 2023-02-16 17:54:14 -05:00
Rahul
b73089deb8 fixed a test 2023-02-16 17:51:50 -05:00
thorntwig
35fe37199d fix minor typos 2023-02-16 20:04:42 +01:00
robcaulk
351c5fbf7f add shuffle_after_split to conftest 2023-02-16 19:48:22 +01:00
Robert Caulk
f68543b151
Merge pull request #8182 from freqtrade/generalize-model-exists
generalize model_exists() for RL and Keras
2023-02-16 19:41:07 +01:00
robcaulk
be85ef2707 add documentation for shuffle_after_split, add to constants 2023-02-16 18:50:11 +01:00
robcaulk
b6a741b421 merge develop into feat/shuffle_after_split 2023-02-16 18:46:01 +01:00
robcaulk
36d65e00f9 generalize model_exists() for RL and Keras 2023-02-16 18:33:40 +01:00
Matthias
a2e1389943 Update Binance leverage code 2023-02-16 18:06:34 +01:00
Matthias
8ef110cc5f Rename ob variable to orderbook 2023-02-16 06:38:58 +01:00
Matthias
de7d274fcf Pass orderbook to dry-run fill logic 2023-02-16 06:38:58 +01:00
Matthias
7c10921564 Improve Orderbook typing to align for diff. exchanges 2023-02-16 06:38:58 +01:00
Matthias
a11f081d2d
Merge pull request #8176 from freqtrade/robcaulk-patch-1
Update freqai.md
2023-02-16 06:14:56 +01:00
Robert Caulk
020c9a5cec
Update freqai.md 2023-02-15 21:54:45 +01:00
Matthias
ecff21ac21 type Orderbook 2023-02-15 07:01:36 +01:00
Matthias
3397e47ccf Rename stoploss() to create_stoploss() 2023-02-14 20:42:08 +01:00
Matthias
6e55a873b3 Rename edge.stoploss to get_stoploss
this will make it clear that it's different from
2023-02-14 07:18:11 +01:00
Matthias
bddec476f9 Fix missing typehint in hyper.py 2023-02-13 20:13:26 +01:00
Matthias
cdd324d0a9 Rename stoploss_reached to ft_stoploss_reached 2023-02-13 20:08:54 +01:00
Matthias
ce7d24f529 Extract ft_stoploss_adjust to seperate method 2023-02-13 19:53:04 +01:00
Matthias
a0e2f98086
Merge pull request #8164 from freqtrade/dependabot/pip/develop/tensorboard-2.12.0
Bump tensorboard from 2.11.2 to 2.12.0
2023-02-13 19:34:14 +01:00
Matthias
69d5459460 Improve stop behavior in SIGTERM cases (docker). 2023-02-13 18:25:15 +01:00
Matthias
aafaff877b
Merge pull request #8170 from freqtrade/dependabot/pip/develop/ccxt-2.7.93
Bump ccxt from 2.7.80 to 2.7.93
2023-02-13 18:17:29 +01:00
dependabot[bot]
9061c04f1d
Bump ccxt from 2.7.80 to 2.7.93
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.7.80 to 2.7.93.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.7.80...2.7.93)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 16:09:57 +00:00
Matthias
9a2f6d2416
Merge pull request #8165 from freqtrade/dependabot/pip/develop/aiofiles-23.1.0
Bump aiofiles from 22.1.0 to 23.1.0
2023-02-13 09:50:11 +01:00
Matthias
b5121d3f4c
Merge pull request #8166 from freqtrade/dependabot/pip/develop/aiohttp-3.8.4
Bump aiohttp from 3.8.3 to 3.8.4
2023-02-13 09:49:56 +01:00
Matthias
f3a6897870 Bump Docker images to latest minor version 2023-02-13 07:12:46 +01:00
Matthias
f16fd0ad23 Reenable binanceus active test 2023-02-13 07:12:46 +01:00
dependabot[bot]
f681ee7942
Bump aiohttp from 3.8.3 to 3.8.4
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.3 to 3.8.4.
- [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.3...v3.8.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 06:11:49 +00:00
dependabot[bot]
50a9df9b29
Bump aiofiles from 22.1.0 to 23.1.0
Bumps [aiofiles](https://github.com/Tinche/aiofiles) from 22.1.0 to 23.1.0.
- [Release notes](https://github.com/Tinche/aiofiles/releases)
- [Commits](https://github.com/Tinche/aiofiles/compare/v22.1.0...v23.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 06:11:37 +00:00
dependabot[bot]
2a87ad044d
Bump tensorboard from 2.11.2 to 2.12.0
Bumps [tensorboard](https://github.com/tensorflow/tensorboard) from 2.11.2 to 2.12.0.
- [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.11.2...2.12.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-02-13 06:11:33 +00:00
Matthias
a573976406
Merge pull request #8158 from freqtrade/dependabot/pip/develop/types-requests-2.28.11.12
Bump types-requests from 2.28.11.8 to 2.28.11.12
2023-02-13 07:09:58 +01:00
Matthias
0b5b8e4c97
Merge pull request #8163 from freqtrade/dependabot/pip/develop/fastapi-0.91.0
Bump fastapi from 0.89.1 to 0.91.0
2023-02-13 07:09:44 +01:00
Matthias
ee158c1f55
Merge pull request #8162 from freqtrade/dependabot/pip/develop/mypy-1.0.0
Bump mypy from 0.991 to 1.0.0
2023-02-13 07:08:53 +01:00
Matthias
bf242ac4a2
Merge pull request #8156 from freqtrade/dependabot/pip/develop/mkdocs-material-9.0.12
Bump mkdocs-material from 9.0.11 to 9.0.12
2023-02-13 06:39:34 +01:00
Matthias
a800c19c14
Merge pull request #8157 from freqtrade/dependabot/pip/develop/orjson-3.8.6
Bump orjson from 3.8.5 to 3.8.6
2023-02-13 06:37:39 +01:00
Matthias
d14283b0e7
types-requests - precommit 2023-02-13 06:22:13 +01:00
dependabot[bot]
9faa926803
Bump fastapi from 0.89.1 to 0.91.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.89.1 to 0.91.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.89.1...0.91.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-02-13 03:58:55 +00:00
dependabot[bot]
48c331785c
Bump mypy from 0.991 to 1.0.0
Bumps [mypy](https://github.com/python/mypy) from 0.991 to 1.0.0.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.991...v1.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 03:58:34 +00:00
dependabot[bot]
bbb62c8a4b
Bump types-requests from 2.28.11.8 to 2.28.11.12
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.8 to 2.28.11.12.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-02-13 03:57:16 +00:00
dependabot[bot]
b05999f6d5
Bump orjson from 3.8.5 to 3.8.6
Bumps [orjson](https://github.com/ijl/orjson) from 3.8.5 to 3.8.6.
- [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.8.5...3.8.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 03:57:11 +00:00
dependabot[bot]
ee209e3b44
Bump mkdocs-material from 9.0.11 to 9.0.12
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.0.11 to 9.0.12.
- [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.0.11...9.0.12)

---
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-02-13 03:56:56 +00:00
hippocritical
69a63975c1
Merge branch 'freqtrade:develop' into strategy_utils 2023-02-12 20:11:15 +01:00
Rahul
a3cc001f1b initial commit 2023-02-11 18:31:25 -05:00
Matthias
b3fbb263ce
Merge pull request #8152 from Shadyzpop/patch-1
Typo on freqai docs
2023-02-11 20:22:16 +01:00
Shadyzpop
b95ff827d3
Typo on freqai docs
1. `a the` - there is an extra "a" before `the features`
2. `historic` - it should be "historical" to match the correct adjective form.
2023-02-11 17:12:57 +03:00
Matthias
a3b4678ad6 stoploss_price_type for gate 2023-02-11 13:02:55 +01:00
Matthias
a2759b495b
Merge pull request #8149 from freqtrade/gate_rename
Update gateio terminology to Gate
2023-02-11 12:40:58 +01:00
Matthias
bedd3688d0 Properly format proxy configuration 2023-02-11 12:37:40 +01:00
Matthias
c229ba97a9 Update gateio terminology to Gate 2023-02-11 08:15:11 +01:00
Matthias
07e6932a17 Reenable longrun test mark 2023-02-11 08:14:55 +01:00
Matthias
0713fc6a6a
Merge pull request #8148 from stash86/bt-metrics
Add explicit warning that supported price types gonna differ
2023-02-11 08:14:23 +01:00
Stefano Ariestasia
73992dde8d Add explicit warning that supported price types gonna differ on each exchanges 2023-02-11 11:15:31 +09:00
Matthias
42c76d9e0c
Merge pull request #8147 from freqtrade/add-pair-to-env
Add pair to environment for access inside calculate_reward
2023-02-10 19:38:10 +01:00
Matthias
45e24d21d3 Bump ccxt to 2.7.78
closes #8141
2023-02-10 19:35:45 +01:00
Matthias
f440d66210 Add sample_order for gate 2023-02-10 18:12:21 +01:00
robcaulk
8873a565ee expose raw features to the environment for use in calculate_reward 2023-02-10 15:48:18 +01:00
robcaulk
154b6711b3 use function level noqa ignore 2023-02-10 15:26:17 +01:00
robcaulk
4fc0edb8b7 add pair to environment for access inside calculate_reward 2023-02-10 14:45:50 +01:00
Matthias
d47d8c135b Add windows wheel for ta-lib on python 3.11 2023-02-10 07:17:12 +01:00
Matthias
22cbc16238
Merge pull request #8120 from freqtrade/fut/stop_price_type
stoploss price type
2023-02-10 07:02:25 +01:00
Matthias
eab724fe54 Merge branch 'develop' into fut/stop_price_type 2023-02-09 20:02:59 +01:00
Matthias
8d156b2770 Bump ccxt to 2.7.66
closes  #8132
2023-02-08 20:35:24 +01:00
Matthias
3d22ad36b8 Show Config should contain stoploss-on-exchange status 2023-02-08 07:08:42 +01:00
Matthias
102c1e799c realign binance set_leverage override 2023-02-08 07:08:42 +01:00
Matthias
980ffa6bfb Add test for binance rounding leverage 2023-02-08 07:08:42 +01:00
Matthias
997df2032e Add response_log for set_leverage 2023-02-08 07:08:42 +01:00
Matthias
d19ee9c95f Update okx position mode terminology 2023-02-08 07:08:42 +01:00
Matthias
e2d81b0ce0 Skip binanceus ccxt test 2023-02-08 07:08:42 +01:00
Matthias
c15e10fe1f Improve logic for initially placed stoploss 2023-02-08 07:08:42 +01:00
Matthias
2b0e281113
Merge pull request #8136 from freqtrade/dependabot/pip/cryptography-39.0.1
Bump cryptography from 38.0.1 to 39.0.1
2023-02-08 06:33:49 +01:00
dependabot[bot]
67a2cd7086
Bump cryptography from 38.0.1 to 39.0.1
Bumps [cryptography](https://github.com/pyca/cryptography) from 38.0.1 to 39.0.1.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/38.0.1...39.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-08 04:07:21 +00:00
Matthias
5a61e076d7 Remove unused import 2023-02-07 19:19:59 +01:00
Matthias
953be8a7f8 Split validate_order_types to 2 functions to allow selective application 2023-02-07 18:00:44 +01:00
Matthias
8c0c2496c2 Temporarily disable gate advanced stop orders 2023-02-07 07:13:57 +01:00
Matthias
e8dc3dd59a
Merge pull request #8126 from freqtrade/dependabot/pip/develop/types-cachetools-5.3.0.0
Bump types-cachetools from 5.2.1 to 5.3.0.0
2023-02-07 06:21:03 +01:00
Matthias
81619fb4a0 Properly use sqlalchemy column types 2023-02-06 19:51:51 +01:00
Matthias
82dad7ab17
Merge pull request #8086 from freqtrade/feat/cancel_order
Cancel open orders through UI/telegram
2023-02-06 19:43:21 +01:00
Matthias
a6adcb485e Bump several pre-commit hooks versions 2023-02-06 19:34:30 +01:00
Matthias
be335c401d
Merge pull request #8125 from freqtrade/dependabot/pip/develop/ccxt-2.7.45
Bump ccxt from 2.7.12 to 2.7.45
2023-02-06 19:24:23 +01:00
Matthias
b6eb1f9395
Bump pre-commit 2023-02-06 07:09:59 +01:00
Matthias
7f5a624cfd
Merge pull request #8127 from freqtrade/dependabot/pip/develop/numpy-1.24.2
Bump numpy from 1.24.1 to 1.24.2
2023-02-06 07:08:27 +01:00
Matthias
b215329456
Merge pull request #8128 from freqtrade/dependabot/pip/develop/pymdown-extensions-9.9.2
Bump pymdown-extensions from 9.9.1 to 9.9.2
2023-02-06 07:07:47 +01:00
dependabot[bot]
c6601cbd89
Bump pymdown-extensions from 9.9.1 to 9.9.2
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.9.1 to 9.9.2.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.9.1...9.9.2)

---
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-02-06 03:01:25 +00:00
dependabot[bot]
f96cb47727
Bump numpy from 1.24.1 to 1.24.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.24.1 to 1.24.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.24.1...v1.24.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-02-06 03:01:17 +00:00
dependabot[bot]
365522f5c8
Bump types-cachetools from 5.2.1 to 5.3.0.0
Bumps [types-cachetools](https://github.com/python/typeshed) from 5.2.1 to 5.3.0.0.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-06 03:00:52 +00:00
dependabot[bot]
8dde7ab6b8
Bump ccxt from 2.7.12 to 2.7.45
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.7.12 to 2.7.45.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.7.12...2.7.45)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-06 03:00:49 +00:00
Matthias
e964377edf Add new field to full config 2023-02-05 14:58:12 +01:00
Matthias
d904e91663 Add documentation for new setting 2023-02-05 14:55:11 +01:00
Matthias
61ba1a0dc7 Pin telegram in conda environment to <20
closes #8111
2023-02-05 14:39:20 +01:00
Matthias
48d78d8df9
Merge pull request #8116 from freqtrade/dependabot/pip/develop/technical-1.4.0
Bump technical from 1.3.0 to 1.4.0
2023-02-05 13:16:23 +01:00
Matthias
797993d0b7
Merge pull request #8118 from freqtrade/dependabot/pip/develop/isort-5.12.0
Bump isort from 5.11.4 to 5.12.0
2023-02-05 13:15:37 +01:00
Matthias
79d279b99b
Merge pull request #8114 from freqtrade/dependabot/pip/develop/plotly-5.13.0
Bump plotly from 5.11.0 to 5.13.0
2023-02-05 12:43:46 +01:00
Matthias
a577d6ab36
Merge pull request #8112 from freqtrade/dependabot/pip/develop/mkdocs-material-9.0.11
Bump mkdocs-material from 9.0.8 to 9.0.11
2023-02-05 12:42:58 +01:00
Matthias
389e576b3e
Merge pull request #8113 from freqtrade/dependabot/pip/develop/nbconvert-7.2.9
Bump nbconvert from 7.2.8 to 7.2.9
2023-02-05 12:42:17 +01:00
Matthias
47f47a33e3
Merge pull request #8115 from freqtrade/dependabot/pip/develop/pre-commit-3.0.4
Bump pre-commit from 2.21.0 to 3.0.4
2023-02-05 12:41:47 +01:00
Matthias
b8a527e4a0 Add gateio price type field 2023-02-05 10:46:24 +01:00
Matthias
3497de3dd5 Add more validation 2023-02-05 10:38:58 +01:00
Matthias
cf9e99b8e1 Add tests for ordertype validation 2023-02-05 10:38:58 +01:00
Matthias
2738c37845 Test stoploss validation ... 2023-02-05 10:38:58 +01:00
Matthias
c4fc811619 Add stop_price_type support (futures only!). 2023-02-05 10:38:58 +01:00
Matthias
a9241f61f9 Add Price Type Enum 2023-02-05 10:38:58 +01:00
dependabot[bot]
e38e41ab97
Bump isort from 5.11.4 to 5.12.0
Bumps [isort](https://github.com/pycqa/isort) from 5.11.4 to 5.12.0.
- [Release notes](https://github.com/pycqa/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pycqa/isort/compare/5.11.4...5.12.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-05 09:20:10 +00:00
dependabot[bot]
e3f0e66b9a
Bump technical from 1.3.0 to 1.4.0
Bumps [technical](https://github.com/freqtrade/technical) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/freqtrade/technical/releases)
- [Commits](https://github.com/freqtrade/technical/compare/1.3.0...1.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-05 09:19:44 +00:00
dependabot[bot]
b80d196d56
Bump pre-commit from 2.21.0 to 3.0.4
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.21.0 to 3.0.4.
- [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/v2.21.0...v3.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-05 09:19:39 +00:00
dependabot[bot]
c61995aad9
Bump plotly from 5.11.0 to 5.13.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.11.0 to 5.13.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.11.0...v5.13.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-02-05 09:19:31 +00:00
dependabot[bot]
34711eb683
Bump nbconvert from 7.2.8 to 7.2.9
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.2.8 to 7.2.9.
- [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.2.8...v7.2.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-05 09:19:25 +00:00
dependabot[bot]
5ed06cd79b
Bump mkdocs-material from 9.0.8 to 9.0.11
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.0.8 to 9.0.11.
- [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.0.8...9.0.11)

---
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-02-05 09:19:18 +00:00
Matthias
a7fec1f871
Merge pull request #8109 from freqtrade/add-metadata-to-feature-engineering
Pass metadata dictionary to feature_engineering_* and set_freqai_targets()
2023-02-05 09:56:21 +01:00
Matthias
801714a588 Update function signatures in all templates
add typehints to help the user's editor suggest the right things.
2023-02-04 20:04:16 +01:00
robcaulk
0dd2472385 add metadata param to docstrings 2023-02-04 16:56:36 +01:00
robcaulk
e569f6f6df add explicit metadata argument to example strat, include it with backtesting 2023-02-04 16:53:17 +01:00
robcaulk
5da60b718d pass metadata dictionary to feature_engineering_* and set_freqai_targets functions. Add doc 2023-02-04 13:47:11 +01:00
Matthias
55850a5ccd Skip orders when correlated trade was deleted.
closes #8107
2023-02-04 08:39:25 +01:00
Matthias
7991124794
Merge pull request #8102 from TheJoeSchr/develop
setup.sh: checks if git directory is dirty before bothering user with…
2023-02-03 16:56:52 +01:00
Joe Schr
02c0f91f4d fix: removes duplicated if branch 2023-02-03 16:16:30 +01:00
Joe Schr
3fd6d72984 setup.sh: fix truty/falsy return of check_git_changes() 2023-02-03 08:52:26 +01:00
Matthias
3c4ff2e037
Merge pull request #8095 from freqtrade/remove-follow-mode
remove follow mode in favor of producer consumer
2023-02-03 07:02:56 +01:00
Matthias
ef1738fbf6 Remove follow_mode from docs 2023-02-02 19:30:59 +01:00
Matthias
618eb951d3 Add ft_bot_start to notebook docs
part of #8066
2023-02-02 19:26:48 +01:00
Joe Schr
330461cf1e setup.sh: checks if git directory is dirty before bothering user with potentially scary question 2023-02-02 17:00:07 +01:00
Matthias
e95eb220c5
Merge pull request #8101 from obseries/develop
[kucoin] manage kucoin numeric password passed as environment variabl…
2023-02-02 16:58:29 +01:00
Matthias
c093934c24
Merge pull request #8099 from raphaelstar/raphaelstar-patch-2
`order.amount` -> `order.safe_amount`
2023-02-02 16:28:04 +01:00
Luca Forni
b7787a9846
[kucoin] manage kucoin numeric password passed as environment variable as a string 2023-02-02 16:15:23 +01:00
raphaelstar
b4c3e1fd58
order.amount -> order.safe_amount 2023-02-02 15:52:27 +01:00
Matthias
300e9acd37
Merge pull request #8096 from raphaelstar/raphaelstar-patch-1
Make test for `None` explicit
2023-02-02 14:53:46 +01:00
raphaelstar
36f95fb35d
Make test for None explicit
Make test for `None` explicit
2023-02-02 13:29:37 +01:00
robcaulk
ccb4efbe88 remove follow mode in favor of producer consumer 2023-02-02 11:40:23 +01:00
Matthias
1d6738778b
Merge pull request #8088 from Ezrahel/patch-1
Update README.md
2023-02-02 10:22:09 +01:00
Ezrahel
ba7883f549
Update README.md 2023-02-02 03:02:52 +01:00
Matthias
ceaaac6c3a Improve install sequence to install ta-lib after user interactivity 2023-02-01 18:36:48 +00:00
Matthias
21618594b2 Update setup.sh queries to not ask redundant questions 2023-02-01 17:16:11 +00:00
Matthias
8c9de445e7
Merge pull request #8089 from freqtrade/dependabot/pip/setuptools-65.5.1
Bump setuptools from 65.5.0 to 65.5.1
2023-02-01 12:32:43 +01:00
Matthias
d8583ab6e6 Bump setuptools in setup.sh 2023-02-01 11:06:30 +00:00
dependabot[bot]
7569e72f55
Bump setuptools from 65.5.0 to 65.5.1
Bumps [setuptools](https://github.com/pypa/setuptools) from 65.5.0 to 65.5.1.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/CHANGES.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v65.5.0...v65.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 10:11:12 +00:00
Ezrahel
1e12e888d1
Update README.md 2023-02-01 11:06:32 +01:00
Matthias
fb742361e9
Merge pull request #8083 from leonardocustodio/patch-1
Gym aid
2023-02-01 11:05:38 +01:00
Matthias
322d4b5351 improve fix for setup.sh 2023-02-01 09:20:40 +00:00
Matthias
c1a34396d0 Merge branch 'develop' into feat/cancel_order 2023-02-01 07:06:17 +00:00
Matthias
72a98943b1 bybit: Add correct funding_fee_timeframe 2023-02-01 06:58:45 +01:00
Matthias
9bb376296d Update parse_order test 2023-01-31 20:59:55 +01:00
Matthias
839215c437
Fix Doc box error 2023-01-31 20:58:20 +01:00
Matthias
8a0fabed0e Ensure we don't overwrite valid values by invalid exchange responses 2023-01-31 20:55:11 +01:00
Matthias
680136f57d Add workaround patch for kucoin create_order returning empty
While the actual problem is caused by a ccxt change, the change itself makes sense.
once ccxt starts returning the correct status (open) for create-orders, we can remove the fix.

closes #8079
2023-01-31 20:46:34 +01:00
Matthias
448505fbfb Fix minor issue where amount could be empty in rest calls 2023-01-31 20:38:18 +01:00
Matthias
50d3b7bdef Add bybit sample order 2023-01-31 20:00:05 +01:00
Matthias
42f07e6ec2 Improve order_parse tests 2023-01-31 19:45:27 +01:00
Matthias
6012a55828 Improve test 2023-01-31 19:40:42 +01:00
Matthias
9cfbb21cd7 Improve error messages 2023-01-31 19:38:43 +01:00
Matthias
bbc663fce1 Add telegram test 2023-01-31 19:26:26 +01:00
Matthias
1c47c118d6 Add cancel-order api test 2023-01-31 19:26:21 +01:00
Matthias
daafc1c90f Update test and help 2023-01-31 18:16:59 +01:00
Matthias
bd2839fa40 Reorder documentation 2023-01-31 18:13:42 +01:00
Matthias
e291d1bb17 Document telegram /coo command 2023-01-31 18:12:18 +01:00
Matthias
1bdc0e3917 Add coo command to telegram 2023-01-31 18:09:40 +01:00
Leonardo Custodio
152aa994a6
Fix test 2023-01-31 12:46:21 -03:00
Leonardo Custodio
baf2090f9e
Just change the docs 2023-01-31 12:42:39 -03:00
Leonardo Custodio
592eebe516
Add to setup 2023-01-31 12:10:41 -03:00
Leonardo Custodio
8b307357f3
Add to setup 2023-01-31 12:09:14 -03:00
Leonardo Custodio
d27d5624e0
Merge branch 'freqtrade:develop' into patch-1 2023-01-31 12:00:00 -03:00
Matthias
5073c780d8 .agg would like strings, not the sum function. 2023-01-31 11:22:04 +00:00
Matthias
2c1457fb95 Ensure limit is integer (on server) 2023-01-31 11:06:23 +00:00
Matthias
1dc3c58775 Convert missing candle count to int
closes #8082
2023-01-31 11:04:56 +00:00
Matthias
410324ac19 time-jump detection should happen on the trimmed dataframe
Fixes comment in #7615
2023-01-31 10:13:21 +00:00
Matthias
9e619ecc50 Update rest api documentation 2023-01-31 07:26:12 +01:00
Matthias
03302fa0b0 Add cancel_open_order to rest script 2023-01-31 07:24:19 +01:00
Matthias
c43e857cbc Bump API version 2023-01-31 07:09:07 +01:00
Matthias
c855e2d79c Add delete open order endpoint 2023-01-31 07:09:03 +01:00
Matthias
a704c43402 provide cancel-reason to handle_cancel_order 2023-01-31 07:08:12 +01:00
Leonardo Custodio
2b09f01293
Fixes gym issue
https://github.com/freqtrade/freqtrade/issues/8078
2023-01-30 18:52:56 -03:00
Matthias
5a7008f377 rename handle_timedout to handle_cancel_order 2023-01-30 20:02:01 +01:00
Matthias
cd6602882c
Merge pull request #8076 from freqtrade/new_release
New release 2023.1
2023-01-30 18:11:08 +01:00
Matthias
c3ef8ebb10
Merge pull request #8059 from freqtrade/bybit
Bybit futures support 🎉
2023-01-30 18:10:46 +01:00
Matthias
b5c0daa069
Merge pull request #8028 from freqtrade/dependabot/pip/develop/sb3-contrib-1.7.0
Bump sb3-contrib from 1.6.2 to 1.7.0
2023-01-30 11:42:24 +01:00
Matthias
da0ac8190f
Merge pull request #8075 from freqtrade/dependabot/pip/develop/pyarrow-11.0.0
Bump pyarrow from 10.0.1 to 11.0.0
2023-01-30 11:33:23 +01:00
Matthias
3cb9cc63b3 add pyarrow-11 rpi wheel file 2023-01-30 10:04:10 +00:00
Matthias
e77c16d510
Merge pull request #8073 from freqtrade/dependabot/pip/develop/lightgbm-3.3.5
Bump lightgbm from 3.3.4 to 3.3.5
2023-01-30 09:42:14 +01:00
Matthias
f57394c1ce Merge branch 'develop' into bybit 2023-01-30 07:23:41 +01:00
Matthias
f22f613b24
Merge pull request #8074 from freqtrade/dependabot/pip/develop/mkdocs-material-9.0.8
Bump mkdocs-material from 9.0.5 to 9.0.8
2023-01-30 07:22:46 +01:00
Matthias
2593a929d4 Bump version to 2023.2.dev 2023-01-30 07:19:35 +01:00
Matthias
786f746958 Version bump to 2023.1 2023-01-30 07:16:16 +01:00
Matthias
c4482d56ab Merge branch 'stable' into new_release 2023-01-30 07:10:32 +01:00
dependabot[bot]
411ad5641a
Bump pyarrow from 10.0.1 to 11.0.0
Bumps [pyarrow](https://github.com/apache/arrow) from 10.0.1 to 11.0.0.
- [Release notes](https://github.com/apache/arrow/releases)
- [Commits](https://github.com/apache/arrow/compare/go/v10.0.1...apache-arrow-11.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-01-30 03:02:06 +00:00
dependabot[bot]
0dd852516a
Bump mkdocs-material from 9.0.5 to 9.0.8
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.0.5 to 9.0.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.0.5...9.0.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-01-30 03:01:33 +00:00
dependabot[bot]
2fea23d31a
Bump lightgbm from 3.3.4 to 3.3.5
Bumps [lightgbm](https://github.com/microsoft/LightGBM) from 3.3.4 to 3.3.5.
- [Release notes](https://github.com/microsoft/LightGBM/releases)
- [Commits](https://github.com/microsoft/LightGBM/compare/v3.3.4...v3.3.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-30 03:01:12 +00:00
Matthias
ede79590da Update ccxt compat tests with kucoin order 2023-01-29 19:56:13 +01:00
Matthias
fee7b792e1 Bump ccxt 2023-01-29 19:33:13 +01:00
Matthias
507d3d6d9b Add ci for binance.us 2023-01-29 15:14:55 +01:00
Matthias
25dfbb5a08 Compare stake amout >= in backtesting
closes #8067
2023-01-29 12:47:16 +01:00
Matthias
9286cbed86 add partial Docstring to backtesting enter_trade 2023-01-29 11:02:31 +01:00
Matthias
c1e528e116 Version bump ccxt
closes #8010
2023-01-28 19:54:28 +01:00
Matthias
f6ba0fe6ae bybit: fix broken ccxt tests 2023-01-28 18:23:23 +01:00
Matthias
7294db81e2 Bump ccxt to 2.7.7 2023-01-28 18:17:09 +01:00
Matthias
adf29fe1d7
Merge pull request #8065 from Shadyzpop/patch-1
Docs typo fix
2023-01-28 18:11:36 +01:00
Shadyzpop
f7f936c14f
Typo fix 2023-01-28 03:43:18 +03:00
Matthias
d1b069abfb bybit: Update test to align with defaultType change 2023-01-27 20:33:34 +01:00
Matthias
7029b9602c Merge branch 'develop' into bybit 2023-01-27 20:30:05 +01:00
Matthias
020dc3c6e1 filled-date shouldn't update again 2023-01-27 20:21:29 +01:00
Matthias
aa15837589 Add test for filled_date not updating if it's already set 2023-01-27 20:20:15 +01:00
Matthias
fa033965c8 use "swap" for bybit 2023-01-27 19:34:29 +01:00
Matthias
08ede37795 Add documentation note about stoploss on exchange 2023-01-26 19:58:58 +01:00
Matthias
8665d0866d Add test for bybit startup magic 2023-01-26 19:58:42 +01:00
Matthias
1431f7cc3e Set position mode to one-way on startup 2023-01-26 19:54:35 +01:00
Matthias
73ef1d5191 Improve exception wording on binance 2023-01-26 19:53:14 +01:00
Matthias
8647c0192c Fix typo 2023-01-26 07:08:38 +01:00
Matthias
2333dbae40 Update reinforcement learning docs to use correct naming 2023-01-26 07:07:49 +01:00
Matthias
bd913bc24d
Disable provenance in buildx config for pi image 2023-01-25 14:34:52 +01:00
Matthias
9652c00acb
Don't amend docker manifest 2023-01-25 12:20:10 +01:00
Matthias
c12fb1a49c bybit: Some final cleanup 2023-01-24 20:12:50 +01:00
Matthias
25fa6bee74 Override get_funding_fees for bybit 2023-01-24 07:21:56 +01:00
Matthias
051c3be99e add test case for bybit 2023-01-24 07:21:56 +01:00
Matthias
3a83427f92 Add Bybit stoploss support 2023-01-24 07:21:56 +01:00
Matthias
c14553bacb Add bybit to supported Futures exchanges 2023-01-24 07:21:56 +01:00
Matthias
c2b33a0f58 Fix set-leverage function sig 2023-01-24 07:21:56 +01:00
Matthias
7a18e96042 bybit: hot-fix funding fees (temporary - must be changed) 2023-01-24 07:21:56 +01:00
Matthias
f681ce9139 Allow margin and leverage setting failures
(this is important when an exchange "fails" a request if the setting didn't change).
2023-01-24 07:21:56 +01:00
Matthias
31745a9dc2 bybit: Initial implementation liquidation calculation 2023-01-24 07:21:56 +01:00
Matthias
93ce963e9b Update test name 2023-01-24 07:21:56 +01:00
Matthias
752110a268 Add online tests for bybit 2023-01-24 07:21:56 +01:00
Matthias
d05ecd630f Update tests for new liquidation parameter 2023-01-24 07:21:56 +01:00
Matthias
34e7433844 Add leverage to dry-run liquidation price calculation 2023-01-24 07:21:56 +01:00
Matthias
a7b030fff9 Add note about bybit futures 2023-01-24 07:21:56 +01:00
Matthias
3192af8df8 Limit bybit futures markets to USDT 2023-01-24 07:21:56 +01:00
Matthias
63c732a560 Bybit futures data download 2023-01-24 07:21:56 +01:00
Matthias
6c0fa0dc1f Fix typo in docstring 2023-01-24 07:21:43 +01:00
Matthias
078b430828 Add ccxt compat tests for order parsing 2023-01-23 18:22:07 +01:00
Matthias
b0720fdcf5 Bump ccxt to latest version to fix timestamp parsing issues 2023-01-23 18:10:56 +01:00
Matthias
1e43154bc5
Merge pull request #8049 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19.6
Bump types-python-dateutil from 2.8.19.5 to 2.8.19.6
2023-01-23 09:31:34 +01:00
Matthias
228fc757e9
Merge pull request #8050 from freqtrade/dependabot/pip/develop/ccxt-2.6.58
Bump ccxt from 2.6.39 to 2.6.58
2023-01-23 09:31:18 +01:00
dependabot[bot]
7fc39eafbd
Bump ccxt from 2.6.39 to 2.6.58
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.6.39 to 2.6.58.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.6.39...2.6.58)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-23 07:36:53 +00:00
Matthias
3397225df2
Merge pull request #8051 from freqtrade/dependabot/pip/develop/pandas-1.5.3
Bump pandas from 1.5.2 to 1.5.3
2023-01-23 08:10:48 +01:00
Matthias
14d9789f1e
Bump types-dateutil for precommit 2023-01-23 08:04:45 +01:00
dependabot[bot]
d3fbd41f59
Bump types-python-dateutil from 2.8.19.5 to 2.8.19.6
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.19.5 to 2.8.19.6.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-23 06:18:40 +00:00
Matthias
b80c9dfd1e
Merge pull request #8052 from freqtrade/dependabot/pip/develop/types-requests-2.28.11.8
Bump types-requests from 2.28.11.7 to 2.28.11.8
2023-01-23 07:16:41 +01:00
Matthias
5ef6ea4d91
Merge pull request #8048 from freqtrade/dependabot/pip/develop/nbconvert-7.2.8
Bump nbconvert from 7.2.7 to 7.2.8
2023-01-23 06:48:15 +01:00
Matthias
73414e0fbd
Bump types-requests in pre-commit 2023-01-23 06:47:27 +01:00
dependabot[bot]
673f5c325c
Bump types-requests from 2.28.11.7 to 2.28.11.8
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.7 to 2.28.11.8.
- [Release notes](https://github.com/python/typeshed/releases)
- [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-01-23 03:08:24 +00:00
dependabot[bot]
b104b54e6a
Bump pandas from 1.5.2 to 1.5.3
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.5.2 to 1.5.3.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/main/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v1.5.2...v1.5.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-01-23 03:08:20 +00:00
dependabot[bot]
13f6529cca
Bump nbconvert from 7.2.7 to 7.2.8
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.2.7 to 7.2.8.
- [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.2.7...v7.2.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-23 03:07:48 +00:00
Matthias
95987663f4
Merge pull request #8040 from xmatthias/mypy_fixes
Enable mypy defaults for Optional typechecking
2023-01-22 11:18:53 +01:00
Matthias
0642a2768e Add missing bracket
closes #8041
2023-01-22 11:17:31 +01:00
Matthias
58ad5a683a Fix wrong import order in script 2023-01-21 22:48:30 +01:00
Matthias
79d0fd937c Update pyright config to align with mypy 2023-01-21 20:05:33 +01:00
Matthias
741d2db334 Enable implicit_optional for telegram 2023-01-21 20:02:16 +01:00
Matthias
795934116d Remove optional_untyped from config 2023-01-21 20:02:12 +01:00
Matthias
2bf4cf7d5a Update scripts to PEP484 2023-01-21 20:02:07 +01:00
Matthias
8108a48f39 Follow PEP 484 - no implicit optionals 2023-01-21 20:01:56 +01:00
Matthias
bb355cfac5 improve naming of backtest function 2023-01-21 19:46:27 +01:00
Matthias
80bb120026 Simplify backtesting by removing now unnecessary private function 2023-01-21 18:01:01 +01:00
Matthias
89eb1b0084 funding-fees need to be recalculated for detailed timeframes, too.
closes #7978
2023-01-21 17:47:37 +01:00
Matthias
1211b72255 Add test to show behavior reported in #7978 2023-01-21 16:23:32 +01:00
Matthias
772800bf74 Fix bug in stake_amount adjustment
This was preventing a DCA order to take the remaining stake
2023-01-21 08:52:10 +01:00
Matthias
865d678304 Add backtest_detail test for futures 2023-01-20 09:45:02 +00:00
Matthias
28e51e2dfb Simplify some test setups 2023-01-20 08:28:50 +00:00
Matthias
58d48e79da Convert tests/datadir to path object - better mirroring an initialized configuration 2023-01-20 08:07:02 +00:00
Matthias
a5d87859dc Refactor test to reuse variable 2023-01-20 07:27:35 +00:00
Matthias
6e22607387 Add 5m futures testdata to support detail-backtest tests 2023-01-20 07:08:38 +00:00
Matthias
dbddc4c8aa Improve wording on adjust_trade_position callback warning 2023-01-20 07:08:15 +01:00
Matthias
20093ea090 Add warning about callback call frequency in backtesting 2023-01-20 07:06:54 +01:00
Matthias
81349c2a03 Remove edge section from config template 2023-01-19 19:57:34 +01:00
Matthias
07c391322e Remove edge from sample configs (except full).
Edge is barely used, but everyone drags it's config around.
2023-01-19 18:26:22 +01:00
Matthias
a398f4730b Add documentation note about RSA exchange keys
part of #8034
2023-01-19 18:15:50 +01:00
Matthias
a27e63a547 Bump ccxt to 2.6.39
closes #8034
2023-01-19 18:15:50 +01:00
Matthias
cd2a41e76e
Merge pull request #8035 from freqtrade/enable_plotconfig_wsmode
Enable plotconfig wsmode
2023-01-19 06:55:49 +01:00
Matthias
892fb77ec3 Update mypy pre-commit hook 2023-01-18 19:31:20 +01:00
Matthias
634b80f0e7 Add tests for plotconfig in ws mode 2023-01-18 18:15:35 +01:00
Matthias
2298656e45 Bump api_version to 2.23 2023-01-18 18:15:14 +01:00
Matthias
3216a05a9e Enable plot_config to work in webserver mode
(requires strategy argument)
2023-01-18 18:15:07 +01:00
Matthias
da0992f859 add Config typehint in rpc 2023-01-18 06:45:31 +01:00
Matthias
25f89ac194
Merge pull request #8033 from stash86/bt-metrics
update config-freqai-example to match latest binance futures pair syntax
2023-01-18 06:33:37 +01:00
Stefano Ariestasia
00fa904422 update config-freqai-example to match latest binance futures pair syntax 2023-01-18 09:56:15 +09:00
Matthias
4aaa439221
Merge pull request #7976 from adarkforce/max-open-trades
Hyperopt Max open trades
2023-01-17 20:41:48 +01:00
Matthias
c8ecedf6d5 Clarify a variable via typehint 2023-01-17 20:05:18 +01:00
Matthias
6a4fc33c30 Remove <3.8 bandaid 2023-01-17 19:46:56 +01:00
Matthias
7092212ed5 re-add futures tickers quoteVolume assert 2023-01-17 06:57:48 +01:00
Matthias
7713f343a9 Bump ccxt to 2.6.26
closes #8032
2023-01-17 06:46:49 +01:00
Matthias
98dcab49ab Add fetch_tickers test for futures 2023-01-16 23:06:18 +01:00
Matthias
b4fcda2c11 add aiohttp proxy 2023-01-16 22:37:21 +01:00
Matthias
92a5efad0e Fix set_test_proxy usage 2023-01-16 22:09:53 +01:00
Matthias
b193d8418d Deepcopy config before adding proxies 2023-01-16 21:31:01 +01:00
Matthias
f46b62f1a7 Attempt to use and setup a proxy for CI 2023-01-16 21:15:05 +01:00
Matthias
394a973bbb Revert "Attempt to use and setup a proxy for CI"
This reverts commit 48ae248d2d.
2023-01-16 21:14:46 +01:00
Matthias
48ae248d2d Attempt to use and setup a proxy for CI 2023-01-16 21:14:19 +01:00
Antonio Della Fortuna
5e10bb2cca Merge branch 'develop' of https://github.com/freqtrade/freqtrade into max-open-trades 2023-01-16 20:19:46 +01:00
Matthias
75804a7f85
Bump stable-baselines3 alongside with sb3-contrib. 2023-01-16 15:53:44 +01:00
Matthias
81eb9ebc6e
Merge pull request #8031 from froggleston/eea_grp5
Add a new analysis group to output stats grouped by exit_tag
2023-01-16 15:50:47 +01:00
Matthias
8cfa5934db Catch AttributeError when importing modules
closes #8023
2023-01-16 13:54:25 +00:00
froggleston
813724bd82 Add a new analysis group to output stats grouped by exit_tag 2023-01-16 13:28:40 +00:00
Matthias
05dc29e60b
Merge pull request #8021 from freqtrade/dependabot/pip/develop/mkdocs-material-9.0.5
Bump mkdocs-material from 9.0.3 to 9.0.5
2023-01-16 13:31:30 +01:00
Matthias
41d4e516f1
Merge pull request #8024 from freqtrade/dependabot/pip/develop/cryptography-39.0.0
Bump cryptography from 38.0.1 to 39.0.0
2023-01-16 13:31:06 +01:00
Matthias
3ab40358a2
Merge pull request #8026 from freqtrade/dependabot/pip/develop/tensorboard-2.11.2
Bump tensorboard from 2.11.0 to 2.11.2
2023-01-16 13:29:04 +01:00
dependabot[bot]
8de10e3746
Bump mkdocs-material from 9.0.3 to 9.0.5
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.0.3 to 9.0.5.
- [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.0.3...9.0.5)

---
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-01-16 11:34:02 +00:00
Matthias
d7bd9de60e
Merge pull request #8025 from freqtrade/dependabot/pip/develop/fastapi-0.89.1
Bump fastapi from 0.89.0 to 0.89.1
2023-01-16 12:28:08 +01:00
Matthias
d0ad822034
Merge pull request #8029 from freqtrade/dependabot/pip/develop/pymdown-extensions-9.9.1
Bump pymdown-extensions from 9.9 to 9.9.1
2023-01-16 12:27:44 +01:00
dependabot[bot]
7f4883008f
Bump pymdown-extensions from 9.9 to 9.9.1
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.9 to 9.9.1.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.9...9.9.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-01-16 08:53:34 +00:00
dependabot[bot]
a77fdb1594
Bump sb3-contrib from 1.6.2 to 1.7.0
Bumps [sb3-contrib](https://github.com/Stable-Baselines-Team/stable-baselines3-contrib) from 1.6.2 to 1.7.0.
- [Release notes](https://github.com/Stable-Baselines-Team/stable-baselines3-contrib/releases)
- [Commits](https://github.com/Stable-Baselines-Team/stable-baselines3-contrib/compare/v1.6.2...v1.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 08:53:21 +00:00
dependabot[bot]
a4b2dc30b4
Bump tensorboard from 2.11.0 to 2.11.2
Bumps [tensorboard](https://github.com/tensorflow/tensorboard) from 2.11.0 to 2.11.2.
- [Release notes](https://github.com/tensorflow/tensorboard/releases)
- [Changelog](https://github.com/tensorflow/tensorboard/blob/2.11.2/RELEASE.md)
- [Commits](https://github.com/tensorflow/tensorboard/compare/2.11.0...2.11.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 08:53:12 +00:00
dependabot[bot]
8dce617ada
Bump fastapi from 0.89.0 to 0.89.1
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.89.0 to 0.89.1.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.89.0...0.89.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-01-16 08:53:06 +00:00
dependabot[bot]
283c1968bf
Bump cryptography from 38.0.1 to 39.0.0
Bumps [cryptography](https://github.com/pyca/cryptography) from 38.0.1 to 39.0.0.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/38.0.1...39.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 08:52:52 +00:00
Matthias
76c4b2a975
Merge pull request #8019 from freqtrade/dependabot/pip/develop/requests-2.28.2
Bump requests from 2.28.1 to 2.28.2
2023-01-16 09:50:37 +01:00
Matthias
7c2bfae92e
Merge pull request #8018 from freqtrade/dependabot/pip/develop/ccxt-2.6.24
Bump ccxt from 2.6.6 to 2.6.24
2023-01-16 08:13:47 +01:00
Matthias
0296061e49 Fix version comparison to use packaging.version 2023-01-16 06:54:29 +01:00
Matthias
d226f9706b
Merge pull request #8020 from freqtrade/dependabot/pip/develop/xgboost-1.7.3
Bump xgboost from 1.7.2 to 1.7.3
2023-01-16 06:49:47 +01:00
Matthias
7f61fdd9a3
Merge pull request #8022 from freqtrade/dependabot/pip/develop/pytest-7.2.1
Bump pytest from 7.2.0 to 7.2.1
2023-01-16 06:48:49 +01:00
Matthias
77bb6561d5
Merge pull request #8017 from freqtrade/dependabot/pip/develop/orjson-3.8.5
Bump orjson from 3.8.4 to 3.8.5
2023-01-16 06:46:22 +01:00
dependabot[bot]
178a4c8867
Bump requests from 2.28.1 to 2.28.2
Bumps [requests](https://github.com/psf/requests) from 2.28.1 to 2.28.2.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.1...v2.28.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 05:32:39 +00:00
Matthias
6fd9690477
Merge pull request #8015 from freqtrade/dependabot/pip/develop/urllib3-1.26.14
Bump urllib3 from 1.26.13 to 1.26.14
2023-01-16 06:31:39 +01:00
dependabot[bot]
7785809f4a
Bump pytest from 7.2.0 to 7.2.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.0 to 7.2.1.
- [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.2.0...7.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 03:02:08 +00:00
dependabot[bot]
59e6f19dd8
Bump xgboost from 1.7.2 to 1.7.3
Bumps [xgboost](https://github.com/dmlc/xgboost) from 1.7.2 to 1.7.3.
- [Release notes](https://github.com/dmlc/xgboost/releases)
- [Changelog](https://github.com/dmlc/xgboost/blob/master/NEWS.md)
- [Commits](https://github.com/dmlc/xgboost/compare/v1.7.2...v1.7.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 03:01:28 +00:00
dependabot[bot]
dc7b8ac7ba
Bump ccxt from 2.6.6 to 2.6.24
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.6.6 to 2.6.24.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.6.6...2.6.24)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 03:01:13 +00:00
dependabot[bot]
d24fce83d2
Bump orjson from 3.8.4 to 3.8.5
Bumps [orjson](https://github.com/ijl/orjson) from 3.8.4 to 3.8.5.
- [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.8.4...3.8.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 03:01:03 +00:00
dependabot[bot]
9b97ddd0f7
Bump urllib3 from 1.26.13 to 1.26.14
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.13 to 1.26.14.
- [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/1.26.13...1.26.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 03:00:47 +00:00
Matthias
fc9e0ede0b
Merge pull request #8014 from freqtrade/binance_mig
Binance futures naming migration
2023-01-15 21:57:21 +01:00
Matthias
270eed7e14 Fail if detecting invalid ccxt version for binance futures 2023-01-15 19:38:50 +01:00
Antonio Della Fortuna
ab12aace5f changed trades_space to max_open_trades_space 2023-01-15 11:50:40 +01:00
Antonio Della Fortuna
5e64980319 Merge branch 'develop' of https://github.com/freqtrade/freqtrade into max-open-trades 2023-01-15 11:44:35 +01:00
Antonio Della Fortuna
b0f1d914c8 Changed max_open_trades type to int or inf 2023-01-15 11:44:10 +01:00
Matthias
ce323e66ac Remove note about binance futures naming 2023-01-14 21:40:48 +01:00
Matthias
e14f2cc275 Add db migration test 2023-01-14 21:26:00 +01:00
Matthias
5d4a247fa0 Add test for binance data migration 2023-01-14 20:34:04 +01:00
Matthias
cbcee02ded call data migration from backtesting 2023-01-14 20:07:33 +01:00
Matthias
1fc97a8008 use Unified futures naming for futures throughout tests 2023-01-13 21:16:19 +01:00
Matthias
9d1cf040f0 Update test leverage tiers 2023-01-13 20:44:45 +01:00
Matthias
4ea8962ca2 Rename futures test data 2023-01-13 20:44:32 +01:00
Matthias
47b50a8a29 Udpate binance leverage tiers to new pair format 2023-01-13 20:32:25 +01:00
Matthias
c93b265ec8 Run migration commands on certain data commands 2023-01-13 07:27:18 +01:00
Matthias
0be0ef9e77 Remove duplicate binance test
The same test exists in test_exchange, but for most exchanges.
2023-01-13 07:11:44 +01:00
Matthias
0d1172ca43 Update binance future test 2023-01-13 07:04:29 +01:00
Matthias
e43b9b65fa increase minimium ccxt version to 2.6.6 2023-01-13 07:00:13 +01:00
Matthias
b024fafaf8 Use futures_pair in ccxt test correctly 2023-01-12 23:39:02 +01:00
Matthias
5b3304189c trading_mode is not necessarily mandatory 2023-01-12 23:38:53 +01:00
Matthias
183bf6819f Update binance pair naming in ccxt test 2023-01-12 23:35:32 +01:00
Matthias
5ad664aaca Update binance futures name to swap 2023-01-12 23:35:16 +01:00
Matthias
9cb7d6c26e Run binance futures migrations on startup 2023-01-12 23:35:06 +01:00
Matthias
5d45adb37d
Merge pull request #8009 from freqtrade/robcaulk-patch-1
Update freqai-reinforcement-learning.md
2023-01-12 23:33:54 +01:00
Robert Caulk
bfd7803fd8
Update freqai-reinforcement-learning.md 2023-01-12 22:18:22 +01:00
Matthias
ee7b505dcb Add data migration method 2023-01-12 20:59:43 +01:00
Matthias
b1bfd76741 Add binance futures db migration 2023-01-12 20:36:06 +01:00
Matthias
518e8d24dc
Merge pull request #8007 from TheJoeSchr/fix/version-cwd
fix "--version": needs to change working directory
2023-01-12 20:24:28 +01:00
Joe Schr
1cf69f139c refactor "--version" to use "pathlib" instead of "os" 2023-01-12 19:27:41 +01:00
Matthias
1a533668b5
Merge pull request #8008 from freqtrade/fix/NaT_ser_deser
Fix websockets for dataframes with NaT entries
2023-01-12 08:10:14 +01:00
Antonio Della Fortuna
192f75254f Merge branch 'develop' of https://github.com/freqtrade/freqtrade into max-open-trades 2023-01-11 22:21:46 +01:00
Matthias
9d647fd193 Fix websockets for dataframes with NaT entreis 2023-01-11 22:07:20 +01:00
Matthias
ec5d464ff2
Merge pull request #8005 from TheJoeSchr/develop
docs: fix broken link to quickstart
2023-01-11 21:37:34 +01:00
Matthias
684de1937a Fix link syntax to actually work 2023-01-11 21:35:18 +01:00
Joe Schr
08748dd021 fix "--version": needs to change working directory
before calling `git`. otherwise it would display git commit id from the
directory where you are calling `freqtrade` from instead of freqtrade's
current commit id
2023-01-11 21:12:06 +01:00
Joe Schr
4abf06119b docs: fix broken link to quickstart 2023-01-11 20:29:40 +01:00
Antonio Della Fortuna
534aa8f7ff Merge branch 'develop' of https://github.com/freqtrade/freqtrade into max-open-trades
# Conflicts:
#	freqtrade/optimize/backtesting.py
2023-01-11 18:55:57 +01:00
Matthias
00dbc195ac Update huobi ci to use BTC markets 2023-01-11 08:43:07 +00:00
Matthias
f677dea6a4
Merge pull request #7950 from freqtrade/freqai_feature_engineering_functions
FreqAI Strategy - Improve user experience
2023-01-10 20:04:53 +01:00
Wagner Costa
2241f24290 moved deprecated warning to start function 2023-01-10 09:10:30 -03:00
Matthias
a261ee327d
Merge pull request #7994 from freqtrade/dependabot/pip/develop/scipy-1.10.0
Bump scipy from 1.9.3 to 1.10.0
2023-01-10 08:07:24 +01:00
Matthias
67495530b7 Add FreqAI migration documentation 2023-01-10 07:22:28 +01:00
Matthias
6fc3d0e5e1
Merge pull request #7995 from freqtrade/dependabot/pip/develop/httpx-0.23.3
Bump httpx from 0.23.1 to 0.23.3
2023-01-09 20:47:32 +01:00
robcaulk
93aff9325e improve deprecation note 2023-01-09 20:15:03 +01:00
robcaulk
a61274ae18 ensure cached corr-pairs works with new framework 2023-01-09 20:04:36 +01:00
Matthias
811f13e09a
Merge pull request #7981 from freqtrade/backtest_detail_speed
Improve backtest detail speed
2023-01-09 18:21:54 +01:00
Matthias
30bc45a1ba
Merge pull request #7991 from freqtrade/order_amount_price
Separately store Order amount price
2023-01-09 18:15:55 +01:00
Matthias
fbdda8cd15 Always pass Dictionaries to testclient post requests 2023-01-09 18:12:20 +01:00
Matthias
3e5ca0438f
Merge pull request #8000 from freqtrade/dependabot/pip/develop/mkdocs-material-9.0.3
Bump mkdocs-material from 8.5.11 to 9.0.3
2023-01-09 13:37:04 +01:00
dependabot[bot]
3ca2dfc079
Bump httpx from 0.23.1 to 0.23.3
Bumps [httpx](https://github.com/encode/httpx) from 0.23.1 to 0.23.3.
- [Release notes](https://github.com/encode/httpx/releases)
- [Changelog](https://github.com/encode/httpx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/httpx/compare/0.23.1...0.23.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 09:10:30 +00:00
Matthias
d59c48c638
Merge pull request #7996 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.46
Bump sqlalchemy from 1.4.45 to 1.4.46
2023-01-09 09:33:26 +01:00
Matthias
0aca0d20d9 Add some feature flags for mkdocs migration 2023-01-09 07:24:18 +01:00
Matthias
8abe1e1c2e
Merge pull request #8001 from freqtrade/dependabot/pip/develop/orjson-3.8.4
Bump orjson from 3.8.3 to 3.8.4
2023-01-09 06:52:02 +01:00
Matthias
bd7eeb8701
Merge pull request #7998 from freqtrade/dependabot/pip/develop/fastapi-0.89.0
Bump fastapi from 0.88.0 to 0.89.0
2023-01-09 06:51:12 +01:00
Matthias
8a5aef20aa
Merge pull request #7999 from freqtrade/dependabot/pip/develop/ccxt-2.5.56
Bump ccxt from 2.5.46 to 2.5.56
2023-01-09 06:49:29 +01:00
Matthias
7de72a2425
Merge pull request #7993 from freqtrade/dependabot/pip/develop/lightgbm-3.3.4
Bump lightgbm from 3.3.3 to 3.3.4
2023-01-09 06:47:37 +01:00
dependabot[bot]
43b49fef4f
Bump orjson from 3.8.3 to 3.8.4
Bumps [orjson](https://github.com/ijl/orjson) from 3.8.3 to 3.8.4.
- [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.8.3...3.8.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 03:01:33 +00:00
dependabot[bot]
25fd1ea639
Bump mkdocs-material from 8.5.11 to 9.0.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.5.11 to 9.0.3.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Upgrade guide](https://github.com/squidfunk/mkdocs-material/blob/master/docs/upgrade.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.5.11...9.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 03:01:26 +00:00
dependabot[bot]
3b69745c3b
Bump ccxt from 2.5.46 to 2.5.56
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.5.46 to 2.5.56.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.5.46...2.5.56)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 03:01:18 +00:00
dependabot[bot]
79fe8fd85b
Bump fastapi from 0.88.0 to 0.89.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.88.0 to 0.89.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.88.0...0.89.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-01-09 03:01:07 +00:00
dependabot[bot]
d32d70d2ea
Bump sqlalchemy from 1.4.45 to 1.4.46
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.45 to 1.4.46.
- [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-01-09 03:00:58 +00:00
dependabot[bot]
c198ca2967
Bump scipy from 1.9.3 to 1.10.0
Bumps [scipy](https://github.com/scipy/scipy) from 1.9.3 to 1.10.0.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.9.3...v1.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 03:00:45 +00:00
dependabot[bot]
2f0eb95d03
Bump lightgbm from 3.3.3 to 3.3.4
Bumps [lightgbm](https://github.com/microsoft/LightGBM) from 3.3.3 to 3.3.4.
- [Release notes](https://github.com/microsoft/LightGBM/releases)
- [Commits](https://github.com/microsoft/LightGBM/compare/v3.3.3...v3.3.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 03:00:38 +00:00
Antonio Della Fortuna
7d27afd4b8 Fixed test broken due to change in trades_space range 2023-01-08 16:11:41 +01:00
Matthias
ad49541947 Adapt Tests for new mandatory columns 2023-01-08 13:55:52 +01:00
Matthias
305b067e48 Support having no Amount/Price available from the exchange initially 2023-01-08 13:55:09 +01:00
Matthias
fd694f14c2 Add new order columns, ft_amount and ft_price 2023-01-08 13:53:08 +01:00
Antonio Della Fortuna
10d8b016e4 Changed max_open_trades default range for optimization 2023-01-08 12:48:36 +01:00
Antonio Della Fortuna
f77dffc951 align to develop 2023-01-08 12:46:27 +01:00
Antonio Della Fortuna
24ace646c3 Merge branch 'develop' of https://github.com/freqtrade/freqtrade into max-open-trades 2023-01-08 12:40:01 +01:00
Antonio Della Fortuna
464cb4761c Fixed max_open_trades update from hyperopt
Fixed max_open_trades update from hyperopt + removed max_open_trades as a param to backtesting + refactoring
2023-01-08 12:39:39 +01:00
Matthias
550ab2b8e8 Improve select_order to only consider filled where needed. 2023-01-08 11:24:04 +01:00
Matthias
8d4f7341c9
Merge pull request #7987 from stash86/bt-metrics
update calmar, sharpe, and sortino hyperopt losses to use latest formula
2023-01-08 10:37:24 +01:00
Matthias
34dbe9deaa Improve fixture fake results 2023-01-08 10:08:54 +01:00
Matthias
f958459a84
Merge pull request #7989 from freqtrade/dependabot/pip/develop/ccxt-2.5.46
Bump ccxt from 2.4.60 to 2.5.46
2023-01-07 16:32:11 +01:00
dependabot[bot]
1d5440ff71
Bump ccxt from 2.4.60 to 2.5.46
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.4.60 to 2.5.46.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.4.60...2.5.46)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-07 14:19:48 +00:00
Matthias
c7f485687f Fix ccxt test failure
as identified and analyzed https://github.com/ccxt/ccxt/issues/16335
2023-01-07 15:13:22 +01:00
Antonio Della Fortuna
8c3ac56bc5 Merge branch 'develop' of https://github.com/freqtrade/freqtrade into max-open-trades 2023-01-07 11:11:59 +01:00
root
7bf531c8b8 isort fix 2023-01-07 09:50:05 +09:00
Stefano Ariestasia
c1042996db flake8 fix 2023-01-07 09:46:46 +09:00
Stefano Ariestasia
6198b21001 update calmar loss 2023-01-07 09:30:16 +09:00
Stefano Ariestasia
d3b1aa7f01 update sortino calc 2023-01-07 09:19:06 +09:00
Stefano Ariestasia
157bf962f7 add missing imports 2023-01-07 09:14:56 +09:00
Stefano Ariestasia
86ba7dae92 change sharpe hyperopt loss 2023-01-07 08:56:40 +09:00
Matthias
8b456441a9
Merge pull request #7971 from paranoidandy/patch-1
Update FreqaiExampleStrategy.py
2023-01-06 15:16:31 +01:00
Matthias
349d67f582
Merge pull request #7983 from stash86/bt-metrics
Fix typo in calculate_expectancy's description
2023-01-06 07:30:09 +01:00
Stefano Ariestasia
329d95366a
Merge branch 'freqtrade:develop' into bt-metrics 2023-01-06 08:04:00 +08:00
hippocritical
feb6accc6c Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils 2023-01-05 22:56:29 +01:00
hippocritical
4435c4fd0d removed prints for strategy could not be loaded
Changed logic to contain much less if conditions

currently still missing:
Webhook terminology, Telegram notification settings, Strategy/Config settings
2023-01-05 22:56:06 +01:00
Matthias
787d292ba0 Move "drop_candle" decision to coroutine 2023-01-05 22:31:32 +01:00
Wagner Costa
d82264ced9 Merge branch 'develop' into freqai_feature_engineering_functions 2023-01-05 17:55:35 -03:00
Wagner Costa
abdeb72eb0 fix tests 2023-01-05 17:54:56 -03:00
robcaulk
d91ac8b669 improve wording in freqai doc 2023-01-05 20:13:48 +01:00
Matthias
bdf6537c60 Remove unused (and pointless) exchange method 2023-01-05 11:45:15 +01:00
Matthias
4bac66ff0e Type ohlcv coroutine 2023-01-05 11:33:47 +01:00
Matthias
75b0a3e63d Use dedicated type for OHLCV response 2023-01-05 11:30:15 +01:00
Matthias
92800930e9 Improve backtest detail speed 2023-01-05 10:14:58 +01:00
Matthias
5257e8b3ed Fix random test failures on 3.8 2023-01-05 09:12:09 +01:00
hippocritical
e55638ed03
Merge branch 'freqtrade:develop' into strategy_utils 2023-01-04 23:52:35 +01:00
hippocritical
ed55296d20 removed prints for strategy could not be loaded
Changed logic to contain much less if conditions

currently still missing:
Webhook terminology, Telegram notification settings, Strategy/Config settings
2023-01-04 23:49:33 +01:00
Wagner Costa
ed99e7f857 fix corr_pairs startup candle count bug 2023-01-04 14:21:37 -03:00
Matthias
8e5b4750d6 Continue in "regular backtest" case (no detail-data available).
link to #7967
2023-01-04 18:08:45 +01:00
Matthias
6470635753 In cases of no losing trade, sortino ratio can't be calculated.
closes #7977
2023-01-04 17:55:24 +01:00
Matthias
7a43f37eb7
Merge pull request #7972 from Undertoned/develop
Fix Backtesting  Analysis Column Wrong
2023-01-04 16:38:29 +01:00
Antonio Della Fortuna
f2fa476dc6 max_open_trades should be an integer
Max open trades will be always an integer in the strategy (-1 for infinity), but in the config -1 will be parsed as infinity
2023-01-04 16:09:27 +01:00
Wagner Costa
ed2b1b1ed1 Merge branch 'develop' into freqai_feature_engineering_functions 2023-01-04 10:40:20 -03:00
Wagner Costa
801ab39a24 fix get dataframe data to include startup_candle 2023-01-04 10:36:19 -03:00
robcaulk
3cbe51c3ca remove duplicated line 2023-01-04 13:58:25 +01:00
Antonio Della Fortuna
1c5e172683 docs update 2023-01-04 12:54:35 +01:00
Matthias
38a780ef63
Merge pull request #7973 from freqtrade/robcaulk-patch-1
Fix file name in FreqaiExampleStrategy.py
2023-01-04 12:51:14 +01:00
robcaulk
dc25668468 handle data gaps between FreqAI and DP better 2023-01-04 11:41:06 +01:00
Antonio Della Fortuna
ce661cb58b Merge branch 'develop' of https://github.com/freqtrade/freqtrade into max-open-trades 2023-01-04 10:35:09 +01:00
Antonio Della Fortuna
5fd85368a9 Added support for max_open_trades hyperopting 2023-01-04 10:34:44 +01:00
Robert Caulk
c384d1357e
Update FreqaiExampleStrategy.py 2023-01-03 21:52:16 +01:00
Matthias
6f031f005d Fix flake error 2023-01-03 20:29:08 +01:00
zhanglei14
63db1fd894 Fix Backtesting Analysis Column Wrong 2023-01-04 01:38:07 +08:00
Wagner Costa
314c0925bf fix get dataframe data to include startup_candle 2023-01-03 14:02:42 -03:00
paranoidandy
73114b93c2
Update FreqaiExampleStrategy.py
Change can_short to True to enable shorting
2023-01-03 15:11:46 +00:00
hippocritical
71ec32ac9e removed prints for strategy could not be loaded
changed back to ast, astor is not really needed.
2023-01-02 23:35:51 +01:00
hippocritical
697fad0ac4 Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils 2023-01-02 20:46:05 +01:00
hippocritical
0817e1698f requirements thinned out again
StrategyResolver.search_all_objects(enum_failed) set to False since we got no use in True
shortened update_code call
added modified_code8 test which currently still fails. (and thereby is commented out)
2023-01-02 20:45:56 +01:00
Matthias
91d8370909
Merge pull request #7966 from freqtrade/frog-hyper-docs
Fix ROI table comma and spacing
2023-01-02 20:35:05 +01:00
Robert Davey
2c430c806c
Fix ROI table comma and spacing
THanks to `@topdollar` in discord for noticing the typos.
2023-01-02 15:54:49 +00:00
hippocritical
61d7129d7c
Update freqtrade/commands/strategy_utils_commands.py
Co-authored-by: Matthias <xmatthias@outlook.com>
2023-01-02 16:51:05 +01:00
Robert Caulk
52dfb0452c
Update freqai-feature-engineering.md 2023-01-02 16:06:54 +01:00
Matthias
72f9c248f5
Merge pull request #7961 from freqtrade/dependabot/pip/develop/time-machine-2.9.0
Bump time-machine from 2.8.2 to 2.9.0
2023-01-02 09:21:55 +01:00
Matthias
df25dbc048 Don't require a configuration for strategy-updater 2023-01-02 08:52:18 +01:00
Matthias
a712c5d42c Improve if formatting 2023-01-02 08:52:01 +01:00
Matthias
e89609dc3a
Fix crash due to invalid parameter 2023-01-02 08:51:54 +01:00
Matthias
5bb1f4a845
Merge pull request #7962 from freqtrade/dependabot/pip/develop/pydantic-1.10.4
Bump pydantic from 1.10.2 to 1.10.4
2023-01-02 08:26:14 +01:00
Matthias
d1a0ae45e8
Merge pull request #7960 from freqtrade/dependabot/pip/develop/filelock-3.9.0
Bump filelock from 3.8.2 to 3.9.0
2023-01-02 08:25:11 +01:00
dependabot[bot]
724465c798
Bump pydantic from 1.10.2 to 1.10.4
Bumps [pydantic](https://github.com/pydantic/pydantic) from 1.10.2 to 1.10.4.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v1.10.4/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v1.10.2...v1.10.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-02 03:01:07 +00:00
dependabot[bot]
488b4512e0
Bump time-machine from 2.8.2 to 2.9.0
Bumps [time-machine](https://github.com/adamchainz/time-machine) from 2.8.2 to 2.9.0.
- [Release notes](https://github.com/adamchainz/time-machine/releases)
- [Changelog](https://github.com/adamchainz/time-machine/blob/main/HISTORY.rst)
- [Commits](https://github.com/adamchainz/time-machine/compare/2.8.2...2.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-02 03:01:00 +00:00
dependabot[bot]
d304f95c13
Bump filelock from 3.8.2 to 3.9.0
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.8.2 to 3.9.0.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.8.2...3.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-02 03:00:55 +00:00
hippocritical
66f7c91357 Adding tests
added more code inside NameUpdater to grab more variables.
2023-01-01 22:03:45 +01:00
hippocritical
762dd4f024 Adding tests
added more code inside NameUpdater to grab more variables.
2023-01-01 18:57:38 +01:00
hippocritical
a51e44eea3 Adding tests 2023-01-01 12:37:15 +01:00
Matthias
74b924471a type ccxt_compat tests 2022-12-31 10:59:42 +01:00
Matthias
cd7bd9bf9a Update gate liquidation price link 2022-12-31 10:25:21 +01:00
Matthias
6498e352c1 Remove pointless default 2022-12-31 10:23:39 +01:00
Matthias
97e8bb09e8 Update exchange documentation with note about leverage 2022-12-31 10:17:30 +01:00
hippocritical
82218d01f4 sped up the function generic_visit that now skips unnecessary fields
added mentioning of skipped class names since they could not be found
2022-12-30 21:49:09 +01:00
Stefano Ariestasia
5188464fc0 fix typo 2022-12-31 02:03:02 +09:00
Wagner Costa
c8aa7720a2 added again feature check in BT from pred files 2022-12-30 11:16:35 -03:00
Wagner Costa
b39fc6b924 remove add pair to column from docs, fix keyerror bug and adjust hybrid strategy example 2022-12-30 10:42:31 -03:00
robcaulk
b2bab68fba move price assignment to feature_engineering_standard() to reduce un-requested feature additions in RL. Ensure old method of price assignment still works, add deprecation warning to help users migrate their strategies 2022-12-30 13:02:39 +01:00
Matthias
798438df9d Extract funding-rate call to separate method
this will allow overwriting in subclasses.
2022-12-30 07:32:59 +01:00
Matthias
499cc5bae1 Better visualize downloaded candletype in debug mode 2022-12-30 07:15:24 +01:00
hippocritical
a6356c2821 Merge remote-tracking branch 'origin/strategy_utils' into strategy_utils 2022-12-29 22:32:02 +01:00
hippocritical
c6f045afa9 fixing issues of the maintainer
found a bug meaning elts could contain lists of elts (now recurively gone through)

Next in line: writing tests based on StrategyUpdater.update_code
2022-12-29 22:31:33 +01:00
Wagner Costa
2e30bdb9b2 freqai bt - fix tests 2022-12-29 16:35:11 -03:00
Matthias
9a46613975
Merge pull request #7954 from freqtrade/new_release
New release 2022.12
2022-12-29 17:45:08 +01:00
Wagner Costa
2b89f643b7 adjust backtest to new feature engineering functions 2022-12-28 19:03:41 -03:00
Matthias
c78b2080cc Add exception test for interest function 2022-12-28 17:42:35 +01:00
Matthias
6ef15802eb make tables an optional dependency
requirements will still install this though.
2022-12-28 16:04:21 +01:00
Matthias
973cfd0182
Merge pull request #7810 from stash86/bt-metrics
Add more calculations for backtest metrics
2022-12-28 15:57:07 +01:00
Matthias
f0bd6b9589
Merge pull request #7939 from freqtrade/dependabot/pip/develop/tables-3.8.0
Bump tables from 3.7.0 to 3.8.0
2022-12-28 15:55:43 +01:00
Matthias
2805e83c9f Bump Develop version to 2023.1 2022-12-28 15:53:43 +01:00
Matthias
8e8f71ade5 Version bump 2022.12 2022-12-28 15:42:38 +01:00
Matthias
149539d3f9 Merge branch 'stable' into new_release 2022-12-28 15:42:29 +01:00
Matthias
5cb8fe1a50 Add JOSS badge to freqtrade docs and readme.md 2022-12-28 15:40:12 +01:00
Matthias
c52910f28b Improve resiliance against invalid data
closes #7947
2022-12-28 15:30:57 +01:00
Matthias
6434bf6745 Document new backtesting metrics 2022-12-28 15:29:55 +01:00
Matthias
32bbe603cb Fix sortino std calculation 2022-12-28 14:59:49 +01:00
robcaulk
6f7eb71bbb ensure RL works with new naming scheme 2022-12-28 14:52:33 +01:00
Matthias
d5b516842c Fix 2 docstrings 2022-12-28 14:44:23 +01:00
Matthias
f21185d1c4 Add tests for new metrics 2022-12-28 14:05:04 +01:00
Matthias
02eb00fa33 Merge branch 'develop' into pr/stash86/7810 2022-12-28 14:04:54 +01:00
robcaulk
c2936d551b improve doc, update test strats, change function names 2022-12-28 13:25:40 +01:00
Matthias
4d112def17 Remove binance AD from docs page
fixes #7921
2022-12-28 07:10:11 +01:00
hippocritical
126b8dac07
Merge branch 'freqtrade:develop' into strategy_utils 2022-12-27 22:34:24 +01:00
hippocritical
70e9fa6136 implementing the strategy_updater in a first version 2022-12-27 20:43:43 +01:00
Matthias
cd4faa9c59 keep max_stake_amount through backtests 2022-12-27 18:08:20 +01:00
Wagner Costa
8227b4aafe freqAI Strategy - improve user experience 2022-12-27 11:37:01 -03:00
Matthias
62c4675e29 Remove some deprecated fields from the API 2022-12-27 14:28:07 +01:00
Matthias
cb66663fd2 show max_stake_amount in API 2022-12-27 14:28:07 +01:00
Matthias
55001bf321 Keep max_stake_amount (only relevant for DCA orders). 2022-12-27 14:28:07 +01:00
Matthias
6f2c3e2528 Split migration and persistence tests 2022-12-27 14:28:07 +01:00
Matthias
2d6ca5c8bf
Merge pull request #7949 from freqtrade/freqai-doc-update
Improve `purge_old_models` explanation
2022-12-27 13:25:58 +01:00
Robert Caulk
20901c833a
Improve purge_old_models explanation 2022-12-27 10:08:09 +01:00
Matthias
8a37eba0d9
Merge pull request #7946 from freqtrade/dependabot/pip/develop/numpy-1.24.1
Bump numpy from 1.23.5 to 1.24.1
2022-12-26 20:50:26 +01:00
Matthias
882e68c68b Rename backtest-result from new to "not new". 2022-12-26 15:33:14 +01:00
Matthias
6a15a9b412 Update backtest-result_new
fixing the calculation of profit_abs - which was incorrect previously.
2022-12-26 15:33:14 +01:00
dependabot[bot]
1cef40a134
Bump numpy from 1.23.5 to 1.24.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.23.5 to 1.24.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.23.5...v1.24.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 14:31:47 +00:00
Matthias
e881175cc4
Merge pull request #7945 from freqtrade/dependabot/pip/develop/ccxt-2.4.60
Bump ccxt from 2.4.27 to 2.4.60
2022-12-26 15:30:51 +01:00
Matthias
63f114395a is_short should be a boolean 2022-12-26 14:02:47 +01:00
dependabot[bot]
aaeeb86622
Bump ccxt from 2.4.27 to 2.4.60
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.4.27 to 2.4.60.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.4.27...2.4.60)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 12:40:26 +00:00
Matthias
19913e8dc5
Merge pull request #7940 from freqtrade/dependabot/pip/develop/isort-5.11.4
Bump isort from 5.11.3 to 5.11.4
2022-12-26 13:39:39 +01:00
dependabot[bot]
d60b38dad2
Bump tables from 3.7.0 to 3.8.0
Bumps [tables](https://github.com/PyTables/PyTables) from 3.7.0 to 3.8.0.
- [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.7.0...v3.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 09:04:53 +00:00
Matthias
d01def3c61
Merge pull request #7941 from freqtrade/dependabot/pip/develop/pre-commit-2.21.0
Bump pre-commit from 2.20.0 to 2.21.0
2022-12-26 10:03:25 +01:00
Matthias
faab4b2342
Merge pull request #7943 from freqtrade/dependabot/pip/develop/types-requests-2.28.11.7
Bump types-requests from 2.28.11.5 to 2.28.11.7
2022-12-26 10:02:49 +01:00
dependabot[bot]
c5b246af80
Bump isort from 5.11.3 to 5.11.4
Bumps [isort](https://github.com/pycqa/isort) from 5.11.3 to 5.11.4.
- [Release notes](https://github.com/pycqa/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pycqa/isort/compare/5.11.3...5.11.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 08:24:40 +00:00
Matthias
9296ad23d9
Merge pull request #7938 from freqtrade/dependabot/pip/develop/nbconvert-7.2.7
Bump nbconvert from 7.2.6 to 7.2.7
2022-12-26 09:21:43 +01:00
Matthias
00112d81d2
Bump types-requests pre-commit 2022-12-26 09:21:18 +01:00
Matthias
9a556d2639 Remove all mac conflicts 2022-12-26 08:57:01 +01:00
Matthias
18709406c5 use link overwrite 2022-12-26 08:50:55 +01:00
Matthias
9ea8792d3c Attempt brew fix 2022-12-26 08:45:02 +01:00
dependabot[bot]
3993bd7c1c
Bump types-requests from 2.28.11.5 to 2.28.11.7
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.11.5 to 2.28.11.7.
- [Release notes](https://github.com/python/typeshed/releases)
- [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>
2022-12-26 03:01:11 +00:00
dependabot[bot]
e0f60e175f
Bump pre-commit from 2.20.0 to 2.21.0
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.20.0 to 2.21.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/v2.20.0...v2.21.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>
2022-12-26 03:01:00 +00:00
dependabot[bot]
b1bf6d8dc9
Bump nbconvert from 7.2.6 to 7.2.7
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.2.6 to 7.2.7.
- [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.2.6...v7.2.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 03:00:41 +00:00
Stefano Ariestasia
6353f3ac1a fix formulas and implement new metrics 2022-12-26 08:19:51 +09:00
Matthias
7a5439321c Show new metrics in backtesting 2022-12-25 21:29:37 +01:00
Matthias
ce13ce4b10 Update binance stoploss order types
closes #7927
an update to the most recent ccxt version (>2.4.55) would have the same effect.
2022-12-25 09:05:53 +01:00
Matthias
4601705814
Merge pull request #7923 from freqtrade/freqai_backtest
Freqai backtest
2022-12-23 19:17:12 +01:00
Matthias
524da3c7ab Don't actually load models to avoid random failures 2022-12-23 16:19:12 +01:00
Matthias
ad0d7c9a9e Don't allow DCA trades to go beyond max order size
closes  #7924
2022-12-23 16:09:35 +01:00
Matthias
2a7369b56a fix macos CI 2022-12-23 07:38:33 +01:00
Matthias
73792fd6ce Don't attempt to convert None to dict 2022-12-21 06:28:55 +01:00
Matthias
70531224e6 Allow setting identifier via UI 2022-12-20 19:44:01 +01:00
Matthias
07606a9e23 Simplify APi backtest config merging 2022-12-20 19:32:29 +01:00
Matthias
6d9f1fafb7 allow backtest_cache to be provided via backtest API 2022-12-20 19:20:39 +01:00
Matthias
256fac2a2b Add test for freqaimodels endpoint 2022-12-20 07:24:54 +01:00
Matthias
5dbd5c235a Add endpoint for freqAI models 2022-12-20 07:24:54 +01:00
Matthias
3012c55ec5
Merge pull request #7867 from Bloodhunter4rc/remotepairlist
Add Remotepairlist
2022-12-19 19:28:49 +01:00
Matthias
a119fbd895 Small error-message finetuning 2022-12-19 18:19:55 +01:00
Bloodhunter4rc
ebf60d85da self._init_done placed wrong. fixed 2022-12-19 16:25:22 +01:00
Bloodhunter4rc
43f5a16006 parse exception handling, remove info, cache change 2022-12-19 15:36:28 +01:00
Robert Caulk
cc30210b3f
Merge pull request #7908 from freqtrade/add-3action-rl-env
Add 3 Action RL Env
2022-12-19 14:47:57 +01:00
Matthias
095bedf54e
Merge pull request #7915 from freqtrade/dependabot/pip/develop/blosc-1.11.1
Bump blosc from 1.10.6 to 1.11.1
2022-12-19 14:12:00 +01:00
Matthias
4bad2b5c04
Apply suggestions from code review
Co-authored-by: Emre <aemr3@users.noreply.github.com>
2022-12-19 13:27:07 +01:00
robcaulk
5b9e3af276 improve wording 2022-12-19 12:22:15 +01:00
robcaulk
5405d8fa6f add discussion and tips for Base3ActionRLEnvironment 2022-12-19 12:14:53 +01:00
robcaulk
a276ef4b06 ensure long only RL is tested 2022-12-19 11:49:31 +01:00
Matthias
ec3d49ce4c
Merge pull request #7916 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19.5
Bump types-python-dateutil from 2.8.19.4 to 2.8.19.5
2022-12-19 11:20:21 +01:00
Matthias
86b30d2d66 Improve emc test resiliancy 2022-12-19 07:01:32 +01:00
Matthias
2711605df6
Merge pull request #7914 from freqtrade/dependabot/pip/develop/isort-5.11.3
Bump isort from 5.10.1 to 5.11.3
2022-12-19 06:59:28 +01:00
Matthias
daf7653988
Merge pull request #7918 from freqtrade/dependabot/pip/develop/torch-1.13.1
Bump torch from 1.13.0 to 1.13.1
2022-12-19 06:40:27 +01:00
Matthias
cc0d8fa590
Merge pull request #7920 from freqtrade/dependabot/pip/develop/ccxt-2.4.27
Bump ccxt from 2.2.92 to 2.4.27
2022-12-19 06:36:46 +01:00
Matthias
0c8d657d92
update types-dateutil precommit 2022-12-19 06:27:38 +01:00
dependabot[bot]
fa87e08071
Bump ccxt from 2.2.92 to 2.4.27
Bumps [ccxt](https://github.com/ccxt/ccxt) from 2.2.92 to 2.4.27.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/2.2.92...2.4.27)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 03:01:26 +00:00
dependabot[bot]
7216d140de
Bump torch from 1.13.0 to 1.13.1
Bumps [torch](https://github.com/pytorch/pytorch) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/pytorch/pytorch/releases)
- [Changelog](https://github.com/pytorch/pytorch/blob/master/RELEASE.md)
- [Commits](https://github.com/pytorch/pytorch/compare/v1.13.0...v1.13.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 03:01:09 +00:00
dependabot[bot]
06225b9501
Bump types-python-dateutil from 2.8.19.4 to 2.8.19.5
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.19.4 to 2.8.19.5.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 03:00:54 +00:00
dependabot[bot]
d86885c7f9
Bump blosc from 1.10.6 to 1.11.1
Bumps [blosc](https://github.com/blosc/python-blosc) from 1.10.6 to 1.11.1.
- [Release notes](https://github.com/blosc/python-blosc/releases)
- [Changelog](https://github.com/Blosc/python-blosc/blob/main/RELEASE_NOTES.rst)
- [Commits](https://github.com/blosc/python-blosc/compare/v1.10.6...v1.11.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 03:00:46 +00:00
dependabot[bot]
b61fc161bf
Bump isort from 5.10.1 to 5.11.3
Bumps [isort](https://github.com/pycqa/isort) from 5.10.1 to 5.11.3.
- [Release notes](https://github.com/pycqa/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pycqa/isort/compare/5.10.1...5.11.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 03:00:43 +00:00
Bloodhunter4rc
6380c3d462 reduce duplicate code, fix cache check 2022-12-18 23:37:18 +01:00
Bloodhunter4rc
bb33b96ba7 init cache on first iteration, init checks, limit length and charmap to info replace if invalid, move filter logic 2022-12-18 22:28:12 +01:00
Matthias
1f4cc145c4 Move trade docs to advanced section 2022-12-18 20:02:38 +01:00
Matthias
eda72ef26c Add documentation for Order object 2022-12-18 19:40:49 +01:00
Matthias
a439488b74 Add initial trade_object documentation 2022-12-18 17:42:05 +01:00
Matthias
bad6fe77d3 Remove deprecated trade property 2022-12-18 17:21:50 +01:00
Matthias
cb81613aa5
Merge pull request #7907 from freqtrade/add-joss-citation
Add JOSS citation to freqai doc
2022-12-17 19:22:35 +01:00
Robert Caulk
329a0a3f45
Update docs/freqai.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2022-12-17 18:43:20 +01:00
Emre
c293401b22
Add can_short to freqai base model 2022-12-16 23:19:08 +03:00
Emre
e604047158
Enable RL tests on arm mac 2022-12-16 22:57:55 +03:00
Emre
a8c9aa01fb
Add 3ac test 2022-12-16 22:31:44 +03:00
Emre
7727f31507
Add 3 Action RL env 2022-12-16 22:18:49 +03:00
Emre
dde363343c
Add can_short param to base env 2022-12-16 22:16:19 +03:00
Robert Caulk
439914caef
Merge pull request #7906 from initrv/fix-base-env-done-condition
fix base4 env done condition
2022-12-16 15:25:58 +01:00
robcaulk
e4284f4e7b add citation to freqai doc. Update credits 2022-12-16 15:20:46 +01:00
initrv
36948e2a74 fix base4 env done condition 2022-12-16 14:14:05 +03:00
robcaulk
c9bc91c75b add shuffle_after_split option 2022-12-16 11:20:37 +01:00
Matthias
6fa3db3a1d Fix failing tests 2022-12-15 19:36:21 +01:00
Bloodhunter4rc
cd1b8b9cee single space removed for the unit test to pass.. 2022-12-15 18:14:37 +01:00
Bloodhunter4rc
9e20d13e50
Merge branch 'freqtrade:develop' into remotepairlist 2022-12-15 17:38:56 +01:00
Bloodhunter4rc
1d5c66da3b + Unit Tests 2022-12-15 17:38:21 +01:00
Bloodhunter4rc
7f3524949c - print 2022-12-13 21:00:23 +01:00
Bloodhunter4rc
d52c1c7554 Add unit tests 2022-12-13 20:21:06 +01:00
Bloodhunter4rc
6f92c58e33 add docs, add bearer token. 2022-12-12 13:24:33 +01:00
Bloodhunter4rc
f6b90595fa remove html. change var names. 2022-12-12 11:05:03 +01:00
Bloodhunter4rc
66412bfa58 Remove unnecessary loop 2022-12-08 01:51:12 +01:00
Bloodhunter4rc
7efcbbb457 Local File Loading 2022-12-08 01:09:17 +01:00
Bloodhunter4rc
da2747d487 Add Local .json file Loading 2022-12-08 00:52:54 +01:00
Bloodhunter4rc
b144a6357d Remove Duplicate 2022-12-07 18:24:55 +01:00
Bloodhunter4rc
547a75d9c1 Fix Info 2022-12-07 17:49:21 +01:00
Bloodhunter4rc
607d5b2f8f Split to fetch_pairlist function, Info Message 2022-12-07 17:47:38 +01:00
Bloodhunter4rc
48160f3fe9 Flake 8 fix, Json Fetching 2022-12-07 17:01:45 +01:00
Bloodhunter4rc
199fd2d074 +Remote Pairlist 2022-12-07 15:08:33 +01:00
Stefano Ariestasia
89c7c2fec6 isort fix 2022-12-07 18:09:57 +09:00
Stefano Ariestasia
611e35ed81 flake8 fix 2022-12-07 15:47:58 +09:00
Stefano Ariestasia
f410b1b14d Update metrics.py 2022-11-28 08:56:49 +09:00
Matthias
77826ebf78
Merge pull request #7806 from freqtrade/new_release
New release 2022.11
2022-11-27 17:10:48 +01:00
Matthias
5c571f565f Version bump 2022.11 2022-11-27 15:34:00 +01:00
Matthias
178e5a195a Merge branch 'stable' into new_release 2022-11-27 15:33:45 +01:00
Matthias
9adce8d167
Merge pull request #7657 from freqtrade/new_release
New release 2022.10
2022-10-29 09:04:34 +02:00
Matthias
ec7d663496 Version bump 2022.10 2022-10-28 19:34:30 +02:00
Matthias
a56465e049 Merge branch 'stable' into new_release 2022-10-28 19:34:15 +02:00
Matthias
851d1e9da1 Version bump 2022.9.1 2022-10-02 06:59:10 +02:00
Matthias
59cfde3767 Fix pandas deprecation warnings from freqAI 2022-10-02 06:59:10 +02:00
Matthias
c53ff94b8e Force joblib update via setup.py 2022-10-02 06:54:08 +02:00
Robert Caulk
03256fc776 Merge pull request #7508 from aemr3/fix-pca-errors
Fix feature list match for PCA
2022-10-02 06:53:08 +02:00
Matthias
19b3669d97 Decrease message throughput
fixes memory leak by queue raising indefinitely
2022-10-02 06:50:34 +02:00
Matthias
6841bdaa81 Update test to verify webhook won't log-spam on new messagetypes 2022-10-02 06:50:19 +02:00
Matthias
8e101a9f1c Disable log spam from analyze_df in webhook/discord 2022-10-02 06:50:12 +02:00
Matthias
0680ca2fe8
Merge pull request #7497 from freqtrade/new_release
New release 2022.9
2022-09-29 18:06:57 +02:00
Matthias
d0456b698c Version bump 2022.9 2022-09-29 07:22:41 +02:00
Matthias
f3085443d5 Merge branch 'stable' into new_release 2022-09-29 07:22:29 +02:00
Matthias
958a4565db
Merge pull request #7313 from freqtrade/new_release
New release 2022.8
2022-08-30 23:01:19 +02:00
Matthias
2403a03fcb Version bump 2022.8 2022-08-29 06:28:53 +02:00
297 changed files with 26273 additions and 15130 deletions

View File

@ -16,15 +16,16 @@ on:
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
permissions:
repository-projects: read
jobs: jobs:
build_linux: build_linux:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [ ubuntu-18.04, ubuntu-20.04, ubuntu-22.04 ] os: [ ubuntu-20.04, ubuntu-22.04 ]
python-version: ["3.8", "3.9", "3.10"] python-version: ["3.8", "3.9", "3.10", "3.11"]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -90,14 +91,14 @@ jobs:
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 6 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all freqtrade hyperopt --datadir tests/testdata -e 6 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Flake8
run: |
flake8
- name: Sort imports (isort) - name: Sort imports (isort)
run: | run: |
isort --check . isort --check .
- name: Run Ruff
run: |
ruff check --format=github .
- name: Mypy - name: Mypy
run: | run: |
mypy freqtrade scripts tests mypy freqtrade scripts tests
@ -115,7 +116,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ macos-latest ] os: [ macos-latest ]
python-version: ["3.8", "3.9", "3.10"] python-version: ["3.8", "3.9", "3.10", "3.11"]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -148,6 +149,19 @@ jobs:
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: | run: |
brew update brew update
# homebrew fails to update python due to unlinking failures
# https://github.com/actions/runner-images/issues/6817
rm /usr/local/bin/2to3 || true
rm /usr/local/bin/2to3-3.11 || true
rm /usr/local/bin/idle3 || true
rm /usr/local/bin/idle3.11 || true
rm /usr/local/bin/pydoc3 || true
rm /usr/local/bin/pydoc3.11 || true
rm /usr/local/bin/python3 || true
rm /usr/local/bin/python3.11 || true
rm /usr/local/bin/python3-config || true
rm /usr/local/bin/python3.11-config || true
brew install hdf5 c-blosc brew install hdf5 c-blosc
python -m pip install --upgrade pip wheel python -m pip install --upgrade pip wheel
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
@ -173,14 +187,14 @@ jobs:
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Flake8
run: |
flake8
- name: Sort imports (isort) - name: Sort imports (isort)
run: | run: |
isort --check . isort --check .
- name: Run Ruff
run: |
ruff check --format=github .
- name: Mypy - name: Mypy
run: | run: |
mypy freqtrade scripts mypy freqtrade scripts
@ -199,7 +213,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ windows-latest ] os: [ windows-latest ]
python-version: ["3.8", "3.9", "3.10"] python-version: ["3.8", "3.9", "3.10", "3.11"]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -235,9 +249,9 @@ jobs:
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Flake8 - name: Run Ruff
run: | run: |
flake8 ruff check --format=github .
- name: Mypy - name: Mypy
run: | run: |
@ -308,7 +322,6 @@ jobs:
build_linux_online: build_linux_online:
# Run pytest with "live" checks # Run pytest with "live" checks
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
# permissions:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -347,6 +360,8 @@ jobs:
pip install -e . pip install -e .
- name: Tests incl. ccxt compatibility tests - name: Tests incl. ccxt compatibility tests
env:
CI_WEB_PROXY: http://152.67.78.211:13128
run: | run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc --longrun pytest --random-order --cov=freqtrade --cov-config=.coveragerc --longrun
@ -410,7 +425,7 @@ jobs:
python setup.py sdist bdist_wheel python setup.py sdist bdist_wheel
- name: Publish to PyPI (Test) - name: Publish to PyPI (Test)
uses: pypa/gh-action-pypi-publish@v1.6.4 uses: pypa/gh-action-pypi-publish@v1.8.5
if: (github.event_name == 'release') if: (github.event_name == 'release')
with: with:
user: __token__ user: __token__
@ -418,7 +433,7 @@ jobs:
repository_url: https://test.pypi.org/legacy/ repository_url: https://test.pypi.org/legacy/
- name: Publish to PyPI - name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.6.4 uses: pypa/gh-action-pypi-publish@v1.8.5
if: (github.event_name == 'release') if: (github.event_name == 'release')
with: with:
user: __token__ user: __token__
@ -451,12 +466,13 @@ jobs:
- name: Build and test and push docker images - name: Build and test and push docker images
env: env:
IMAGE_NAME: freqtradeorg/freqtrade
BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }} BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }}
run: | run: |
build_helpers/publish_docker_multi.sh build_helpers/publish_docker_multi.sh
deploy_arm: deploy_arm:
permissions:
packages: write
needs: [ deploy ] needs: [ deploy ]
# Only run on 64bit machines # Only run on 64bit machines
runs-on: [self-hosted, linux, ARM64] runs-on: [self-hosted, linux, ARM64]
@ -479,8 +495,9 @@ jobs:
- name: Build and test and push docker images - name: Build and test and push docker images
env: env:
IMAGE_NAME: freqtradeorg/freqtrade
BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }} BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }}
GHCR_USERNAME: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
build_helpers/publish_docker_arm64.sh build_helpers/publish_docker_arm64.sh

View File

@ -2,33 +2,40 @@
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
repos: repos:
- repo: https://github.com/pycqa/flake8 - repo: https://github.com/pycqa/flake8
rev: "4.0.1" rev: "6.0.0"
hooks: hooks:
- id: flake8 - id: flake8
# stages: [push] # stages: [push]
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
rev: "v0.942" rev: "v1.0.1"
hooks: hooks:
- id: mypy - id: mypy
exclude: build_helpers exclude: build_helpers
additional_dependencies: additional_dependencies:
- types-cachetools==5.2.1 - types-cachetools==5.3.0.5
- types-filelock==3.2.7 - types-filelock==3.2.7
- types-requests==2.28.11.5 - types-requests==2.28.11.17
- types-tabulate==0.9.0.0 - types-tabulate==0.9.0.2
- types-python-dateutil==2.8.19.4 - types-python-dateutil==2.8.19.12
- SQLAlchemy==2.0.9
# stages: [push] # stages: [push]
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: "5.10.1" rev: "5.12.0"
hooks: hooks:
- id: isort - id: isort
name: isort (python) name: isort (python)
# stages: [push] # stages: [push]
- repo: https://github.com/charliermarsh/ruff-pre-commit
# Ruff version.
rev: 'v0.0.255'
hooks:
- id: ruff
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0 rev: v4.4.0
hooks: hooks:
- id: end-of-file-fixer - id: end-of-file-fixer
exclude: | exclude: |

View File

@ -45,16 +45,17 @@ pytest tests/test_<file_name>.py::test_<method_name>
### 2. Test if your code is PEP8 compliant ### 2. Test if your code is PEP8 compliant
#### Run Flake8 #### Run Ruff
```bash ```bash
flake8 freqtrade tests scripts ruff .
``` ```
We receive a lot of code that fails the `flake8` checks. We receive a lot of code that fails the `ruff` checks.
To help with that, we encourage you to install the git pre-commit To help with that, we encourage you to install the git pre-commit
hook that will warn you when you try to commit code that fails these checks. hook that will warn you when you try to commit code that fails these checks.
Guide for installing them is [here](http://flake8.pycqa.org/en/latest/user/using-hooks.html).
you can manually run pre-commit with `pre-commit run -a`.
##### Additional styles applied ##### Additional styles applied

View File

@ -1,4 +1,4 @@
FROM python:3.10.7-slim-bullseye as base FROM python:3.10.11-slim-bullseye as base
# Setup env # Setup env
ENV LANG C.UTF-8 ENV LANG C.UTF-8

View File

@ -1,6 +1,7 @@
# ![freqtrade](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/freqtrade_poweredby.svg) # ![freqtrade](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/freqtrade_poweredby.svg)
[![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/) [![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/)
[![DOI](https://joss.theoj.org/papers/10.21105/joss.04864/status.svg)](https://doi.org/10.21105/joss.04864)
[![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop) [![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop)
[![Documentation](https://readthedocs.org/projects/freqtrade/badge/)](https://www.freqtrade.io) [![Documentation](https://readthedocs.org/projects/freqtrade/badge/)](https://www.freqtrade.io)
[![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability) [![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability)
@ -39,6 +40,7 @@ Please read the [exchange specific notes](docs/exchanges.md) to learn about even
- [X] [Binance](https://www.binance.com/) - [X] [Binance](https://www.binance.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [OKX](https://okx.com/) - [X] [OKX](https://okx.com/)
- [X] [Bybit](https://bybit.com/)
Please make sure to read the [exchange specific notes](docs/exchanges.md), as well as the [trading with leverage](docs/leverage.md) documentation before diving in. Please make sure to read the [exchange specific notes](docs/exchanges.md), as well as the [trading with leverage](docs/leverage.md) documentation before diving in.
@ -163,6 +165,10 @@ first. If it hasn't been reported, please
ensure you follow the template guide so that the team can assist you as ensure you follow the template guide so that the team can assist you as
quickly as possible. quickly as possible.
For every [issue](https://github.com/freqtrade/freqtrade/issues/new/choose) created, kindly follow up and mark satisfaction or reminder to close issue when equilibrium ground is reached.
--Maintain github's [community policy](https://docs.github.com/en/site-policy/github-terms/github-community-code-of-conduct)--
### [Feature Requests](https://github.com/freqtrade/freqtrade/labels/enhancement) ### [Feature Requests](https://github.com/freqtrade/freqtrade/labels/enhancement)
Have you a great idea to improve the bot you want to share? Please, Have you a great idea to improve the bot you want to share? Please,

Binary file not shown.

View File

@ -8,8 +8,8 @@ if [ -n "$2" ] || [ ! -f "${INSTALL_LOC}/lib/libta_lib.a" ]; then
tar zxvf ta-lib-0.4.0-src.tar.gz tar zxvf ta-lib-0.4.0-src.tar.gz
cd ta-lib \ cd ta-lib \
&& sed -i.bak "s|0.00000001|0.000000000000000001 |g" src/ta_func/ta_utility.h \ && sed -i.bak "s|0.00000001|0.000000000000000001 |g" src/ta_func/ta_utility.h \
&& curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' -o config.guess \ && curl 'https://raw.githubusercontent.com/gcc-mirror/gcc/master/config.guess' -o config.guess \
&& curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' -o config.sub \ && curl 'https://raw.githubusercontent.com/gcc-mirror/gcc/master/config.sub' -o config.sub \
&& ./configure --prefix=${INSTALL_LOC}/ \ && ./configure --prefix=${INSTALL_LOC}/ \
&& make && make
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then

View File

@ -14,5 +14,8 @@ if ($pyv -eq '3.9') {
if ($pyv -eq '3.10') { if ($pyv -eq '3.10') {
pip install build_helpers\TA_Lib-0.4.25-cp310-cp310-win_amd64.whl pip install build_helpers\TA_Lib-0.4.25-cp310-cp310-win_amd64.whl
} }
if ($pyv -eq '3.11') {
pip install build_helpers\TA_Lib-0.4.25-cp311-cp311-win_amd64.whl
}
pip install -r requirements-dev.txt pip install -r requirements-dev.txt
pip install -e . pip install -e .

View File

@ -8,12 +8,17 @@ import yaml
pre_commit_file = Path('.pre-commit-config.yaml') pre_commit_file = Path('.pre-commit-config.yaml')
require_dev = Path('requirements-dev.txt') require_dev = Path('requirements-dev.txt')
require = Path('requirements.txt')
with require_dev.open('r') as rfile: with require_dev.open('r') as rfile:
requirements = rfile.readlines() requirements = rfile.readlines()
with require.open('r') as rfile:
requirements.extend(rfile.readlines())
# Extract types only # Extract types only
type_reqs = [r.strip('\n') for r in requirements if r.startswith('types-')] type_reqs = [r.strip('\n') for r in requirements if r.startswith(
'types-') or r.startswith('SQLAlchemy')]
with pre_commit_file.open('r') as file: with pre_commit_file.open('r') as file:
f = yaml.load(file, Loader=yaml.FullLoader) f = yaml.load(file, Loader=yaml.FullLoader)

View File

@ -3,18 +3,22 @@
# Use BuildKit, otherwise building on ARM fails # Use BuildKit, otherwise building on ARM fails
export DOCKER_BUILDKIT=1 export DOCKER_BUILDKIT=1
IMAGE_NAME=freqtradeorg/freqtrade
CACHE_IMAGE=freqtradeorg/freqtrade_cache
GHCR_IMAGE_NAME=ghcr.io/freqtrade/freqtrade
# Replace / with _ to create a valid tag # Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g") TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot TAG_PLOT=${TAG}_plot
TAG_FREQAI=${TAG}_freqai TAG_FREQAI=${TAG}_freqai
TAG_FREQAI_RL=${TAG_FREQAI}rl TAG_FREQAI_RL=${TAG_FREQAI}rl
TAG_FREQAI_TORCH=${TAG_FREQAI}torch
TAG_PI="${TAG}_pi" TAG_PI="${TAG}_pi"
TAG_ARM=${TAG}_arm TAG_ARM=${TAG}_arm
TAG_PLOT_ARM=${TAG_PLOT}_arm TAG_PLOT_ARM=${TAG_PLOT}_arm
TAG_FREQAI_ARM=${TAG_FREQAI}_arm TAG_FREQAI_ARM=${TAG_FREQAI}_arm
TAG_FREQAI_RL_ARM=${TAG_FREQAI_RL}_arm TAG_FREQAI_RL_ARM=${TAG_FREQAI_RL}_arm
CACHE_IMAGE=freqtradeorg/freqtrade_cache
echo "Running for ${TAG}" echo "Running for ${TAG}"
@ -38,13 +42,13 @@ if [ $? -ne 0 ]; then
echo "failed building multiarch images" echo "failed building multiarch images"
return 1 return 1
fi fi
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_PLOT_ARM} -f docker/Dockerfile.plot .
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_FREQAI_ARM} -f docker/Dockerfile.freqai .
docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_FREQAI_ARM} -t freqtrade:${TAG_FREQAI_RL_ARM} -f docker/Dockerfile.freqai_rl .
# Tag image for upload and next build step # Tag image for upload and next build step
docker tag freqtrade:$TAG_ARM ${CACHE_IMAGE}:$TAG_ARM docker tag freqtrade:$TAG_ARM ${CACHE_IMAGE}:$TAG_ARM
docker build --cache-from freqtrade:${TAG_ARM} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_PLOT_ARM} -f docker/Dockerfile.plot .
docker build --cache-from freqtrade:${TAG_ARM} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_FREQAI_ARM} -f docker/Dockerfile.freqai .
docker build --cache-from freqtrade:${TAG_ARM} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_FREQAI_RL_ARM} -f docker/Dockerfile.freqai_rl .
docker tag freqtrade:$TAG_PLOT_ARM ${CACHE_IMAGE}:$TAG_PLOT_ARM docker tag freqtrade:$TAG_PLOT_ARM ${CACHE_IMAGE}:$TAG_PLOT_ARM
docker tag freqtrade:$TAG_FREQAI_ARM ${CACHE_IMAGE}:$TAG_FREQAI_ARM docker tag freqtrade:$TAG_FREQAI_ARM ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker tag freqtrade:$TAG_FREQAI_RL_ARM ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM docker tag freqtrade:$TAG_FREQAI_RL_ARM ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM
@ -59,7 +63,6 @@ fi
docker images docker images
# docker push ${IMAGE_NAME}
docker push ${CACHE_IMAGE}:$TAG_PLOT_ARM docker push ${CACHE_IMAGE}:$TAG_PLOT_ARM
docker push ${CACHE_IMAGE}:$TAG_FREQAI_ARM docker push ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL_ARM
@ -70,25 +73,47 @@ docker push ${CACHE_IMAGE}:$TAG_ARM
# Otherwise installation might fail. # Otherwise installation might fail.
echo "create manifests" echo "create manifests"
docker manifest create --amend ${IMAGE_NAME}:${TAG} ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG} docker manifest create ${IMAGE_NAME}:${TAG} ${CACHE_IMAGE}:${TAG} ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI}
docker manifest push -p ${IMAGE_NAME}:${TAG} docker manifest push -p ${IMAGE_NAME}:${TAG}
docker manifest create ${IMAGE_NAME}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM} ${CACHE_IMAGE}:${TAG_PLOT} docker manifest create ${IMAGE_NAME}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_PLOT} docker manifest push -p ${IMAGE_NAME}:${TAG_PLOT}
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI_ARM} ${CACHE_IMAGE}:${TAG_FREQAI} docker manifest create ${IMAGE_NAME}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI} docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI}
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM} ${CACHE_IMAGE}:${TAG_FREQAI_RL} docker manifest create ${IMAGE_NAME}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI_RL} docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI_RL}
# Create special Torch tag - which is identical to the RL tag.
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI_TORCH} ${CACHE_IMAGE}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM}
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI_TORCH}
# copy images to ghcr.io
alias crane="docker run --rm -i -v $(pwd)/.crane:/home/nonroot/.docker/ gcr.io/go-containerregistry/crane"
mkdir .crane
chmod a+rwx .crane
echo "${GHCR_TOKEN}" | crane auth login ghcr.io -u "${GHCR_USERNAME}" --password-stdin
crane copy ${IMAGE_NAME}:${TAG_FREQAI_RL} ${GHCR_IMAGE_NAME}:${TAG_FREQAI_RL}
crane copy ${IMAGE_NAME}:${TAG_FREQAI_RL} ${GHCR_IMAGE_NAME}:${TAG_FREQAI_TORCH}
crane copy ${IMAGE_NAME}:${TAG_FREQAI} ${GHCR_IMAGE_NAME}:${TAG_FREQAI}
crane copy ${IMAGE_NAME}:${TAG_PLOT} ${GHCR_IMAGE_NAME}:${TAG_PLOT}
crane copy ${IMAGE_NAME}:${TAG} ${GHCR_IMAGE_NAME}:${TAG}
# Tag as latest for develop builds # Tag as latest for develop builds
if [ "${TAG}" = "develop" ]; then if [ "${TAG}" = "develop" ]; then
echo 'Tagging image as latest'
docker manifest create ${IMAGE_NAME}:latest ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG} docker manifest create ${IMAGE_NAME}:latest ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG}
docker manifest push -p ${IMAGE_NAME}:latest docker manifest push -p ${IMAGE_NAME}:latest
crane copy ${IMAGE_NAME}:latest ${GHCR_IMAGE_NAME}:latest
fi fi
docker images docker images
rm -rf .crane
# Cleanup old images from arm64 node. # Cleanup old images from arm64 node.
docker image prune -a --force --filter "until=24h" docker image prune -a --force --filter "until=24h"

View File

@ -2,6 +2,8 @@
# The below assumes a correctly setup docker buildx environment # The below assumes a correctly setup docker buildx environment
IMAGE_NAME=freqtradeorg/freqtrade
CACHE_IMAGE=freqtradeorg/freqtrade_cache
# Replace / with _ to create a valid tag # Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g") TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot TAG_PLOT=${TAG}_plot
@ -11,7 +13,6 @@ TAG_PI="${TAG}_pi"
PI_PLATFORM="linux/arm/v7" PI_PLATFORM="linux/arm/v7"
echo "Running for ${TAG}" echo "Running for ${TAG}"
CACHE_IMAGE=freqtradeorg/freqtrade_cache
CACHE_TAG=${CACHE_IMAGE}:${TAG_PI}_cache CACHE_TAG=${CACHE_IMAGE}:${TAG_PI}_cache
# Add commit and commit_message to docker container # Add commit and commit_message to docker container
@ -26,7 +27,10 @@ if [ "${GITHUB_EVENT_NAME}" = "schedule" ]; then
--cache-to=type=registry,ref=${CACHE_TAG} \ --cache-to=type=registry,ref=${CACHE_TAG} \
-f docker/Dockerfile.armhf \ -f docker/Dockerfile.armhf \
--platform ${PI_PLATFORM} \ --platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG_PI} --push . -t ${IMAGE_NAME}:${TAG_PI} \
--push \
--provenance=false \
.
else else
echo "event ${GITHUB_EVENT_NAME}: building with cache" echo "event ${GITHUB_EVENT_NAME}: building with cache"
# Build regular image # Build regular image
@ -35,12 +39,16 @@ else
# Pull last build to avoid rebuilding the whole image # Pull last build to avoid rebuilding the whole image
# docker pull --platform ${PI_PLATFORM} ${IMAGE_NAME}:${TAG} # docker pull --platform ${PI_PLATFORM} ${IMAGE_NAME}:${TAG}
# disable provenance due to https://github.com/docker/buildx/issues/1509
docker buildx build \ docker buildx build \
--cache-from=type=registry,ref=${CACHE_TAG} \ --cache-from=type=registry,ref=${CACHE_TAG} \
--cache-to=type=registry,ref=${CACHE_TAG} \ --cache-to=type=registry,ref=${CACHE_TAG} \
-f docker/Dockerfile.armhf \ -f docker/Dockerfile.armhf \
--platform ${PI_PLATFORM} \ --platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG_PI} --push . -t ${IMAGE_NAME}:${TAG_PI} \
--push \
--provenance=false \
.
fi fi
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -50,9 +58,9 @@ fi
# Tag image for upload and next build step # Tag image for upload and next build step
docker tag freqtrade:$TAG ${CACHE_IMAGE}:$TAG docker tag freqtrade:$TAG ${CACHE_IMAGE}:$TAG
docker build --cache-from freqtrade:${TAG} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG} -t freqtrade:${TAG_PLOT} -f docker/Dockerfile.plot . docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG} -t freqtrade:${TAG_PLOT} -f docker/Dockerfile.plot .
docker build --cache-from freqtrade:${TAG} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG} -t freqtrade:${TAG_FREQAI} -f docker/Dockerfile.freqai . docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG} -t freqtrade:${TAG_FREQAI} -f docker/Dockerfile.freqai .
docker build --cache-from freqtrade:${TAG_FREQAI} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_FREQAI} -t freqtrade:${TAG_FREQAI_RL} -f docker/Dockerfile.freqai_rl . docker build --build-arg sourceimage=freqtrade --build-arg sourcetag=${TAG_FREQAI} -t freqtrade:${TAG_FREQAI_RL} -f docker/Dockerfile.freqai_rl .
docker tag freqtrade:$TAG_PLOT ${CACHE_IMAGE}:$TAG_PLOT docker tag freqtrade:$TAG_PLOT ${CACHE_IMAGE}:$TAG_PLOT
docker tag freqtrade:$TAG_FREQAI ${CACHE_IMAGE}:$TAG_FREQAI docker tag freqtrade:$TAG_FREQAI ${CACHE_IMAGE}:$TAG_FREQAI
@ -68,12 +76,10 @@ fi
docker images docker images
docker push ${CACHE_IMAGE} docker push ${CACHE_IMAGE}:$TAG
docker push ${CACHE_IMAGE}:$TAG_PLOT docker push ${CACHE_IMAGE}:$TAG_PLOT
docker push ${CACHE_IMAGE}:$TAG_FREQAI docker push ${CACHE_IMAGE}:$TAG_FREQAI
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL
docker push ${CACHE_IMAGE}:$TAG
docker images docker images

View File

@ -59,20 +59,6 @@
"pairlists": [ "pairlists": [
{"method": "StaticPairList"} {"method": "StaticPairList"}
], ],
"edge": {
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,
"stoploss_range_step": -0.01,
"minimum_winrate": 0.60,
"minimum_expectancy": 0.20,
"min_trade_number": 10,
"max_trade_duration_minute": 1440,
"remove_pumps": false
},
"telegram": { "telegram": {
"enabled": false, "enabled": false,
"token": "your_telegram_token", "token": "your_telegram_token",

View File

@ -56,20 +56,6 @@
"pairlists": [ "pairlists": [
{"method": "StaticPairList"} {"method": "StaticPairList"}
], ],
"edge": {
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,
"stoploss_range_step": -0.01,
"minimum_winrate": 0.60,
"minimum_expectancy": 0.20,
"min_trade_number": 10,
"max_trade_duration_minute": 1440,
"remove_pumps": false
},
"telegram": { "telegram": {
"enabled": false, "enabled": false,
"token": "your_telegram_token", "token": "your_telegram_token",

View File

@ -21,8 +21,8 @@
"ccxt_config": {}, "ccxt_config": {},
"ccxt_async_config": {}, "ccxt_async_config": {},
"pair_whitelist": [ "pair_whitelist": [
"1INCH/USDT", "1INCH/USDT:USDT",
"ALGO/USDT" "ALGO/USDT:USDT"
], ],
"pair_blacklist": [] "pair_blacklist": []
}, },
@ -48,7 +48,7 @@
], ],
"freqai": { "freqai": {
"enabled": true, "enabled": true,
"purge_old_models": true, "purge_old_models": 2,
"train_period_days": 15, "train_period_days": 15,
"backtest_period_days": 7, "backtest_period_days": 7,
"live_retrain_hours": 0, "live_retrain_hours": 0,
@ -60,8 +60,8 @@
"1h" "1h"
], ],
"include_corr_pairlist": [ "include_corr_pairlist": [
"BTC/USDT", "BTC/USDT:USDT",
"ETH/USDT" "ETH/USDT:USDT"
], ],
"label_period_candles": 20, "label_period_candles": 20,
"include_shifted_candles": 2, "include_shifted_candles": 2,

View File

@ -60,6 +60,7 @@
"force_entry": "market", "force_entry": "market",
"stoploss": "market", "stoploss": "market",
"stoploss_on_exchange": false, "stoploss_on_exchange": false,
"stoploss_price_type": "last",
"stoploss_on_exchange_interval": 60, "stoploss_on_exchange_interval": 60,
"stoploss_on_exchange_limit_ratio": 0.99 "stoploss_on_exchange_limit_ratio": 0.99
}, },

View File

@ -64,20 +64,6 @@
"pairlists": [ "pairlists": [
{"method": "StaticPairList"} {"method": "StaticPairList"}
], ],
"edge": {
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,
"stoploss_range_step": -0.01,
"minimum_winrate": 0.60,
"minimum_expectancy": 0.20,
"min_trade_number": 10,
"max_trade_duration_minute": 1440,
"remove_pumps": false
},
"telegram": { "telegram": {
"enabled": false, "enabled": false,
"token": "your_telegram_token", "token": "your_telegram_token",

View File

@ -1,4 +1,4 @@
FROM python:3.9.12-slim-bullseye as base FROM python:3.9.16-slim-bullseye as base
# Setup env # Setup env
ENV LANG C.UTF-8 ENV LANG C.UTF-8

View File

@ -32,7 +32,7 @@ To analyze the entry/exit tags, we now need to use the `freqtrade backtesting-an
with `--analysis-groups` option provided with space-separated arguments (default `0 1 2`): with `--analysis-groups` option provided with space-separated arguments (default `0 1 2`):
``` bash ``` bash
freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 1 2 3 4 freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 1 2 3 4 5
``` ```
This command will read from the last backtesting results. The `--analysis-groups` option is This command will read from the last backtesting results. The `--analysis-groups` option is
@ -43,6 +43,7 @@ ranging from the simplest (0) to the most detailed per pair, per buy and per sel
* 2: profit summaries grouped by enter_tag and exit_tag * 2: profit summaries grouped by enter_tag and exit_tag
* 3: profit summaries grouped by pair and enter_tag * 3: profit summaries grouped by pair and enter_tag
* 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large) * 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large)
* 5: profit summaries grouped by exit_tag
More options are available by running with the `-h` option. More options are available by running with the `-h` option.

View File

@ -75,7 +75,7 @@ This function needs to return a floating point number (`float`). Smaller numbers
## Overriding pre-defined spaces ## Overriding pre-defined spaces
To override a pre-defined space (`roi_space`, `generate_roi_table`, `stoploss_space`, `trailing_space`), define a nested class called Hyperopt and define the required spaces as follows: To override a pre-defined space (`roi_space`, `generate_roi_table`, `stoploss_space`, `trailing_space`, `max_open_trades_space`), define a nested class called Hyperopt and define the required spaces as follows:
```python ```python
from freqtrade.optimize.space import Categorical, Dimension, Integer, SKDecimal from freqtrade.optimize.space import Categorical, Dimension, Integer, SKDecimal
@ -123,6 +123,12 @@ class MyAwesomeStrategy(IStrategy):
Categorical([True, False], name='trailing_only_offset_is_reached'), Categorical([True, False], name='trailing_only_offset_is_reached'),
] ]
# Define a custom max_open_trades space
def max_open_trades_space(self) -> List[Dimension]:
return [
Integer(-1, 10, name='max_open_trades'),
]
``` ```
!!! Note !!! Note

View File

@ -192,7 +192,7 @@ $RepeatedMsgReduction on
### Logging to journald ### Logging to journald
This needs the `systemd` python package installed as the dependency, which is not available on Windows. Hence, the whole journald logging functionality is not available for a bot running on Windows. This needs the `cysystemd` python package installed as dependency (`pip install cysystemd`), which is not available on Windows. Hence, the whole journald logging functionality is not available for a bot running on Windows.
To send Freqtrade log messages to `journald` system service use the `--logfile` command line option with the value in the following format: To send Freqtrade log messages to `journald` system service use the `--logfile` command line option with the value in the following format:

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -274,19 +274,20 @@ A backtesting result will look like that:
| XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 0 23 34.3 | | XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 0 23 34.3 |
| ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 0 15 31.8 | | ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 0 15 31.8 |
| TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 0 243 43.4 | | TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 0 243 43.4 |
========================================================= EXIT REASON STATS ==========================================================
| Exit Reason | Exits | Wins | Draws | Losses |
|:-------------------|--------:|------:|-------:|--------:|
| trailing_stop_loss | 205 | 150 | 0 | 55 |
| stop_loss | 166 | 0 | 0 | 166 |
| exit_signal | 56 | 36 | 0 | 20 |
| force_exit | 2 | 0 | 0 | 2 |
====================================================== LEFT OPEN TRADES REPORT ====================================================== ====================================================== LEFT OPEN TRADES REPORT ======================================================
| Pair | Entries | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Win Draw Loss Win% | | Pair | Entries | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Win Draw Loss Win% |
|:---------|---------:|---------------:|---------------:|-----------------:|---------------:|:---------------|--------------------:| |:---------|---------:|---------------:|---------------:|-----------------:|---------------:|:---------------|--------------------:|
| ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 0 0 100 | | ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 0 0 100 |
| LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 0 0 100 | | LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 0 0 100 |
| TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 0 0 100 | | TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 0 0 100 |
==================== EXIT REASON STATS ====================
| Exit Reason | Exits | Wins | Draws | Losses |
|:-------------------|--------:|------:|-------:|--------:|
| trailing_stop_loss | 205 | 150 | 0 | 55 |
| stop_loss | 166 | 0 | 0 | 166 |
| exit_signal | 56 | 36 | 0 | 20 |
| force_exit | 2 | 0 | 0 | 2 |
================== SUMMARY METRICS ================== ================== SUMMARY METRICS ==================
| Metric | Value | | Metric | Value |
|-----------------------------+---------------------| |-----------------------------+---------------------|
@ -300,7 +301,11 @@ A backtesting result will look like that:
| Absolute profit | 0.00762792 BTC | | Absolute profit | 0.00762792 BTC |
| Total profit % | 76.2% | | Total profit % | 76.2% |
| CAGR % | 460.87% | | CAGR % | 460.87% |
| Sortino | 1.88 |
| Sharpe | 2.97 |
| Calmar | 6.29 |
| Profit factor | 1.11 | | Profit factor | 1.11 |
| Expectancy | -0.15 |
| Avg. stake amount | 0.001 BTC | | Avg. stake amount | 0.001 BTC |
| Total trade volume | 0.429 BTC | | Total trade volume | 0.429 BTC |
| | | | | |
@ -400,7 +405,11 @@ It contains some useful key metrics about performance of your strategy on backte
| Absolute profit | 0.00762792 BTC | | Absolute profit | 0.00762792 BTC |
| Total profit % | 76.2% | | Total profit % | 76.2% |
| CAGR % | 460.87% | | CAGR % | 460.87% |
| Sortino | 1.88 |
| Sharpe | 2.97 |
| Calmar | 6.29 |
| Profit factor | 1.11 | | Profit factor | 1.11 |
| Expectancy | -0.15 |
| Avg. stake amount | 0.001 BTC | | Avg. stake amount | 0.001 BTC |
| Total trade volume | 0.429 BTC | | Total trade volume | 0.429 BTC |
| | | | | |
@ -447,6 +456,9 @@ It contains some useful key metrics about performance of your strategy on backte
- `Absolute profit`: Profit made in stake currency. - `Absolute profit`: Profit made in stake currency.
- `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital Starting capital) / Starting capital`. - `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital Starting capital) / Starting capital`.
- `CAGR %`: Compound annual growth rate. - `CAGR %`: Compound annual growth rate.
- `Sortino`: Annualized Sortino ratio.
- `Sharpe`: Annualized Sharpe ratio.
- `Calmar`: Annualized Calmar ratio.
- `Profit factor`: profit / loss. - `Profit factor`: profit / loss.
- `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount. - `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount.
- `Total trade volume`: Volume generated on the exchange to reach the above profit. - `Total trade volume`: Volume generated on the exchange to reach the above profit.

View File

@ -12,6 +12,9 @@ This page provides you some basic concepts on how Freqtrade works and operates.
* **Indicators**: Technical indicators (SMA, EMA, RSI, ...). * **Indicators**: Technical indicators (SMA, EMA, RSI, ...).
* **Limit order**: Limit orders which execute at the defined limit price or better. * **Limit order**: Limit orders which execute at the defined limit price or better.
* **Market order**: Guaranteed to fill, may move price depending on the order size. * **Market order**: Guaranteed to fill, may move price depending on the order size.
* **Current Profit**: Currently pending (unrealized) profit for this trade. This is mainly used throughout the bot and UI.
* **Realized Profit**: Already realized profit. Only relevant in combination with [partial exits](strategy-callbacks.md#adjust-trade-position) - which also explains the calculation logic for this.
* **Total Profit**: Combined realized and unrealized profit. The relative number (%) is calculated against the total investment in this trade.
## Fee handling ## Fee handling
@ -57,10 +60,10 @@ This loop will be repeated again and again until the bot is stopped.
* Load historic data for configured pairlist. * Load historic data for configured pairlist.
* Calls `bot_start()` once. * Calls `bot_start()` once.
* Calls `bot_loop_start()` once.
* Calculate indicators (calls `populate_indicators()` once per pair). * Calculate indicators (calls `populate_indicators()` once per pair).
* Calculate entry / exit signals (calls `populate_entry_trend()` and `populate_exit_trend()` once per pair). * Calculate entry / exit signals (calls `populate_entry_trend()` and `populate_exit_trend()` once per pair).
* Loops per candle simulating entry and exit points. * Loops per candle simulating entry and exit points.
* Calls `bot_loop_start()` strategy callback.
* Check for Order timeouts, either via the `unfilledtimeout` configuration, or via `check_entry_timeout()` / `check_exit_timeout()` strategy callbacks. * Check for Order timeouts, either via the `unfilledtimeout` configuration, or via `check_entry_timeout()` / `check_exit_timeout()` strategy callbacks.
* Calls `adjust_entry_price()` strategy callback for open entry orders. * Calls `adjust_entry_price()` strategy callback for open entry orders.
* Check for trade entry signals (`enter_long` / `enter_short` columns). * Check for trade entry signals (`enter_long` / `enter_short` columns).
@ -75,3 +78,7 @@ This loop will be repeated again and again until the bot is stopped.
!!! Note !!! Note
Both Backtesting and Hyperopt include exchange default Fees in the calculation. Custom fees can be passed to backtesting / hyperopt by specifying the `--fee` argument. Both Backtesting and Hyperopt include exchange default Fees in the calculation. Custom fees can be passed to backtesting / hyperopt by specifying the `--fee` argument.
!!! Warning "Callback call frequency"
Backtesting will call each callback at max. once per candle (`--timeframe-detail` modifies this behavior to once per detailed candle).
Most callbacks will be called once per iteration in live (usually every ~5s) - which can cause backtesting mismatches.

View File

@ -11,7 +11,7 @@ Per default, the bot loads the configuration from the `config.json` file, locate
You can specify a different configuration file used by the bot with the `-c/--config` command-line option. You can specify a different configuration file used by the bot with the `-c/--config` command-line option.
If you used the [Quick start](installation.md/#quick-start) method for installing If you used the [Quick start](docker_quickstart.md#docker-quick-start) method for installing
the bot, the installation script should have already created the default configuration file (`config.json`) for you. the bot, the installation script should have already created the default configuration file (`config.json`) for you.
If the default configuration file is not created we recommend to use `freqtrade new-config --config config.json` to generate a basic configuration file. If the default configuration file is not created we recommend to use `freqtrade new-config --config config.json` to generate a basic configuration file.
@ -134,7 +134,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| Parameter | Description | | Parameter | Description |
|------------|-------------| |------------|-------------|
| `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the length of your pairlist is another limitation that can apply. If -1 then it is ignored (i.e. potentially unlimited open trades, limited by the pairlist). [More information below](#configuring-amount-per-trade).<br> **Datatype:** Positive integer or -1. | `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the length of your pairlist is another limitation that can apply. If -1 then it is ignored (i.e. potentially unlimited open trades, limited by the pairlist). [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Positive integer or -1.
| `stake_currency` | **Required.** Crypto-currency used for trading. <br> **Datatype:** String | `stake_currency` | **Required.** Crypto-currency used for trading. <br> **Datatype:** String
| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). <br> **Datatype:** Positive float or `"unlimited"`. | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). <br> **Datatype:** Positive float or `"unlimited"`.
| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade). <br>*Defaults to `0.99` 99%).*<br> **Datatype:** Positive float between `0.1` and `1.0`. | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade). <br>*Defaults to `0.99` 99%).*<br> **Datatype:** Positive float between `0.1` and `1.0`.
@ -263,6 +263,7 @@ Values set in the configuration file always overwrite values set in the strategy
* `minimal_roi` * `minimal_roi`
* `timeframe` * `timeframe`
* `stoploss` * `stoploss`
* `max_open_trades`
* `trailing_stop` * `trailing_stop`
* `trailing_stop_positive` * `trailing_stop_positive`
* `trailing_stop_positive_offset` * `trailing_stop_positive_offset`
@ -665,7 +666,7 @@ You should also make sure to read the [Exchanges](exchanges.md) section of the d
### Using proxy with Freqtrade ### Using proxy with Freqtrade
To use a proxy with freqtrade, export your proxy settings using the variables `"HTTP_PROXY"` and `"HTTPS_PROXY"` set to the appropriate values. To use a proxy with freqtrade, export your proxy settings using the variables `"HTTP_PROXY"` and `"HTTPS_PROXY"` set to the appropriate values.
This will have the proxy settings applied to everything (telegram, coingecko, ...) except exchange requests. This will have the proxy settings applied to everything (telegram, coingecko, ...) **except** for exchange requests.
``` bash ``` bash
export HTTP_PROXY="http://addr:port" export HTTP_PROXY="http://addr:port"
@ -681,11 +682,12 @@ To use a proxy for exchange connections - you will have to define the proxies as
{ {
"exchange": { "exchange": {
"ccxt_config": { "ccxt_config": {
"aiohttp_proxy": "http://addr:port", "aiohttp_proxy": "http://addr:port",
"proxies": { "proxies": {
"http": "http://addr:port", "http": "http://addr:port",
"https": "http://addr:port" "https": "http://addr:port"
}, },
}
} }
} }
``` ```

View File

@ -74,3 +74,8 @@ Webhook terminology changed from "sell" to "exit", and from "buy" to "entry", re
* `webhooksell`, `webhookexit` -> `exit` * `webhooksell`, `webhookexit` -> `exit`
* `webhooksellfill`, `webhookexitfill` -> `exit_fill` * `webhooksellfill`, `webhookexitfill` -> `exit_fill`
* `webhooksellcancel`, `webhookexitcancel` -> `exit_cancel` * `webhooksellcancel`, `webhookexitcancel` -> `exit_cancel`
## Removal of `populate_any_indicators`
version 2023.3 saw the removal of `populate_any_indicators` in favor of split methods for feature engineering and targets. Please read the [migration document](strategy_migration.md#freqai-strategy) for full details.

View File

@ -24,7 +24,7 @@ This will spin up a local server (usually on port 8000) so you can see if everyt
To configure a development environment, you can either use the provided [DevContainer](#devcontainer-setup), or use the `setup.sh` script and answer "y" when asked "Do you want to install dependencies for dev [y/N]? ". To configure a development environment, you can either use the provided [DevContainer](#devcontainer-setup), or use the `setup.sh` script and answer "y" when asked "Do you want to install dependencies for dev [y/N]? ".
Alternatively (e.g. if your system is not supported by the setup.sh script), follow the manual installation process and run `pip3 install -e .[all]`. Alternatively (e.g. if your system is not supported by the setup.sh script), follow the manual installation process and run `pip3 install -e .[all]`.
This will install all required tools for development, including `pytest`, `flake8`, `mypy`, and `coveralls`. This will install all required tools for development, including `pytest`, `ruff`, `mypy`, and `coveralls`.
Then install the git hook scripts by running `pre-commit install`, so your changes will be verified locally before committing. Then install the git hook scripts by running `pre-commit install`, so your changes will be verified locally before committing.
This avoids a lot of waiting for CI already, as some basic formatting checks are done locally on your machine. This avoids a lot of waiting for CI already, as some basic formatting checks are done locally on your machine.
@ -363,7 +363,7 @@ from pathlib import Path
exchange = ccxt.binance({ exchange = ccxt.binance({
'apiKey': '<apikey>', 'apiKey': '<apikey>',
'secret': '<secret>' 'secret': '<secret>'
'options': {'defaultType': 'future'} 'options': {'defaultType': 'swap'}
}) })
_ = exchange.load_markets() _ = exchange.load_markets()

View File

@ -75,6 +75,25 @@ Binance has been split into 2, and users must use the correct ccxt exchange ID f
* [binance.com](https://www.binance.com/) - International users. Use exchange id: `binance`. * [binance.com](https://www.binance.com/) - International users. Use exchange id: `binance`.
* [binance.us](https://www.binance.us/) - US based users. Use exchange id: `binanceus`. * [binance.us](https://www.binance.us/) - US based users. Use exchange id: `binanceus`.
### Binance RSA keys
Freqtrade supports binance RSA API keys.
We recommend to use them as environment variable.
``` bash
export FREQTRADE__EXCHANGE__SECRET="$(cat ./rsa_binance.private)"
```
They can however also be configured via configuration file. Since json doesn't support multi-line strings, you'll have to replace all newlines with `\n` to have a valid json file.
``` json
// ...
"key": "<someapikey>",
"secret": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBABACAFQA<...>s8KX8=\n-----END PRIVATE KEY-----"
// ...
```
### Binance Futures ### Binance Futures
Binance has specific (unfortunately complex) [Futures Trading Quantitative Rules](https://www.binance.com/en/support/faq/4f462ebe6ff445d4a170be7d9e897272) which need to be followed, and which prohibit a too low stake-amount (among others) for too many orders. Binance has specific (unfortunately complex) [Futures Trading Quantitative Rules](https://www.binance.com/en/support/faq/4f462ebe6ff445d4a170be7d9e897272) which need to be followed, and which prohibit a too low stake-amount (among others) for too many orders.
@ -224,8 +243,8 @@ OKX requires a passphrase for each api key, you will therefore need to add this
OKX only provides 100 candles per api call. Therefore, the strategy will only have a pretty low amount of data available in backtesting mode. OKX only provides 100 candles per api call. Therefore, the strategy will only have a pretty low amount of data available in backtesting mode.
!!! Warning "Futures" !!! Warning "Futures"
OKX Futures has the concept of "position mode" - which can be Net or long/short (hedge mode). OKX Futures has the concept of "position mode" - which can be "Buy/Sell" or long/short (hedge mode).
Freqtrade supports both modes (we recommend to use net mode) - but changing the mode mid-trading is not supported and will lead to exceptions and failures to place trades. Freqtrade supports both modes (we recommend to use Buy/Sell mode) - but changing the mode mid-trading is not supported and will lead to exceptions and failures to place trades.
OKX also only provides MARK candles for the past ~3 months. Backtesting futures prior to that date will therefore lead to slight deviations, as funding-fees cannot be calculated correctly without this data. OKX also only provides MARK candles for the past ~3 months. Backtesting futures prior to that date will therefore lead to slight deviations, as funding-fees cannot be calculated correctly without this data.
## Gate.io ## Gate.io
@ -236,6 +255,18 @@ OKX requires a passphrase for each api key, you will therefore need to add this
Gate.io allows the use of `POINT` to pay for fees. As this is not a tradable currency (no regular market available), automatic fee calculations will fail (and default to a fee of 0). Gate.io allows the use of `POINT` to pay for fees. As this is not a tradable currency (no regular market available), automatic fee calculations will fail (and default to a fee of 0).
The configuration parameter `exchange.unknown_fee_rate` can be used to specify the exchange rate between Point and the stake currency. Obviously, changing the stake-currency will also require changes to this value. The configuration parameter `exchange.unknown_fee_rate` can be used to specify the exchange rate between Point and the stake currency. Obviously, changing the stake-currency will also require changes to this value.
## Bybit
Futures trading on bybit is currently supported for USDT markets, and will use isolated futures mode.
Users with unified accounts (there's no way back) can create a Sub-account which will start as "non-unified", and can therefore use isolated futures.
On startup, freqtrade will set the position mode to "One-way Mode" for the whole (sub)account. This avoids making this call over and over again (slowing down bot operations), but means that changes to this setting may result in exceptions and errors.
As bybit doesn't provide funding rate history, the dry-run calculation is used for live trades as well.
!!! Tip "Stoploss on Exchange"
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.
## All exchanges ## 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. 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.

View File

@ -2,7 +2,7 @@
## Supported Markets ## Supported Markets
Freqtrade supports spot trading only. Freqtrade supports spot trading, as well as (isolated) futures trading for some selected exchanges. Please refer to the [documentation start page](index.md#supported-futures-exchanges-experimental) for an uptodate list of supported exchanges.
### Can my bot open short positions? ### Can my bot open short positions?
@ -248,8 +248,26 @@ The Edge module is mostly a result of brainstorming of [@mishaker](https://githu
You can find further info on expectancy, win rate, risk management and position size in the following sources: You can find further info on expectancy, win rate, risk management and position size in the following sources:
- https://www.tradeciety.com/ultimate-math-guide-for-traders/ - https://www.tradeciety.com/ultimate-math-guide-for-traders/
- http://www.vantharp.com/tharp-concepts/expectancy.asp
- https://samuraitradingacademy.com/trading-expectancy/ - https://samuraitradingacademy.com/trading-expectancy/
- https://www.learningmarkets.com/determining-expectancy-in-your-trading/ - https://www.learningmarkets.com/determining-expectancy-in-your-trading/
- http://www.lonestocktrader.com/make-money-trading-positive-expectancy/ - https://www.lonestocktrader.com/make-money-trading-positive-expectancy/
- https://www.babypips.com/trading/trade-expectancy-matter - https://www.babypips.com/trading/trade-expectancy-matter
## Official channels
Freqtrade is using exclusively the following official channels:
* [Freqtrade discord server](https://discord.gg/p7nuUNVfP7)
* [Freqtrade documentation (https://freqtrade.io)](https://freqtrade.io)
* [Freqtrade github organization](https://github.com/freqtrade)
Nobody affiliated with the freqtrade project will ask you about your exchange keys or anything else exposing your funds to exploitation.
Should you be asked to expose your exchange keys or send funds to some random wallet, then please don't follow these instructions.
Failing to follow these guidelines will not be responsibility of freqtrade.
## "Freqtrade token"
Freqtrade does not have a Crypto token offering.
Token offerings you find on the internet referring Freqtrade, FreqAI or freqUI must be considered to be a scam, trying to exploit freqtrade's popularity for their own, nefarious gains.

View File

@ -9,7 +9,7 @@ FreqAI is configured through the typical [Freqtrade config file](configuration.m
```json ```json
"freqai": { "freqai": {
"enabled": true, "enabled": true,
"purge_old_models": true, "purge_old_models": 2,
"train_period_days": 30, "train_period_days": 30,
"backtest_period_days": 7, "backtest_period_days": 7,
"identifier" : "unique-id", "identifier" : "unique-id",
@ -43,116 +43,113 @@ The FreqAI strategy requires including the following lines of code in the standa
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# the model will return all labels created by user in `populate_any_indicators` # the model will return all labels created by user in `set_freqai_labels()`
# (& appended targets), an indication of whether or not the prediction should be accepted, # (& appended targets), an indication of whether or not the prediction should be accepted,
# the target mean/std values for each of the labels created by user in # the target mean/std values for each of the labels created by user in
# `populate_any_indicators()` for each training period. # `feature_engineering_*` for each training period.
dataframe = self.freqai.start(dataframe, metadata, self) dataframe = self.freqai.start(dataframe, metadata, self)
return dataframe return dataframe
def populate_any_indicators( def feature_engineering_expand_all(self, dataframe, period, **kwargs):
self, pair, df, tf, informative=None, set_generalized_indicators=False
):
""" """
Function designed to automatically generate, name and merge features *Only functional with FreqAI enabled strategies*
from user indicated timeframes in the configuration file. User controls the indicators This function will automatically expand the defined features on the config defined
passed to the training/prediction by prepending indicators with `'%-' + pair ` `indicator_periods_candles`, `include_timeframes`, `include_shifted_candles`, and
(see convention below). I.e. user should not prepend any supporting metrics `include_corr_pairs`. In other words, a single feature defined in this function
(e.g. bb_lowerband below) with % unless they explicitly want to pass that metric to the will automatically expand to a total of
model. `indicator_periods_candles` * `include_timeframes` * `include_shifted_candles` *
:param pair: pair to be used as informative `include_corr_pairs` numbers of features added to the model.
:param df: strategy dataframe which will receive merges from informatives
:param tf: timeframe of the dataframe which will modify the feature names All features must be prepended with `%` to be recognized by FreqAI internals.
:param informative: the dataframe associated with the informative pair
:param df: strategy dataframe which will receive the features
:param period: period of the indicator - usage example:
dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
""" """
if informative is None: dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
informative = self.dp.get_pair_dataframe(pair, tf) dataframe["%-mfi-period"] = ta.MFI(dataframe, timeperiod=period)
dataframe["%-adx-period"] = ta.ADX(dataframe, timeperiod=period)
dataframe["%-sma-period"] = ta.SMA(dataframe, timeperiod=period)
dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
# first loop is automatically duplicating indicators for time periods return dataframe
for t in self.freqai_info["feature_parameters"]["indicator_periods_candles"]:
t = int(t)
informative[f"%-{pair}rsi-period_{t}"] = ta.RSI(informative, timeperiod=t)
informative[f"%-{pair}mfi-period_{t}"] = ta.MFI(informative, timeperiod=t)
informative[f"%-{pair}adx-period_{t}"] = ta.ADX(informative, window=t)
indicators = [col for col in informative if col.startswith("%")] def feature_engineering_expand_basic(self, dataframe, **kwargs):
# This loop duplicates and shifts all indicators to add a sense of recency to data """
for n in range(self.freqai_info["feature_parameters"]["include_shifted_candles"] + 1): *Only functional with FreqAI enabled strategies*
if n == 0: This function will automatically expand the defined features on the config defined
continue `include_timeframes`, `include_shifted_candles`, and `include_corr_pairs`.
informative_shift = informative[indicators].shift(n) In other words, a single feature defined in this function
informative_shift = informative_shift.add_suffix("_shift-" + str(n)) will automatically expand to a total of
informative = pd.concat((informative, informative_shift), axis=1) `include_timeframes` * `include_shifted_candles` * `include_corr_pairs`
numbers of features added to the model.
df = merge_informative_pair(df, informative, self.config["timeframe"], tf, ffill=True) Features defined here will *not* be automatically duplicated on user defined
skip_columns = [ `indicator_periods_candles`
(s + "_" + tf) for s in ["date", "open", "high", "low", "close", "volume"]
]
df = df.drop(columns=skip_columns)
# Add generalized indicators here (because in live, it will call this All features must be prepended with `%` to be recognized by FreqAI internals.
# function to populate indicators during training). Notice how we ensure not to
# add them multiple times
if set_generalized_indicators:
# user adds targets here by prepending them with &- (see convention below) :param df: strategy dataframe which will receive the features
# If user wishes to use multiple targets, a multioutput prediction model dataframe["%-pct-change"] = dataframe["close"].pct_change()
# needs to be used such as templates/CatboostPredictionMultiModel.py dataframe["%-ema-200"] = ta.EMA(dataframe, timeperiod=200)
df["&-s_close"] = ( """
df["close"] dataframe["%-pct-change"] = dataframe["close"].pct_change()
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"]) dataframe["%-raw_volume"] = dataframe["volume"]
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"]) dataframe["%-raw_price"] = dataframe["close"]
.mean() return dataframe
/ df["close"]
- 1 def feature_engineering_standard(self, dataframe, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
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 created by all other
freqai_feature_engineering_* functions.
This function is a good place to do custom exotic feature extractions (e.g. tsfresh).
This function is a good place for any feature that should not be auto-expanded upon
(e.g. day of the week).
All features must be prepended with `%` to be recognized by FreqAI internals.
:param df: strategy dataframe which will receive the features
usage example: dataframe["%-day_of_week"] = (dataframe["date"].dt.dayofweek + 1) / 7
"""
dataframe["%-day_of_week"] = (dataframe["date"].dt.dayofweek + 1) / 7
dataframe["%-hour_of_day"] = (dataframe["date"].dt.hour + 1) / 25
return dataframe
def set_freqai_targets(self, dataframe, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
Required function to set the targets for the model.
All targets must be prepended with `&` to be recognized by the FreqAI internals.
:param df: strategy dataframe which will receive the targets
usage example: dataframe["&-target"] = dataframe["close"].shift(-1) / dataframe["close"]
"""
dataframe["&-s_close"] = (
dataframe["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ dataframe["close"]
- 1
) )
return df
``` ```
Notice how the `populate_any_indicators()` is where [features](freqai-feature-engineering.md#feature-engineering) and labels/targets are added. A full example strategy is available in `templates/FreqaiExampleStrategy.py`. Notice how the `feature_engineering_*()` is where [features](freqai-feature-engineering.md#feature-engineering) are added. Meanwhile `set_freqai_targets()` adds the labels/targets. A full example strategy is available in `templates/FreqaiExampleStrategy.py`.
Notice also the location of the labels under `if set_generalized_indicators:` at the bottom of the example. This is where single features and labels/targets should be added to the feature set to avoid duplication of them from various configuration parameters that multiply the feature set, such as `include_timeframes`.
!!! Note !!! Note
The `self.freqai.start()` function cannot be called outside the `populate_indicators()`. The `self.freqai.start()` function cannot be called outside the `populate_indicators()`.
!!! Note !!! Note
Features **must** be defined in `populate_any_indicators()`. Defining FreqAI features in `populate_indicators()` Features **must** be defined in `feature_engineering_*()`. Defining FreqAI features in `populate_indicators()`
will cause the algorithm to fail in live/dry mode. In order to add generalized features that are not associated with a specific pair or timeframe, the following structure inside `populate_any_indicators()` should be used will cause the algorithm to fail in live/dry mode. In order to add generalized features that are not associated with a specific pair or timeframe, you should use `feature_engineering_standard()`
(as exemplified in `freqtrade/templates/FreqaiExampleStrategy.py`): (as exemplified in `freqtrade/templates/FreqaiExampleStrategy.py`).
```python
def populate_any_indicators(self, pair, df, tf, informative=None, set_generalized_indicators=False):
...
# Add generalized indicators here (because in live, it will call only this function to populate
# indicators for retraining). Notice how we ensure not to add them multiple times by associating
# these generalized indicators to the basepair/timeframe
if set_generalized_indicators:
df['%-day_of_week'] = (df["date"].dt.dayofweek + 1) / 7
df['%-hour_of_day'] = (df['date'].dt.hour + 1) / 25
# user adds targets here by prepending them with &- (see convention below)
# If user wishes to use multiple targets, a multioutput prediction model
# needs to be used such as templates/CatboostPredictionMultiModel.py
df["&-s_close"] = (
df["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ df["close"]
- 1
)
```
Please see the example script located in `freqtrade/templates/FreqaiExampleStrategy.py` for a full example of `populate_any_indicators()`.
## Important dataframe key patterns ## Important dataframe key patterns
@ -160,18 +157,18 @@ Below are the values you can expect to include/use inside a typical strategy dat
| DataFrame Key | Description | | DataFrame Key | Description |
|------------|-------------| |------------|-------------|
| `df['&*']` | Any dataframe column prepended with `&` in `populate_any_indicators()` is treated as a training target (label) inside FreqAI (typically following the naming convention `&-s*`). For example, to predict the close price 40 candles into the future, you would set `df['&-s_close'] = df['close'].shift(-self.freqai_info["feature_parameters"]["label_period_candles"])` with `"label_period_candles": 40` in the config. FreqAI makes the predictions and gives them back under the same key (`df['&-s_close']`) to be used in `populate_entry/exit_trend()`. <br> **Datatype:** Depends on the output of the model. | `df['&*']` | Any dataframe column prepended with `&` in `set_freqai_targets()` is treated as a training target (label) inside FreqAI (typically following the naming convention `&-s*`). For example, to predict the close price 40 candles into the future, you would set `df['&-s_close'] = df['close'].shift(-self.freqai_info["feature_parameters"]["label_period_candles"])` with `"label_period_candles": 40` in the config. FreqAI makes the predictions and gives them back under the same key (`df['&-s_close']`) to be used in `populate_entry/exit_trend()`. <br> **Datatype:** Depends on the output of the model.
| `df['&*_std/mean']` | Standard deviation and mean values of the defined labels during training (or live tracking with `fit_live_predictions_candles`). Commonly used to understand the rarity of a prediction (use the z-score as shown in `templates/FreqaiExampleStrategy.py` and explained [here](#creating-a-dynamic-target-threshold) to evaluate how often a particular prediction was observed during training or historically with `fit_live_predictions_candles`). <br> **Datatype:** Float. | `df['&*_std/mean']` | Standard deviation and mean values of the defined labels during training (or live tracking with `fit_live_predictions_candles`). Commonly used to understand the rarity of a prediction (use the z-score as shown in `templates/FreqaiExampleStrategy.py` and explained [here](#creating-a-dynamic-target-threshold) to evaluate how often a particular prediction was observed during training or historically with `fit_live_predictions_candles`). <br> **Datatype:** Float.
| `df['do_predict']` | Indication of an outlier data point. The return value is integer between -2 and 2, which lets you know if the prediction is trustworthy or not. `do_predict==1` means that the prediction is trustworthy. If the Dissimilarity Index (DI, see details [here](freqai-feature-engineering.md#identifying-outliers-with-the-dissimilarity-index-di)) of the input data point is above the threshold defined in the config, FreqAI will subtract 1 from `do_predict`, resulting in `do_predict==0`. If `use_SVM_to_remove_outliers()` is active, the Support Vector Machine (SVM, see details [here](freqai-feature-engineering.md#identifying-outliers-using-a-support-vector-machine-svm)) may also detect outliers in training and prediction data. In this case, the SVM will also subtract 1 from `do_predict`. If the input data point was considered an outlier by the SVM but not by the DI, or vice versa, the result will be `do_predict==0`. If both the DI and the SVM considers the input data point to be an outlier, the result will be `do_predict==-1`. As with the SVM, if `use_DBSCAN_to_remove_outliers` is active, DBSCAN (see details [here](freqai-feature-engineering.md#identifying-outliers-with-dbscan)) may also detect outliers and subtract 1 from `do_predict`. Hence, if both the SVM and DBSCAN are active and identify a datapoint that was above the DI threshold as an outlier, the result will be `do_predict==-2`. A particular case is when `do_predict == 2`, which means that the model has expired due to exceeding `expired_hours`. <br> **Datatype:** Integer between -2 and 2. | `df['do_predict']` | Indication of an outlier data point. The return value is integer between -2 and 2, which lets you know if the prediction is trustworthy or not. `do_predict==1` means that the prediction is trustworthy. If the Dissimilarity Index (DI, see details [here](freqai-feature-engineering.md#identifying-outliers-with-the-dissimilarity-index-di)) of the input data point is above the threshold defined in the config, FreqAI will subtract 1 from `do_predict`, resulting in `do_predict==0`. If `use_SVM_to_remove_outliers()` is active, the Support Vector Machine (SVM, see details [here](freqai-feature-engineering.md#identifying-outliers-using-a-support-vector-machine-svm)) may also detect outliers in training and prediction data. In this case, the SVM will also subtract 1 from `do_predict`. If the input data point was considered an outlier by the SVM but not by the DI, or vice versa, the result will be `do_predict==0`. If both the DI and the SVM considers the input data point to be an outlier, the result will be `do_predict==-1`. As with the SVM, if `use_DBSCAN_to_remove_outliers` is active, DBSCAN (see details [here](freqai-feature-engineering.md#identifying-outliers-with-dbscan)) may also detect outliers and subtract 1 from `do_predict`. Hence, if both the SVM and DBSCAN are active and identify a datapoint that was above the DI threshold as an outlier, the result will be `do_predict==-2`. A particular case is when `do_predict == 2`, which means that the model has expired due to exceeding `expired_hours`. <br> **Datatype:** Integer between -2 and 2.
| `df['DI_values']` | Dissimilarity Index (DI) values are proxies for the level of confidence FreqAI has in the prediction. A lower DI means the prediction is close to the training data, i.e., higher prediction confidence. See details about the DI [here](freqai-feature-engineering.md#identifying-outliers-with-the-dissimilarity-index-di). <br> **Datatype:** Float. | `df['DI_values']` | Dissimilarity Index (DI) values are proxies for the level of confidence FreqAI has in the prediction. A lower DI means the prediction is close to the training data, i.e., higher prediction confidence. See details about the DI [here](freqai-feature-engineering.md#identifying-outliers-with-the-dissimilarity-index-di). <br> **Datatype:** Float.
| `df['%*']` | Any dataframe column prepended with `%` in `populate_any_indicators()` is treated as a training feature. For example, you can include the RSI in the training feature set (similar to in `templates/FreqaiExampleStrategy.py`) by setting `df['%-rsi']`. See more details on how this is done [here](freqai-feature-engineering.md). <br> **Note:** Since the number of features prepended with `%` can multiply very quickly (10s of thousands of features are easily engineered using the multiplictative functionality of, e.g., `include_shifted_candles` and `include_timeframes` as described in the [parameter table](freqai-parameter-table.md)), these features are removed from the dataframe that is returned from FreqAI to the strategy. To keep a particular type of feature for plotting purposes, you would prepend it with `%%`. <br> **Datatype:** Depends on the output of the model. | `df['%*']` | Any dataframe column prepended with `%` in `feature_engineering_*()` is treated as a training feature. For example, you can include the RSI in the training feature set (similar to in `templates/FreqaiExampleStrategy.py`) by setting `df['%-rsi']`. See more details on how this is done [here](freqai-feature-engineering.md). <br> **Note:** Since the number of features prepended with `%` can multiply very quickly (10s of thousands of features are easily engineered using the multiplictative functionality of, e.g., `include_shifted_candles` and `include_timeframes` as described in the [parameter table](freqai-parameter-table.md)), these features are removed from the dataframe that is returned from FreqAI to the strategy. To keep a particular type of feature for plotting purposes, you would prepend it with `%%`. <br> **Datatype:** Depends on the output of the model.
## Setting the `startup_candle_count` ## Setting the `startup_candle_count`
The `startup_candle_count` in the FreqAI strategy needs to be set up in the same way as in the standard Freqtrade strategy (see details [here](strategy-customization.md#strategy-startup-period)). This value is used by Freqtrade to ensure that a sufficient amount of data is provided when calling the `dataprovider`, to avoid any NaNs at the beginning of the first training. You can easily set this value by identifying the longest period (in candle units) which is passed to the indicator creation functions (e.g., Ta-Lib functions). In the presented example, `startup_candle_count` is 20 since this is the maximum value in `indicators_periods_candles`. The `startup_candle_count` in the FreqAI strategy needs to be set up in the same way as in the standard Freqtrade strategy (see details [here](strategy-customization.md#strategy-startup-period)). This value is used by Freqtrade to ensure that a sufficient amount of data is provided when calling the `dataprovider`, to avoid any NaNs at the beginning of the first training. You can easily set this value by identifying the longest period (in candle units) which is passed to the indicator creation functions (e.g., TA-Lib functions). In the presented example, `startup_candle_count` is 20 since this is the maximum value in `indicators_periods_candles`.
!!! Note !!! Note
There are instances where the Ta-Lib functions actually require more data than just the passed `period` or else the feature dataset gets populated with NaNs. Anecdotally, multiplying the `startup_candle_count` by 2 always leads to a fully NaN free training dataset. Hence, it is typically safest to multiply the expected `startup_candle_count` by 2. Look out for this log message to confirm that the data is clean: There are instances where the TA-Lib functions actually require more data than just the passed `period` or else the feature dataset gets populated with NaNs. Anecdotally, multiplying the `startup_candle_count` by 2 always leads to a fully NaN free training dataset. Hence, it is typically safest to multiply the expected `startup_candle_count` by 2. Look out for this log message to confirm that the data is clean:
``` ```
2022-08-31 15:14:04 - freqtrade.freqai.data_kitchen - INFO - dropped 0 training points due to NaNs in populated dataset 4319. 2022-08-31 15:14:04 - freqtrade.freqai.data_kitchen - INFO - dropped 0 training points due to NaNs in populated dataset 4319.
@ -208,7 +205,7 @@ All of the aforementioned model libraries implement gradient boosted decision tr
* LightGBM: https://lightgbm.readthedocs.io/en/v3.3.2/# * LightGBM: https://lightgbm.readthedocs.io/en/v3.3.2/#
* XGBoost: https://xgboost.readthedocs.io/en/stable/# * XGBoost: https://xgboost.readthedocs.io/en/stable/#
There are also numerous online articles describing and comparing the algorithms. Some relatively light-weight examples would be [CatBoost vs. LightGBM vs. XGBoost — Which is the best algorithm?](https://towardsdatascience.com/catboost-vs-lightgbm-vs-xgboost-c80f40662924#:~:text=In%20CatBoost%2C%20symmetric%20trees%2C%20or,the%20same%20depth%20can%20differ.) and [XGBoost, LightGBM or CatBoost — which boosting algorithm should I use?](https://medium.com/riskified-technology/xgboost-lightgbm-or-catboost-which-boosting-algorithm-should-i-use-e7fda7bb36bc). Keep in mind that the performance of each model is highly dependent on the application and so any reported metrics might not be true for your particular use of the model. There are also numerous online articles describing and comparing the algorithms. Some relatively lightweight examples would be [CatBoost vs. LightGBM vs. XGBoost — Which is the best algorithm?](https://towardsdatascience.com/catboost-vs-lightgbm-vs-xgboost-c80f40662924#:~:text=In%20CatBoost%2C%20symmetric%20trees%2C%20or,the%20same%20depth%20can%20differ.) and [XGBoost, LightGBM or CatBoost — which boosting algorithm should I use?](https://medium.com/riskified-technology/xgboost-lightgbm-or-catboost-which-boosting-algorithm-should-i-use-e7fda7bb36bc). Keep in mind that the performance of each model is highly dependent on the application and so any reported metrics might not be true for your particular use of the model.
Apart from the models already available in FreqAI, it is also possible to customize and create your own prediction models using the `IFreqaiModel` class. You are encouraged to inherit `fit()`, `train()`, and `predict()` to customize various aspects of the training procedures. You can place custom FreqAI models in `user_data/freqaimodels` - and freqtrade will pick them up from there based on the provided `--freqaimodel` name - which has to correspond to the class name of your custom model. Apart from the models already available in FreqAI, it is also possible to customize and create your own prediction models using the `IFreqaiModel` class. You are encouraged to inherit `fit()`, `train()`, and `predict()` to customize various aspects of the training procedures. You can place custom FreqAI models in `user_data/freqaimodels` - and freqtrade will pick them up from there based on the provided `--freqaimodel` name - which has to correspond to the class name of your custom model.
Make sure to use unique names to avoid overriding built-in models. Make sure to use unique names to avoid overriding built-in models.
@ -239,3 +236,161 @@ If you want to predict multiple targets you must specify all labels in the same
df['&s-up_or_down'] = np.where( df["close"].shift(-100) > df["close"], 'up', 'down') df['&s-up_or_down'] = np.where( df["close"].shift(-100) > df["close"], 'up', 'down')
df['&s-up_or_down'] = np.where( df["close"].shift(-100) == df["close"], 'same', df['&s-up_or_down']) df['&s-up_or_down'] = np.where( df["close"].shift(-100) == df["close"], 'same', df['&s-up_or_down'])
``` ```
## PyTorch Module
### Quick start
The easiest way to quickly run a pytorch model is with the following command (for regression task):
```bash
freqtrade trade --config config_examples/config_freqai.example.json --strategy FreqaiExampleStrategy --freqaimodel PyTorchMLPRegressor --strategy-path freqtrade/templates
```
!!! note "Installation/docker"
The PyTorch module requires large packages such as `torch`, which should be explicitly requested during `./setup.sh -i` by answering "y" to the question "Do you also want dependencies for freqai-rl or PyTorch (~700mb additional space required) [y/N]?".
Users who prefer docker should ensure they use the docker image appended with `_freqaitorch`.
### Structure
#### Model
You can construct your own Neural Network architecture in PyTorch by simply defining your `nn.Module` class inside your custom [`IFreqaiModel` file](#using-different-prediction-models) and then using that class in your `def train()` function. Here is an example of logistic regression model implementation using PyTorch (should be used with nn.BCELoss criterion) for classification tasks.
```python
class LogisticRegression(nn.Module):
def __init__(self, input_size: int):
super().__init__()
# Define your layers
self.linear = nn.Linear(input_size, 1)
self.activation = nn.Sigmoid()
def forward(self, x: torch.Tensor) -> torch.Tensor:
# Define the forward pass
out = self.linear(x)
out = self.activation(out)
return out
class MyCoolPyTorchClassifier(BasePyTorchClassifier):
"""
This is a custom IFreqaiModel showing how a user might setup their own
custom Neural Network architecture for their training.
"""
@property
def data_convertor(self) -> PyTorchDataConvertor:
return DefaultPyTorchDataConvertor(target_tensor_type=torch.float)
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
config = self.freqai_info.get("model_training_parameters", {})
self.learning_rate: float = config.get("learning_rate", 3e-4)
self.model_kwargs: Dict[str, Any] = config.get("model_kwargs", {})
self.trainer_kwargs: Dict[str, Any] = config.get("trainer_kwargs", {})
def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
"""
User sets up the training and test data to fit their desired model here
:param data_dictionary: the dictionary holding all data for train, test,
labels, weights
:param dk: The datakitchen object for the current coin/model
"""
class_names = self.get_class_names()
self.convert_label_column_to_int(data_dictionary, dk, class_names)
n_features = data_dictionary["train_features"].shape[-1]
model = LogisticRegression(
input_dim=n_features
)
model.to(self.device)
optimizer = torch.optim.AdamW(model.parameters(), lr=self.learning_rate)
criterion = torch.nn.CrossEntropyLoss()
init_model = self.get_init_model(dk.pair)
trainer = PyTorchModelTrainer(
model=model,
optimizer=optimizer,
criterion=criterion,
model_meta_data={"class_names": class_names},
device=self.device,
init_model=init_model,
data_convertor=self.data_convertor,
**self.trainer_kwargs,
)
trainer.fit(data_dictionary, self.splits)
return trainer
```
#### Trainer
The `PyTorchModelTrainer` performs the idiomatic PyTorch train loop:
Define our model, loss function, and optimizer, and then move them to the appropriate device (GPU or CPU). Inside the loop, we iterate through the batches in the dataloader, move the data to the device, compute the prediction and loss, backpropagate, and update the model parameters using the optimizer.
In addition, the trainer is responsible for the following:
- saving and loading the model
- converting the data from `pandas.DataFrame` to `torch.Tensor`.
#### Integration with Freqai module
Like all freqai models, PyTorch models inherit `IFreqaiModel`. `IFreqaiModel` declares three abstract methods: `train`, `fit`, and `predict`. we implement these methods in three levels of hierarchy.
From top to bottom:
1. `BasePyTorchModel` - Implements the `train` method. all `BasePyTorch*` inherit it. responsible for general data preparation (e.g., data normalization) and calling the `fit` method. Sets `device` attribute used by children classes. Sets `model_type` attribute used by the parent class.
2. `BasePyTorch*` - Implements the `predict` method. Here, the `*` represents a group of algorithms, such as classifiers or regressors. responsible for data preprocessing, predicting, and postprocessing if needed.
3. `PyTorch*Classifier` / `PyTorch*Regressor` - implements the `fit` method. responsible for the main train flaw, where we initialize the trainer and model objects.
![image](assets/freqai_pytorch-diagram.png)
#### Full example
Building a PyTorch regressor using MLP (multilayer perceptron) model, MSELoss criterion, and AdamW optimizer.
```python
class PyTorchMLPRegressor(BasePyTorchRegressor):
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
config = self.freqai_info.get("model_training_parameters", {})
self.learning_rate: float = config.get("learning_rate", 3e-4)
self.model_kwargs: Dict[str, Any] = config.get("model_kwargs", {})
self.trainer_kwargs: Dict[str, Any] = config.get("trainer_kwargs", {})
def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
n_features = data_dictionary["train_features"].shape[-1]
model = PyTorchMLPModel(
input_dim=n_features,
output_dim=1,
**self.model_kwargs
)
model.to(self.device)
optimizer = torch.optim.AdamW(model.parameters(), lr=self.learning_rate)
criterion = torch.nn.MSELoss()
init_model = self.get_init_model(dk.pair)
trainer = PyTorchModelTrainer(
model=model,
optimizer=optimizer,
criterion=criterion,
device=self.device,
init_model=init_model,
target_tensor_type=torch.float,
**self.trainer_kwargs,
)
trainer.fit(data_dictionary)
return trainer
```
Here we create a `PyTorchMLPRegressor` class that implements the `fit` method. The `fit` method specifies the training building blocks: model, optimizer, criterion, and trainer. We inherit both `BasePyTorchRegressor` and `BasePyTorchModel`, where the former implements the `predict` method that is suitable for our regression task, and the latter implements the train method.
??? Note "Setting Class Names for Classifiers"
When using classifiers, the user must declare the class names (or targets) by overriding the `IFreqaiModel.class_names` attribute. This is achieved by setting `self.freqai.class_names` in the FreqAI strategy inside the `set_freqai_targets` method.
For example, if you are using a binary classifier to predict price movements as up or down, you can set the class names as follows:
```python
def set_freqai_targets(self, dataframe: DataFrame, metadata: Dict, **kwargs):
self.freqai.class_names = ["down", "up"]
dataframe['&s-up_or_down'] = np.where(dataframe["close"].shift(-100) >
dataframe["close"], 'up', 'down')
return dataframe
```
To see a full example, you can refer to the [classifier test strategy class](https://github.com/freqtrade/freqtrade/blob/develop/tests/strategy/strats/freqai_test_classifier.py).

View File

@ -2,96 +2,150 @@
## Defining the features ## Defining the features
Low level feature engineering is performed in the user strategy within a function called `populate_any_indicators()`. That function sets the `base features` such as, `RSI`, `MFI`, `EMA`, `SMA`, time of day, volume, etc. The `base features` can be custom indicators or they can be imported from any technical-analysis library that you can find. One important syntax rule is that all `base features` string names are prepended with `%-{pair}`, while labels/targets are prepended with `&`. Low level feature engineering is performed in the user strategy within a set of functions called `feature_engineering_*`. These function set the `base features` such as, `RSI`, `MFI`, `EMA`, `SMA`, time of day, volume, etc. The `base features` can be custom indicators or they can be imported from any technical-analysis library that you can find. FreqAI is equipped with a set of functions to simplify rapid large-scale feature engineering:
!!! Note | Function | Description |
Adding the full pair string, e.g. XYZ/USD, in the feature name enables improved performance for dataframe caching on the backend. If you decide *not* to add the full pair string in the feature string, FreqAI will operate in a reduced performance mode. |---------------|-------------|
| `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_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.
Meanwhile, high level feature engineering is handled within `"feature_parameters":{}` in the FreqAI config. Within this file, it is possible to decide large scale feature expansions on top of the `base_features` such as "including correlated pairs" or "including informative timeframes" or even "including recent candles." Meanwhile, high level feature engineering is handled within `"feature_parameters":{}` in the FreqAI config. Within this file, it is possible to decide large scale feature expansions on top of the `base_features` such as "including correlated pairs" or "including informative timeframes" or even "including recent candles."
It is advisable to start from the template `populate_any_indicators()` in the source provided example strategy (found in `templates/FreqaiExampleStrategy.py`) to ensure that the feature definitions are following the correct conventions. Here is an example of how to set the indicators and labels in the strategy: It is advisable to start from the template `feature_engineering_*` functions in the source provided example strategy (found in `templates/FreqaiExampleStrategy.py`) to ensure that the feature definitions are following the correct conventions. Here is an example of how to set the indicators and labels in the strategy:
```python ```python
def populate_any_indicators( def feature_engineering_expand_all(self, dataframe, period, metadata, **kwargs):
self, pair, df, tf, informative=None, set_generalized_indicators=False
):
""" """
Function designed to automatically generate, name, and merge features *Only functional with FreqAI enabled strategies*
from user-indicated timeframes in the configuration file. The user controls the indicators This function will automatically expand the defined features on the config defined
passed to the training/prediction by prepending indicators with `'%-' + pair ` `indicator_periods_candles`, `include_timeframes`, `include_shifted_candles`, and
(see convention below). I.e., the user should not prepend any supporting metrics `include_corr_pairs`. In other words, a single feature defined in this function
(e.g., bb_lowerband below) with % unless they explicitly want to pass that metric to the will automatically expand to a total of
model. `indicator_periods_candles` * `include_timeframes` * `include_shifted_candles` *
:param pair: pair to be used as informative `include_corr_pairs` numbers of features added to the model.
:param df: strategy dataframe which will receive merges from informatives
:param tf: timeframe of the dataframe which will modify the feature names All features must be prepended with `%` to be recognized by FreqAI internals.
:param informative: the dataframe associated with the informative pair
Access metadata such as the current pair/timeframe/period with:
`metadata["pair"]` `metadata["tf"]` `metadata["period"]`
:param df: strategy dataframe which will receive the features
:param period: period of the indicator - usage example:
:param metadata: metadata of current pair
dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
""" """
if informative is None: dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
informative = self.dp.get_pair_dataframe(pair, tf) dataframe["%-mfi-period"] = ta.MFI(dataframe, timeperiod=period)
dataframe["%-adx-period"] = ta.ADX(dataframe, timeperiod=period)
dataframe["%-sma-period"] = ta.SMA(dataframe, timeperiod=period)
dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
# first loop is automatically duplicating indicators for time periods bollinger = qtpylib.bollinger_bands(
for t in self.freqai_info["feature_parameters"]["indicator_periods_candles"]: qtpylib.typical_price(dataframe), window=period, stds=2.2
t = int(t) )
informative[f"%-{pair}rsi-period_{t}"] = ta.RSI(informative, timeperiod=t) dataframe["bb_lowerband-period"] = bollinger["lower"]
informative[f"%-{pair}mfi-period_{t}"] = ta.MFI(informative, timeperiod=t) dataframe["bb_middleband-period"] = bollinger["mid"]
informative[f"%-{pair}adx-period_{t}"] = ta.ADX(informative, window=t) dataframe["bb_upperband-period"] = bollinger["upper"]
bollinger = qtpylib.bollinger_bands( dataframe["%-bb_width-period"] = (
qtpylib.typical_price(informative), window=t, stds=2.2 dataframe["bb_upperband-period"]
- dataframe["bb_lowerband-period"]
) / dataframe["bb_middleband-period"]
dataframe["%-close-bb_lower-period"] = (
dataframe["close"] / dataframe["bb_lowerband-period"]
)
dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period)
dataframe["%-relative_volume-period"] = (
dataframe["volume"] / dataframe["volume"].rolling(period).mean()
)
return dataframe
def feature_engineering_expand_basic(self, dataframe, metadata, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
This function will automatically expand the defined features on the config defined
`include_timeframes`, `include_shifted_candles`, and `include_corr_pairs`.
In other words, a single feature defined in this function
will automatically expand to a total of
`include_timeframes` * `include_shifted_candles` * `include_corr_pairs`
numbers of features added to the model.
Features defined here will *not* be automatically duplicated on user defined
`indicator_periods_candles`
Access metadata such as the current pair/timeframe with:
`metadata["pair"]` `metadata["tf"]`
All features must be prepended with `%` to be recognized by FreqAI internals.
:param df: strategy dataframe which will receive the features
:param metadata: metadata of current pair
dataframe["%-pct-change"] = dataframe["close"].pct_change()
dataframe["%-ema-200"] = ta.EMA(dataframe, timeperiod=200)
"""
dataframe["%-pct-change"] = dataframe["close"].pct_change()
dataframe["%-raw_volume"] = dataframe["volume"]
dataframe["%-raw_price"] = dataframe["close"]
return dataframe
def feature_engineering_standard(self, dataframe, metadata, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
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 created by all other
freqai_feature_engineering_* functions.
This function is a good place to do custom exotic feature extractions (e.g. tsfresh).
This function is a good place for any feature that should not be auto-expanded upon
(e.g. day of the week).
Access metadata such as the current pair with:
`metadata["pair"]`
All features must be prepended with `%` to be recognized by FreqAI internals.
:param df: strategy dataframe which will receive the features
:param metadata: metadata of current pair
usage example: dataframe["%-day_of_week"] = (dataframe["date"].dt.dayofweek + 1) / 7
"""
dataframe["%-day_of_week"] = (dataframe["date"].dt.dayofweek + 1) / 7
dataframe["%-hour_of_day"] = (dataframe["date"].dt.hour + 1) / 25
return dataframe
def set_freqai_targets(self, dataframe, metadata, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
Required function to set the targets for the model.
All targets must be prepended with `&` to be recognized by the FreqAI internals.
Access metadata such as the current pair with:
`metadata["pair"]`
:param df: strategy dataframe which will receive the targets
:param metadata: metadata of current pair
usage example: dataframe["&-target"] = dataframe["close"].shift(-1) / dataframe["close"]
"""
dataframe["&-s_close"] = (
dataframe["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ dataframe["close"]
- 1
) )
informative[f"{pair}bb_lowerband-period_{t}"] = bollinger["lower"]
informative[f"{pair}bb_middleband-period_{t}"] = bollinger["mid"] return dataframe
informative[f"{pair}bb_upperband-period_{t}"] = bollinger["upper"]
informative[f"%-{pair}bb_width-period_{t}"] = (
informative[f"{pair}bb_upperband-period_{t}"]
- informative[f"{pair}bb_lowerband-period_{t}"]
) / informative[f"{pair}bb_middleband-period_{t}"]
informative[f"%-{pair}close-bb_lower-period_{t}"] = (
informative["close"] / informative[f"{pair}bb_lowerband-period_{t}"]
)
informative[f"%-{pair}relative_volume-period_{t}"] = (
informative["volume"] / informative["volume"].rolling(t).mean()
)
indicators = [col for col in informative if col.startswith("%")]
# This loop duplicates and shifts all indicators to add a sense of recency to data
for n in range(self.freqai_info["feature_parameters"]["include_shifted_candles"] + 1):
if n == 0:
continue
informative_shift = informative[indicators].shift(n)
informative_shift = informative_shift.add_suffix("_shift-" + str(n))
informative = pd.concat((informative, informative_shift), axis=1)
df = merge_informative_pair(df, informative, self.config["timeframe"], tf, ffill=True)
skip_columns = [
(s + "_" + tf) for s in ["date", "open", "high", "low", "close", "volume"]
]
df = df.drop(columns=skip_columns)
# Add generalized indicators here (because in live, it will call this
# function to populate indicators during training). Notice how we ensure not to
# add them multiple times
if set_generalized_indicators:
df["%-day_of_week"] = (df["date"].dt.dayofweek + 1) / 7
df["%-hour_of_day"] = (df["date"].dt.hour + 1) / 25
# user adds targets here by prepending them with &- (see convention below)
# If user wishes to use multiple targets, a multioutput prediction model
# needs to be used such as templates/CatboostPredictionMultiModel.py
df["&-s_close"] = (
df["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ df["close"]
- 1
)
return df
``` ```
In the presented example, the user does not wish to pass the `bb_lowerband` as a feature to the model, In the presented example, the user does not wish to pass the `bb_lowerband` as a feature to the model,
@ -118,15 +172,28 @@ After having defined the `base features`, the next step is to expand upon them u
} }
``` ```
The `include_timeframes` in the config above are the timeframes (`tf`) of each call to `populate_any_indicators()` in the strategy. In the presented case, the user is asking for the `5m`, `15m`, and `4h` timeframes of the `rsi`, `mfi`, `roc`, and `bb_width` to be included in the feature set. The `include_timeframes` in the config above are the timeframes (`tf`) of each call to `feature_engineering_expand_*()` in the strategy. In the presented case, the user is asking for the `5m`, `15m`, and `4h` timeframes of the `rsi`, `mfi`, `roc`, and `bb_width` to be included in the feature set.
You can ask for each of the defined features to be included also for informative pairs using the `include_corr_pairlist`. This means that the feature set will include all the features from `populate_any_indicators` on all the `include_timeframes` for each of the correlated pairs defined in the config (`ETH/USD`, `LINK/USD`, and `BNB/USD` in the presented example). You can ask for each of the defined features to be included also for informative pairs using the `include_corr_pairlist`. This means that the feature set will include all the features from `feature_engineering_expand_*()` on all the `include_timeframes` for each of the correlated pairs defined in the config (`ETH/USD`, `LINK/USD`, and `BNB/USD` in the presented example).
`include_shifted_candles` indicates the number of previous candles to include in the feature set. For example, `include_shifted_candles: 2` tells FreqAI to include the past 2 candles for each of the features in the feature set. `include_shifted_candles` indicates the number of previous candles to include in the feature set. For example, `include_shifted_candles: 2` tells FreqAI to include the past 2 candles for each of the features in the feature set.
In total, the number of features the user of the presented example strat has created is: length of `include_timeframes` * no. features in `populate_any_indicators()` * length of `include_corr_pairlist` * no. `include_shifted_candles` * length of `indicator_periods_candles` In total, the number of features the user of the presented example strat has created is: length of `include_timeframes` * no. features in `feature_engineering_expand_*()` * length of `include_corr_pairlist` * no. `include_shifted_candles` * length of `indicator_periods_candles`
$= 3 * 3 * 3 * 2 * 2 = 108$. $= 3 * 3 * 3 * 2 * 2 = 108$.
### Gain finer control over `feature_engineering_*` functions with `metadata`
All `feature_engineering_*` and `set_freqai_targets()` functions are passed a `metadata` dictionary which contains information about the `pair`, `tf` (timeframe), and `period` that FreqAI is automating for feature building. As such, a user can use `metadata` inside `feature_engineering_*` functions as criteria for blocking/reserving features for certain timeframes, periods, pairs etc.
```python
def feature_engineering_expand_all(self, dataframe, period, metadata, **kwargs):
if metadata["tf"] == "1h":
dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period)
```
This will block `ta.ROC()` from being added to any timeframes other than `"1h"`.
### Returning additional info from training ### Returning additional info from training
Important metrics can be returned to the strategy at the end of each model training by assigning them to `dk.data['extra_returns_per_train']['my_new_value'] = XYZ` inside the custom prediction model class. Important metrics can be returned to the strategy at the end of each model training by assigning them to `dk.data['extra_returns_per_train']['my_new_value'] = XYZ` inside the custom prediction model class.
@ -167,7 +234,7 @@ This will perform PCA on the features and reduce their dimensionality so that th
## Inlier metric ## Inlier metric
The `inlier_metric` is a metric aimed at quantifying how similar a the features of a data point are to the most recent historic data points. The `inlier_metric` is a metric aimed at quantifying how similar the features of a data point are to the most recent historical data points.
You define the lookback window by setting `inlier_metric_window` and FreqAI computes the distance between the present time point and each of the previous `inlier_metric_window` lookback points. A Weibull function is fit to each of the lookback distributions and its cumulative distribution function (CDF) is used to produce a quantile for each lookback point. The `inlier_metric` is then computed for each time point as the average of the corresponding lookback quantiles. The figure below explains the concept for an `inlier_metric_window` of 5. You define the lookback window by setting `inlier_metric_window` and FreqAI computes the distance between the present time point and each of the previous `inlier_metric_window` lookback points. A Weibull function is fit to each of the lookback distributions and its cumulative distribution function (CDF) is used to produce a quantile for each lookback point. The `inlier_metric` is then computed for each time point as the average of the corresponding lookback quantiles. The figure below explains the concept for an `inlier_metric_window` of 5.

View File

@ -15,10 +15,9 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| `identifier` | **Required.** <br> A unique ID for the current model. If models are saved to disk, the `identifier` allows for reloading specific pre-trained models/data. <br> **Datatype:** String. | `identifier` | **Required.** <br> A unique ID for the current model. If models are saved to disk, the `identifier` allows for reloading specific pre-trained models/data. <br> **Datatype:** String.
| `live_retrain_hours` | Frequency of retraining during dry/live runs. <br> **Datatype:** Float > 0. <br> Default: `0` (models retrain as often as possible). | `live_retrain_hours` | Frequency of retraining during dry/live runs. <br> **Datatype:** Float > 0. <br> Default: `0` (models retrain as often as possible).
| `expiration_hours` | Avoid making predictions if a model is more than `expiration_hours` old. <br> **Datatype:** Positive integer. <br> Default: `0` (models never expire). | `expiration_hours` | Avoid making predictions if a model is more than `expiration_hours` old. <br> **Datatype:** Positive integer. <br> Default: `0` (models never expire).
| `purge_old_models` | Delete obsolete models. <br> **Datatype:** Boolean. <br> Default: `False` (all historic models remain on disk). | `purge_old_models` | Number of models to keep on disk (not relevant to backtesting). Default is 2, which means that dry/live runs will keep the latest 2 models on disk. Setting to 0 keeps all models. This parameter also accepts a boolean to maintain backwards compatibility. <br> **Datatype:** Integer. <br> Default: `2`.
| `save_backtest_models` | Save models to disk when running backtesting. Backtesting operates most efficiently by saving the prediction data and reusing them directly for subsequent runs (when you wish to tune entry/exit parameters). Saving backtesting models to disk also allows to use the same model files for starting a dry/live instance with the same model `identifier`. <br> **Datatype:** Boolean. <br> Default: `False` (no models are saved). | `save_backtest_models` | Save models to disk when running backtesting. Backtesting operates most efficiently by saving the prediction data and reusing them directly for subsequent runs (when you wish to tune entry/exit parameters). Saving backtesting models to disk also allows to use the same model files for starting a dry/live instance with the same model `identifier`. <br> **Datatype:** Boolean. <br> Default: `False` (no models are saved).
| `fit_live_predictions_candles` | Number of historical candles to use for computing target (label) statistics from prediction data, instead of from the training dataset (more information can be found [here](freqai-configuration.md#creating-a-dynamic-target-threshold)). <br> **Datatype:** Positive integer. | `fit_live_predictions_candles` | Number of historical candles to use for computing target (label) statistics from prediction data, instead of from the training dataset (more information can be found [here](freqai-configuration.md#creating-a-dynamic-target-threshold)). <br> **Datatype:** Positive integer.
| `follow_mode` | Use a `follower` that will look for models associated with a specific `identifier` and load those for inferencing. A `follower` will **not** train new models. <br> **Datatype:** Boolean. <br> Default: `False`.
| `continual_learning` | Use the final state of the most recently trained model as starting point for the new model, allowing for incremental learning (more information can be found [here](freqai-running.md#continual-learning)). <br> **Datatype:** Boolean. <br> Default: `False`. | `continual_learning` | Use the final state of the most recently trained model as starting point for the new model, allowing for incremental learning (more information can be found [here](freqai-running.md#continual-learning)). <br> **Datatype:** Boolean. <br> Default: `False`.
| `write_metrics_to_disk` | Collect train timings, inference timings and cpu usage in json file. <br> **Datatype:** Boolean. <br> Default: `False` | `write_metrics_to_disk` | Collect train timings, inference timings and cpu usage in json file. <br> **Datatype:** Boolean. <br> Default: `False`
| `data_kitchen_thread_count` | <br> Designate the number of threads you want to use for data processing (outlier methods, normalization, etc.). This has no impact on the number of threads used for training. If user does not set it (default), FreqAI will use max number of threads - 2 (leaving 1 physical core available for Freqtrade bot and FreqUI) <br> **Datatype:** Positive integer. | `data_kitchen_thread_count` | <br> Designate the number of threads you want to use for data processing (outlier methods, normalization, etc.). This has no impact on the number of threads used for training. If user does not set it (default), FreqAI will use max number of threads - 2 (leaving 1 physical core available for Freqtrade bot and FreqUI) <br> **Datatype:** Positive integer.
@ -29,12 +28,12 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
|------------|-------------| |------------|-------------|
| | **Feature parameters within the `freqai.feature_parameters` sub dictionary** | | **Feature parameters within the `freqai.feature_parameters` sub dictionary**
| `feature_parameters` | A dictionary containing the parameters used to engineer the feature set. Details and examples are shown [here](freqai-feature-engineering.md). <br> **Datatype:** Dictionary. | `feature_parameters` | A dictionary containing the parameters used to engineer the feature set. Details and examples are shown [here](freqai-feature-engineering.md). <br> **Datatype:** Dictionary.
| `include_timeframes` | A list of timeframes that all indicators in `populate_any_indicators` will be created for. The list is added as features to the base indicators dataset. <br> **Datatype:** List of timeframes (strings). | `include_timeframes` | A list of timeframes that all indicators in `feature_engineering_expand_*()` will be created for. The list is added as features to the base indicators dataset. <br> **Datatype:** List of timeframes (strings).
| `include_corr_pairlist` | A list of correlated coins that FreqAI will add as additional features to all `pair_whitelist` coins. All indicators set in `populate_any_indicators` during feature engineering (see details [here](freqai-feature-engineering.md)) will be created for each correlated coin. The correlated coins features are added to the base indicators dataset. <br> **Datatype:** List of assets (strings). | `include_corr_pairlist` | A list of correlated coins that FreqAI will add as additional features to all `pair_whitelist` coins. All indicators set in `feature_engineering_expand_*()` during feature engineering (see details [here](freqai-feature-engineering.md)) will be created for each correlated coin. The correlated coins features are added to the base indicators dataset. <br> **Datatype:** List of assets (strings).
| `label_period_candles` | Number of candles into the future that the labels are created for. This is used in `populate_any_indicators` (see `templates/FreqaiExampleStrategy.py` for detailed usage). You can create custom labels and choose whether to make use of this parameter or not. <br> **Datatype:** Positive integer. | `label_period_candles` | Number of candles into the future that the labels are created for. This is used in `feature_engineering_expand_all()` (see `templates/FreqaiExampleStrategy.py` for detailed usage). You can create custom labels and choose whether to make use of this parameter or not. <br> **Datatype:** Positive integer.
| `include_shifted_candles` | Add features from previous candles to subsequent candles with the intent of adding historical information. If used, FreqAI will duplicate and shift all features from the `include_shifted_candles` previous candles so that the information is available for the subsequent candle. <br> **Datatype:** Positive integer. | `include_shifted_candles` | Add features from previous candles to subsequent candles with the intent of adding historical information. If used, FreqAI will duplicate and shift all features from the `include_shifted_candles` previous candles so that the information is available for the subsequent candle. <br> **Datatype:** Positive integer.
| `weight_factor` | Weight training data points according to their recency (see details [here](freqai-feature-engineering.md#weighting-features-for-temporal-importance)). <br> **Datatype:** Positive float (typically < 1). | `weight_factor` | Weight training data points according to their recency (see details [here](freqai-feature-engineering.md#weighting-features-for-temporal-importance)). <br> **Datatype:** Positive float (typically < 1).
| `indicator_max_period_candles` | **No longer used (#7325)**. Replaced by `startup_candle_count` which is set in the [strategy](freqai-configuration.md#building-a-freqai-strategy). `startup_candle_count` is timeframe independent and defines the maximum *period* used in `populate_any_indicators()` for indicator creation. FreqAI uses this parameter together with the maximum timeframe in `include_time_frames` to calculate how many data points to download such that the first data point does not include a NaN. <br> **Datatype:** Positive integer. | `indicator_max_period_candles` | **No longer used (#7325)**. Replaced by `startup_candle_count` which is set in the [strategy](freqai-configuration.md#building-a-freqai-strategy). `startup_candle_count` is timeframe independent and defines the maximum *period* used in `feature_engineering_*()` for indicator creation. FreqAI uses this parameter together with the maximum timeframe in `include_time_frames` to calculate how many data points to download such that the first data point does not include a NaN. <br> **Datatype:** Positive integer.
| `indicator_periods_candles` | Time periods to calculate indicators for. The indicators are added to the base indicator dataset. <br> **Datatype:** List of positive integers. | `indicator_periods_candles` | Time periods to calculate indicators for. The indicators are added to the base indicator dataset. <br> **Datatype:** List of positive integers.
| `principal_component_analysis` | Automatically reduce the dimensionality of the data set using Principal Component Analysis. See details about how it works [here](#reducing-data-dimensionality-with-principal-component-analysis) <br> **Datatype:** Boolean. <br> Default: `False`. | `principal_component_analysis` | Automatically reduce the dimensionality of the data set using Principal Component Analysis. See details about how it works [here](#reducing-data-dimensionality-with-principal-component-analysis) <br> **Datatype:** Boolean. <br> Default: `False`.
| `plot_feature_importances` | Create a feature importance plot for each model for the top/bottom `plot_feature_importances` number of features. Plot is stored in `user_data/models/<identifier>/sub-train-<COIN>_<timestamp>.html`. <br> **Datatype:** Integer. <br> Default: `0`. | `plot_feature_importances` | Create a feature importance plot for each model for the top/bottom `plot_feature_importances` number of features. Plot is stored in `user_data/models/<identifier>/sub-train-<COIN>_<timestamp>.html`. <br> **Datatype:** Integer. <br> Default: `0`.
@ -46,13 +45,15 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| `noise_standard_deviation` | If set, FreqAI adds noise to the training features with the aim of preventing overfitting. FreqAI generates random deviates from a gaussian distribution with a standard deviation of `noise_standard_deviation` and adds them to all data points. `noise_standard_deviation` should be kept relative to the normalized space, i.e., between -1 and 1. In other words, since data in FreqAI is always normalized to be between -1 and 1, `noise_standard_deviation: 0.05` would result in 32% of the data being randomly increased/decreased by more than 2.5% (i.e., the percent of data falling within the first standard deviation). <br> **Datatype:** Integer. <br> Default: `0`. | `noise_standard_deviation` | If set, FreqAI adds noise to the training features with the aim of preventing overfitting. FreqAI generates random deviates from a gaussian distribution with a standard deviation of `noise_standard_deviation` and adds them to all data points. `noise_standard_deviation` should be kept relative to the normalized space, i.e., between -1 and 1. In other words, since data in FreqAI is always normalized to be between -1 and 1, `noise_standard_deviation: 0.05` would result in 32% of the data being randomly increased/decreased by more than 2.5% (i.e., the percent of data falling within the first standard deviation). <br> **Datatype:** Integer. <br> Default: `0`.
| `outlier_protection_percentage` | Enable to prevent outlier detection methods from discarding too much data. If more than `outlier_protection_percentage` % of points are detected as outliers by the SVM or DBSCAN, FreqAI will log a warning message and ignore outlier detection, i.e., the original dataset will be kept intact. If the outlier protection is triggered, no predictions will be made based on the training dataset. <br> **Datatype:** Float. <br> Default: `30`. | `outlier_protection_percentage` | Enable to prevent outlier detection methods from discarding too much data. If more than `outlier_protection_percentage` % of points are detected as outliers by the SVM or DBSCAN, FreqAI will log a warning message and ignore outlier detection, i.e., the original dataset will be kept intact. If the outlier protection is triggered, no predictions will be made based on the training dataset. <br> **Datatype:** Float. <br> Default: `30`.
| `reverse_train_test_order` | Split the feature dataset (see below) and use the latest data split for training and test on historical split of the data. This allows the model to be trained up to the most recent data point, while avoiding overfitting. However, you should be careful to understand the unorthodox nature of this parameter before employing it. <br> **Datatype:** Boolean. <br> Default: `False` (no reversal). | `reverse_train_test_order` | Split the feature dataset (see below) and use the latest data split for training and test on historical split of the data. This allows the model to be trained up to the most recent data point, while avoiding overfitting. However, you should be careful to understand the unorthodox nature of this parameter before employing it. <br> **Datatype:** Boolean. <br> Default: `False` (no reversal).
| `shuffle_after_split` | Split the data into train and test sets, and then shuffle both sets individually. <br> **Datatype:** Boolean. <br> Default: `False`.
| `buffer_train_data_candles` | Cut `buffer_train_data_candles` off the beginning and end of the training data *after* the indicators were populated. The main example use is when predicting maxima and minima, the argrelextrema function cannot know the maxima/minima at the edges of the timerange. To improve model accuracy, it is best to compute argrelextrema on the full timerange and then use this function to cut off the edges (buffer) by the kernel. In another case, if the targets are set to a shifted price movement, this buffer is unnecessary because the shifted candles at the end of the timerange will be NaN and FreqAI will automatically cut those off of the training dataset.<br> **Datatype:** Integer. <br> Default: `0`.
### Data split parameters ### Data split parameters
| Parameter | Description | | Parameter | Description |
|------------|-------------| |------------|-------------|
| | **Data split parameters within the `freqai.data_split_parameters` sub dictionary** | | **Data split parameters within the `freqai.data_split_parameters` sub dictionary**
| `data_split_parameters` | Include any additional parameters available from Scikit-learn `test_train_split()`, which are shown [here](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) (external website). <br> **Datatype:** Dictionary. | `data_split_parameters` | Include any additional parameters available from scikit-learn `test_train_split()`, which are shown [here](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) (external website). <br> **Datatype:** Dictionary.
| `test_size` | The fraction of data that should be used for testing instead of training. <br> **Datatype:** Positive float < 1. | `test_size` | The fraction of data that should be used for testing instead of training. <br> **Datatype:** Positive float < 1.
| `shuffle` | Shuffle the training data points during training. Typically, to not remove the chronological order of data in time-series forecasting, this is set to `False`. <br> **Datatype:** Boolean. <br> Defaut: `False`. | `shuffle` | Shuffle the training data points during training. Typically, to not remove the chronological order of data in time-series forecasting, this is set to `False`. <br> **Datatype:** Boolean. <br> Defaut: `False`.
@ -83,12 +84,34 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| `add_state_info` | Tell FreqAI to include state information in the feature set for training and inferencing. The current state variables include trade duration, current profit, trade position. This is only available in dry/live runs, and is automatically switched to false for backtesting. <br> **Datatype:** bool. <br> Default: `False`. | `add_state_info` | Tell FreqAI to include state information in the feature set for training and inferencing. The current state variables include trade duration, current profit, trade position. This is only available in dry/live runs, and is automatically switched to false for backtesting. <br> **Datatype:** bool. <br> Default: `False`.
| `net_arch` | Network architecture which is well described in [`stable_baselines3` doc](https://stable-baselines3.readthedocs.io/en/master/guide/custom_policy.html#examples). In summary: `[<shared layers>, dict(vf=[<non-shared value network layers>], pi=[<non-shared policy network layers>])]`. By default this is set to `[128, 128]`, which defines 2 shared hidden layers with 128 units each. | `net_arch` | Network architecture which is well described in [`stable_baselines3` doc](https://stable-baselines3.readthedocs.io/en/master/guide/custom_policy.html#examples). In summary: `[<shared layers>, dict(vf=[<non-shared value network layers>], pi=[<non-shared policy network layers>])]`. By default this is set to `[128, 128]`, which defines 2 shared hidden layers with 128 units each.
| `randomize_starting_position` | Randomize the starting point of each episode to avoid overfitting. <br> **Datatype:** bool. <br> Default: `False`. | `randomize_starting_position` | Randomize the starting point of each episode to avoid overfitting. <br> **Datatype:** bool. <br> Default: `False`.
| `drop_ohlc_from_features` | Do not include the normalized ohlc data in the feature set passed to the agent during training (ohlc will still be used for driving the environment in all cases) <br> **Datatype:** Boolean. <br> **Default:** `False`
### PyTorch parameters
#### general
| Parameter | Description |
|------------|-------------|
| | **Model training parameters within the `freqai.model_training_parameters` sub dictionary**
| `learning_rate` | Learning rate to be passed to the optimizer. <br> **Datatype:** float. <br> Default: `3e-4`.
| `model_kwargs` | Parameters to be passed to the model class. <br> **Datatype:** dict. <br> Default: `{}`.
| `trainer_kwargs` | Parameters to be passed to the trainer class. <br> **Datatype:** dict. <br> Default: `{}`.
#### trainer_kwargs
| Parameter | Description |
|------------|-------------|
| | **Model training parameters within the `freqai.model_training_parameters.model_kwargs` sub dictionary**
| `max_iters` | The number of training iterations to run. iteration here refers to the number of times we call self.optimizer.step(). used to calculate n_epochs. <br> **Datatype:** int. <br> Default: `100`.
| `batch_size` | The size of the batches to use during training.. <br> **Datatype:** int. <br> Default: `64`.
| `max_n_eval_batches` | The maximum number batches to use for evaluation.. <br> **Datatype:** int, optional. <br> Default: `None`.
### Additional parameters ### Additional parameters
| Parameter | Description | | Parameter | Description |
|------------|-------------| |------------|-------------|
| | **Extraneous parameters** | | **Extraneous parameters**
| `freqai.keras` | If the selected model makes use of Keras (typical for Tensorflow-based prediction models), this flag needs to be activated so that the model save/loading follows Keras standards. <br> **Datatype:** Boolean. <br> Default: `False`. | `freqai.keras` | If the selected model makes use of Keras (typical for TensorFlow-based prediction models), this flag needs to be activated so that the model save/loading follows Keras standards. <br> **Datatype:** Boolean. <br> Default: `False`.
| `freqai.conv_width` | The width of a convolutional neural network input tensor. This replaces the need for shifting candles (`include_shifted_candles`) by feeding in historical data points as the second dimension of the tensor. Technically, this parameter can also be used for regressors, but it only adds computational overhead and does not change the model training/prediction. <br> **Datatype:** Integer. <br> Default: `2`. | `freqai.conv_width` | The width of a convolutional neural network input tensor. This replaces the need for shifting candles (`include_shifted_candles`) by feeding in historical data points as the second dimension of the tensor. Technically, this parameter can also be used for regressors, but it only adds computational overhead and does not change the model training/prediction. <br> **Datatype:** Integer. <br> Default: `2`.
| `freqai.reduce_df_footprint` | Recast all numeric columns to float32/int32, with the objective of reducing ram/disk usage and decreasing train/inference timing. This parameter is set in the main level of the Freqtrade configuration file (not inside FreqAI). <br> **Datatype:** Boolean. <br> Default: `False`. | `freqai.reduce_df_footprint` | Recast all numeric columns to float32/int32, with the objective of reducing ram/disk usage and decreasing train/inference timing. This parameter is set in the main level of the Freqtrade configuration file (not inside FreqAI). <br> **Datatype:** Boolean. <br> Default: `False`.

View File

@ -24,7 +24,7 @@ The framework is built on stable_baselines3 (torch) and OpenAI gym for the base
### Important considerations ### Important considerations
As explained above, the agent is "trained" in an artificial trading "environment". In our case, that environment may seem quite similar to a real Freqtrade backtesting environment, but it is *NOT*. In fact, the RL training environment is much more simplified. It does not incorporate any of the complicated strategy logic, such as callbacks like `custom_exit`, `custom_stoploss`, leverage controls, etc. The RL environment is instead a very "raw" representation of the true market, where the agent has free-will to learn the policy (read: stoploss, take profit, etc.) which is enforced by the `calculate_reward()`. Thus, it is important to consider that the agent training environment is not identical to the real world. As explained above, the agent is "trained" in an artificial trading "environment". In our case, that environment may seem quite similar to a real Freqtrade backtesting environment, but it is *NOT*. In fact, the RL training environment is much more simplified. It does not incorporate any of the complicated strategy logic, such as callbacks like `custom_exit`, `custom_stoploss`, leverage controls, etc. The RL environment is instead a very "raw" representation of the true market, where the agent has free will to learn the policy (read: stoploss, take profit, etc.) which is enforced by the `calculate_reward()`. Thus, it is important to consider that the agent training environment is not identical to the real world.
## Running Reinforcement Learning ## Running Reinforcement Learning
@ -34,65 +34,36 @@ Setting up and running a Reinforcement Learning model is the same as running a R
freqtrade trade --freqaimodel ReinforcementLearner --strategy MyRLStrategy --config config.json freqtrade trade --freqaimodel ReinforcementLearner --strategy MyRLStrategy --config config.json
``` ```
where `ReinforcementLearner` will use the templated `ReinforcementLearner` from `freqai/prediction_models/ReinforcementLearner` (or a custom user defined one located in `user_data/freqaimodels`). The strategy, on the other hand, follows the same base [feature engineering](freqai-feature-engineering.md) with `populate_any_indicators` as a typical Regressor: where `ReinforcementLearner` will use the templated `ReinforcementLearner` from `freqai/prediction_models/ReinforcementLearner` (or a custom user defined one located in `user_data/freqaimodels`). The strategy, on the other hand, follows the same base [feature engineering](freqai-feature-engineering.md) with `feature_engineering_*` as a typical Regressor. The difference lies in the creation of the targets, Reinforcement Learning doesn't require them. However, FreqAI requires a default (neutral) value to be set in the action column:
```python ```python
def populate_any_indicators( def set_freqai_targets(self, dataframe, **kwargs):
self, pair, df, tf, informative=None, set_generalized_indicators=False """
): *Only functional with FreqAI enabled strategies*
Required function to set the targets for the model.
All targets must be prepended with `&` to be recognized by the FreqAI internals.
if informative is None: More details about feature engineering available:
informative = self.dp.get_pair_dataframe(pair, tf)
# first loop is automatically duplicating indicators for time periods https://www.freqtrade.io/en/latest/freqai-feature-engineering
for t in self.freqai_info["feature_parameters"]["indicator_periods_candles"]:
t = int(t) :param df: strategy dataframe which will receive the targets
informative[f"%-{pair}rsi-period_{t}"] = ta.RSI(informative, timeperiod=t) usage example: dataframe["&-target"] = dataframe["close"].shift(-1) / dataframe["close"]
informative[f"%-{pair}mfi-period_{t}"] = ta.MFI(informative, timeperiod=t) """
informative[f"%-{pair}adx-period_{t}"] = ta.ADX(informative, window=t) # For RL, there are no direct targets to set. This is filler (neutral)
# until the agent sends an action.
# The following raw price values are necessary for RL models dataframe["&-action"] = 0
informative[f"%-{pair}raw_close"] = informative["close"]
informative[f"%-{pair}raw_open"] = informative["open"]
informative[f"%-{pair}raw_high"] = informative["high"]
informative[f"%-{pair}raw_low"] = informative["low"]
indicators = [col for col in informative if col.startswith("%")]
# This loop duplicates and shifts all indicators to add a sense of recency to data
for n in range(self.freqai_info["feature_parameters"]["include_shifted_candles"] + 1):
if n == 0:
continue
informative_shift = informative[indicators].shift(n)
informative_shift = informative_shift.add_suffix("_shift-" + str(n))
informative = pd.concat((informative, informative_shift), axis=1)
df = merge_informative_pair(df, informative, self.config["timeframe"], tf, ffill=True)
skip_columns = [
(s + "_" + tf) for s in ["date", "open", "high", "low", "close", "volume"]
]
df = df.drop(columns=skip_columns)
# Add generalized indicators here (because in live, it will call this
# function to populate indicators during training). Notice how we ensure not to
# add them multiple times
if set_generalized_indicators:
# For RL, there are no direct targets to set. This is filler (neutral)
# until the agent sends an action.
df["&-action"] = 0
return df
``` ```
Most of the function remains the same as for typical Regressors, however, the function above shows how the strategy must pass the raw price data to the agent so that it has access to raw OHLCV in the training environment: Most of the function remains the same as for typical Regressors, however, the function below shows how the strategy must pass the raw price data to the agent so that it has access to raw OHLCV in the training environment:
```python ```python
def feature_engineering_standard(self, dataframe, **kwargs):
# The following features are necessary for RL models # The following features are necessary for RL models
informative[f"%-{pair}raw_close"] = informative["close"] dataframe[f"%-raw_close"] = dataframe["close"]
informative[f"%-{pair}raw_open"] = informative["open"] dataframe[f"%-raw_open"] = dataframe["open"]
informative[f"%-{pair}raw_high"] = informative["high"] dataframe[f"%-raw_high"] = dataframe["high"]
informative[f"%-{pair}raw_low"] = informative["low"] dataframe[f"%-raw_low"] = dataframe["low"]
``` ```
Finally, there is no explicit "label" to make - instead it is necessary to assign the `&-action` column which will contain the agent's actions when accessed in `populate_entry/exit_trends()`. In the present example, the neutral action to 0. This value should align with the environment used. FreqAI provides two environments, both use 0 as the neutral action. Finally, there is no explicit "label" to make - instead it is necessary to assign the `&-action` column which will contain the agent's actions when accessed in `populate_entry/exit_trends()`. In the present example, the neutral action to 0. This value should align with the environment used. FreqAI provides two environments, both use 0 as the neutral action.
@ -204,10 +175,23 @@ As you begin to modify the strategy and the prediction model, you will quickly r
pnl = self.get_unrealized_profit() pnl = self.get_unrealized_profit()
factor = 100 factor = 100
pair = self.pair.replace(':', '')
# you can use feature values from dataframe
# Assumes the shifted RSI indicator has been generated in the strategy.
rsi_now = self.raw_features[f"%-rsi-period_10_shift-1_{pair}_"
f"{self.config['timeframe']}"].iloc[self._current_tick]
# reward agent for entering trades # reward agent for entering trades
if action in (Actions.Long_enter.value, Actions.Short_enter.value) \ if (action in (Actions.Long_enter.value, Actions.Short_enter.value)
and self._position == Positions.Neutral: and self._position == Positions.Neutral):
return 25 if rsi_now < 40:
factor = 40 / rsi_now
else:
factor = 1
return 25 * factor
# discourage agent from not entering trades # discourage agent from not entering trades
if action == Actions.Neutral.value and self._position == Positions.Neutral: if action == Actions.Neutral.value and self._position == Positions.Neutral:
return -1 return -1
@ -264,23 +248,22 @@ FreqAI also provides a built in episodic summary logger called `self.tensorboard
""" """
def calculate_reward(self, action: int) -> float: def calculate_reward(self, action: int) -> float:
if not self._is_valid(action): if not self._is_valid(action):
self.tensorboard_log("is_valid") self.tensorboard_log("invalid")
return -2 return -2
``` ```
!!! Note !!! Note
The `self.tensorboard_log()` function is designed for tracking incremented objects only i.e. events, actions inside the training environment. If the event of interest is a float, the float can be passed as the second argument e.g. `self.tensorboard_log("float_metric1", 0.23)` would add 0.23 to `float_metric`. In this case you can also disable incrementing using `inc=False` parameter. The `self.tensorboard_log()` function is designed for tracking incremented objects only i.e. events, actions inside the training environment. If the event of interest is a float, the float can be passed as the second argument e.g. `self.tensorboard_log("float_metric1", 0.23)`. In this case the metric values are not incremented.
### Choosing a base environment ### Choosing a base environment
FreqAI provides two base environments, `Base4ActionEnvironment` and `Base5ActionEnvironment`. As the names imply, the environments are customized for agents that can select from 4 or 5 actions. In the `Base4ActionEnvironment`, the agent can enter long, enter short, hold neutral, or exit position. Meanwhile, in the `Base5ActionEnvironment`, the agent has the same actions as Base4, but instead of a single exit action, it separates exit long and exit short. The main changes stemming from the environment selection include: FreqAI provides three base environments, `Base3ActionRLEnvironment`, `Base4ActionEnvironment` and `Base5ActionEnvironment`. As the names imply, the environments are customized for agents that can select from 3, 4 or 5 actions. The `Base3ActionEnvironment` is the simplest, the agent can select from hold, long, or short. This environment can also be used for long-only bots (it automatically follows the `can_short` flag from the strategy), where long is the enter condition and short is the exit condition. Meanwhile, in the `Base4ActionEnvironment`, the agent can enter long, enter short, hold neutral, or exit position. Finally, in the `Base5ActionEnvironment`, the agent has the same actions as Base4, but instead of a single exit action, it separates exit long and exit short. The main changes stemming from the environment selection include:
* the actions available in the `calculate_reward` * the actions available in the `calculate_reward`
* the actions consumed by the user strategy * the actions consumed by the user strategy
Both of the FreqAI provided environments inherit from an action/position agnostic environment object called the `BaseEnvironment`, which contains all shared logic. The architecture is designed to be easily customized. The simplest customization is the `calculate_reward()` (see details [here](#creating-a-custom-reward-function)). However, the customizations can be further extended into any of the functions inside the environment. You can do this by simply overriding those functions inside your `MyRLEnv` in the prediction model file. Or for more advanced customizations, it is encouraged to create an entirely new environment inherited from `BaseEnvironment`. All of the FreqAI provided environments inherit from an action/position agnostic environment object called the `BaseEnvironment`, which contains all shared logic. The architecture is designed to be easily customized. The simplest customization is the `calculate_reward()` (see details [here](#creating-a-custom-reward-function)). However, the customizations can be further extended into any of the functions inside the environment. You can do this by simply overriding those functions inside your `MyRLEnv` in the prediction model file. Or for more advanced customizations, it is encouraged to create an entirely new environment inherited from `BaseEnvironment`.
!!! Note !!! Note
FreqAI does not provide by default, a long-only training environment. However, creating one should be as simple as copy-pasting one of the built in environments and removing the `short` actions (and all associated references to those). Only the `Base3ActionRLEnv` can do long-only training/trading (set the user strategy attribute `can_short = False`).

View File

@ -67,6 +67,10 @@ Backtesting mode requires [downloading the necessary data](#downloading-data-to-
*want* to retrain a new model with the same config file, you should simply change the `identifier`. *want* to retrain a new model with the same config file, you should simply change the `identifier`.
This way, you can return to using any model you wish by simply specifying the `identifier`. This way, you can return to using any model you wish by simply specifying the `identifier`.
!!! Note
Backtesting calls `set_freqai_targets()` one time for each backtest window (where the number of windows is the full backtest timerange divided by the `backtest_period_days` parameter). Doing this means that the targets simulate dry/live behavior without look ahead bias. However, the definition of the features in `feature_engineering_*()` is performed once on the entire backtest timerange. This means that you should be sure that features do look-ahead into the future.
More details about look-ahead bias can be found in [Common Mistakes](strategy-customization.md#common-mistakes-when-developing-strategies).
--- ---
### Saving prediction data ### Saving prediction data
@ -116,7 +120,7 @@ In the presented example config, the user will only allow predictions on models
Model training parameters are unique to the selected machine learning library. FreqAI allows you to set any parameter for any library using the `model_training_parameters` dictionary in the config. The example config (found in `config_examples/config_freqai.example.json`) shows some of the example parameters associated with `Catboost` and `LightGBM`, but you can add any parameters available in those libraries or any other machine learning library you choose to implement. Model training parameters are unique to the selected machine learning library. FreqAI allows you to set any parameter for any library using the `model_training_parameters` dictionary in the config. The example config (found in `config_examples/config_freqai.example.json`) shows some of the example parameters associated with `Catboost` and `LightGBM`, but you can add any parameters available in those libraries or any other machine learning library you choose to implement.
Data split parameters are defined in `data_split_parameters` which can be any parameters associated with Scikit-learn's `train_test_split()` function. `train_test_split()` has a parameters called `shuffle` which allows to shuffle the data or keep it unshuffled. This is particularly useful to avoid biasing training with temporally auto-correlated data. More details about these parameters can be found the [Scikit-learn website](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) (external website). Data split parameters are defined in `data_split_parameters` which can be any parameters associated with scikit-learn's `train_test_split()` function. `train_test_split()` has a parameters called `shuffle` which allows to shuffle the data or keep it unshuffled. This is particularly useful to avoid biasing training with temporally auto-correlated data. More details about these parameters can be found the [scikit-learn website](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) (external website).
The FreqAI specific parameter `label_period_candles` defines the offset (number of candles into the future) used for the `labels`. In the presented [example config](freqai-configuration.md#setting-up-the-configuration-file), the user is asking for `labels` that are 24 candles in the future. The FreqAI specific parameter `label_period_candles` defines the offset (number of candles into the future) used for the `labels`. In the presented [example config](freqai-configuration.md#setting-up-the-configuration-file), the user is asking for `labels` that are 24 candles in the future.
@ -124,6 +128,9 @@ The FreqAI specific parameter `label_period_candles` defines the offset (number
You can choose to adopt a continual learning scheme by setting `"continual_learning": true` in the config. By enabling `continual_learning`, after training an initial model from scratch, subsequent trainings will start from the final model state of the preceding training. This gives the new model a "memory" of the previous state. By default, this is set to `False` which means that all new models are trained from scratch, without input from previous models. You can choose to adopt a continual learning scheme by setting `"continual_learning": true` in the config. By enabling `continual_learning`, after training an initial model from scratch, subsequent trainings will start from the final model state of the preceding training. This gives the new model a "memory" of the previous state. By default, this is set to `False` which means that all new models are trained from scratch, without input from previous models.
???+ danger "Continual learning enforces a constant parameter space"
Since `continual_learning` means that the model parameter space *cannot* change between trainings, `principal_component_analysis` is automatically disabled when `continual_learning` is enabled. Hint: PCA changes the parameter space and the number of features, learn more about PCA [here](freqai-feature-engineering.md#data-dimensionality-reduction-with-principal-component-analysis).
## Hyperopt ## Hyperopt
You can hyperopt using the same command as for [typical Freqtrade hyperopt](hyperopt.md): You can hyperopt using the same command as for [typical Freqtrade hyperopt](hyperopt.md):
@ -135,7 +142,7 @@ freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --strategy FreqaiExampleSt
`hyperopt` requires you to have the data pre-downloaded in the same fashion as if you were doing [backtesting](#backtesting). In addition, you must consider some restrictions when trying to hyperopt FreqAI strategies: `hyperopt` requires you to have the data pre-downloaded in the same fashion as if you were doing [backtesting](#backtesting). In addition, you must consider some restrictions when trying to hyperopt FreqAI strategies:
- The `--analyze-per-epoch` hyperopt parameter is not compatible with FreqAI. - The `--analyze-per-epoch` hyperopt parameter is not compatible with FreqAI.
- It's not possible to hyperopt indicators in the `populate_any_indicators()` function. This means that you cannot optimize model parameters using hyperopt. Apart from this exception, it is possible to optimize all other [spaces](hyperopt.md#running-hyperopt-with-smaller-search-space). - It's not possible to hyperopt indicators in the `feature_engineering_*()` and `set_freqai_targets()` functions. This means that you cannot optimize model parameters using hyperopt. Apart from this exception, it is possible to optimize all other [spaces](hyperopt.md#running-hyperopt-with-smaller-search-space).
- The backtesting instructions also apply to hyperopt. - The backtesting instructions also apply to hyperopt.
The best method for combining hyperopt and FreqAI is to focus on hyperopting entry/exit thresholds/criteria. You need to focus on hyperopting parameters that are not used in your features. For example, you should not try to hyperopt rolling window lengths in the feature creation, or any part of the FreqAI config which changes predictions. In order to efficiently hyperopt the FreqAI strategy, FreqAI stores predictions as dataframes and reuses them. Hence the requirement to hyperopt entry/exit thresholds/criteria only. The best method for combining hyperopt and FreqAI is to focus on hyperopting entry/exit thresholds/criteria. You need to focus on hyperopting parameters that are not used in your features. For example, you should not try to hyperopt rolling window lengths in the feature creation, or any part of the FreqAI config which changes predictions. In order to efficiently hyperopt the FreqAI strategy, FreqAI stores predictions as dataframes and reuses them. Hence the requirement to hyperopt entry/exit thresholds/criteria only.
@ -161,20 +168,3 @@ tensorboard --logdir user_data/models/unique-id
where `unique-id` is the `identifier` set in the `freqai` configuration file. This command must be run in a separate shell if you wish to view the output in your browser at 127.0.0.1:6060 (6060 is the default port used by Tensorboard). where `unique-id` is the `identifier` set in the `freqai` configuration file. This command must be run in a separate shell if you wish to view the output in your browser at 127.0.0.1:6060 (6060 is the default port used by Tensorboard).
![tensorboard](assets/tensorboard.jpg) ![tensorboard](assets/tensorboard.jpg)
## Setting up a follower
You can indicate to the bot that it should not train models, but instead should look for models trained by a leader with a specific `identifier` by defining:
```json
"freqai": {
"enabled": true,
"follow_mode": true,
"identifier": "example",
"feature_parameters": {
// leader bots feature_parameters inserted here
},
}
```
In this example, the user has a leader bot with the `"identifier": "example"`. The leader bot is already running or is launched simultaneously with the follower. The follower will load models created by the leader and inference them to obtain predictions instead of training its own models. The user will also need to duplicate the `feature_parameters` parameters from from the leaders freqai configuration file into the freqai section of the followers config.

View File

@ -4,7 +4,10 @@
## Introduction ## Introduction
FreqAI is a software designed to automate a variety of tasks associated with training a predictive machine learning model to generate market forecasts given a set of input signals. In general, the FreqAI aims to be a sand-box for easily deploying robust machine-learning libraries on real-time data ([details])(#freqai-position-in-open-source-machine-learning-landscape). FreqAI is a software designed to automate a variety of tasks associated with training a predictive machine learning model to generate market forecasts given a set of input signals. In general, FreqAI aims to be a sandbox for easily deploying robust machine learning libraries on real-time data ([details](#freqai-position-in-open-source-machine-learning-landscape)).
!!! Note
FreqAI is, and always will be, a not-for-profit, open-source project. FreqAI does *not* have a crypto token, FreqAI does *not* sell signals, and FreqAI does not have a domain besides the present [freqtrade documentation](https://www.freqtrade.io/en/latest/freqai/).
Features include: Features include:
@ -19,7 +22,7 @@ Features include:
* **Automatic data download** - Compute timeranges for data downloads and update historic data (in live deployments) * **Automatic data download** - Compute timeranges for data downloads and update historic data (in live deployments)
* **Cleaning of incoming data** - Handle NaNs safely before training and model inferencing * **Cleaning of incoming data** - Handle NaNs safely before training and model inferencing
* **Dimensionality reduction** - Reduce the size of the training data via [Principal Component Analysis](freqai-feature-engineering.md#data-dimensionality-reduction-with-principal-component-analysis) * **Dimensionality reduction** - Reduce the size of the training data via [Principal Component Analysis](freqai-feature-engineering.md#data-dimensionality-reduction-with-principal-component-analysis)
* **Deploying bot fleets** - Set one bot to train models while a fleet of [follower bots](freqai-running.md#setting-up-a-follower) inference the models and handle trades * **Deploying bot fleets** - Set one bot to train models while a fleet of [consumers](producer-consumer.md) use signals.
## Quick start ## Quick start
@ -68,14 +71,32 @@ pip install -r requirements-freqai.txt
!!! Note !!! Note
Catboost will not be installed on arm devices (raspberry, Mac M1, ARM based VPS, ...), since it does not provide wheels for this platform. Catboost will not be installed on arm devices (raspberry, Mac M1, ARM based VPS, ...), since it does not provide wheels for this platform.
!!! Note "python 3.11"
Some dependencies (Catboost, Torch) currently don't support python 3.11. Freqtrade therefore only supports python 3.10 for these models/dependencies.
Tests involving these dependencies are skipped on 3.11.
### Usage with docker ### Usage with docker
If you are using docker, a dedicated tag with FreqAI dependencies is available as `:freqai`. As such - you can replace the image line in your docker-compose file with `image: freqtradeorg/freqtrade:develop_freqai`. This image contains the regular FreqAI dependencies. Similar to native installs, Catboost will not be available on ARM based devices. If you are using docker, a dedicated tag with FreqAI dependencies is available as `:freqai`. As such - you can replace the image line in your docker compose file with `image: freqtradeorg/freqtrade:develop_freqai`. This image contains the regular FreqAI dependencies. Similar to native installs, Catboost will not be available on ARM based devices.
### FreqAI position in open-source machine learning landscape ### FreqAI position in open-source machine learning landscape
Forecasting chaotic time-series based systems, such as equity/cryptocurrency markets, requires a broad set of tools geared toward testing a wide range of hypotheses. Fortunately, a recent maturation of robust machine learning libraries (e.g. `scikit-learn`) has opened up a wide range of research possibilities. Scientists from a diverse range of fields can now easily prototype their studies on an abundance of established machine learning algorithms. Similarly, these user-friendly libraries enable "citzen scientists" to use their basic Python skills for data-exploration. However, leveraging these machine learning libraries on historical and live chaotic data sources can be logistically difficult and expensive. Additionally, robust data-collection, storage, and handling presents a disparate challenge. [`FreqAI`](#freqai) aims to provide a generalized and extensible open-sourced framework geared toward live deployments of adaptive modeling for market forecasting. The `FreqAI` framework is effectively a sandbox for the rich world of open-source machine learning libraries. Inside the `FreqAI` sandbox, users find they can combine a wide variety of third-party libraries to test creative hypotheses on a free live 24/7 chaotic data source - cryptocurrency exchange data. Forecasting chaotic time-series based systems, such as equity/cryptocurrency markets, requires a broad set of tools geared toward testing a wide range of hypotheses. Fortunately, a recent maturation of robust machine learning libraries (e.g. `scikit-learn`) has opened up a wide range of research possibilities. Scientists from a diverse range of fields can now easily prototype their studies on an abundance of established machine learning algorithms. Similarly, these user-friendly libraries enable "citzen scientists" to use their basic Python skills for data exploration. However, leveraging these machine learning libraries on historical and live chaotic data sources can be logistically difficult and expensive. Additionally, robust data collection, storage, and handling presents a disparate challenge. [`FreqAI`](#freqai) aims to provide a generalized and extensible open-sourced framework geared toward live deployments of adaptive modeling for market forecasting. The `FreqAI` framework is effectively a sandbox for the rich world of open-source machine learning libraries. Inside the `FreqAI` sandbox, users find they can combine a wide variety of third-party libraries to test creative hypotheses on a free live 24/7 chaotic data source - cryptocurrency exchange data.
### Citing FreqAI
FreqAI is [published in the Journal of Open Source Software](https://joss.theoj.org/papers/10.21105/joss.04864). If you find FreqAI useful in your research, please use the following citation:
```bibtex
@article{Caulk2022,
doi = {10.21105/joss.04864},
url = {https://doi.org/10.21105/joss.04864},
year = {2022}, publisher = {The Open Journal},
volume = {7}, number = {80}, pages = {4864},
author = {Robert A. Caulk and Elin Törnquist and Matthias Voppichler and Andrew R. Lawless and Ryan McMullan and Wagner Costa Santos and Timothy C. Pogue and Johan van der Vlugt and Stefan P. Gehring and Pascal Schmidt},
title = {FreqAI: generalizing adaptive modeling for chaotic time-series market forecasts},
journal = {Journal of Open Source Software} }
```
## Common pitfalls ## Common pitfalls
@ -99,6 +120,8 @@ Code review and software architecture brainstorming:
Software development: Software development:
Wagner Costa @wagnercosta Wagner Costa @wagnercosta
Emre Suzen @aemr3
Timothy Pogue @wizrds
Beta testing and bug reporting: Beta testing and bug reporting:
Stefan Gehring @bloodhunter4rc, @longyu, Andrew Lawless @paranoidandy, Pascal Schmidt @smidelis, Ryan McMullan @smarmau, Juha Nykänen @suikula, Johan van der Vlugt @jooopiert, Richárd Józsa @richardjosza, Timothy Pogue @wizrds Stefan Gehring @bloodhunter4rc, @longyu, Andrew Lawless @paranoidandy, Pascal Schmidt @smidelis, Ryan McMullan @smarmau, Juha Nykänen @suikula, Johan van der Vlugt @jooopiert, Richárd Józsa @richardjosza

View File

@ -50,7 +50,7 @@ usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--eps] [--dmmp] [--enable-protections] [--eps] [--dmmp] [--enable-protections]
[--dry-run-wallet DRY_RUN_WALLET] [--dry-run-wallet DRY_RUN_WALLET]
[--timeframe-detail TIMEFRAME_DETAIL] [-e INT] [--timeframe-detail TIMEFRAME_DETAIL] [-e INT]
[--spaces {all,buy,sell,roi,stoploss,trailing,protection,default} [{all,buy,sell,roi,stoploss,trailing,protection,default} ...]] [--spaces {all,buy,sell,roi,stoploss,trailing,protection,trades,default} [{all,buy,sell,roi,stoploss,trailing,protection,trades,default} ...]]
[--print-all] [--no-color] [--print-json] [-j JOBS] [--print-all] [--no-color] [--print-json] [-j JOBS]
[--random-state INT] [--min-trades INT] [--random-state INT] [--min-trades INT]
[--hyperopt-loss NAME] [--disable-param-export] [--hyperopt-loss NAME] [--disable-param-export]
@ -96,7 +96,7 @@ optional arguments:
Specify detail timeframe for backtesting (`1m`, `5m`, Specify detail timeframe for backtesting (`1m`, `5m`,
`30m`, `1h`, `1d`). `30m`, `1h`, `1d`).
-e INT, --epochs INT Specify number of epochs (default: 100). -e INT, --epochs INT Specify number of epochs (default: 100).
--spaces {all,buy,sell,roi,stoploss,trailing,protection,default} [{all,buy,sell,roi,stoploss,trailing,protection,default} ...] --spaces {all,buy,sell,roi,stoploss,trailing,protection,trades,default} [{all,buy,sell,roi,stoploss,trailing,protection,trades,default} ...]
Specify which parameters to hyperopt. Space-separated Specify which parameters to hyperopt. Space-separated
list. list.
--print-all Print all results, not only the best ones. --print-all Print all results, not only the best ones.
@ -180,6 +180,7 @@ Rarely you may also need to create a [nested class](advanced-hyperopt.md#overrid
* `generate_roi_table` - for custom ROI optimization (if you need the ranges for the values in the ROI table that differ from default or the number of entries (steps) in the ROI table which differs from the default 4 steps) * `generate_roi_table` - for custom ROI optimization (if you need the ranges for the values in the ROI table that differ from default or the number of entries (steps) in the ROI table which differs from the default 4 steps)
* `stoploss_space` - for custom stoploss optimization (if you need the range for the stoploss parameter in the optimization hyperspace that differs from default) * `stoploss_space` - for custom stoploss optimization (if you need the range for the stoploss parameter in the optimization hyperspace that differs from default)
* `trailing_space` - for custom trailing stop optimization (if you need the ranges for the trailing stop parameters in the optimization hyperspace that differ from default) * `trailing_space` - for custom trailing stop optimization (if you need the ranges for the trailing stop parameters in the optimization hyperspace that differ from default)
* `max_open_trades_space` - for custom max_open_trades optimization (if you need the ranges for the max_open_trades parameter in the optimization hyperspace that differ from default)
!!! Tip "Quickly optimize ROI, stoploss and trailing stoploss" !!! Tip "Quickly optimize ROI, stoploss and trailing stoploss"
You can quickly optimize the spaces `roi`, `stoploss` and `trailing` without changing anything in your strategy. You can quickly optimize the spaces `roi`, `stoploss` and `trailing` without changing anything in your strategy.
@ -365,7 +366,7 @@ class MyAwesomeStrategy(IStrategy):
timeframe = '15m' timeframe = '15m'
minimal_roi = { minimal_roi = {
"0": 0.10 "0": 0.10
}, }
# Define the parameter spaces # Define the parameter spaces
buy_ema_short = IntParameter(3, 50, default=5) buy_ema_short = IntParameter(3, 50, default=5)
buy_ema_long = IntParameter(15, 200, default=50) buy_ema_long = IntParameter(15, 200, default=50)
@ -400,7 +401,7 @@ class MyAwesomeStrategy(IStrategy):
return dataframe return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = [] conditions = []
conditions.append(qtpylib.crossed_above( conditions.append(qtpylib.crossed_above(
dataframe[f'ema_long_{self.buy_ema_long.value}'], dataframe[f'ema_short_{self.buy_ema_short.value}'] dataframe[f'ema_long_{self.buy_ema_long.value}'], dataframe[f'ema_short_{self.buy_ema_short.value}']
)) ))
@ -643,6 +644,7 @@ Legal values are:
* `roi`: just optimize the minimal profit table for your strategy * `roi`: just optimize the minimal profit table for your strategy
* `stoploss`: search for the best stoploss value * `stoploss`: search for the best stoploss value
* `trailing`: search for the best trailing stop values * `trailing`: search for the best trailing stop values
* `trades`: search for the best max open trades values
* `protection`: search for the best protection parameters (read the [protections section](#optimizing-protections) on how to properly define these) * `protection`: search for the best protection parameters (read the [protections section](#optimizing-protections) on how to properly define these)
* `default`: `all` except `trailing` and `protection` * `default`: `all` except `trailing` and `protection`
* space-separated list of any of the above values for example `--spaces roi stoploss` * space-separated list of any of the above values for example `--spaces roi stoploss`
@ -916,5 +918,5 @@ Once the optimized strategy has been implemented into your strategy, you should
To achieve same the results (number of trades, their durations, profit, etc.) as during Hyperopt, please use the same configuration and parameters (timerange, timeframe, ...) used for hyperopt `--dmmp`/`--disable-max-market-positions` and `--eps`/`--enable-position-stacking` for Backtesting. To achieve same the results (number of trades, their durations, profit, etc.) as during Hyperopt, please use the same configuration and parameters (timerange, timeframe, ...) used for hyperopt `--dmmp`/`--disable-max-market-positions` and `--eps`/`--enable-position-stacking` for Backtesting.
Should results not match, please double-check to make sure you transferred all conditions correctly. Should results not match, please double-check to make sure you transferred all conditions correctly.
Pay special care to the stoploss (and trailing stoploss) parameters, as these are often set in configuration files, which override changes to the strategy. Pay special care to the stoploss, max_open_trades and trailing stoploss parameters, as these are often set in configuration files, which override changes to the strategy.
You should also carefully review the log of your backtest to ensure that there were no parameters inadvertently set by the configuration (like `stoploss` or `trailing_stop`). You should also carefully review the log of your backtest to ensure that there were no parameters inadvertently set by the configuration (like `stoploss`, `max_open_trades` or `trailing_stop`).

View File

@ -23,6 +23,7 @@ You may also use something like `.*DOWN/BTC` or `.*UP/BTC` to exclude leveraged
* [`StaticPairList`](#static-pair-list) (default, if not configured differently) * [`StaticPairList`](#static-pair-list) (default, if not configured differently)
* [`VolumePairList`](#volume-pair-list) * [`VolumePairList`](#volume-pair-list)
* [`ProducerPairList`](#producerpairlist) * [`ProducerPairList`](#producerpairlist)
* [`RemotePairList`](#remotepairlist)
* [`AgeFilter`](#agefilter) * [`AgeFilter`](#agefilter)
* [`OffsetFilter`](#offsetfilter) * [`OffsetFilter`](#offsetfilter)
* [`PerformanceFilter`](#performancefilter) * [`PerformanceFilter`](#performancefilter)
@ -173,6 +174,48 @@ You can limit the length of the pairlist with the optional parameter `number_ass
`ProducerPairList` can also be used multiple times in sequence, combining the pairs from multiple producers. `ProducerPairList` can also be used multiple times in sequence, combining the pairs from multiple producers.
Obviously in complex such configurations, the Producer may not provide data for all pairs, so the strategy must be fit for this. Obviously in complex such configurations, the Producer may not provide data for all pairs, so the strategy must be fit for this.
#### RemotePairList
It allows the user to fetch a pairlist from a remote server or a locally stored json file within the freqtrade directory, enabling dynamic updates and customization of the trading pairlist.
The RemotePairList is defined in the pairlists section of the configuration settings. It uses the following configuration options:
```json
"pairlists": [
{
"method": "RemotePairList",
"pairlist_url": "https://example.com/pairlist",
"number_assets": 10,
"refresh_period": 1800,
"keep_pairlist_on_failure": true,
"read_timeout": 60,
"bearer_token": "my-bearer-token"
}
]
```
The `pairlist_url` option specifies the URL of the remote server where the pairlist is located, or the path to a local file (if file:/// is prepended). This allows the user to use either a remote server or a local file as the source for the pairlist.
The user is responsible for providing a server or local file that returns a JSON object with the following structure:
```json
{
"pairs": ["XRP/USDT", "ETH/USDT", "LTC/USDT"],
"refresh_period": 1800,
}
```
The `pairs` property should contain a list of strings with the trading pairs to be used by the bot. The `refresh_period` property is optional and specifies the number of seconds that the pairlist should be cached before being refreshed.
The optional `keep_pairlist_on_failure` specifies whether the previous received pairlist should be used if the remote server is not reachable or returns an error. The default value is true.
The optional `read_timeout` specifies the maximum amount of time (in seconds) to wait for a response from the remote source, The default value is 60.
The optional `bearer_token` will be included in the requests Authorization Header.
!!! Note
In case of a server error the last received pairlist will be kept if `keep_pairlist_on_failure` is set to true, when set to false a empty pairlist is returned.
#### AgeFilter #### AgeFilter
Removes pairs that have been listed on the exchange for less than `min_days_listed` days (defaults to `10`) or more than `max_days_listed` days (defaults `None` mean infinity). Removes pairs that have been listed on the exchange for less than `min_days_listed` days (defaults to `10`) or more than `max_days_listed` days (defaults `None` mean infinity).

View File

@ -149,7 +149,7 @@ The below example assumes a timeframe of 1 hour:
* Locks each pair after selling for an additional 5 candles (`CooldownPeriod`), giving other pairs a chance to get filled. * Locks each pair after selling for an additional 5 candles (`CooldownPeriod`), giving other pairs a chance to get filled.
* Stops trading for 4 hours (`4 * 1h candles`) if the last 2 days (`48 * 1h candles`) had 20 trades, which caused a max-drawdown of more than 20%. (`MaxDrawdown`). * Stops trading for 4 hours (`4 * 1h candles`) if the last 2 days (`48 * 1h candles`) had 20 trades, which caused a max-drawdown of more than 20%. (`MaxDrawdown`).
* Stops trading if more than 4 stoploss occur for all pairs within a 1 day (`24 * 1h candles`) limit (`StoplossGuard`). * Stops trading if more than 4 stoploss occur for all pairs within a 1 day (`24 * 1h candles`) limit (`StoplossGuard`).
* Locks all pairs that had 4 Trades within the last 6 hours (`6 * 1h candles`) with a combined profit ratio of below 0.02 (<2%) (`LowProfitPairs`). * Locks all pairs that had 2 Trades within the last 6 hours (`6 * 1h candles`) with a combined profit ratio of below 0.02 (<2%) (`LowProfitPairs`).
* Locks all pairs for 2 candles that had a profit of below 0.01 (<1%) within the last 24h (`24 * 1h candles`), a minimum of 4 trades. * Locks all pairs for 2 candles that had a profit of below 0.01 (<1%) within the last 24h (`24 * 1h candles`), a minimum of 4 trades.
``` python ``` python

View File

@ -1,6 +1,7 @@
![freqtrade](assets/freqtrade_poweredby.svg) ![freqtrade](assets/freqtrade_poweredby.svg)
[![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/) [![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/)
[![DOI](https://joss.theoj.org/papers/10.21105/joss.04864/status.svg)](https://doi.org/10.21105/joss.04864)
[![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop) [![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop)
[![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability) [![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability)
@ -51,6 +52,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual,
- [X] [Binance](https://www.binance.com/) - [X] [Binance](https://www.binance.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [OKX](https://okx.com/) - [X] [OKX](https://okx.com/)
- [X] [Bybit](https://bybit.com/)
Please make sure to read the [exchange specific notes](exchanges.md), as well as the [trading with leverage](leverage.md) documentation before diving in. Please make sure to read the [exchange specific notes](exchanges.md), as well as the [trading with leverage](leverage.md) documentation before diving in.

View File

@ -30,6 +30,12 @@ The easiest way to install and run Freqtrade is to clone the bot Github reposito
!!! Warning "Up-to-date clock" !!! Warning "Up-to-date clock"
The clock on the system running the bot must be accurate, synchronized to a NTP server frequently enough to avoid problems with communication to the exchanges. The clock on the system running the bot must be accurate, synchronized to a NTP server frequently enough to avoid problems with communication to the exchanges.
!!! Error "Running setup.py install for gym did not run successfully."
If you get an error related with gym we suggest you to downgrade setuptools it to version 65.5.0 you can do it with the following command:
```bash
pip install setuptools==65.5.0
```
------ ------
## Requirements ## Requirements
@ -284,10 +290,8 @@ cd freqtrade
#### Freqtrade install: Conda Environment #### Freqtrade install: Conda Environment
Prepare conda-freqtrade environment, using file `environment.yml`, which exist in main freqtrade directory
```bash ```bash
conda env create -n freqtrade-conda -f environment.yml conda create --name freqtrade python=3.10
``` ```
!!! Note "Creating Conda Environment" !!! Note "Creating Conda Environment"
@ -296,12 +300,9 @@ conda env create -n freqtrade-conda -f environment.yml
```bash ```bash
# choose your own packages # choose your own packages
conda env create -n [name of the environment] [python version] [packages] conda env create -n [name of the environment] [python version] [packages]
# point to file with packages
conda env create -n [name of the environment] -f [file]
``` ```
#### Enter/exit freqtrade-conda environment #### Enter/exit freqtrade environment
To check available environments, type To check available environments, type
@ -313,7 +314,7 @@ Enter installed environment
```bash ```bash
# enter conda environment # enter conda environment
conda activate freqtrade-conda conda activate freqtrade
# exit conda environment - don't do it now # exit conda environment - don't do it now
conda deactivate conda deactivate
@ -323,6 +324,7 @@ Install last python dependencies with pip
```bash ```bash
python3 -m pip install --upgrade pip python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
python3 -m pip install -e . python3 -m pip install -e .
``` ```
@ -330,7 +332,7 @@ Patch conda libta-lib (Linux only)
```bash ```bash
# Ensure that the environment is active! # Ensure that the environment is active!
conda activate freqtrade-conda conda activate freqtrade
cd build_helpers cd build_helpers
bash install_ta-lib.sh ${CONDA_PREFIX} nosudo bash install_ta-lib.sh ${CONDA_PREFIX} nosudo
@ -349,8 +351,8 @@ conda env list
# activate base environment # activate base environment
conda activate conda activate
# activate freqtrade-conda environment # activate freqtrade environment
conda activate freqtrade-conda conda activate freqtrade
#deactivate any conda environments #deactivate any conda environments
conda deactivate conda deactivate

View File

@ -67,8 +67,6 @@ You will also have to pick a "margin mode" (explanation below) - with freqtrade
Freqtrade follows the [ccxt naming conventions for futures](https://docs.ccxt.com/en/latest/manual.html?#perpetual-swap-perpetual-future). Freqtrade follows the [ccxt naming conventions for futures](https://docs.ccxt.com/en/latest/manual.html?#perpetual-swap-perpetual-future).
A futures pair will therefore have the naming of `base/quote:settle` (e.g. `ETH/USDT:USDT`). A futures pair will therefore have the naming of `base/quote:settle` (e.g. `ETH/USDT:USDT`).
Binance is currently still an exception to this naming scheme, where pairs are named `ETH/USDT` also for futures markets, but will be aligned as soon as CCXT is ready.
### Margin mode ### Margin mode
On top of `trading_mode` - you will also have to configure your `margin_mode`. On top of `trading_mode` - you will also have to configure your `margin_mode`.
@ -92,6 +90,8 @@ One account is used to share collateral between markets (trading pairs). Margin
"margin_mode": "cross" "margin_mode": "cross"
``` ```
Please read the [exchange specific notes](exchanges.md) for exchanges that support this mode and how they differ.
## Set leverage to use ## Set leverage to use
Different strategies and risk profiles will require different levels of leverage. Different strategies and risk profiles will require different levels of leverage.

View File

@ -11,9 +11,6 @@
{% endif %} {% endif %}
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" {{ hidden }}> <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" {{ hidden }}>
<div class="md-sidebar__scrollwrap"> <div class="md-sidebar__scrollwrap">
<div id="widget-wrapper">
</div>
<div class="md-sidebar__inner"> <div class="md-sidebar__inner">
{% include "partials/nav.html" %} {% include "partials/nav.html" %}
</div> </div>
@ -44,25 +41,4 @@
<script src="https://code.jquery.com/jquery-3.4.1.min.js" <script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<!-- Load binance SDK -->
<script async defer src="https://public.bnbstatic.com/static/js/broker-sdk/broker-sdk@1.0.0.min.js"></script>
<script>
window.onload = function () {
var sidebar = document.getElementById('widget-wrapper')
var newDiv = document.createElement("div");
newDiv.id = "widget";
try {
sidebar.prepend(newDiv);
window.binanceBrokerPortalSdk.initBrokerSDK('#widget', {
apiHost: 'https://www.binance.com',
brokerId: 'R4BD3S82',
slideTime: 4e4,
});
} catch(err) {
console.log(err)
}
}
</script>
{% endblock %} {% endblock %}

View File

@ -42,14 +42,14 @@ Enable subscribing to an instance by adding the `external_message_consumer` sect
| `producers` | **Required.** List of producers <br> **Datatype:** Array. | `producers` | **Required.** List of producers <br> **Datatype:** Array.
| `producers.name` | **Required.** Name of this producer. This name must be used in calls to `get_producer_pairs()` and `get_producer_df()` if more than one producer is used.<br> **Datatype:** string | `producers.name` | **Required.** Name of this producer. This name must be used in calls to `get_producer_pairs()` and `get_producer_df()` if more than one producer is used.<br> **Datatype:** string
| `producers.host` | **Required.** The hostname or IP address from your producer.<br> **Datatype:** string | `producers.host` | **Required.** The hostname or IP address from your producer.<br> **Datatype:** string
| `producers.port` | **Required.** The port matching the above host.<br> **Datatype:** string | `producers.port` | **Required.** The port matching the above host.<br>*Defaults to `8080`.*<br> **Datatype:** Integer
| `producers.secure` | **Optional.** Use ssl in websockets connection. Default False.<br> **Datatype:** string | `producers.secure` | **Optional.** Use ssl in websockets connection. Default False.<br> **Datatype:** string
| `producers.ws_token` | **Required.** `ws_token` as configured on the producer.<br> **Datatype:** string | `producers.ws_token` | **Required.** `ws_token` as configured on the producer.<br> **Datatype:** string
| | **Optional settings** | | **Optional settings**
| `wait_timeout` | Timeout until we ping again if no message is received. <br>*Defaults to `300`.*<br> **Datatype:** Integer - in seconds. | `wait_timeout` | Timeout until we ping again if no message is received. <br>*Defaults to `300`.*<br> **Datatype:** Integer - in seconds.
| `wait_timeout` | Ping timeout <br>*Defaults to `10`.*<br> **Datatype:** Integer - in seconds. | `ping_timeout` | Ping timeout <br>*Defaults to `10`.*<br> **Datatype:** Integer - in seconds.
| `sleep_time` | Sleep time before retrying to connect.<br>*Defaults to `10`.*<br> **Datatype:** Integer - in seconds. | `sleep_time` | Sleep time before retrying to connect.<br>*Defaults to `10`.*<br> **Datatype:** Integer - in seconds.
| `remove_entry_exit_signals` | Remove signal columns from the dataframe (set them to 0) on dataframe receipt.<br>*Defaults to `10`.*<br> **Datatype:** Integer - in seconds. | `remove_entry_exit_signals` | Remove signal columns from the dataframe (set them to 0) on dataframe receipt.<br>*Defaults to `False`.*<br> **Datatype:** Boolean.
| `message_size_limit` | Size limit per message<br>*Defaults to `8`.*<br> **Datatype:** Integer - Megabytes. | `message_size_limit` | Size limit per message<br>*Defaults to `8`.*<br> **Datatype:** Integer - Megabytes.
Instead of (or as well as) calculating indicators in `populate_indicators()` the follower instance listens on the connection to a producer instance's messages (or multiple producer instances in advanced configurations) and requests the producer's most recently analyzed dataframes for each pair in the active whitelist. Instead of (or as well as) calculating indicators in `populate_indicators()` the follower instance listens on the connection to a producer instance's messages (or multiple producer instances in advanced configurations) and requests the producer's most recently analyzed dataframes for each pair in the active whitelist.

View File

@ -1,6 +1,6 @@
markdown==3.3.7 markdown==3.3.7
mkdocs==1.4.2 mkdocs==1.4.2
mkdocs-material==8.5.11 mkdocs-material==9.1.6
mdx_truly_sane_lists==1.3 mdx_truly_sane_lists==1.3
pymdown-extensions==9.9 pymdown-extensions==9.11
jinja2==3.1.2 jinja2==3.1.2

View File

@ -9,9 +9,6 @@ This same command can also be used to update freqUI, should there be a new relea
Once the bot is started in trade / dry-run mode (with `freqtrade trade`) - the UI will be available under the configured port below (usually `http://127.0.0.1:8080`). Once the bot is started in trade / dry-run mode (with `freqtrade trade`) - the UI will be available under the configured port below (usually `http://127.0.0.1:8080`).
!!! info "Alpha release"
FreqUI is still considered an alpha release - if you encounter bugs or inconsistencies please open a [FreqUI issue](https://github.com/freqtrade/frequi/issues/new/choose).
!!! Note "developers" !!! Note "developers"
Developers should not use this method, but instead use the method described in the [freqUI repository](https://github.com/freqtrade/frequi) to get the source-code of freqUI. Developers should not use this method, but instead use the method described in the [freqUI repository](https://github.com/freqtrade/frequi) to get the source-code of freqUI.
@ -163,7 +160,7 @@ python3 scripts/rest_client.py --config rest_config.json <command> [optional par
| `strategy <strategy>` | Get specific Strategy content. **Alpha** | `strategy <strategy>` | Get specific Strategy content. **Alpha**
| `available_pairs` | List available backtest data. **Alpha** | `available_pairs` | List available backtest data. **Alpha**
| `version` | Show version. | `version` | Show version.
| `sysinfo` | Show informations about the system load. | `sysinfo` | Show information about the system load.
| `health` | Show bot health (last bot loop). | `health` | Show bot health (last bot loop).
!!! Warning "Alpha status" !!! Warning "Alpha status"
@ -192,6 +189,11 @@ blacklist
:param add: List of coins to add (example: "BNB/BTC") :param add: List of coins to add (example: "BNB/BTC")
cancel_open_order
Cancel open order for trade.
:param trade_id: Cancels open orders for this trade.
count count
Return the amount of open trades. Return the amount of open trades.
@ -274,7 +276,6 @@ reload_config
Reload configuration. Reload configuration.
show_config show_config
Returns part of the configuration, relevant for trading operations. Returns part of the configuration, relevant for trading operations.
start start
@ -320,6 +321,7 @@ version
whitelist whitelist
Show the current whitelist. Show the current whitelist.
``` ```
### Message WebSocket ### Message WebSocket

View File

@ -23,10 +23,22 @@ These modes can be configured with these values:
'stoploss_on_exchange_limit_ratio': 0.99 'stoploss_on_exchange_limit_ratio': 0.99
``` ```
!!! Note Stoploss on exchange is only supported for the following exchanges, and not all exchanges support both stop-limit and stop-market.
Stoploss on exchange is only supported for Binance (stop-loss-limit), Huobi (stop-limit), Kraken (stop-loss-market, stop-loss-limit), Gateio (stop-limit), and Kucoin (stop-limit and stop-market) as of now. The Order-type will be ignored if only one mode is available.
<ins>Do not set too low/tight stoploss value if using stop loss on exchange!</ins>
If set to low/tight then you have greater risk of missing fill on the order and stoploss will not work. | Exchange | stop-loss type |
|----------|-------------|
| Binance | limit |
| Binance Futures | market, limit |
| Huobi | limit |
| kraken | market, limit |
| Gate | limit |
| Okx | limit |
| Kucoin | stop-limit, stop-market|
!!! Note "Tight stoploss"
<ins>Do not set too low/tight stoploss value when using stop loss on exchange!</ins>
If set to low/tight you will have greater risk of missing fill on the order and stoploss will not work.
### stoploss_on_exchange and stoploss_on_exchange_limit_ratio ### stoploss_on_exchange and stoploss_on_exchange_limit_ratio
@ -52,6 +64,18 @@ The bot cannot do these every 5 seconds (at each iteration), otherwise it would
So this parameter will tell the bot how often it should update the stoploss order. The default value is 60 (1 minute). So this parameter will tell the bot how often it should update the stoploss order. The default value is 60 (1 minute).
This same logic will reapply a stoploss order on the exchange should you cancel it accidentally. This same logic will reapply a stoploss order on the exchange should you cancel it accidentally.
### stoploss_price_type
!!! Warning "Only applies to futures"
`stoploss_price_type` only applies to futures markets (on exchanges where it's available).
Freqtrade will perform a validation of this setting on startup, failing to start if an invalid setting for your exchange has been selected.
Supported price types are gonna differs between each exchanges. Please check with your exchange on which price types it supports.
Stoploss on exchange on futures markets can trigger on different price types.
The naming for these prices in exchange terminology often varies, but is usually something around "last" (or "contract price" ), "mark" and "index".
Acceptable values for this setting are `"last"`, `"mark"` and `"index"` - which freqtrade will transfer automatically to the corresponding API type, and place the [stoploss on exchange](#stoploss_on_exchange-and-stoploss_on_exchange_limit_ratio) order correspondingly.
### force_exit ### force_exit
`force_exit` is an optional value, which defaults to the same value as `exit` and is used when sending a `/forceexit` command from Telegram or from the Rest API. `force_exit` is an optional value, which defaults to the same value as `exit` and is used when sending a `/forceexit` command from Telegram or from the Rest API.

View File

@ -80,7 +80,7 @@ class AwesomeStrategy(IStrategy):
## Enter Tag ## Enter Tag
When your strategy has multiple buy signals, you can name the signal that triggered. When your strategy has multiple buy signals, you can name the signal that triggered.
Then you can access you buy signal on `custom_exit` Then you can access your buy signal on `custom_exit`
```python ```python
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

View File

@ -51,7 +51,8 @@ During hyperopt, this runs only once at startup.
## Bot loop start ## Bot loop start
A simple callback which is called once at the start of every bot throttling iteration (roughly every 5 seconds, unless configured differently). A simple callback which is called once at the start of every bot throttling iteration in dry/live mode (roughly every 5
seconds, unless configured differently) or once per candle in backtest/hyperopt mode.
This can be used to perform calculations which are pair independent (apply to all pairs), loading of external data, etc. This can be used to perform calculations which are pair independent (apply to all pairs), loading of external data, etc.
``` python ``` python
@ -61,11 +62,12 @@ class AwesomeStrategy(IStrategy):
# ... populate_* methods # ... populate_* methods
def bot_loop_start(self, **kwargs) -> None: def bot_loop_start(self, current_time: datetime, **kwargs) -> None:
""" """
Called at the start of the bot iteration (one loop). Called at the start of the bot iteration (one loop).
Might be used to perform pair-independent tasks Might be used to perform pair-independent tasks
(e.g. gather some remote resource for comparison) (e.g. gather some remote resource for comparison)
:param current_time: datetime object, containing the current datetime
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
""" """
if self.config['runmode'].value in ('live', 'dry_run'): if self.config['runmode'].value in ('live', 'dry_run'):
@ -316,11 +318,11 @@ class AwesomeStrategy(IStrategy):
# evaluate highest to lowest, so that highest possible stop is used # evaluate highest to lowest, so that highest possible stop is used
if current_profit > 0.40: if current_profit > 0.40:
return stoploss_from_open(0.25, current_profit, is_short=trade.is_short) return stoploss_from_open(0.25, current_profit, is_short=trade.is_short, leverage=trade.leverage)
elif current_profit > 0.25: elif current_profit > 0.25:
return stoploss_from_open(0.15, current_profit, is_short=trade.is_short) return stoploss_from_open(0.15, current_profit, is_short=trade.is_short, leverage=trade.leverage)
elif current_profit > 0.20: elif current_profit > 0.20:
return stoploss_from_open(0.07, current_profit, is_short=trade.is_short) return stoploss_from_open(0.07, current_profit, is_short=trade.is_short, leverage=trade.leverage)
# return maximum stoploss value, keeping current stoploss price unchanged # return maximum stoploss value, keeping current stoploss price unchanged
return 1 return 1
@ -659,6 +661,7 @@ Position adjustments will always be applied in the direction of the trade, so a
!!! Warning "Backtesting" !!! Warning "Backtesting"
During backtesting this callback is called for each candle in `timeframe` or `timeframe_detail`, so run-time performance will be affected. During backtesting this callback is called for each candle in `timeframe` or `timeframe_detail`, so run-time performance will be affected.
This can also cause deviating results between live and backtesting, since backtesting can adjust the trade only once per candle, whereas live could adjust the trade multiple times per candle.
``` python ``` python
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
@ -827,7 +830,7 @@ class AwesomeStrategy(IStrategy):
""" """
# Limit orders to use and follow SMA200 as price target for the first 10 minutes since entry trigger for BTC/USDT pair. # Limit orders to use and follow SMA200 as price target for the first 10 minutes since entry trigger for BTC/USDT pair.
if pair == 'BTC/USDT' and entry_tag == 'long_sma200' and side == 'long' and (current_time - timedelta(minutes=10) > trade.open_date_utc: if pair == 'BTC/USDT' and entry_tag == 'long_sma200' and side == 'long' and (current_time - timedelta(minutes=10)) > trade.open_date_utc:
# just cancel the order if it has been filled more than half of the amount # just cancel the order if it has been filled more than half of the amount
if order.filled > order.remaining: if order.filled > order.remaining:
return None return None

View File

@ -881,7 +881,7 @@ All columns of the informative dataframe will be available on the returning data
### *stoploss_from_open()* ### *stoploss_from_open()*
Stoploss values returned from `custom_stoploss` must specify a percentage relative to `current_rate`, but sometimes you may want to specify a stoploss relative to the open price instead. `stoploss_from_open()` is a helper function to calculate a stoploss value that can be returned from `custom_stoploss` which will be equivalent to the desired percentage above the open price. Stoploss values returned from `custom_stoploss` must specify a percentage relative to `current_rate`, but sometimes you may want to specify a stoploss relative to the entry point instead. `stoploss_from_open()` is a helper function to calculate a stoploss value that can be returned from `custom_stoploss` which will be equivalent to the desired trade profit above the entry point.
??? Example "Returning a stoploss relative to the open price from the custom stoploss function" ??? Example "Returning a stoploss relative to the open price from the custom stoploss function"
@ -889,6 +889,8 @@ Stoploss values returned from `custom_stoploss` must specify a percentage relati
If we want a stop price at 7% above the open price we can call `stoploss_from_open(0.07, current_profit, False)` which will return `0.1157024793`. 11.57% below $121 is $107, which is the same as 7% above $100. If we want a stop price at 7% above the open price we can call `stoploss_from_open(0.07, current_profit, False)` which will return `0.1157024793`. 11.57% below $121 is $107, which is the same as 7% above $100.
This function will consider leverage - so at 10x leverage, the actual stoploss would be 0.7% above $100 (0.7% * 10x = 7%).
``` python ``` python
@ -907,7 +909,7 @@ Stoploss values returned from `custom_stoploss` must specify a percentage relati
# once the profit has risen above 10%, keep the stoploss at 7% above the open price # once the profit has risen above 10%, keep the stoploss at 7% above the open price
if current_profit > 0.10: if current_profit > 0.10:
return stoploss_from_open(0.07, current_profit, is_short=trade.is_short) return stoploss_from_open(0.07, current_profit, is_short=trade.is_short, leverage=trade.leverage)
return 1 return 1
@ -954,12 +956,14 @@ In some situations it may be confusing to deal with stops relative to current ra
## Additional data (Wallets) ## Additional data (Wallets)
The strategy provides access to the `Wallets` object. This contains the current balances on the exchange. The strategy provides access to the `wallets` object. This contains the current balances on the exchange.
!!! Note !!! Note "Backtesting / Hyperopt"
Wallets is not available during backtesting / hyperopt. Wallets behaves differently depending on the function it's called.
Within `populate_*()` methods, it'll return the full wallet as configured.
Within [callbacks](strategy-callbacks.md), you'll get the wallet state corresponding to the actual simulated wallet at that point in the simulation process.
Please always check if `Wallets` is available to avoid failures during backtesting. Please always check if `wallets` is available to avoid failures during backtesting.
``` python ``` python
if self.wallets: if self.wallets:
@ -989,38 +993,18 @@ from freqtrade.persistence import Trade
The following example queries for the current pair and trades from today, however other filters can easily be added. The following example queries for the current pair and trades from today, however other filters can easily be added.
``` python ``` python
if self.config['runmode'].value in ('live', 'dry_run'): trades = Trade.get_trades_proxy(pair=metadata['pair'],
trades = Trade.get_trades([Trade.pair == metadata['pair'], open_date=datetime.now(timezone.utc) - timedelta(days=1),
Trade.open_date > datetime.utcnow() - timedelta(days=1), is_open=False,
Trade.is_open.is_(False), ]).order_by(Trade.close_date).all()
]).order_by(Trade.close_date).all() # Summarize profit for this pair.
# Summarize profit for this pair. curdayprofit = sum(trade.close_profit for trade in trades)
curdayprofit = sum(trade.close_profit for trade in trades)
``` ```
Get amount of stake_currency currently invested in Trades: For a full list of available methods, please consult the [Trade object](trade-object.md) documentation.
``` python
if self.config['runmode'].value in ('live', 'dry_run'):
total_stakes = Trade.total_open_trades_stakes()
```
Retrieve performance per pair.
Returns a List of dicts per pair.
``` python
if self.config['runmode'].value in ('live', 'dry_run'):
performance = Trade.get_overall_performance()
```
Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of 0.015).
``` json
{"pair": "ETH/BTC", "profit": 0.015, "count": 5}
```
!!! Warning !!! Warning
Trade history is not available during backtesting or hyperopt. Trade history is not available in `populate_*` methods during backtesting or hyperopt, and will result in empty results.
## Prevent trades from happening for a specific pair ## Prevent trades from happening for a specific pair
@ -1056,11 +1040,10 @@ from datetime import timedelta, datetime, timezone
# Within populate indicators (or populate_buy): # Within populate indicators (or populate_buy):
if self.config['runmode'].value in ('live', 'dry_run'): if self.config['runmode'].value in ('live', 'dry_run'):
# fetch closed trades for the last 2 days # fetch closed trades for the last 2 days
trades = Trade.get_trades([Trade.pair == metadata['pair'], trades = Trade.get_trades_proxy(
Trade.open_date > datetime.utcnow() - timedelta(days=2), pair=metadata['pair'], is_open=False,
Trade.is_open.is_(False), open_date=datetime.now(timezone.utc) - timedelta(days=2))
]).all()
# Analyze the conditions you'd like to lock the pair .... will probably be different for every strategy # Analyze the conditions you'd like to lock the pair .... will probably be different for every strategy
sumprofit = sum(trade.close_profit for trade in trades) sumprofit = sum(trade.close_profit for trade in trades)
if sumprofit < 0: if sumprofit < 0:

View File

@ -80,6 +80,7 @@ from freqtrade.resolvers import StrategyResolver
from freqtrade.data.dataprovider import DataProvider from freqtrade.data.dataprovider import DataProvider
strategy = StrategyResolver.load_strategy(config) strategy = StrategyResolver.load_strategy(config)
strategy.dp = DataProvider(config, None, None) strategy.dp = DataProvider(config, None, None)
strategy.ft_bot_start()
# Generate buy/sell signals using strategy # Generate buy/sell signals using strategy
df = strategy.analyze_ticker(candles, {'pair': pair}) df = strategy.analyze_ticker(candles, {'pair': pair})

View File

@ -477,3 +477,254 @@ after:
"ignore_buying_expired_candle_after": 120 "ignore_buying_expired_candle_after": 120
} }
``` ```
## FreqAI strategy
The `populate_any_indicators()` method has been split into `feature_engineering_expand_all()`, `feature_engineering_expand_basic()`, `feature_engineering_standard()` and`set_freqai_targets()`.
For each new function, the pair (and timeframe where necessary) will be automatically added to the column.
As such, the definition of features becomes much simpler with the new logic.
For a full explanation of each method, please go to the corresponding [freqAI documentation page](freqai-feature-engineering.md#defining-the-features)
``` python linenums="1" hl_lines="12-37 39-42 63-65 67-75"
def populate_any_indicators(
self, pair, df, tf, informative=None, set_generalized_indicators=False
):
if informative is None:
informative = self.dp.get_pair_dataframe(pair, tf)
# first loop is automatically duplicating indicators for time periods
for t in self.freqai_info["feature_parameters"]["indicator_periods_candles"]:
t = int(t)
informative[f"%-{pair}rsi-period_{t}"] = ta.RSI(informative, timeperiod=t)
informative[f"%-{pair}mfi-period_{t}"] = ta.MFI(informative, timeperiod=t)
informative[f"%-{pair}adx-period_{t}"] = ta.ADX(informative, timeperiod=t)
informative[f"%-{pair}sma-period_{t}"] = ta.SMA(informative, timeperiod=t)
informative[f"%-{pair}ema-period_{t}"] = ta.EMA(informative, timeperiod=t)
bollinger = qtpylib.bollinger_bands(
qtpylib.typical_price(informative), window=t, stds=2.2
)
informative[f"{pair}bb_lowerband-period_{t}"] = bollinger["lower"]
informative[f"{pair}bb_middleband-period_{t}"] = bollinger["mid"]
informative[f"{pair}bb_upperband-period_{t}"] = bollinger["upper"]
informative[f"%-{pair}bb_width-period_{t}"] = (
informative[f"{pair}bb_upperband-period_{t}"]
- informative[f"{pair}bb_lowerband-period_{t}"]
) / informative[f"{pair}bb_middleband-period_{t}"]
informative[f"%-{pair}close-bb_lower-period_{t}"] = (
informative["close"] / informative[f"{pair}bb_lowerband-period_{t}"]
)
informative[f"%-{pair}roc-period_{t}"] = ta.ROC(informative, timeperiod=t)
informative[f"%-{pair}relative_volume-period_{t}"] = (
informative["volume"] / informative["volume"].rolling(t).mean()
) # (1)
informative[f"%-{pair}pct-change"] = informative["close"].pct_change()
informative[f"%-{pair}raw_volume"] = informative["volume"]
informative[f"%-{pair}raw_price"] = informative["close"]
# (2)
indicators = [col for col in informative if col.startswith("%")]
# This loop duplicates and shifts all indicators to add a sense of recency to data
for n in range(self.freqai_info["feature_parameters"]["include_shifted_candles"] + 1):
if n == 0:
continue
informative_shift = informative[indicators].shift(n)
informative_shift = informative_shift.add_suffix("_shift-" + str(n))
informative = pd.concat((informative, informative_shift), axis=1)
df = merge_informative_pair(df, informative, self.config["timeframe"], tf, ffill=True)
skip_columns = [
(s + "_" + tf) for s in ["date", "open", "high", "low", "close", "volume"]
]
df = df.drop(columns=skip_columns)
# Add generalized indicators here (because in live, it will call this
# function to populate indicators during training). Notice how we ensure not to
# add them multiple times
if set_generalized_indicators:
df["%-day_of_week"] = (df["date"].dt.dayofweek + 1) / 7
df["%-hour_of_day"] = (df["date"].dt.hour + 1) / 25
# (3)
# user adds targets here by prepending them with &- (see convention below)
df["&-s_close"] = (
df["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ df["close"]
- 1
) # (4)
return df
```
1. Features - Move to `feature_engineering_expand_all`
2. Basic features, not expanded across `include_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()`.
### freqai - feature engineering expand all
Features will now expand automatically. As such, the expansion loops, as well as the `{pair}` / `{timeframe}` parts will need to be removed.
``` python linenums="1"
def feature_engineering_expand_all(self, dataframe, period, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
This function will automatically expand the defined features on the config defined
`indicator_periods_candles`, `include_timeframes`, `include_shifted_candles`, and
`include_corr_pairs`. In other words, a single feature defined in this function
will automatically expand to a total of
`indicator_periods_candles` * `include_timeframes` * `include_shifted_candles` *
`include_corr_pairs` numbers of features added to the model.
All features must be prepended with `%` to be recognized by FreqAI internals.
More details on how these config defined parameters accelerate feature engineering
in the documentation at:
https://www.freqtrade.io/en/latest/freqai-parameter-table/#feature-parameters
https://www.freqtrade.io/en/latest/freqai-feature-engineering/#defining-the-features
:param df: strategy dataframe which will receive the features
:param period: period of the indicator - usage example:
dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
"""
dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
dataframe["%-mfi-period"] = ta.MFI(dataframe, timeperiod=period)
dataframe["%-adx-period"] = ta.ADX(dataframe, timeperiod=period)
dataframe["%-sma-period"] = ta.SMA(dataframe, timeperiod=period)
dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
bollinger = qtpylib.bollinger_bands(
qtpylib.typical_price(dataframe), window=period, stds=2.2
)
dataframe["bb_lowerband-period"] = bollinger["lower"]
dataframe["bb_middleband-period"] = bollinger["mid"]
dataframe["bb_upperband-period"] = bollinger["upper"]
dataframe["%-bb_width-period"] = (
dataframe["bb_upperband-period"]
- dataframe["bb_lowerband-period"]
) / dataframe["bb_middleband-period"]
dataframe["%-close-bb_lower-period"] = (
dataframe["close"] / dataframe["bb_lowerband-period"]
)
dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period)
dataframe["%-relative_volume-period"] = (
dataframe["volume"] / dataframe["volume"].rolling(period).mean()
)
return dataframe
```
### Freqai - feature engineering basic
Basic features. Make sure to remove the `{pair}` part from your features.
``` python linenums="1"
def feature_engineering_expand_basic(self, dataframe, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
This function will automatically expand the defined features on the config defined
`include_timeframes`, `include_shifted_candles`, and `include_corr_pairs`.
In other words, a single feature defined in this function
will automatically expand to a total of
`include_timeframes` * `include_shifted_candles` * `include_corr_pairs`
numbers of features added to the model.
Features defined here will *not* be automatically duplicated on user defined
`indicator_periods_candles`
All features must be prepended with `%` to be recognized by FreqAI internals.
More details on how these config defined parameters accelerate feature engineering
in the documentation at:
https://www.freqtrade.io/en/latest/freqai-parameter-table/#feature-parameters
https://www.freqtrade.io/en/latest/freqai-feature-engineering/#defining-the-features
:param df: strategy dataframe which will receive the features
dataframe["%-pct-change"] = dataframe["close"].pct_change()
dataframe["%-ema-200"] = ta.EMA(dataframe, timeperiod=200)
"""
dataframe["%-pct-change"] = dataframe["close"].pct_change()
dataframe["%-raw_volume"] = dataframe["volume"]
dataframe["%-raw_price"] = dataframe["close"]
return dataframe
```
### FreqAI - feature engineering standard
``` python linenums="1"
def feature_engineering_standard(self, dataframe, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
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 created by all other
freqai_feature_engineering_* functions.
This function is a good place to do custom exotic feature extractions (e.g. tsfresh).
This function is a good place for any feature that should not be auto-expanded upon
(e.g. day of the week).
All features must be prepended with `%` to be recognized by FreqAI internals.
More details about feature engineering available:
https://www.freqtrade.io/en/latest/freqai-feature-engineering
:param df: strategy dataframe which will receive the features
usage example: dataframe["%-day_of_week"] = (dataframe["date"].dt.dayofweek + 1) / 7
"""
dataframe["%-day_of_week"] = dataframe["date"].dt.dayofweek
dataframe["%-hour_of_day"] = dataframe["date"].dt.hour
return dataframe
```
### FreqAI - set Targets
Targets now get their own, dedicated method.
``` python linenums="1"
def set_freqai_targets(self, dataframe, **kwargs):
"""
*Only functional with FreqAI enabled strategies*
Required function to set the targets for the model.
All targets must be prepended with `&` to be recognized by the FreqAI internals.
More details about feature engineering available:
https://www.freqtrade.io/en/latest/freqai-feature-engineering
:param df: strategy dataframe which will receive the targets
usage example: dataframe["&-target"] = dataframe["close"].shift(-1) / dataframe["close"]
"""
dataframe["&-s_close"] = (
dataframe["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ dataframe["close"]
- 1
)
return dataframe
```

View File

@ -11,18 +11,3 @@
.rst-versions .rst-other-versions { .rst-versions .rst-other-versions {
color: white; color: white;
} }
#widget-wrapper {
height: calc(220px * 0.5625 + 18px);
width: 220px;
margin: 0 auto 16px auto;
border-style: solid;
border-color: var(--md-code-bg-color);
border-width: 1px;
border-radius: 5px;
}
@media screen and (max-width: calc(76.25em - 1px)) {
#widget-wrapper { display: none; }
}

View File

@ -152,7 +152,7 @@ You can create your own keyboard in `config.json`:
!!! Note "Supported Commands" !!! Note "Supported Commands"
Only the following commands are allowed. Command arguments are not supported! Only the following commands are allowed. Command arguments are not supported!
`/start`, `/stop`, `/status`, `/status table`, `/trades`, `/profit`, `/performance`, `/daily`, `/stats`, `/count`, `/locks`, `/balance`, `/stopentry`, `/reload_config`, `/show_config`, `/logs`, `/whitelist`, `/blacklist`, `/edge`, `/help`, `/version` `/start`, `/stop`, `/status`, `/status table`, `/trades`, `/profit`, `/performance`, `/daily`, `/stats`, `/count`, `/locks`, `/balance`, `/stopentry`, `/reload_config`, `/show_config`, `/logs`, `/whitelist`, `/blacklist`, `/edge`, `/help`, `/version`, `/marketdir`
## Telegram commands ## Telegram commands
@ -162,26 +162,34 @@ official commands. You can ask at any moment for help with `/help`.
| Command | Description | | Command | Description |
|----------|-------------| |----------|-------------|
| **System commands**
| `/start` | Starts the trader | `/start` | Starts the trader
| `/stop` | Stops the trader | `/stop` | Stops the trader
| `/stopbuy | /stopentry` | Stops the trader from opening new trades. Gracefully closes open trades according to their rules. | `/stopbuy | /stopentry` | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `/reload_config` | Reloads the configuration file | `/reload_config` | Reloads the configuration file
| `/show_config` | Shows part of the current configuration with relevant settings to operation | `/show_config` | Shows part of the current configuration with relevant settings to operation
| `/logs [limit]` | Show last log messages. | `/logs [limit]` | Show last log messages.
| `/help` | Show help message
| `/version` | Show version
| **Status** |
| `/status` | Lists all open trades | `/status` | Lists all open trades
| `/status <trade_id>` | Lists one or more specific trade. Separate multiple <trade_id> with a blank space. | `/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 (**) | `/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 (**)
| `/trades [limit]` | List all recently closed trades in a table format. | `/trades [limit]` | List all recently closed trades in a table format.
| `/delete <trade_id>` | Delete a specific trade from the Database. Tries to close open orders. Requires manual handling of this trade on the exchange.
| `/count` | Displays number of trades used and available | `/count` | Displays number of trades used and available
| `/locks` | Show currently locked pairs. | `/locks` | Show currently locked pairs.
| `/unlock <pair or lock_id>` | Remove the lock for this pair (or for this lock id). | `/unlock <pair or lock_id>` | Remove the lock for this pair (or for this lock id).
| `/profit [<n>]` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default) | `/marketdir [long | short | even | none]` | Updates the user managed variable that represents the current market direction. If no direction is provided, the currently set direction will be displayed.
| **Modify Trade states** |
| `/forceexit <trade_id> | /fx <tradeid>` | Instantly exits the given trade (Ignoring `minimum_roi`). | `/forceexit <trade_id> | /fx <tradeid>` | Instantly exits the given trade (Ignoring `minimum_roi`).
| `/forceexit all | /fx all` | Instantly exits all open trades (Ignoring `minimum_roi`). | `/forceexit all | /fx all` | Instantly exits all open trades (Ignoring `minimum_roi`).
| `/fx` | alias for `/forceexit` | `/fx` | alias for `/forceexit`
| `/forcelong <pair> [rate]` | Instantly buys the given pair. Rate is optional and only applies to limit orders. (`force_entry_enable` must be set to True) | `/forcelong <pair> [rate]` | Instantly buys the given pair. Rate is optional and only applies to limit orders. (`force_entry_enable` must be set to True)
| `/forceshort <pair> [rate]` | Instantly shorts the given pair. Rate is optional and only applies to limit orders. This will only work on non-spot markets. (`force_entry_enable` must be set to True) | `/forceshort <pair> [rate]` | Instantly shorts the given pair. Rate is optional and only applies to limit orders. This will only work on non-spot markets. (`force_entry_enable` must be set to True)
| `/delete <trade_id>` | Delete a specific trade from the Database. Tries to close open orders. Requires manual handling of this trade on the exchange.
| `/cancel_open_order <trade_id> | /coo <trade_id>` | Cancel an open order for a trade.
| **Metrics** |
| `/profit [<n>]` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default)
| `/performance` | Show performance of each finished trade grouped by pair | `/performance` | Show performance of each finished trade grouped by pair
| `/balance` | Show account balance per currency | `/balance` | Show account balance per currency
| `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7) | `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7)
@ -193,8 +201,7 @@ official commands. You can ask at any moment for help with `/help`.
| `/whitelist [sorted] [baseonly]` | Show the current whitelist. Optionally display in alphabetical order and/or with just the base currency of each pairing. | `/whitelist [sorted] [baseonly]` | Show the current whitelist. Optionally display in alphabetical order and/or with just the base currency of each pairing.
| `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist. | `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist.
| `/edge` | Show validated pairs by Edge if it is enabled. | `/edge` | Show validated pairs by Edge if it is enabled.
| `/help` | Show help message
| `/version` | Show version
## Telegram commands in action ## Telegram commands in action
@ -236,7 +243,7 @@ Enter Tag is configurable via Strategy.
> **Enter Tag:** Awesome Long Signal > **Enter Tag:** Awesome Long Signal
> **Open Rate:** `0.00007489` > **Open Rate:** `0.00007489`
> **Current Rate:** `0.00007489` > **Current Rate:** `0.00007489`
> **Current Profit:** `12.95%` > **Unrealized Profit:** `12.95%`
> **Stoploss:** `0.00007389 (-0.02%)` > **Stoploss:** `0.00007389 (-0.02%)`
### /status table ### /status table
@ -272,6 +279,7 @@ Return a summary of your profit/loss and performance.
> ∙ `33.095 EUR` > ∙ `33.095 EUR`
> >
> **Total Trade Count:** `138` > **Total Trade Count:** `138`
> **Bot started:** `2022-07-11 18:40:44`
> **First Trade opened:** `3 days ago` > **First Trade opened:** `3 days ago`
> **Latest Trade opened:** `2 minutes ago` > **Latest Trade opened:** `2 minutes ago`
> **Avg. Duration:** `2:33:45` > **Avg. Duration:** `2:33:45`
@ -285,6 +293,7 @@ The relative profit of `15.2 Σ%` is be based on the starting capital - so in th
Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits. Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits.
Profit Factor is calculated as gross profits / gross losses - and should serve as an overall metric for the strategy. Profit Factor is calculated as gross profits / gross losses - and should serve as an overall metric for the strategy.
Max drawdown corresponds to the backtesting metric `Absolute Drawdown (Account)` - calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`. Max drawdown corresponds to the backtesting metric `Absolute Drawdown (Account)` - calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`.
Bot started date will refer to the date the bot was first started. For older bots, this will default to the first trade's open date.
### /forceexit <trade_id> ### /forceexit <trade_id>
@ -410,3 +419,27 @@ ARDR/ETH 0.366667 0.143059 -0.01
### /version ### /version
> **Version:** `0.14.3` > **Version:** `0.14.3`
### /marketdir
If a market direction is provided the command updates the user managed variable that represents the current market direction.
This variable is not set to any valid market direction on bot startup and must be set by the user. The example below is for `/marketdir long`:
```
Successfully updated marketdirection from none to long.
```
If no market direction is provided the command outputs the currently set market directions. The example below is for `/marketdir`:
```
Currently set marketdirection: even
```
You can use the market direction in your strategy via `self.market_direction`.
!!! Warning "Bot restarts"
Please note that the market direction is not persisted, and will be reset after a bot restart/reload.
!!! Danger "Backtesting"
As this value/variable is intended to be changed manually in dry/live trading.
Strategies using `market_direction` will probably not produce reliable, reproducible results (changes to this variable will not be reflected for backtesting). Use at your own risk.

148
docs/trade-object.md Normal file
View File

@ -0,0 +1,148 @@
# Trade Object
## Trade
A position freqtrade enters is stored in a `Trade` object - which is persisted to the database.
It's a core concept of freqtrade - and something you'll come across in many sections of the documentation, which will most likely point you to this location.
It will be passed to the strategy in many [strategy callbacks](strategy-callbacks.md). The object passed to the strategy cannot be modified directly. Indirect modifications may occur based on callback results.
## Trade - Available attributes
The following attributes / properties are available for each individual trade - and can be used with `trade.<property>` (e.g. `trade.pair`).
| Attribute | DataType | Description |
|------------|-------------|-------------|
`pair`| string | Pair of this trade
`is_open`| boolean | Is the trade currently open, or has it been concluded
`open_rate`| float | Rate this trade was entered at (Avg. entry rate in case of trade-adjustments)
`close_rate`| float | Close rate - only set when is_open = False
`stake_amount`| float | Amount in Stake (or Quote) currency.
`amount`| float | Amount in Asset / Base currency that is currently owned.
`open_date`| datetime | Timestamp when trade was opened **use `open_date_utc` instead**
`open_date_utc`| datetime | Timestamp when trade was opened - in UTC
`close_date`| datetime | Timestamp when trade was closed **use `close_date_utc` instead**
`close_date_utc`| datetime | Timestamp when trade was closed - in UTC
`close_profit`| float | Relative profit at the time of trade closure. `0.01` == 1%
`close_profit_abs`| float | Absolute profit (in stake currency) at the time of trade closure.
`leverage` | float | Leverage used for this trade - defaults to 1.0 in spot markets.
`enter_tag`| string | Tag provided on entry via the `enter_tag` column in the dataframe
`is_short` | boolean | True for short trades, False otherwise
`orders` | Order[] | List of order objects attached to this trade (includes both filled and cancelled orders)
`date_last_filled_utc` | datetime | Time of the last filled order
`entry_side` | "buy" / "sell" | Order Side the trade was entered
`exit_side` | "buy" / "sell" | Order Side that will result in a trade exit / position reduction.
`trade_direction` | "long" / "short" | Trade direction in text - long or short.
`nr_of_successful_entries` | int | Number of successful (filled) entry orders
`nr_of_successful_exits` | int | Number of successful (filled) exit orders
## Class methods
The following are class methods - which return generic information, and usually result in an explicit query against the database.
They can be used as `Trade.<method>` - e.g. `open_trades = Trade.get_open_trade_count()`
!!! Warning "Backtesting/hyperopt"
Most methods will work in both backtesting / hyperopt and live/dry modes.
During backtesting, it's limited to usage in [strategy callbacks](strategy-callbacks.md). Usage in `populate_*()` methods is not supported and will result in wrong results.
### get_trades_proxy
When your strategy needs some information on existing (open or close) trades - it's best to use `Trade.get_trades_proxy()`.
Usage:
``` python
from freqtrade.persistence import Trade
from datetime import timedelta
# ...
trade_hist = Trade.get_trades_proxy(pair='ETH/USDT', is_open=False, open_date=current_date - timedelta(days=2))
```
`get_trades_proxy()` supports the following keyword arguments. All arguments are optional - calling `get_trades_proxy()` without arguments will return a list of all trades in the database.
* `pair` e.g. `pair='ETH/USDT'`
* `is_open` e.g. `is_open=False`
* `open_date` e.g. `open_date=current_date - timedelta(days=2)`
* `close_date` e.g. `close_date=current_date - timedelta(days=5)`
### get_open_trade_count
Get the number of currently open trades
``` python
from freqtrade.persistence import Trade
# ...
open_trades = Trade.get_open_trade_count()
```
### get_total_closed_profit
Retrieve the total profit the bot has generated so far.
Aggregates `close_profit_abs` for all closed trades.
``` python
from freqtrade.persistence import Trade
# ...
profit = Trade.get_total_closed_profit()
```
### total_open_trades_stakes
Retrieve the total stake_amount that's currently in trades.
``` python
from freqtrade.persistence import Trade
# ...
profit = Trade.total_open_trades_stakes()
```
### get_overall_performance
Retrieve the overall performance - similar to the `/performance` telegram command.
``` python
from freqtrade.persistence import Trade
# ...
if self.config['runmode'].value in ('live', 'dry_run'):
performance = Trade.get_overall_performance()
```
Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of 0.015).
``` json
{"pair": "ETH/BTC", "profit": 0.015, "count": 5}
```
## Order Object
An `Order` object represents an order on the exchange (or a simulated order in dry-run mode).
An `Order` object will always be tied to it's corresponding [`Trade`](#trade-object), and only really makes sense in the context of a trade.
### Order - Available attributes
an Order object is typically attached to a trade.
Most properties here can be None as they are dependant on the exchange response.
| Attribute | DataType | Description |
|------------|-------------|-------------|
`trade` | Trade | Trade object this order is attached to
`ft_pair` | string | Pair this order is for
`ft_is_open` | boolean | is the order filled?
`order_type` | string | Order type as defined on the exchange - usually market, limit or stoploss
`status` | string | Status as defined by ccxt. Usually open, closed, expired or canceled
`side` | string | Buy or Sell
`price` | float | Price the order was placed at
`average` | float | Average price the order filled at
`amount` | float | Amount in base currency
`filled` | float | Filled amount (in base currency)
`remaining` | float | Remaining amount
`cost` | float | Cost of the order - usually average * filled
`order_date` | datetime | Order creation date **use `order_date_utc` instead**
`order_date_utc` | datetime | Order creation date (in UTC)
`order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead**
`order_fill_date_utc` | datetime | Order fill date

View File

@ -955,3 +955,47 @@ Print trades with id 2 and 3 as json
``` bash ``` bash
freqtrade show-trades --db-url sqlite:///tradesv3.sqlite --trade-ids 2 3 --print-json freqtrade show-trades --db-url sqlite:///tradesv3.sqlite --trade-ids 2 3 --print-json
``` ```
### Strategy-Updater
Updates listed strategies or all strategies within the strategies folder to be v3 compliant.
If the command runs without --strategy-list then all strategies inside the strategies folder will be converted.
Your original strategy will remain available in the `user_data/strategies_orig_updater/` directory.
!!! Warning "Conversion results"
Strategy updater will work on a "best effort" approach. Please do your due diligence and verify the results of the conversion.
We also recommend to run a python formatter (e.g. `black`) to format results in a sane manner.
```
usage: freqtrade strategy-updater [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
options:
-h, --help show this help message and exit
--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]
Provide a space-separated list of strategies to
backtest. Please note that timeframe needs to be set
either in config or via command line. When using this
together with `--export trades`, the strategy-name is
injected into the filename (so `backtest-data.json`
becomes `backtest-data-SampleStrategy.json`
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--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:
`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.
```

View File

@ -26,7 +26,7 @@ Install ta-lib according to the [ta-lib documentation](https://github.com/mrjbq7
As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial pre-compiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which need to be downloaded and installed using `pip install TA_Lib-0.4.25-cp38-cp38-win_amd64.whl` (make sure to use the version matching your python version). As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial pre-compiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which need to be downloaded and installed using `pip install TA_Lib-0.4.25-cp38-cp38-win_amd64.whl` (make sure to use the version matching your python version).
Freqtrade provides these dependencies for the latest 3 Python versions (3.8, 3.9 and 3.10) and for 64bit Windows. Freqtrade provides these dependencies for the latest 3 Python versions (3.8, 3.9, 3.10 and 3.11) and for 64bit Windows.
Other versions must be downloaded from the above link. Other versions must be downloaded from the above link.
``` powershell ``` powershell

View File

@ -1,75 +0,0 @@
name: freqtrade
channels:
- conda-forge
# - defaults
dependencies:
# 1/4 req main
- python>=3.8,<=3.10
- numpy
- pandas
- pip
- py-find-1st
- aiohttp
- SQLAlchemy
- python-telegram-bot
- arrow
- cachetools
- requests
- urllib3
- jsonschema
- TA-Lib
- tabulate
- jinja2
- blosc
- sdnotify
- fastapi
- uvicorn
- pyjwt
- aiofiles
- psutil
- colorama
- questionary
- prompt-toolkit
- schedule
- python-dateutil
- joblib
- pyarrow
# ============================
# 2/4 req dev
- coveralls
- flake8
- mypy
- pytest
- pytest-asyncio
- pytest-cov
- pytest-mock
- isort
- nbconvert
# ============================
# 3/4 req hyperopt
- scipy
- scikit-learn
- filelock
- scikit-optimize
- progressbar2
# ============================
# 4/4 req plot
- plotly
- jupyter
- pip:
- pycoingecko
# - py_find_1st
- tables
- pytest-random-order
- ccxt
- flake8-tidy-imports
- -e .
# - python-rapidjso

View File

@ -1,19 +1,20 @@
""" Freqtrade bot """ """ Freqtrade bot """
__version__ = '2022.12.dev' __version__ = '2023.4.dev'
if 'dev' in __version__: if 'dev' in __version__:
from pathlib import Path
try: try:
import subprocess import subprocess
freqtrade_basedir = Path(__file__).parent
__version__ = __version__ + '-' + subprocess.check_output( __version__ = __version__ + '-' + subprocess.check_output(
['git', 'log', '--format="%h"', '-n 1'], ['git', 'log', '--format="%h"', '-n 1'],
stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"') stderr=subprocess.DEVNULL, cwd=freqtrade_basedir).decode("utf-8").rstrip().strip('"')
except Exception: # pragma: no cover except Exception: # pragma: no cover
# git not available, ignore # git not available, ignore
try: try:
# Try Fallback to freqtrade_commit file (created by CI while building docker image) # Try Fallback to freqtrade_commit file (created by CI while building docker image)
from pathlib import Path
versionfile = Path('./freqtrade_commit') versionfile = Path('./freqtrade_commit')
if versionfile.is_file(): if versionfile.is_file():
__version__ = f"docker-{__version__}-{versionfile.read_text()[:8]}" __version__ = f"docker-{__version__}-{versionfile.read_text()[:8]}"

0
freqtrade/__main__.py Normal file → Executable file
View File

View File

@ -22,5 +22,6 @@ from freqtrade.commands.optimize_commands import (start_backtesting, start_backt
start_edge, start_hyperopt) start_edge, start_hyperopt)
from freqtrade.commands.pairlist_commands import start_test_pairlist from freqtrade.commands.pairlist_commands import start_test_pairlist
from freqtrade.commands.plot_commands import start_plot_dataframe, start_plot_profit from freqtrade.commands.plot_commands import start_plot_dataframe, start_plot_profit
from freqtrade.commands.strategy_utils_commands import start_strategy_update
from freqtrade.commands.trade_commands import start_trading from freqtrade.commands.trade_commands import start_trading
from freqtrade.commands.webserver_commands import start_webserver from freqtrade.commands.webserver_commands import start_webserver

4
freqtrade/commands/analyze_commands.py Executable file → Normal file
View File

@ -40,8 +40,8 @@ def setup_analyze_configuration(args: Dict[str, Any], method: RunMode) -> Dict[s
if (not Path(signals_file).exists()): if (not Path(signals_file).exists()):
raise OperationalException( raise OperationalException(
(f"Cannot find latest backtest signals file: {signals_file}." f"Cannot find latest backtest signals file: {signals_file}."
"Run backtesting with `--export signals`.") "Run backtesting with `--export signals`."
) )
return config return config

View File

@ -111,10 +111,13 @@ ARGS_ANALYZE_ENTRIES_EXITS = ["exportfilename", "analysis_groups", "enter_reason
NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes", NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes",
"list-markets", "list-pairs", "list-strategies", "list-freqaimodels", "list-markets", "list-pairs", "list-strategies", "list-freqaimodels",
"list-data", "hyperopt-list", "hyperopt-show", "backtest-filter", "list-data", "hyperopt-list", "hyperopt-show", "backtest-filter",
"plot-dataframe", "plot-profit", "show-trades", "trades-to-ohlcv"] "plot-dataframe", "plot-profit", "show-trades", "trades-to-ohlcv",
"strategy-updater"]
NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-strategy"] NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-strategy"]
ARGS_STRATEGY_UTILS = ["strategy_list", "strategy_path", "recursive_strategy_search"]
class Arguments: class Arguments:
""" """
@ -198,8 +201,8 @@ class Arguments:
start_list_freqAI_models, start_list_markets, start_list_freqAI_models, start_list_markets,
start_list_strategies, start_list_timeframes, start_list_strategies, start_list_timeframes,
start_new_config, start_new_strategy, start_plot_dataframe, start_new_config, start_new_strategy, start_plot_dataframe,
start_plot_profit, start_show_trades, start_test_pairlist, start_plot_profit, start_show_trades, start_strategy_update,
start_trading, start_webserver) start_test_pairlist, start_trading, start_webserver)
subparsers = self.parser.add_subparsers(dest='command', subparsers = self.parser.add_subparsers(dest='command',
# Use custom message when no subhandler is added # Use custom message when no subhandler is added
@ -440,3 +443,11 @@ class Arguments:
parents=[_common_parser]) parents=[_common_parser])
webserver_cmd.set_defaults(func=start_webserver) webserver_cmd.set_defaults(func=start_webserver)
self._build_args(optionlist=ARGS_WEBSERVER, parser=webserver_cmd) self._build_args(optionlist=ARGS_WEBSERVER, parser=webserver_cmd)
# Add strategy_updater subcommand
strategy_updater_cmd = subparsers.add_parser('strategy-updater',
help='updates outdated strategy'
'files to the current version',
parents=[_common_parser])
strategy_updater_cmd.set_defaults(func=start_strategy_update)
self._build_args(optionlist=ARGS_STRATEGY_UTILS, parser=strategy_updater_cmd)

View File

@ -108,7 +108,7 @@ def ask_user_config() -> Dict[str, Any]:
"binance", "binance",
"binanceus", "binanceus",
"bittrex", "bittrex",
"gateio", "gate",
"huobi", "huobi",
"kraken", "kraken",
"kucoin", "kucoin",
@ -123,7 +123,7 @@ def ask_user_config() -> Dict[str, Any]:
"message": "Do you want to trade Perpetual Swaps (perpetual futures)?", "message": "Do you want to trade Perpetual Swaps (perpetual futures)?",
"default": False, "default": False,
"filter": lambda val: 'futures' if val else 'spot', "filter": lambda val: 'futures' if val else 'spot',
"when": lambda x: x["exchange_name"] in ['binance', 'gateio', 'okx'], "when": lambda x: x["exchange_name"] in ['binance', 'gate', 'okx'],
}, },
{ {
"type": "autocomplete", "type": "autocomplete",

View File

@ -251,7 +251,8 @@ AVAILABLE_CLI_OPTIONS = {
"spaces": Arg( "spaces": Arg(
'--spaces', '--spaces',
help='Specify which parameters to hyperopt. Space-separated list.', help='Specify which parameters to hyperopt. Space-separated list.',
choices=['all', 'buy', 'sell', 'roi', 'stoploss', 'trailing', 'protection', 'default'], choices=['all', 'buy', 'sell', 'roi', 'stoploss',
'trailing', 'protection', 'trades', 'default'],
nargs='+', nargs='+',
default='default', default='default',
), ),
@ -632,10 +633,11 @@ AVAILABLE_CLI_OPTIONS = {
"1: by enter_tag, " "1: by enter_tag, "
"2: by enter_tag and exit_tag, " "2: by enter_tag and exit_tag, "
"3: by pair and enter_tag, " "3: by pair and enter_tag, "
"4: by pair, enter_ and exit_tag (this can get quite large)"), "4: by pair, enter_ and exit_tag (this can get quite large), "
"5: by exit_tag"),
nargs='+', nargs='+',
default=['0', '1', '2'], default=['0', '1', '2'],
choices=['0', '1', '2', '3', '4'], choices=['0', '1', '2', '3', '4', '5'],
), ),
"enter_reason_list": Arg( "enter_reason_list": Arg(
"--enter-reason-list", "--enter-reason-list",

View File

@ -5,7 +5,7 @@ from datetime import datetime, timedelta
from typing import Any, Dict, List from typing import Any, Dict, List
from freqtrade.configuration import TimeRange, setup_utils_configuration from freqtrade.configuration import TimeRange, setup_utils_configuration
from freqtrade.constants import DATETIME_PRINT_FORMAT from freqtrade.constants import DATETIME_PRINT_FORMAT, Config
from freqtrade.data.converter import convert_ohlcv_format, convert_trades_format from freqtrade.data.converter import convert_ohlcv_format, convert_trades_format
from freqtrade.data.history import (convert_trades_to_ohlcv, refresh_backtest_ohlcv_data, from freqtrade.data.history import (convert_trades_to_ohlcv, refresh_backtest_ohlcv_data,
refresh_backtest_trades_data) refresh_backtest_trades_data)
@ -14,20 +14,30 @@ from freqtrade.exceptions import OperationalException
from freqtrade.exchange import market_is_active, timeframe_to_minutes from freqtrade.exchange import market_is_active, timeframe_to_minutes
from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist, expand_pairlist from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist, expand_pairlist
from freqtrade.resolvers import ExchangeResolver from freqtrade.resolvers import ExchangeResolver
from freqtrade.util.binance_mig import migrate_binance_futures_data
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def _data_download_sanity(config: Config) -> None:
if 'days' in config and 'timerange' in config:
raise OperationalException("--days and --timerange are mutually exclusive. "
"You can only specify one or the other.")
if 'pairs' not in config:
raise OperationalException(
"Downloading data requires a list of pairs. "
"Please check the documentation on how to configure this.")
def start_download_data(args: Dict[str, Any]) -> None: def start_download_data(args: Dict[str, Any]) -> None:
""" """
Download data (former download_backtest_data.py script) Download data (former download_backtest_data.py script)
""" """
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
if 'days' in config and 'timerange' in config: _data_download_sanity(config)
raise OperationalException("--days and --timerange are mutually exclusive. "
"You can only specify one or the other.")
timerange = TimeRange() timerange = TimeRange()
if 'days' in config: if 'days' in config:
time_since = (datetime.now() - timedelta(days=config['days'])).strftime("%Y%m%d") time_since = (datetime.now() - timedelta(days=config['days'])).strftime("%Y%m%d")
@ -39,11 +49,6 @@ def start_download_data(args: Dict[str, Any]) -> None:
# Remove stake-currency to skip checks which are not relevant for datadownload # Remove stake-currency to skip checks which are not relevant for datadownload
config['stake_currency'] = '' config['stake_currency'] = ''
if 'pairs' not in config:
raise OperationalException(
"Downloading data requires a list of pairs. "
"Please check the documentation on how to configure this.")
pairs_not_available: List[str] = [] pairs_not_available: List[str] = []
# Init exchange # Init exchange
@ -86,6 +91,7 @@ def start_download_data(args: Dict[str, Any]) -> None:
"Please use `--dl-trades` instead for this exchange " "Please use `--dl-trades` instead for this exchange "
"(will unfortunately take a long time)." "(will unfortunately take a long time)."
) )
migrate_binance_futures_data(config)
pairs_not_available = refresh_backtest_ohlcv_data( pairs_not_available = refresh_backtest_ohlcv_data(
exchange, pairs=expanded_pairs, timeframes=config['timeframes'], exchange, pairs=expanded_pairs, timeframes=config['timeframes'],
datadir=config['datadir'], timerange=timerange, datadir=config['datadir'], timerange=timerange,
@ -145,6 +151,7 @@ def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None:
""" """
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if ohlcv: if ohlcv:
migrate_binance_futures_data(config)
candle_types = [CandleType.from_string(ct) for ct in config.get('candle_types', ['spot'])] candle_types = [CandleType.from_string(ct) for ct in config.get('candle_types', ['spot'])]
for candle_type in candle_types: for candle_type in candle_types:
convert_ohlcv_format(config, convert_ohlcv_format(config,
@ -197,11 +204,14 @@ def start_list_data(args: Dict[str, Any]) -> None:
pair, timeframe, candle_type, pair, timeframe, candle_type,
*dhc.ohlcv_data_min_max(pair, timeframe, candle_type) *dhc.ohlcv_data_min_max(pair, timeframe, candle_type)
) for pair, timeframe, candle_type in paircombs] ) for pair, timeframe, candle_type in paircombs]
print(tabulate([ print(tabulate([
(pair, timeframe, candle_type, (pair, timeframe, candle_type,
start.strftime(DATETIME_PRINT_FORMAT), start.strftime(DATETIME_PRINT_FORMAT),
end.strftime(DATETIME_PRINT_FORMAT)) end.strftime(DATETIME_PRINT_FORMAT))
for pair, timeframe, candle_type, start, end in paircombs1 for pair, timeframe, candle_type, start, end in sorted(
paircombs1,
key=lambda x: (x[0], timeframe_to_minutes(x[1]), x[2]))
], ],
headers=("Pair", "Timeframe", "Type", 'From', 'To'), headers=("Pair", "Timeframe", "Type", 'From', 'To'),
tablefmt='psql', stralign='right')) tablefmt='psql', stralign='right'))

View File

@ -1,7 +1,7 @@
import logging import logging
from typing import Any, Dict from typing import Any, Dict
from sqlalchemy import func from sqlalchemy import func, select
from freqtrade.configuration.config_setup import setup_utils_configuration from freqtrade.configuration.config_setup import setup_utils_configuration
from freqtrade.enums import RunMode from freqtrade.enums import RunMode
@ -20,7 +20,7 @@ def start_convert_db(args: Dict[str, Any]) -> None:
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
init_db(config['db_url']) init_db(config['db_url'])
session_target = Trade._session session_target = Trade.session
init_db(config['db_url_from']) init_db(config['db_url_from'])
logger.info("Starting db migration.") logger.info("Starting db migration.")
@ -36,16 +36,16 @@ def start_convert_db(args: Dict[str, Any]) -> None:
session_target.commit() session_target.commit()
for pairlock in PairLock.query: for pairlock in PairLock.get_all_locks():
pairlock_count += 1 pairlock_count += 1
make_transient(pairlock) make_transient(pairlock)
session_target.add(pairlock) session_target.add(pairlock)
session_target.commit() session_target.commit()
# Update sequences # Update sequences
max_trade_id = session_target.query(func.max(Trade.id)).scalar() max_trade_id = session_target.scalar(select(func.max(Trade.id)))
max_order_id = session_target.query(func.max(Order.id)).scalar() max_order_id = session_target.scalar(select(func.max(Order.id)))
max_pairlock_id = session_target.query(func.max(PairLock.id)).scalar() max_pairlock_id = session_target.scalar(select(func.max(PairLock.id)))
set_sequence_ids(session_target.get_bind(), set_sequence_ids(session_target.get_bind(),
trade_id=max_trade_id, trade_id=max_trade_id,

0
freqtrade/commands/hyperopt_commands.py Executable file → Normal file
View File

View File

@ -0,0 +1,55 @@
import logging
import sys
import time
from pathlib import Path
from typing import Any, Dict
from freqtrade.configuration import setup_utils_configuration
from freqtrade.enums import RunMode
from freqtrade.resolvers import StrategyResolver
from freqtrade.strategy.strategyupdater import StrategyUpdater
logger = logging.getLogger(__name__)
def start_strategy_update(args: Dict[str, Any]) -> None:
"""
Start the strategy updating script
:param args: Cli args from Arguments()
:return: None
"""
if sys.version_info == (3, 8): # pragma: no cover
sys.exit("Freqtrade strategy updater requires Python version >= 3.9")
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
strategy_objs = StrategyResolver.search_all_objects(
config, enum_failed=False, recursive=config.get('recursive_strategy_search', False))
filtered_strategy_objs = []
if args['strategy_list']:
filtered_strategy_objs = [
strategy_obj for strategy_obj in strategy_objs
if strategy_obj['name'] in args['strategy_list']
]
else:
# Use all available entries.
filtered_strategy_objs = strategy_objs
processed_locations = set()
for strategy_obj in filtered_strategy_objs:
if strategy_obj['location'] not in processed_locations:
processed_locations.add(strategy_obj['location'])
start_conversion(strategy_obj, config)
def start_conversion(strategy_obj, config):
print(f"Conversion of {Path(strategy_obj['location']).name} started.")
instance_strategy_updater = StrategyUpdater()
start = time.perf_counter()
instance_strategy_updater.start(config, strategy_obj)
elapsed = time.perf_counter() - start
print(f"Conversion of {Path(strategy_obj['location']).name} took {elapsed:.1f} seconds.")

View File

@ -1,4 +1,5 @@
import logging import logging
import signal
from typing import Any, Dict from typing import Any, Dict
@ -12,15 +13,20 @@ def start_trading(args: Dict[str, Any]) -> int:
# Import here to avoid loading worker module when it's not used # Import here to avoid loading worker module when it's not used
from freqtrade.worker import Worker from freqtrade.worker import Worker
def term_handler(signum, frame):
# Raise KeyboardInterrupt - so we can handle it in the same way as Ctrl-C
raise KeyboardInterrupt()
# Create and run worker # Create and run worker
worker = None worker = None
try: try:
signal.signal(signal.SIGTERM, term_handler)
worker = Worker(args) worker = Worker(args)
worker.run() worker.run()
except Exception as e: except Exception as e:
logger.error(str(e)) logger.error(str(e))
logger.exception("Fatal exception!") logger.exception("Fatal exception!")
except KeyboardInterrupt: except (KeyboardInterrupt):
logger.info('SIGINT received, aborting ...') logger.info('SIGINT received, aborting ...')
finally: finally:
if worker: if worker:

View File

@ -27,10 +27,7 @@ def _extend_validator(validator_class):
if 'default' in subschema: if 'default' in subschema:
instance.setdefault(prop, subschema['default']) instance.setdefault(prop, subschema['default'])
for error in validate_properties( yield from validate_properties(validator, properties, instance, schema)
validator, properties, instance, schema,
):
yield error
return validators.extend( return validators.extend(
validator_class, {'properties': set_defaults} validator_class, {'properties': set_defaults}

View File

@ -28,7 +28,7 @@ class Configuration:
Reuse this class for the bot, backtesting, hyperopt and every script that required configuration Reuse this class for the bot, backtesting, hyperopt and every script that required configuration
""" """
def __init__(self, args: Dict[str, Any], runmode: RunMode = None) -> None: def __init__(self, args: Dict[str, Any], runmode: Optional[RunMode] = None) -> None:
self.args = args self.args = args
self.config: Optional[Config] = None self.config: Optional[Config] = None
self.runmode = runmode self.runmode = runmode

View File

@ -32,7 +32,7 @@ def flat_vars_to_nested_dict(env_dict: Dict[str, Any], prefix: str) -> Dict[str,
:param prefix: Prefix to consider (usually FREQTRADE__) :param prefix: Prefix to consider (usually FREQTRADE__)
:return: Nested dict based on available and relevant variables. :return: Nested dict based on available and relevant variables.
""" """
no_convert = ['CHAT_ID'] no_convert = ['CHAT_ID', 'PASSWORD']
relevant_vars: Dict[str, Any] = {} relevant_vars: Dict[str, Any] = {}
for env_var, val in sorted(env_dict.items()): for env_var, val in sorted(env_dict.items()):

View File

@ -6,7 +6,7 @@ import re
import sys import sys
from copy import deepcopy from copy import deepcopy
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List from typing import Any, Dict, List, Optional
import rapidjson import rapidjson
@ -58,7 +58,7 @@ def load_config_file(path: str) -> Dict[str, Any]:
""" """
try: try:
# Read config from stdin if requested in the options # Read config from stdin if requested in the options
with open(path) if path != '-' else sys.stdin as file: with Path(path).open() if path != '-' else sys.stdin as file:
config = rapidjson.load(file, parse_mode=CONFIG_PARSE_MODE) config = rapidjson.load(file, parse_mode=CONFIG_PARSE_MODE)
except FileNotFoundError: except FileNotFoundError:
raise OperationalException( raise OperationalException(
@ -75,7 +75,8 @@ def load_config_file(path: str) -> Dict[str, Any]:
return config return config
def load_from_files(files: List[str], base_path: Path = None, level: int = 0) -> Dict[str, Any]: def load_from_files(
files: List[str], base_path: Optional[Path] = None, level: int = 0) -> Dict[str, Any]:
""" """
Recursively load configuration files if specified. Recursively load configuration files if specified.
Sub-files are assumed to be relative to the initial config. Sub-files are assumed to be relative to the initial config.

View File

@ -116,7 +116,7 @@ class TimeRange:
:param text: value from --timerange :param text: value from --timerange
:return: Start and End range period :return: Start and End range period
""" """
if text is None: if not text:
return TimeRange(None, None, 0, 0) return TimeRange(None, None, 0, 0)
syntax = [(r'^-(\d{8})$', (None, 'date')), syntax = [(r'^-(\d{8})$', (None, 'date')),
(r'^(\d{8})-$', ('date', None)), (r'^(\d{8})-$', ('date', None)),

View File

@ -5,7 +5,7 @@ bot constants
""" """
from typing import Any, Dict, List, Literal, Tuple from typing import Any, Dict, List, Literal, Tuple
from freqtrade.enums import CandleType, RPCMessageType from freqtrade.enums import CandleType, PriceType, RPCMessageType
DEFAULT_CONFIG = 'config.json' DEFAULT_CONFIG = 'config.json'
@ -25,19 +25,21 @@ PRICING_SIDES = ['ask', 'bid', 'same', 'other']
ORDERTYPE_POSSIBILITIES = ['limit', 'market'] ORDERTYPE_POSSIBILITIES = ['limit', 'market']
_ORDERTIF_POSSIBILITIES = ['GTC', 'FOK', 'IOC', 'PO'] _ORDERTIF_POSSIBILITIES = ['GTC', 'FOK', 'IOC', 'PO']
ORDERTIF_POSSIBILITIES = _ORDERTIF_POSSIBILITIES + [t.lower() for t in _ORDERTIF_POSSIBILITIES] ORDERTIF_POSSIBILITIES = _ORDERTIF_POSSIBILITIES + [t.lower() for t in _ORDERTIF_POSSIBILITIES]
STOPLOSS_PRICE_TYPES = [p for p in PriceType]
HYPEROPT_LOSS_BUILTIN = ['ShortTradeDurHyperOptLoss', 'OnlyProfitHyperOptLoss', HYPEROPT_LOSS_BUILTIN = ['ShortTradeDurHyperOptLoss', 'OnlyProfitHyperOptLoss',
'SharpeHyperOptLoss', 'SharpeHyperOptLossDaily', 'SharpeHyperOptLoss', 'SharpeHyperOptLossDaily',
'SortinoHyperOptLoss', 'SortinoHyperOptLossDaily', 'SortinoHyperOptLoss', 'SortinoHyperOptLossDaily',
'CalmarHyperOptLoss', 'CalmarHyperOptLoss',
'MaxDrawDownHyperOptLoss', 'MaxDrawDownRelativeHyperOptLoss', 'MaxDrawDownHyperOptLoss', 'MaxDrawDownRelativeHyperOptLoss',
'ProfitDrawDownHyperOptLoss'] 'ProfitDrawDownHyperOptLoss']
AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', 'ProducerPairList', AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', 'ProducerPairList', 'RemotePairList',
'AgeFilter', 'OffsetFilter', 'PerformanceFilter', 'AgeFilter', 'OffsetFilter', 'PerformanceFilter',
'PrecisionFilter', 'PriceFilter', 'RangeStabilityFilter', 'PrecisionFilter', 'PriceFilter', 'RangeStabilityFilter',
'ShuffleFilter', 'SpreadFilter', 'VolatilityFilter'] 'ShuffleFilter', 'SpreadFilter', 'VolatilityFilter']
AVAILABLE_PROTECTIONS = ['CooldownPeriod', 'LowProfitPairs', 'MaxDrawdown', 'StoplossGuard'] AVAILABLE_PROTECTIONS = ['CooldownPeriod',
AVAILABLE_DATAHANDLERS_TRADES = ['json', 'jsongz', 'hdf5'] 'LowProfitPairs', 'MaxDrawdown', 'StoplossGuard']
AVAILABLE_DATAHANDLERS = AVAILABLE_DATAHANDLERS_TRADES + ['feather', 'parquet'] AVAILABLE_DATAHANDLERS_TRADES = ['json', 'jsongz', 'hdf5', 'feather']
AVAILABLE_DATAHANDLERS = AVAILABLE_DATAHANDLERS_TRADES + ['parquet']
BACKTEST_BREAKDOWNS = ['day', 'week', 'month'] BACKTEST_BREAKDOWNS = ['day', 'week', 'month']
BACKTEST_CACHE_AGE = ['none', 'day', 'week', 'month'] BACKTEST_CACHE_AGE = ['none', 'day', 'week', 'month']
BACKTEST_CACHE_DEFAULT = 'day' BACKTEST_CACHE_DEFAULT = 'day'
@ -62,6 +64,7 @@ USERPATH_FREQAIMODELS = 'freqaimodels'
TELEGRAM_SETTING_OPTIONS = ['on', 'off', 'silent'] TELEGRAM_SETTING_OPTIONS = ['on', 'off', 'silent']
WEBHOOK_FORMAT_OPTIONS = ['form', 'json', 'raw'] WEBHOOK_FORMAT_OPTIONS = ['form', 'json', 'raw']
FULL_DATAFRAME_THRESHOLD = 100 FULL_DATAFRAME_THRESHOLD = 100
CUSTOM_TAG_MAX_LENGTH = 255
ENV_VAR_PREFIX = 'FREQTRADE__' ENV_VAR_PREFIX = 'FREQTRADE__'
@ -229,6 +232,7 @@ CONF_SCHEMA = {
'default': 'market'}, 'default': 'market'},
'stoploss': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES}, 'stoploss': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
'stoploss_on_exchange': {'type': 'boolean'}, 'stoploss_on_exchange': {'type': 'boolean'},
'stoploss_price_type': {'type': 'string', 'enum': STOPLOSS_PRICE_TYPES},
'stoploss_on_exchange_interval': {'type': 'number'}, 'stoploss_on_exchange_interval': {'type': 'number'},
'stoploss_on_exchange_limit_ratio': {'type': 'number', 'minimum': 0.0, 'stoploss_on_exchange_limit_ratio': {'type': 'number', 'minimum': 0.0,
'maximum': 1.0} 'maximum': 1.0}
@ -544,7 +548,7 @@ CONF_SCHEMA = {
"enabled": {"type": "boolean", "default": False}, "enabled": {"type": "boolean", "default": False},
"keras": {"type": "boolean", "default": False}, "keras": {"type": "boolean", "default": False},
"write_metrics_to_disk": {"type": "boolean", "default": False}, "write_metrics_to_disk": {"type": "boolean", "default": False},
"purge_old_models": {"type": "boolean", "default": True}, "purge_old_models": {"type": ["boolean", "number"], "default": 2},
"conv_width": {"type": "integer", "default": 1}, "conv_width": {"type": "integer", "default": 1},
"train_period_days": {"type": "integer", "default": 0}, "train_period_days": {"type": "integer", "default": 0},
"backtest_period_days": {"type": "number", "default": 7}, "backtest_period_days": {"type": "number", "default": 7},
@ -566,7 +570,9 @@ CONF_SCHEMA = {
"shuffle": {"type": "boolean", "default": False}, "shuffle": {"type": "boolean", "default": False},
"nu": {"type": "number", "default": 0.1} "nu": {"type": "number", "default": 0.1}
}, },
} },
"shuffle_after_split": {"type": "boolean", "default": False},
"buffer_train_data_candles": {"type": "integer", "default": 0}
}, },
"required": ["include_timeframes", "include_corr_pairlist", ] "required": ["include_timeframes", "include_corr_pairlist", ]
}, },
@ -584,6 +590,7 @@ CONF_SCHEMA = {
"rl_config": { "rl_config": {
"type": "object", "type": "object",
"properties": { "properties": {
"drop_ohlc_from_features": {"type": "boolean", "default": False},
"train_cycles": {"type": "integer"}, "train_cycles": {"type": "integer"},
"max_trade_duration_candles": {"type": "integer"}, "max_trade_duration_candles": {"type": "integer"},
"add_state_info": {"type": "boolean", "default": False}, "add_state_info": {"type": "boolean", "default": False},
@ -592,7 +599,7 @@ CONF_SCHEMA = {
"model_type": {"type": "string", "default": "PPO"}, "model_type": {"type": "string", "default": "PPO"},
"policy_type": {"type": "string", "default": "MlpPolicy"}, "policy_type": {"type": "string", "default": "MlpPolicy"},
"net_arch": {"type": "array", "default": [128, 128]}, "net_arch": {"type": "array", "default": [128, 128]},
"randomize_startinng_position": {"type": "boolean", "default": False}, "randomize_starting_position": {"type": "boolean", "default": False},
"model_reward_parameters": { "model_reward_parameters": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -636,7 +643,6 @@ SCHEMA_TRADE_REQUIRED = [
SCHEMA_BACKTEST_REQUIRED = [ SCHEMA_BACKTEST_REQUIRED = [
'exchange', 'exchange',
'max_open_trades',
'stake_currency', 'stake_currency',
'stake_amount', 'stake_amount',
'dry_run_wallet', 'dry_run_wallet',
@ -646,6 +652,7 @@ SCHEMA_BACKTEST_REQUIRED = [
SCHEMA_BACKTEST_REQUIRED_FINAL = SCHEMA_BACKTEST_REQUIRED + [ SCHEMA_BACKTEST_REQUIRED_FINAL = SCHEMA_BACKTEST_REQUIRED + [
'stoploss', 'stoploss',
'minimal_roi', 'minimal_roi',
'max_open_trades'
] ]
SCHEMA_MINIMAL_REQUIRED = [ SCHEMA_MINIMAL_REQUIRED = [
@ -679,5 +686,7 @@ EntryExit = Literal['entry', 'exit']
BuySell = Literal['buy', 'sell'] BuySell = Literal['buy', 'sell']
MakerTaker = Literal['maker', 'taker'] MakerTaker = Literal['maker', 'taker']
BidAsk = Literal['bid', 'ask'] BidAsk = Literal['bid', 'ask']
OBLiteral = Literal['asks', 'bids']
Config = Dict[str, Any] Config = Dict[str, Any]
IntOrInf = float

View File

@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional, Union
import numpy as np import numpy as np
import pandas as pd import pandas as pd
from freqtrade.constants import LAST_BT_RESULT_FN from freqtrade.constants import LAST_BT_RESULT_FN, IntOrInf
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import json_load from freqtrade.misc import json_load
from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename
@ -20,8 +20,8 @@ from freqtrade.persistence import LocalTrade, Trade, init_db
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Newest format # Newest format
BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date', BT_DATA_COLUMNS = ['pair', 'stake_amount', 'max_stake_amount', 'amount',
'open_rate', 'close_rate', 'open_date', 'close_date', 'open_rate', 'close_rate',
'fee_open', 'fee_close', 'trade_duration', 'fee_open', 'fee_close', 'trade_duration',
'profit_ratio', 'profit_abs', 'exit_reason', 'profit_ratio', 'profit_abs', 'exit_reason',
'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs', 'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs',
@ -90,7 +90,8 @@ def get_latest_hyperopt_filename(directory: Union[Path, str]) -> str:
return 'hyperopt_results.pickle' return 'hyperopt_results.pickle'
def get_latest_hyperopt_file(directory: Union[Path, str], predef_filename: str = None) -> Path: def get_latest_hyperopt_file(
directory: Union[Path, str], predef_filename: Optional[str] = None) -> Path:
""" """
Get latest hyperopt export based on '.last_result.json'. Get latest hyperopt export based on '.last_result.json'.
:param directory: Directory to search for last result :param directory: Directory to search for last result
@ -193,7 +194,7 @@ def get_backtest_resultlist(dirname: Path):
def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, str], def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, str],
min_backtest_date: datetime = None) -> Dict[str, Any]: min_backtest_date: Optional[datetime] = None) -> Dict[str, Any]:
""" """
Find existing backtest stats that match specified run IDs and load them. Find existing backtest stats that match specified run IDs and load them.
:param dirname: pathlib.Path object, or string pointing to the file. :param dirname: pathlib.Path object, or string pointing to the file.
@ -241,6 +242,27 @@ def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, s
return results return results
def _load_backtest_data_df_compatibility(df: pd.DataFrame) -> pd.DataFrame:
"""
Compatibility support for older backtest data.
"""
df['open_date'] = pd.to_datetime(df['open_date'], utc=True)
df['close_date'] = pd.to_datetime(df['close_date'], utc=True)
# Compatibility support for pre short Columns
if 'is_short' not in df.columns:
df['is_short'] = False
if 'leverage' not in df.columns:
df['leverage'] = 1.0
if 'enter_tag' not in df.columns:
df['enter_tag'] = df['buy_tag']
df = df.drop(['buy_tag'], axis=1)
if 'max_stake_amount' not in df.columns:
df['max_stake_amount'] = df['stake_amount']
if 'orders' not in df.columns:
df['orders'] = None
return df
def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = None) -> pd.DataFrame: def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = None) -> pd.DataFrame:
""" """
Load backtest data file. Load backtest data file.
@ -269,24 +291,7 @@ def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = Non
data = data['strategy'][strategy]['trades'] data = data['strategy'][strategy]['trades']
df = pd.DataFrame(data) df = pd.DataFrame(data)
if not df.empty: if not df.empty:
df['open_date'] = pd.to_datetime(df['open_date'], df = _load_backtest_data_df_compatibility(df)
utc=True,
infer_datetime_format=True
)
df['close_date'] = pd.to_datetime(df['close_date'],
utc=True,
infer_datetime_format=True
)
# Compatibility support for pre short Columns
if 'is_short' not in df.columns:
df['is_short'] = 0
if 'leverage' not in df.columns:
df['leverage'] = 1.0
if 'enter_tag' not in df.columns:
df['enter_tag'] = df['buy_tag']
df = df.drop(['buy_tag'], axis=1)
if 'orders' not in df.columns:
df['orders'] = None
else: else:
# old format - only with lists. # old format - only with lists.
@ -322,7 +327,7 @@ def analyze_trade_parallelism(results: pd.DataFrame, timeframe: str) -> pd.DataF
def evaluate_result_multi(results: pd.DataFrame, timeframe: str, def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
max_open_trades: int) -> pd.DataFrame: max_open_trades: IntOrInf) -> pd.DataFrame:
""" """
Find overlapping trades by expanding each trade once per period it was open Find overlapping trades by expanding each trade once per period it was open
and then counting overlaps and then counting overlaps
@ -335,7 +340,7 @@ def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
return df_final[df_final['open_trades'] > max_open_trades] return df_final[df_final['open_trades'] > max_open_trades]
def trade_list_to_dataframe(trades: List[LocalTrade]) -> pd.DataFrame: def trade_list_to_dataframe(trades: Union[List[Trade], List[LocalTrade]]) -> pd.DataFrame:
""" """
Convert list of Trade objects to pandas Dataframe Convert list of Trade objects to pandas Dataframe
:param trades: List of trade objects :param trades: List of trade objects
@ -362,7 +367,7 @@ def load_trades_from_db(db_url: str, strategy: Optional[str] = None) -> pd.DataF
filters = [] filters = []
if strategy: if strategy:
filters.append(Trade.strategy == strategy) filters.append(Trade.strategy == strategy)
trades = trade_list_to_dataframe(Trade.get_trades(filters).all()) trades = trade_list_to_dataframe(list(Trade.get_trades(filters).all()))
return trades return trades

View File

@ -34,7 +34,7 @@ def ohlcv_to_dataframe(ohlcv: list, timeframe: str, pair: str, *,
cols = DEFAULT_DATAFRAME_COLUMNS cols = DEFAULT_DATAFRAME_COLUMNS
df = DataFrame(ohlcv, columns=cols) df = DataFrame(ohlcv, columns=cols)
df['date'] = to_datetime(df['date'], unit='ms', utc=True, infer_datetime_format=True) df['date'] = to_datetime(df['date'], unit='ms', utc=True)
# Some exchanges return int values for Volume and even for OHLC. # Some exchanges return int values for Volume and even for OHLC.
# Convert them since TA-LIB indicators used in the strategy assume floats # Convert them since TA-LIB indicators used in the strategy assume floats

View File

@ -9,7 +9,7 @@ from collections import deque
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
from pandas import DataFrame, to_timedelta from pandas import DataFrame, Timedelta, Timestamp, to_timedelta
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.constants import (FULL_DATAFRAME_THRESHOLD, Config, ListPairsWithTimeframes, from freqtrade.constants import (FULL_DATAFRAME_THRESHOLD, Config, ListPairsWithTimeframes,
@ -18,8 +18,10 @@ from freqtrade.data.history import load_pair_history
from freqtrade.enums import CandleType, RPCMessageType, RunMode from freqtrade.enums import CandleType, RPCMessageType, RunMode
from freqtrade.exceptions import ExchangeError, OperationalException from freqtrade.exceptions import ExchangeError, OperationalException
from freqtrade.exchange import Exchange, timeframe_to_seconds from freqtrade.exchange import Exchange, timeframe_to_seconds
from freqtrade.exchange.types import OrderBook
from freqtrade.misc import append_candles_to_dataframe from freqtrade.misc import append_candles_to_dataframe
from freqtrade.rpc import RPCManager from freqtrade.rpc import RPCManager
from freqtrade.rpc.rpc_types import RPCAnalyzedDFMsg
from freqtrade.util import PeriodicCache from freqtrade.util import PeriodicCache
@ -117,8 +119,7 @@ class DataProvider:
:param new_candle: This is a new candle :param new_candle: This is a new candle
""" """
if self.__rpc: if self.__rpc:
self.__rpc.send_msg( msg: RPCAnalyzedDFMsg = {
{
'type': RPCMessageType.ANALYZED_DF, 'type': RPCMessageType.ANALYZED_DF,
'data': { 'data': {
'key': pair_key, 'key': pair_key,
@ -126,7 +127,7 @@ class DataProvider:
'la': datetime.now(timezone.utc) 'la': datetime.now(timezone.utc)
} }
} }
) self.__rpc.send_msg(msg)
if new_candle: if new_candle:
self.__rpc.send_msg({ self.__rpc.send_msg({
'type': RPCMessageType.NEW_CANDLE, 'type': RPCMessageType.NEW_CANDLE,
@ -206,9 +207,11 @@ class DataProvider:
existing_df, _ = self.__producer_pairs_df[producer_name][pair_key] existing_df, _ = self.__producer_pairs_df[producer_name][pair_key]
# CHECK FOR MISSING CANDLES # CHECK FOR MISSING CANDLES
timeframe_delta = to_timedelta(timeframe) # Convert the timeframe to a timedelta for pandas # Convert the timeframe to a timedelta for pandas
local_last = existing_df.iloc[-1]['date'] # We want the last date from our copy timeframe_delta: Timedelta = to_timedelta(timeframe)
incoming_first = dataframe.iloc[0]['date'] # We want the first date from the incoming local_last: Timestamp = existing_df.iloc[-1]['date'] # We want the last date from our copy
# We want the first date from the incoming
incoming_first: Timestamp = dataframe.iloc[0]['date']
# Remove existing candles that are newer than the incoming first candle # Remove existing candles that are newer than the incoming first candle
existing_df1 = existing_df[existing_df['date'] < incoming_first] existing_df1 = existing_df[existing_df['date'] < incoming_first]
@ -221,7 +224,7 @@ class DataProvider:
# we missed some candles between our data and the incoming # we missed some candles between our data and the incoming
# so return False and candle_difference. # so return False and candle_difference.
if candle_difference > 1: if candle_difference > 1:
return (False, candle_difference) return (False, int(candle_difference))
if existing_df1.empty: if existing_df1.empty:
appended_df = dataframe appended_df = dataframe
else: else:
@ -281,7 +284,7 @@ class DataProvider:
def historic_ohlcv( def historic_ohlcv(
self, self,
pair: str, pair: str,
timeframe: str = None, timeframe: Optional[str] = None,
candle_type: str = '' candle_type: str = ''
) -> DataFrame: ) -> DataFrame:
""" """
@ -333,7 +336,7 @@ class DataProvider:
def get_pair_dataframe( def get_pair_dataframe(
self, self,
pair: str, pair: str,
timeframe: str = None, timeframe: Optional[str] = None,
candle_type: str = '' candle_type: str = ''
) -> DataFrame: ) -> DataFrame:
""" """
@ -415,16 +418,14 @@ class DataProvider:
def refresh(self, def refresh(self,
pairlist: ListPairsWithTimeframes, pairlist: ListPairsWithTimeframes,
helping_pairs: ListPairsWithTimeframes = None) -> None: helping_pairs: Optional[ListPairsWithTimeframes] = None) -> None:
""" """
Refresh data, called with each cycle Refresh data, called with each cycle
""" """
if self._exchange is None: if self._exchange is None:
raise OperationalException(NO_EXCHANGE_EXCEPTION) raise OperationalException(NO_EXCHANGE_EXCEPTION)
if helping_pairs: final_pairs = (pairlist + helping_pairs) if helping_pairs else pairlist
self._exchange.refresh_latest_ohlcv(pairlist + helping_pairs) self._exchange.refresh_latest_ohlcv(final_pairs)
else:
self._exchange.refresh_latest_ohlcv(pairlist)
@property @property
def available_pairs(self) -> ListPairsWithTimeframes: def available_pairs(self) -> ListPairsWithTimeframes:
@ -439,7 +440,7 @@ class DataProvider:
def ohlcv( def ohlcv(
self, self,
pair: str, pair: str,
timeframe: str = None, timeframe: Optional[str] = None,
copy: bool = True, copy: bool = True,
candle_type: str = '' candle_type: str = ''
) -> DataFrame: ) -> DataFrame:
@ -487,7 +488,7 @@ class DataProvider:
except ExchangeError: except ExchangeError:
return {} return {}
def orderbook(self, pair: str, maximum: int) -> Dict[str, List]: def orderbook(self, pair: str, maximum: int) -> OrderBook:
""" """
Fetch latest l2 orderbook data Fetch latest l2 orderbook data
Warning: Does a network request - so use with common sense. Warning: Does a network request - so use with common sense.

16
freqtrade/data/entryexitanalysis.py Executable file → Normal file
View File

@ -24,9 +24,9 @@ def _load_signal_candles(backtest_dir: Path):
scpf = Path(backtest_dir.parent / f"{backtest_dir.stem}_signals.pkl") scpf = Path(backtest_dir.parent / f"{backtest_dir.stem}_signals.pkl")
try: try:
scp = open(scpf, "rb") with scpf.open("rb") as scp:
signal_candles = joblib.load(scp) signal_candles = joblib.load(scp)
logger.info(f"Loaded signal candles: {str(scpf)}") logger.info(f"Loaded signal candles: {str(scpf)}")
except Exception as e: except Exception as e:
logger.error("Cannot load signal candles from pickled results: ", e) logger.error("Cannot load signal candles from pickled results: ", e)
@ -52,7 +52,7 @@ def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_cand
return analysed_trades_dict return analysed_trades_dict
def _analyze_candles_and_indicators(pair, trades, signal_candles): def _analyze_candles_and_indicators(pair, trades: pd.DataFrame, signal_candles: pd.DataFrame):
buyf = signal_candles buyf = signal_candles
if len(buyf) > 0: if len(buyf) > 0:
@ -120,7 +120,7 @@ def _do_group_table_output(bigdf, glist):
else: else:
agg_mask = {'profit_abs': ['count', 'sum', 'median', 'mean'], agg_mask = {'profit_abs': ['count', 'sum', 'median', 'mean'],
'profit_ratio': ['sum', 'median', 'mean']} 'profit_ratio': ['median', 'mean', 'sum']}
agg_cols = ['num_buys', 'profit_abs_sum', 'profit_abs_median', agg_cols = ['num_buys', 'profit_abs_sum', 'profit_abs_median',
'profit_abs_mean', 'median_profit_pct', 'mean_profit_pct', 'profit_abs_mean', 'median_profit_pct', 'mean_profit_pct',
'total_profit_pct'] 'total_profit_pct']
@ -141,6 +141,12 @@ def _do_group_table_output(bigdf, glist):
# 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large) # 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large)
if g == "4": if g == "4":
group_mask = ['pair', 'enter_reason', 'exit_reason'] group_mask = ['pair', 'enter_reason', 'exit_reason']
# 5: profit summaries grouped by exit_tag
if g == "5":
group_mask = ['exit_reason']
sortcols = ['exit_reason']
if group_mask: if group_mask:
new = bigdf.groupby(group_mask).agg(agg_mask).reset_index() new = bigdf.groupby(group_mask).agg(agg_mask).reset_index()
new.columns = group_mask + agg_cols new.columns = group_mask + agg_cols

View File

@ -4,7 +4,7 @@ from typing import Optional
from pandas import DataFrame, read_feather, to_datetime from pandas import DataFrame, read_feather, to_datetime
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, TradeList from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList
from freqtrade.enums import CandleType from freqtrade.enums import CandleType
from .idatahandler import IDataHandler from .idatahandler import IDataHandler
@ -63,10 +63,7 @@ class FeatherDataHandler(IDataHandler):
pairdata.columns = self._columns pairdata.columns = self._columns
pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float', pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float',
'low': 'float', 'close': 'float', 'volume': 'float'}) 'low': 'float', 'close': 'float', 'volume': 'float'})
pairdata['date'] = to_datetime(pairdata['date'], pairdata['date'] = to_datetime(pairdata['date'], unit='ms', utc=True)
unit='ms',
utc=True,
infer_datetime_format=True)
return pairdata return pairdata
def ohlcv_append( def ohlcv_append(
@ -92,12 +89,11 @@ class FeatherDataHandler(IDataHandler):
:param data: List of Lists containing trade data, :param data: List of Lists containing trade data,
column sequence as in DEFAULT_TRADES_COLUMNS column sequence as in DEFAULT_TRADES_COLUMNS
""" """
# filename = self._pair_trades_filename(self._datadir, pair) filename = self._pair_trades_filename(self._datadir, pair)
self.create_dir_if_needed(filename)
raise NotImplementedError() tradesdata = DataFrame(data, columns=DEFAULT_TRADES_COLUMNS)
# array = pa.array(data) tradesdata.to_feather(filename, compression_level=9, compression='lz4')
# array
# feather.write_feather(data, filename)
def trades_append(self, pair: str, data: TradeList): def trades_append(self, pair: str, data: TradeList):
""" """
@ -116,14 +112,13 @@ class FeatherDataHandler(IDataHandler):
:param timerange: Timerange to load trades for - currently not implemented :param timerange: Timerange to load trades for - currently not implemented
:return: List of trades :return: List of trades
""" """
raise NotImplementedError() filename = self._pair_trades_filename(self._datadir, pair)
# filename = self._pair_trades_filename(self._datadir, pair) if not filename.exists():
# tradesdata = misc.file_load_json(filename) return []
# if not tradesdata: tradesdata = read_feather(filename)
# return []
# return tradesdata return tradesdata.values.tolist()
@classmethod @classmethod
def _get_file_extension(cls): def _get_file_extension(cls):

View File

@ -28,8 +28,8 @@ def load_pair_history(pair: str,
fill_up_missing: bool = True, fill_up_missing: bool = True,
drop_incomplete: bool = False, drop_incomplete: bool = False,
startup_candles: int = 0, startup_candles: int = 0,
data_format: str = None, data_format: Optional[str] = None,
data_handler: IDataHandler = None, data_handler: Optional[IDataHandler] = None,
candle_type: CandleType = CandleType.SPOT candle_type: CandleType = CandleType.SPOT
) -> DataFrame: ) -> DataFrame:
""" """
@ -69,7 +69,7 @@ def load_data(datadir: Path,
fail_without_data: bool = False, fail_without_data: bool = False,
data_format: str = 'json', data_format: str = 'json',
candle_type: CandleType = CandleType.SPOT, candle_type: CandleType = CandleType.SPOT,
user_futures_funding_rate: int = None, user_futures_funding_rate: Optional[int] = None,
) -> Dict[str, DataFrame]: ) -> Dict[str, DataFrame]:
""" """
Load ohlcv history data for a list of pairs. Load ohlcv history data for a list of pairs.
@ -116,7 +116,7 @@ def refresh_data(*, datadir: Path,
timeframe: str, timeframe: str,
pairs: List[str], pairs: List[str],
exchange: Exchange, exchange: Exchange,
data_format: str = None, data_format: Optional[str] = None,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
candle_type: CandleType, candle_type: CandleType,
) -> None: ) -> None:
@ -189,7 +189,7 @@ def _download_pair_history(pair: str, *,
timeframe: str = '5m', timeframe: str = '5m',
process: str = '', process: str = '',
new_pairs_days: int = 30, new_pairs_days: int = 30,
data_handler: IDataHandler = None, data_handler: Optional[IDataHandler] = None,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
candle_type: CandleType, candle_type: CandleType,
erase: bool = False, erase: bool = False,
@ -272,7 +272,7 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes
datadir: Path, trading_mode: str, datadir: Path, trading_mode: str,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
new_pairs_days: int = 30, erase: bool = False, new_pairs_days: int = 30, erase: bool = False,
data_format: str = None, data_format: Optional[str] = None,
prepend: bool = False, prepend: bool = False,
) -> List[str]: ) -> List[str]:
""" """

View File

@ -308,7 +308,7 @@ class IDataHandler(ABC):
timerange=timerange_startup, timerange=timerange_startup,
candle_type=candle_type candle_type=candle_type
) )
if self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data, True): if self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data):
return pairdf return pairdf
else: else:
enddate = pairdf.iloc[-1]['date'] enddate = pairdf.iloc[-1]['date']
@ -316,7 +316,7 @@ class IDataHandler(ABC):
if timerange_startup: if timerange_startup:
self._validate_pairdata(pair, pairdf, timeframe, candle_type, timerange_startup) self._validate_pairdata(pair, pairdf, timeframe, candle_type, timerange_startup)
pairdf = trim_dataframe(pairdf, timerange_startup) pairdf = trim_dataframe(pairdf, timerange_startup)
if self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data): if self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data, True):
return pairdf return pairdf
# incomplete candles should only be dropped if we didn't trim the end beforehand. # incomplete candles should only be dropped if we didn't trim the end beforehand.
@ -374,6 +374,21 @@ class IDataHandler(ABC):
logger.warning(f"{pair}, {candle_type}, {timeframe}, " logger.warning(f"{pair}, {candle_type}, {timeframe}, "
f"data ends at {pairdata.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}") f"data ends at {pairdata.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}")
def rename_futures_data(
self, pair: str, new_pair: str, timeframe: str, candle_type: CandleType):
"""
Temporary method to migrate data from old naming to new naming (BTC/USDT -> BTC/USDT:USDT)
Only used for binance to support the binance futures naming unification.
"""
file_old = self._pair_data_filename(self._datadir, pair, timeframe, candle_type)
file_new = self._pair_data_filename(self._datadir, new_pair, timeframe, candle_type)
# print(file_old, file_new)
if file_new.exists():
logger.warning(f"{file_new} exists already, can't migrate {pair}.")
return
file_old.rename(file_new)
def get_datahandlerclass(datatype: str) -> Type[IDataHandler]: def get_datahandlerclass(datatype: str) -> Type[IDataHandler]:
""" """
@ -403,8 +418,8 @@ def get_datahandlerclass(datatype: str) -> Type[IDataHandler]:
raise ValueError(f"No datahandler for datatype {datatype} available.") raise ValueError(f"No datahandler for datatype {datatype} available.")
def get_datahandler(datadir: Path, data_format: str = None, def get_datahandler(datadir: Path, data_format: Optional[str] = None,
data_handler: IDataHandler = None) -> IDataHandler: data_handler: Optional[IDataHandler] = None) -> IDataHandler:
""" """
:param datadir: Folder to save data :param datadir: Folder to save data
:param data_format: dataformat to use :param data_format: dataformat to use

View File

@ -75,10 +75,7 @@ class JsonDataHandler(IDataHandler):
return DataFrame(columns=self._columns) return DataFrame(columns=self._columns)
pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float', pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float',
'low': 'float', 'close': 'float', 'volume': 'float'}) 'low': 'float', 'close': 'float', 'volume': 'float'})
pairdata['date'] = to_datetime(pairdata['date'], pairdata['date'] = to_datetime(pairdata['date'], unit='ms', utc=True)
unit='ms',
utc=True,
infer_datetime_format=True)
return pairdata return pairdata
def ohlcv_append( def ohlcv_append(

View File

@ -62,10 +62,7 @@ class ParquetDataHandler(IDataHandler):
pairdata.columns = self._columns pairdata.columns = self._columns
pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float', pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float',
'low': 'float', 'close': 'float', 'volume': 'float'}) 'low': 'float', 'close': 'float', 'volume': 'float'})
pairdata['date'] = to_datetime(pairdata['date'], pairdata['date'] = to_datetime(pairdata['date'], unit='ms', utc=True)
unit='ms',
utc=True,
infer_datetime_format=True)
return pairdata return pairdata
def ohlcv_append( def ohlcv_append(

View File

@ -1,4 +1,6 @@
import logging import logging
import math
from datetime import datetime
from typing import Dict, Tuple from typing import Dict, Tuple
import numpy as np import numpy as np
@ -190,3 +192,119 @@ def calculate_cagr(days_passed: int, starting_balance: float, final_balance: flo
:return: CAGR :return: CAGR
""" """
return (final_balance / starting_balance) ** (1 / (days_passed / 365)) - 1 return (final_balance / starting_balance) ** (1 / (days_passed / 365)) - 1
def calculate_expectancy(trades: pd.DataFrame) -> float:
"""
Calculate expectancy
:param trades: DataFrame containing trades (requires columns close_date and profit_abs)
:return: expectancy
"""
if len(trades) == 0:
return 0
expectancy = 1
profit_sum = trades.loc[trades['profit_abs'] > 0, 'profit_abs'].sum()
loss_sum = abs(trades.loc[trades['profit_abs'] < 0, 'profit_abs'].sum())
nb_win_trades = len(trades.loc[trades['profit_abs'] > 0])
nb_loss_trades = len(trades.loc[trades['profit_abs'] < 0])
if (nb_win_trades > 0) and (nb_loss_trades > 0):
average_win = profit_sum / nb_win_trades
average_loss = loss_sum / nb_loss_trades
risk_reward_ratio = average_win / average_loss
winrate = nb_win_trades / len(trades)
expectancy = ((1 + risk_reward_ratio) * winrate) - 1
elif nb_win_trades == 0:
expectancy = 0
return expectancy
def calculate_sortino(trades: pd.DataFrame, min_date: datetime, max_date: datetime,
starting_balance: float) -> float:
"""
Calculate sortino
:param trades: DataFrame containing trades (requires columns profit_abs)
:return: sortino
"""
if (len(trades) == 0) or (min_date is None) or (max_date is None) or (min_date == max_date):
return 0
total_profit = trades['profit_abs'] / starting_balance
days_period = max(1, (max_date - min_date).days)
expected_returns_mean = total_profit.sum() / days_period
down_stdev = np.std(trades.loc[trades['profit_abs'] < 0, 'profit_abs'] / starting_balance)
if down_stdev != 0 and not np.isnan(down_stdev):
sortino_ratio = expected_returns_mean / down_stdev * np.sqrt(365)
else:
# Define high (negative) sortino ratio to be clear that this is NOT optimal.
sortino_ratio = -100
# print(expected_returns_mean, down_stdev, sortino_ratio)
return sortino_ratio
def calculate_sharpe(trades: pd.DataFrame, min_date: datetime, max_date: datetime,
starting_balance: float) -> float:
"""
Calculate sharpe
:param trades: DataFrame containing trades (requires column profit_abs)
:return: sharpe
"""
if (len(trades) == 0) or (min_date is None) or (max_date is None) or (min_date == max_date):
return 0
total_profit = trades['profit_abs'] / starting_balance
days_period = max(1, (max_date - min_date).days)
expected_returns_mean = total_profit.sum() / days_period
up_stdev = np.std(total_profit)
if up_stdev != 0:
sharp_ratio = expected_returns_mean / up_stdev * np.sqrt(365)
else:
# Define high (negative) sharpe ratio to be clear that this is NOT optimal.
sharp_ratio = -100
# print(expected_returns_mean, up_stdev, sharp_ratio)
return sharp_ratio
def calculate_calmar(trades: pd.DataFrame, min_date: datetime, max_date: datetime,
starting_balance: float) -> float:
"""
Calculate calmar
:param trades: DataFrame containing trades (requires columns close_date and profit_abs)
:return: calmar
"""
if (len(trades) == 0) or (min_date is None) or (max_date is None) or (min_date == max_date):
return 0
total_profit = trades['profit_abs'].sum() / starting_balance
days_period = max(1, (max_date - min_date).days)
# adding slippage of 0.1% per trade
# total_profit = total_profit - 0.0005
expected_returns_mean = total_profit / days_period * 100
# calculate max drawdown
try:
_, _, _, _, _, max_drawdown = calculate_max_drawdown(
trades, value_col="profit_abs", starting_balance=starting_balance
)
except ValueError:
max_drawdown = 0
if max_drawdown != 0:
calmar_ratio = expected_returns_mean / max_drawdown * math.sqrt(365)
else:
# Define high (negative) calmar ratio to be clear that this is NOT optimal.
calmar_ratio = -100
# print(expected_returns_mean, max_drawdown, calmar_ratio)
return calmar_ratio

View File

@ -195,7 +195,7 @@ class Edge:
def stake_amount(self, pair: str, free_capital: float, def stake_amount(self, pair: str, free_capital: float,
total_capital: float, capital_in_trade: float) -> float: total_capital: float, capital_in_trade: float) -> float:
stoploss = self.stoploss(pair) stoploss = self.get_stoploss(pair)
available_capital = (total_capital + capital_in_trade) * self._capital_ratio available_capital = (total_capital + capital_in_trade) * self._capital_ratio
allowed_capital_at_risk = available_capital * self._allowed_risk allowed_capital_at_risk = available_capital * self._allowed_risk
max_position_size = abs(allowed_capital_at_risk / stoploss) max_position_size = abs(allowed_capital_at_risk / stoploss)
@ -214,7 +214,7 @@ class Edge:
) )
return round(position_size, 15) return round(position_size, 15)
def stoploss(self, pair: str) -> float: def get_stoploss(self, pair: str) -> float:
if pair in self._cached_pairs: if pair in self._cached_pairs:
return self._cached_pairs[pair].stoploss return self._cached_pairs[pair].stoploss
else: else:

View File

@ -5,7 +5,9 @@ from freqtrade.enums.exitchecktuple import ExitCheckTuple
from freqtrade.enums.exittype import ExitType from freqtrade.enums.exittype import ExitType
from freqtrade.enums.hyperoptstate import HyperoptState from freqtrade.enums.hyperoptstate import HyperoptState
from freqtrade.enums.marginmode import MarginMode from freqtrade.enums.marginmode import MarginMode
from freqtrade.enums.marketstatetype import MarketDirection
from freqtrade.enums.ordertypevalue import OrderTypeValues from freqtrade.enums.ordertypevalue import OrderTypeValues
from freqtrade.enums.pricetype import PriceType
from freqtrade.enums.rpcmessagetype import NO_ECHO_MESSAGES, RPCMessageType, RPCRequestType from freqtrade.enums.rpcmessagetype import NO_ECHO_MESSAGES, RPCMessageType, RPCRequestType
from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode
from freqtrade.enums.signaltype import SignalDirection, SignalTagType, SignalType from freqtrade.enums.signaltype import SignalDirection, SignalTagType, SignalType

View File

@ -13,6 +13,9 @@ class CandleType(str, Enum):
FUNDING_RATE = "funding_rate" FUNDING_RATE = "funding_rate"
# BORROW_RATE = "borrow_rate" # * unimplemented # BORROW_RATE = "borrow_rate" # * unimplemented
def __str__(self):
return f"{self.name.lower()}"
@staticmethod @staticmethod
def from_string(value: str) -> 'CandleType': def from_string(value: str) -> 'CandleType':
if not value: if not value:

View File

@ -0,0 +1,15 @@
from enum import Enum
class MarketDirection(Enum):
"""
Enum for various market directions.
"""
LONG = "long"
SHORT = "short"
EVEN = "even"
NONE = "none"
def __str__(self):
# convert to string
return self.value

View File

@ -0,0 +1,8 @@
from enum import Enum
class PriceType(str, Enum):
"""Enum to distinguish possible trigger prices for stoplosses"""
LAST = "last"
MARK = "mark"
INDEX = "index"

View File

@ -4,6 +4,7 @@ from enum import Enum
class RPCMessageType(str, Enum): class RPCMessageType(str, Enum):
STATUS = 'status' STATUS = 'status'
WARNING = 'warning' WARNING = 'warning'
EXCEPTION = 'exception'
STARTUP = 'startup' STARTUP = 'startup'
ENTRY = 'entry' ENTRY = 'entry'
@ -37,5 +38,8 @@ class RPCRequestType(str, Enum):
WHITELIST = 'whitelist' WHITELIST = 'whitelist'
ANALYZED_DF = 'analyzed_df' ANALYZED_DF = 'analyzed_df'
def __str__(self):
return self.value
NO_ECHO_MESSAGES = (RPCMessageType.ANALYZED_DF, RPCMessageType.WHITELIST, RPCMessageType.NEW_CANDLE) NO_ECHO_MESSAGES = (RPCMessageType.ANALYZED_DF, RPCMessageType.WHITELIST, RPCMessageType.NEW_CANDLE)

View File

@ -10,6 +10,9 @@ class SignalType(Enum):
ENTER_SHORT = "enter_short" ENTER_SHORT = "enter_short"
EXIT_SHORT = "exit_short" EXIT_SHORT = "exit_short"
def __str__(self):
return f"{self.name.lower()}"
class SignalTagType(Enum): class SignalTagType(Enum):
""" """
@ -18,7 +21,13 @@ class SignalTagType(Enum):
ENTER_TAG = "enter_tag" ENTER_TAG = "enter_tag"
EXIT_TAG = "exit_tag" EXIT_TAG = "exit_tag"
def __str__(self):
return f"{self.name.lower()}"
class SignalDirection(str, Enum): class SignalDirection(str, Enum):
LONG = 'long' LONG = 'long'
SHORT = 'short' SHORT = 'short'
def __str__(self):
return f"{self.name.lower()}"

View File

@ -8,16 +8,16 @@ from freqtrade.exchange.bitpanda import Bitpanda
from freqtrade.exchange.bittrex import Bittrex from freqtrade.exchange.bittrex import Bittrex
from freqtrade.exchange.bybit import Bybit from freqtrade.exchange.bybit import Bybit
from freqtrade.exchange.coinbasepro import Coinbasepro from freqtrade.exchange.coinbasepro import Coinbasepro
from freqtrade.exchange.exchange_utils import (amount_to_contract_precision, amount_to_contracts, from freqtrade.exchange.exchange_utils import (ROUND_DOWN, ROUND_UP, amount_to_contract_precision,
amount_to_precision, available_exchanges, amount_to_contracts, amount_to_precision,
ccxt_exchanges, contracts_to_amount, available_exchanges, ccxt_exchanges,
date_minus_candles, is_exchange_known_ccxt, contracts_to_amount, date_minus_candles,
market_is_active, price_to_precision, is_exchange_known_ccxt, market_is_active,
timeframe_to_minutes, timeframe_to_msecs, price_to_precision, timeframe_to_minutes,
timeframe_to_next_date, timeframe_to_prev_date, timeframe_to_msecs, timeframe_to_next_date,
timeframe_to_seconds, validate_exchange, timeframe_to_prev_date, timeframe_to_seconds,
validate_exchanges) validate_exchange, validate_exchanges)
from freqtrade.exchange.gateio import Gateio from freqtrade.exchange.gate import Gate
from freqtrade.exchange.hitbtc import Hitbtc from freqtrade.exchange.hitbtc import Hitbtc
from freqtrade.exchange.huobi import Huobi from freqtrade.exchange.huobi import Huobi
from freqtrade.exchange.kraken import Kraken from freqtrade.exchange.kraken import Kraken

View File

@ -7,11 +7,11 @@ from typing import Dict, List, Optional, Tuple
import arrow import arrow
import ccxt import ccxt
from freqtrade.enums import CandleType, MarginMode, TradingMode from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.exchange.common import retrier from freqtrade.exchange.common import retrier
from freqtrade.exchange.types import Tickers from freqtrade.exchange.types import OHLCVResponse, Tickers
from freqtrade.misc import deep_merge_dicts, json_load from freqtrade.misc import deep_merge_dicts, json_load
@ -23,16 +23,22 @@ class Binance(Exchange):
_ft_has: Dict = { _ft_has: Dict = {
"stoploss_on_exchange": True, "stoploss_on_exchange": True,
"stoploss_order_types": {"limit": "stop_loss_limit"}, "stoploss_order_types": {"limit": "stop_loss_limit"},
"order_time_in_force": ['GTC', 'FOK', 'IOC'], "order_time_in_force": ["GTC", "FOK", "IOC", "PO"],
"ohlcv_candle_limit": 1000, "ohlcv_candle_limit": 1000,
"trades_pagination": "id", "trades_pagination": "id",
"trades_pagination_arg": "fromId", "trades_pagination_arg": "fromId",
"l2_limit_range": [5, 10, 20, 50, 100, 500, 1000], "l2_limit_range": [5, 10, 20, 50, 100, 500, 1000],
"ccxt_futures_name": "future"
} }
_ft_has_futures: Dict = { _ft_has_futures: Dict = {
"stoploss_order_types": {"limit": "limit", "market": "market"}, "stoploss_order_types": {"limit": "stop", "market": "stop_market"},
"order_time_in_force": ["GTC", "FOK", "IOC"],
"tickers_have_price": False, "tickers_have_price": False,
"floor_leverage": True,
"stop_price_type_field": "workingType",
"stop_price_type_value_mapping": {
PriceType.LAST: "CONTRACT_PRICE",
PriceType.MARK: "MARK_PRICE",
},
} }
_supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [
@ -78,33 +84,9 @@ class Binance(Exchange):
raise DDosProtection(e) from e raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e: except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError( raise TemporaryError(
f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e f'Error in additional_exchange_init due to {e.__class__.__name__}. Message: {e}'
except ccxt.BaseError as e: ) from e
raise OperationalException(e) from e
@retrier
def _set_leverage(
self,
leverage: float,
pair: Optional[str] = None,
trading_mode: Optional[TradingMode] = None
):
"""
Set's the leverage before making a trade, in order to not
have the same leverage on every trade
"""
trading_mode = trading_mode or self.trading_mode
if self._config['dry_run'] or trading_mode != TradingMode.FUTURES:
return
try:
self._api.set_leverage(symbol=pair, leverage=round(leverage))
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e
except ccxt.BaseError as e: except ccxt.BaseError as e:
raise OperationalException(e) from e raise OperationalException(e) from e
@ -112,7 +94,7 @@ class Binance(Exchange):
since_ms: int, candle_type: CandleType, since_ms: int, candle_type: CandleType,
is_new_pair: bool = False, raise_: bool = False, is_new_pair: bool = False, raise_: bool = False,
until_ms: Optional[int] = None until_ms: Optional[int] = None
) -> Tuple[str, str, str, List]: ) -> OHLCVResponse:
""" """
Overwrite to introduce "fast new pair" functionality by detecting the pair's listing date Overwrite to introduce "fast new pair" functionality by detecting the pair's listing date
Does not work for other exchanges, which don't return the earliest data when called with "0" Does not work for other exchanges, which don't return the earliest data when called with "0"
@ -150,6 +132,7 @@ class Binance(Exchange):
is_short: bool, is_short: bool,
amount: float, amount: float,
stake_amount: float, stake_amount: float,
leverage: float,
wallet_balance: float, # Or margin balance wallet_balance: float, # Or margin balance
mm_ex_1: float = 0.0, # (Binance) Cross only mm_ex_1: float = 0.0, # (Binance) Cross only
upnl_ex_1: float = 0.0, # (Binance) Cross only upnl_ex_1: float = 0.0, # (Binance) Cross only
@ -159,11 +142,12 @@ class Binance(Exchange):
MARGIN: https://www.binance.com/en/support/faq/f6b010588e55413aa58b7d63ee0125ed MARGIN: https://www.binance.com/en/support/faq/f6b010588e55413aa58b7d63ee0125ed
PERPETUAL: https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93 PERPETUAL: https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
:param exchange_name: :param pair: Pair to calculate liquidation price for
:param open_rate: Entry price of position :param open_rate: Entry price of position
:param is_short: True if the trade is a short, false otherwise :param is_short: True if the trade is a short, false otherwise
:param amount: Absolute value of position size incl. leverage (in base currency) :param amount: Absolute value of position size incl. leverage (in base currency)
:param stake_amount: Stake amount - Collateral in settle currency. :param stake_amount: Stake amount - Collateral in settle currency.
:param leverage: Leverage used for this position.
:param trading_mode: SPOT, MARGIN, FUTURES, etc. :param trading_mode: SPOT, MARGIN, FUTURES, etc.
:param margin_mode: Either ISOLATED or CROSS :param margin_mode: Either ISOLATED or CROSS
:param wallet_balance: Amount of margin_mode in the wallet being used to trade :param wallet_balance: Amount of margin_mode in the wallet being used to trade
@ -212,7 +196,7 @@ class Binance(Exchange):
leverage_tiers_path = ( leverage_tiers_path = (
Path(__file__).parent / 'binance_leverage_tiers.json' Path(__file__).parent / 'binance_leverage_tiers.json'
) )
with open(leverage_tiers_path) as json_file: with leverage_tiers_path.open() as json_file:
return json_load(json_file) return json_load(json_file)
else: else:
try: try:

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,16 @@
""" Bybit exchange subclass """ """ Bybit exchange subclass """
import logging import logging
from typing import Dict, List, Tuple from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple
from freqtrade.enums import MarginMode, TradingMode import ccxt
from freqtrade.constants import BuySell
from freqtrade.enums import MarginMode, PriceType, TradingMode
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.exchange.common import retrier
from freqtrade.exchange.exchange_utils import timeframe_to_msecs
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -20,18 +27,27 @@ class Bybit(Exchange):
""" """
_ft_has: Dict = { _ft_has: Dict = {
"ohlcv_candle_limit": 1000, "ohlcv_candle_limit": 200,
"ccxt_futures_name": "linear",
"ohlcv_has_history": False, "ohlcv_has_history": False,
} }
_ft_has_futures: Dict = { _ft_has_futures: Dict = {
"ohlcv_has_history": True, "ohlcv_has_history": True,
"mark_ohlcv_timeframe": "4h",
"funding_fee_timeframe": "8h",
"stoploss_on_exchange": True,
"stoploss_order_types": {"limit": "limit", "market": "market"},
"stop_price_type_field": "triggerBy",
"stop_price_type_value_mapping": {
PriceType.LAST: "LastPrice",
PriceType.MARK: "MarkPrice",
PriceType.INDEX: "IndexPrice",
},
} }
_supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [
# TradingMode.SPOT always supported and not required in this list # TradingMode.SPOT always supported and not required in this list
# (TradingMode.FUTURES, MarginMode.CROSS), # (TradingMode.FUTURES, MarginMode.CROSS),
# (TradingMode.FUTURES, MarginMode.ISOLATED) (TradingMode.FUTURES, MarginMode.ISOLATED)
] ]
@property @property
@ -47,3 +63,158 @@ class Bybit(Exchange):
}) })
config.update(super()._ccxt_config) config.update(super()._ccxt_config)
return config return config
def market_is_future(self, market: Dict[str, Any]) -> bool:
main = super().market_is_future(market)
# For ByBit, we'll only support USDT markets for now.
return (
main and market['settle'] == 'USDT'
)
@retrier
def additional_exchange_init(self) -> None:
"""
Additional exchange initialization logic.
.api will be available at this point.
Must be overridden in child methods if required.
"""
try:
if self.trading_mode == TradingMode.FUTURES and not self._config['dry_run']:
position_mode = self._api.set_position_mode(False)
self._log_exchange_response('set_position_mode', position_mode)
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Error in additional_exchange_init due to {e.__class__.__name__}. Message: {e}'
) from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
async def _fetch_funding_rate_history(
self,
pair: str,
timeframe: str,
limit: int,
since_ms: Optional[int] = None,
) -> List[List]:
"""
Fetch funding rate history
Necessary workaround until https://github.com/ccxt/ccxt/issues/15990 is fixed.
"""
params = {}
if since_ms:
until = since_ms + (timeframe_to_msecs(timeframe) * self._ft_has['ohlcv_candle_limit'])
params.update({'until': until})
# Funding rate
data = await self._api_async.fetch_funding_rate_history(
pair, since=since_ms,
params=params)
# Convert funding rate to candle pattern
data = [[x['timestamp'], x['fundingRate'], 0, 0, 0, 0] for x in data]
return data
def _lev_prep(self, pair: str, leverage: float, side: BuySell, accept_fail: bool = False):
if self.trading_mode != TradingMode.SPOT:
params = {'leverage': leverage}
self.set_margin_mode(pair, self.margin_mode, accept_fail=True, params=params)
self._set_leverage(leverage, pair, accept_fail=True)
def _get_params(
self,
side: BuySell,
ordertype: str,
leverage: float,
reduceOnly: bool,
time_in_force: str = 'GTC',
) -> Dict:
params = super()._get_params(
side=side,
ordertype=ordertype,
leverage=leverage,
reduceOnly=reduceOnly,
time_in_force=time_in_force,
)
if self.trading_mode == TradingMode.FUTURES and self.margin_mode:
params['position_idx'] = 0
return params
def dry_run_liquidation_price(
self,
pair: str,
open_rate: float, # Entry price of position
is_short: bool,
amount: float,
stake_amount: float,
leverage: float,
wallet_balance: float, # Or margin balance
mm_ex_1: float = 0.0, # (Binance) Cross only
upnl_ex_1: float = 0.0, # (Binance) Cross only
) -> Optional[float]:
"""
Important: Must be fetching data from cached values as this is used by backtesting!
PERPETUAL:
bybit:
https://www.bybithelp.com/HelpCenterKnowledge/bybitHC_Article?language=en_US&id=000001067
Long:
Liquidation Price = (
Entry Price * (1 - Initial Margin Rate + Maintenance Margin Rate)
- Extra Margin Added/ Contract)
Short:
Liquidation Price = (
Entry Price * (1 + Initial Margin Rate - Maintenance Margin Rate)
+ Extra Margin Added/ Contract)
Implementation Note: Extra margin is currently not used.
:param pair: Pair to calculate liquidation price for
:param open_rate: Entry price of position
:param is_short: True if the trade is a short, false otherwise
:param amount: Absolute value of position size incl. leverage (in base currency)
:param stake_amount: Stake amount - Collateral in settle currency.
:param leverage: Leverage used for this position.
:param trading_mode: SPOT, MARGIN, FUTURES, etc.
:param margin_mode: Either ISOLATED or CROSS
:param wallet_balance: Amount of margin_mode in the wallet being used to trade
Cross-Margin Mode: crossWalletBalance
Isolated-Margin Mode: isolatedWalletBalance
"""
market = self.markets[pair]
mm_ratio, _ = self.get_maintenance_ratio_and_amt(pair, stake_amount)
if self.trading_mode == TradingMode.FUTURES and self.margin_mode == MarginMode.ISOLATED:
if market['inverse']:
raise OperationalException(
"Freqtrade does not yet support inverse contracts")
initial_margin_rate = 1 / leverage
# See docstring - ignores extra margin!
if is_short:
return open_rate * (1 + initial_margin_rate - mm_ratio)
else:
return open_rate * (1 - initial_margin_rate + mm_ratio)
else:
raise OperationalException(
"Freqtrade only supports isolated futures for leverage trading")
def get_funding_fees(
self, pair: str, amount: float, is_short: bool, open_date: datetime) -> float:
"""
Fetch funding fees, either from the exchange (live) or calculates them
based on funding rate/mark price history
:param pair: The quote/base pair of the trade
:param is_short: trade direction
:param amount: Trade amount
:param open_date: Open date of the trade
:return: funding fee since open_date
:raises: ExchangeError if something goes wrong.
"""
# 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)
return 0.0

View File

@ -46,13 +46,13 @@ MAP_EXCHANGE_CHILDCLASS = {
'binanceje': 'binance', 'binanceje': 'binance',
'binanceusdm': 'binance', 'binanceusdm': 'binance',
'okex': 'okx', 'okex': 'okx',
'gate': 'gateio', 'gateio': 'gate',
} }
SUPPORTED_EXCHANGES = [ SUPPORTED_EXCHANGES = [
'binance', 'binance',
'bittrex', 'bittrex',
'gateio', 'gate',
'huobi', 'huobi',
'kraken', 'kraken',
'okx', 'okx',

View File

@ -3,11 +3,11 @@
Cryptocurrency Exchanges support Cryptocurrency Exchanges support
""" """
import asyncio import asyncio
import http
import inspect import inspect
import logging import logging
from copy import deepcopy from copy import deepcopy
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from math import floor
from threading import Lock from threading import Lock
from typing import Any, Coroutine, Dict, List, Literal, Optional, Tuple, Union from typing import Any, Coroutine, Dict, List, Literal, Optional, Tuple, Union
@ -21,22 +21,24 @@ from pandas import DataFrame, concat
from freqtrade.constants import (DEFAULT_AMOUNT_RESERVE_PERCENT, NON_OPEN_EXCHANGE_STATES, BidAsk, from freqtrade.constants import (DEFAULT_AMOUNT_RESERVE_PERCENT, NON_OPEN_EXCHANGE_STATES, BidAsk,
BuySell, Config, EntryExit, ListPairsWithTimeframes, MakerTaker, BuySell, Config, EntryExit, ListPairsWithTimeframes, MakerTaker,
PairWithTimeframe) OBLiteral, PairWithTimeframe)
from freqtrade.data.converter import clean_ohlcv_dataframe, ohlcv_to_dataframe, trades_dict_to_list from freqtrade.data.converter import clean_ohlcv_dataframe, ohlcv_to_dataframe, trades_dict_to_list
from freqtrade.enums import OPTIMIZE_MODES, CandleType, MarginMode, TradingMode from freqtrade.enums import OPTIMIZE_MODES, CandleType, MarginMode, TradingMode
from freqtrade.enums.pricetype import PriceType
from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError, from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError,
InvalidOrderException, OperationalException, PricingError, InvalidOrderException, OperationalException, PricingError,
RetryableOrderError, TemporaryError) RetryableOrderError, TemporaryError)
from freqtrade.exchange.common import (API_FETCH_ORDER_RETRY_COUNT, remove_credentials, retrier, from freqtrade.exchange.common import (API_FETCH_ORDER_RETRY_COUNT, remove_credentials, retrier,
retrier_async) retrier_async)
from freqtrade.exchange.exchange_utils import (CcxtModuleType, amount_to_contract_precision, from freqtrade.exchange.exchange_utils import (ROUND, ROUND_DOWN, ROUND_UP, CcxtModuleType,
amount_to_contracts, amount_to_precision, amount_to_contract_precision, amount_to_contracts,
contracts_to_amount, date_minus_candles, amount_to_precision, contracts_to_amount,
is_exchange_known_ccxt, market_is_active, date_minus_candles, is_exchange_known_ccxt,
price_to_precision, timeframe_to_minutes, market_is_active, price_to_precision,
timeframe_to_msecs, timeframe_to_next_date, timeframe_to_minutes, timeframe_to_msecs,
timeframe_to_prev_date, timeframe_to_seconds) timeframe_to_next_date, timeframe_to_prev_date,
from freqtrade.exchange.types import Ticker, Tickers timeframe_to_seconds)
from freqtrade.exchange.types import OHLCVResponse, OrderBook, Ticker, Tickers
from freqtrade.misc import (chunks, deep_merge_dicts, file_dump_json, file_load_json, from freqtrade.misc import (chunks, deep_merge_dicts, file_dump_json, file_load_json,
safe_value_fallback2) safe_value_fallback2)
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
@ -45,12 +47,6 @@ from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Workaround for adding samesite support to pre 3.8 python
# Only applies to python3.7, and only on certain exchanges (kraken)
# Replicates the fix from starlette (which is actually causing this problem)
http.cookies.Morsel._reserved["samesite"] = "SameSite" # type: ignore
class Exchange: class Exchange:
# Parameters to add directly to buy/sell calls (like agreeing to trading agreement) # Parameters to add directly to buy/sell calls (like agreeing to trading agreement)
@ -64,8 +60,8 @@ class Exchange:
# or by specifying them in the configuration. # or by specifying them in the configuration.
_ft_has_default: Dict = { _ft_has_default: Dict = {
"stoploss_on_exchange": False, "stoploss_on_exchange": False,
"stop_price_param": "stopPrice",
"order_time_in_force": ["GTC"], "order_time_in_force": ["GTC"],
"time_in_force_parameter": "timeInForce",
"ohlcv_params": {}, "ohlcv_params": {},
"ohlcv_candle_limit": 500, "ohlcv_candle_limit": 500,
"ohlcv_has_history": True, # Some exchanges (Kraken) don't provide history via ohlcv "ohlcv_has_history": True, # Some exchanges (Kraken) don't provide history via ohlcv
@ -74,6 +70,7 @@ class Exchange:
# Check https://github.com/ccxt/ccxt/issues/10767 for removal of ohlcv_volume_currency # Check https://github.com/ccxt/ccxt/issues/10767 for removal of ohlcv_volume_currency
"ohlcv_volume_currency": "base", # "base" or "quote" "ohlcv_volume_currency": "base", # "base" or "quote"
"tickers_have_quoteVolume": True, "tickers_have_quoteVolume": True,
"tickers_have_bid_ask": True, # bid / ask empty for fetch_tickers
"tickers_have_price": True, "tickers_have_price": True,
"trades_pagination": "time", # Possible are "time" or "id" "trades_pagination": "time", # Possible are "time" or "id"
"trades_pagination_arg": "since", "trades_pagination_arg": "since",
@ -85,6 +82,8 @@ class Exchange:
"fee_cost_in_contracts": False, # Fee cost needs contract conversion "fee_cost_in_contracts": False, # Fee cost needs contract conversion
"needs_trading_fees": False, # use fetch_trading_fees to cache fees "needs_trading_fees": False, # use fetch_trading_fees to cache fees
"order_props_in_contracts": ['amount', 'cost', 'filled', 'remaining'], "order_props_in_contracts": ['amount', 'cost', 'filled', 'remaining'],
# Override createMarketBuyOrderRequiresPrice where ccxt has it wrong
"marketOrderRequiresPrice": False,
} }
_ft_has: Dict = {} _ft_has: Dict = {}
_ft_has_futures: Dict = {} _ft_has_futures: Dict = {}
@ -210,6 +209,8 @@ class Exchange:
and self._api_async.session): and self._api_async.session):
logger.debug("Closing async ccxt session.") logger.debug("Closing async ccxt session.")
self.loop.run_until_complete(self._api_async.close()) self.loop.run_until_complete(self._api_async.close())
if self.loop and not self.loop.is_closed():
self.loop.close()
def validate_config(self, config): def validate_config(self, config):
# Check if timeframe is available # Check if timeframe is available
@ -474,7 +475,7 @@ class Exchange:
try: try:
if self._api_async: if self._api_async:
self.loop.run_until_complete( self.loop.run_until_complete(
self._api_async.load_markets(reload=reload)) self._api_async.load_markets(reload=reload, params={}))
except (asyncio.TimeoutError, ccxt.BaseError) as e: except (asyncio.TimeoutError, ccxt.BaseError) as e:
logger.warning('Could not load async markets. Reason: %s', e) logger.warning('Could not load async markets. Reason: %s', e)
@ -483,7 +484,7 @@ class Exchange:
def _load_markets(self) -> None: def _load_markets(self) -> None:
""" Initialize markets both sync and async """ """ Initialize markets both sync and async """
try: try:
self._markets = self._api.load_markets() self._markets = self._api.load_markets(params={})
self._load_async_markets() self._load_async_markets()
self._last_markets_refresh = arrow.utcnow().int_timestamp self._last_markets_refresh = arrow.utcnow().int_timestamp
if self._ft_has['needs_trading_fees']: if self._ft_has['needs_trading_fees']:
@ -501,7 +502,7 @@ class Exchange:
return None return None
logger.debug("Performing scheduled market reload..") logger.debug("Performing scheduled market reload..")
try: try:
self._markets = self._api.load_markets(reload=True) self._markets = self._api.load_markets(reload=True, params={})
# Also reload async markets to avoid issues with newly listed pairs # Also reload async markets to avoid issues with newly listed pairs
self._load_async_markets(reload=True) self._load_async_markets(reload=True)
self._last_markets_refresh = arrow.utcnow().int_timestamp self._last_markets_refresh = arrow.utcnow().int_timestamp
@ -606,12 +607,27 @@ class Exchange:
if not self.exchange_has('createMarketOrder'): if not self.exchange_has('createMarketOrder'):
raise OperationalException( raise OperationalException(
f'Exchange {self.name} does not support market orders.') f'Exchange {self.name} does not support market orders.')
self.validate_stop_ordertypes(order_types)
def validate_stop_ordertypes(self, order_types: Dict) -> None:
"""
Validate stoploss order types
"""
if (order_types.get("stoploss_on_exchange") if (order_types.get("stoploss_on_exchange")
and not self._ft_has.get("stoploss_on_exchange", False)): and not self._ft_has.get("stoploss_on_exchange", False)):
raise OperationalException( raise OperationalException(
f'On exchange stoploss is not supported for {self.name}.' f'On exchange stoploss is not supported for {self.name}.'
) )
if self.trading_mode == TradingMode.FUTURES:
price_mapping = self._ft_has.get('stop_price_type_value_mapping', {}).keys()
if (
order_types.get("stoploss_on_exchange", False) is True
and 'stoploss_price_type' in order_types
and order_types['stoploss_price_type'] not in price_mapping
):
raise OperationalException(
f'On exchange stoploss price type is not supported for {self.name}.'
)
def validate_pricing(self, pricing: Dict) -> None: def validate_pricing(self, pricing: Dict) -> None:
if pricing.get('use_order_book', False) and not self.exchange_has('fetchL2OrderBook'): if pricing.get('use_order_book', False) and not self.exchange_has('fetchL2OrderBook'):
@ -682,7 +698,7 @@ class Exchange:
f"Freqtrade does not support {mm_value} {trading_mode.value} on {self.name}" f"Freqtrade does not support {mm_value} {trading_mode.value} on {self.name}"
) )
def get_option(self, param: str, default: Any = None) -> Any: def get_option(self, param: str, default: Optional[Any] = None) -> Any:
""" """
Get parameter value from _ft_has Get parameter value from _ft_has
""" """
@ -720,12 +736,14 @@ class Exchange:
""" """
return amount_to_precision(amount, self.get_precision_amount(pair), self.precisionMode) return amount_to_precision(amount, self.get_precision_amount(pair), self.precisionMode)
def price_to_precision(self, pair: str, price: float) -> float: def price_to_precision(self, pair: str, price: float, *, rounding_mode: int = ROUND) -> float:
""" """
Returns the price rounded up to the precision the Exchange accepts. Returns the price rounded to the precision the Exchange accepts.
Rounds up The default price_rounding_mode in conf is ROUND.
For stoploss calculations, must use ROUND_UP for longs, and ROUND_DOWN for shorts.
""" """
return price_to_precision(price, self.get_precision_price(pair), self.precisionMode) return price_to_precision(price, self.get_precision_price(pair),
self.precisionMode, rounding_mode=rounding_mode)
def price_get_one_pip(self, pair: str, price: float) -> float: def price_get_one_pip(self, pair: str, price: float) -> float:
""" """
@ -748,12 +766,12 @@ class Exchange:
return self._get_stake_amount_limit(pair, price, stoploss, 'min', leverage) return self._get_stake_amount_limit(pair, price, stoploss, 'min', leverage)
def get_max_pair_stake_amount(self, pair: str, price: float, leverage: float = 1.0) -> float: def get_max_pair_stake_amount(self, pair: str, price: float, leverage: float = 1.0) -> float:
max_stake_amount = self._get_stake_amount_limit(pair, price, 0.0, 'max') max_stake_amount = self._get_stake_amount_limit(pair, price, 0.0, 'max', leverage)
if max_stake_amount is None: if max_stake_amount is None:
# * Should never be executed # * Should never be executed
raise OperationalException(f'{self.name}.get_max_pair_stake_amount should' raise OperationalException(f'{self.name}.get_max_pair_stake_amount should'
'never set max_stake_amount to None') 'never set max_stake_amount to None')
return max_stake_amount / leverage return max_stake_amount
def _get_stake_amount_limit( def _get_stake_amount_limit(
self, self,
@ -771,43 +789,41 @@ class Exchange:
except KeyError: except KeyError:
raise ValueError(f"Can't get market information for symbol {pair}") raise ValueError(f"Can't get market information for symbol {pair}")
if isMin:
# reserve some percent defined in config (5% default) + stoploss
margin_reserve: float = 1.0 + self._config.get('amount_reserve_percent',
DEFAULT_AMOUNT_RESERVE_PERCENT)
stoploss_reserve = (
margin_reserve / (1 - abs(stoploss)) if abs(stoploss) != 1 else 1.5
)
# it should not be more than 50%
stoploss_reserve = max(min(stoploss_reserve, 1.5), 1)
else:
margin_reserve = 1.0
stoploss_reserve = 1.0
stake_limits = [] stake_limits = []
limits = market['limits'] limits = market['limits']
if (limits['cost'][limit] is not None): if (limits['cost'][limit] is not None):
stake_limits.append( stake_limits.append(
self._contracts_to_amount( self._contracts_to_amount(pair, limits['cost'][limit]) * stoploss_reserve
pair,
limits['cost'][limit]
)
) )
if (limits['amount'][limit] is not None): if (limits['amount'][limit] is not None):
stake_limits.append( stake_limits.append(
self._contracts_to_amount( self._contracts_to_amount(pair, limits['amount'][limit]) * price * margin_reserve
pair,
limits['amount'][limit] * price
)
) )
if not stake_limits: if not stake_limits:
return None if isMin else float('inf') return None if isMin else float('inf')
# reserve some percent defined in config (5% default) + stoploss
amount_reserve_percent = 1.0 + self._config.get('amount_reserve_percent',
DEFAULT_AMOUNT_RESERVE_PERCENT)
amount_reserve_percent = (
amount_reserve_percent / (1 - abs(stoploss)) if abs(stoploss) != 1 else 1.5
)
# it should not be more than 50%
amount_reserve_percent = max(min(amount_reserve_percent, 1.5), 1)
# The value returned should satisfy both limits: for amount (base currency) and # The value returned should satisfy both limits: for amount (base currency) and
# for cost (quote, stake currency), so max() is used here. # for cost (quote, stake currency), so max() is used here.
# See also #2575 at github. # See also #2575 at github.
return self._get_stake_amount_considering_leverage( return self._get_stake_amount_considering_leverage(
max(stake_limits) * amount_reserve_percent, max(stake_limits) if isMin else min(stake_limits),
leverage or 1.0 leverage or 1.0
) if isMin else min(stake_limits) )
def _get_stake_amount_considering_leverage(self, stake_amount: float, leverage: float) -> float: def _get_stake_amount_considering_leverage(self, stake_amount: float, leverage: float) -> float:
""" """
@ -840,7 +856,7 @@ class Exchange:
'remaining': _amount, 'remaining': _amount,
'datetime': arrow.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ'), 'datetime': arrow.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
'timestamp': arrow.utcnow().int_timestamp * 1000, 'timestamp': arrow.utcnow().int_timestamp * 1000,
'status': "closed" if ordertype == "market" and not stop_loss else "open", 'status': "open",
'fee': None, 'fee': None,
'info': {}, 'info': {},
'leverage': leverage 'leverage': leverage
@ -850,20 +866,33 @@ class Exchange:
dry_order["stopPrice"] = dry_order["price"] dry_order["stopPrice"] = dry_order["price"]
# Workaround to avoid filling stoploss orders immediately # Workaround to avoid filling stoploss orders immediately
dry_order["ft_order_type"] = "stoploss" dry_order["ft_order_type"] = "stoploss"
orderbook: Optional[OrderBook] = None
if self.exchange_has('fetchL2OrderBook'):
orderbook = self.fetch_l2_order_book(pair, 20)
if ordertype == "limit" and orderbook:
# Allow a 3% price difference
allowed_diff = 0.03
if self._dry_is_price_crossed(pair, side, rate, orderbook, allowed_diff):
logger.info(
f"Converted order {pair} to market order due to price {rate} crossing spread "
f"by more than {allowed_diff:.2%}.")
dry_order["type"] = "market"
if dry_order["type"] == "market" and not dry_order.get("ft_order_type"): if dry_order["type"] == "market" and not dry_order.get("ft_order_type"):
# Update market order pricing # Update market order pricing
average = self.get_dry_market_fill_price(pair, side, amount, rate) average = self.get_dry_market_fill_price(pair, side, amount, rate, orderbook)
dry_order.update({ dry_order.update({
'average': average, 'average': average,
'filled': _amount, 'filled': _amount,
'remaining': 0.0, 'remaining': 0.0,
'status': "closed",
'cost': (dry_order['amount'] * average) / leverage 'cost': (dry_order['amount'] * average) / leverage
}) })
# market orders will always incurr taker fees # market orders will always incurr taker fees
dry_order = self.add_dry_order_fee(pair, dry_order, 'taker') dry_order = self.add_dry_order_fee(pair, dry_order, 'taker')
dry_order = self.check_dry_limit_order_filled(dry_order, immediate=True) dry_order = self.check_dry_limit_order_filled(
dry_order, immediate=True, orderbook=orderbook)
self._dry_run_open_orders[dry_order["id"]] = dry_order self._dry_run_open_orders[dry_order["id"]] = dry_order
# Copy order and close it - so the returned order is open unless it's a market order # Copy order and close it - so the returned order is open unless it's a market order
@ -885,20 +914,22 @@ class Exchange:
}) })
return dry_order return dry_order
def get_dry_market_fill_price(self, pair: str, side: str, amount: float, rate: float) -> float: def get_dry_market_fill_price(self, pair: str, side: str, amount: float, rate: float,
orderbook: Optional[OrderBook]) -> float:
""" """
Get the market order fill price based on orderbook interpolation Get the market order fill price based on orderbook interpolation
""" """
if self.exchange_has('fetchL2OrderBook'): if self.exchange_has('fetchL2OrderBook'):
ob = self.fetch_l2_order_book(pair, 20) if not orderbook:
ob_type = 'asks' if side == 'buy' else 'bids' orderbook = self.fetch_l2_order_book(pair, 20)
ob_type: OBLiteral = 'asks' if side == 'buy' else 'bids'
slippage = 0.05 slippage = 0.05
max_slippage_val = rate * ((1 + slippage) if side == 'buy' else (1 - slippage)) max_slippage_val = rate * ((1 + slippage) if side == 'buy' else (1 - slippage))
remaining_amount = amount remaining_amount = amount
filled_amount = 0.0 filled_amount = 0.0
book_entry_price = 0.0 book_entry_price = 0.0
for book_entry in ob[ob_type]: for book_entry in orderbook[ob_type]:
book_entry_price = book_entry[0] book_entry_price = book_entry[0]
book_entry_coin_volume = book_entry[1] book_entry_coin_volume = book_entry[1]
if remaining_amount > 0: if remaining_amount > 0:
@ -926,20 +957,20 @@ class Exchange:
return rate return rate
def _is_dry_limit_order_filled(self, pair: str, side: str, limit: float) -> bool: def _dry_is_price_crossed(self, pair: str, side: str, limit: float,
orderbook: Optional[OrderBook] = None, offset: float = 0.0) -> bool:
if not self.exchange_has('fetchL2OrderBook'): if not self.exchange_has('fetchL2OrderBook'):
return True return True
ob = self.fetch_l2_order_book(pair, 1) if not orderbook:
orderbook = self.fetch_l2_order_book(pair, 1)
try: try:
if side == 'buy': if side == 'buy':
price = ob['asks'][0][0] price = orderbook['asks'][0][0]
logger.debug(f"{pair} checking dry buy-order: price={price}, limit={limit}") if limit * (1 - offset) >= price:
if limit >= price:
return True return True
else: else:
price = ob['bids'][0][0] price = orderbook['bids'][0][0]
logger.debug(f"{pair} checking dry sell-order: price={price}, limit={limit}") if limit * (1 + offset) <= price:
if limit <= price:
return True return True
except IndexError: except IndexError:
# Ignore empty orderbooks when filling - can be filled with the next iteration. # Ignore empty orderbooks when filling - can be filled with the next iteration.
@ -947,7 +978,8 @@ class Exchange:
return False return False
def check_dry_limit_order_filled( def check_dry_limit_order_filled(
self, order: Dict[str, Any], immediate: bool = False) -> Dict[str, Any]: self, order: Dict[str, Any], immediate: bool = False,
orderbook: Optional[OrderBook] = None) -> Dict[str, Any]:
""" """
Check dry-run limit order fill and update fee (if it filled). Check dry-run limit order fill and update fee (if it filled).
""" """
@ -955,7 +987,7 @@ class Exchange:
and order['type'] in ["limit"] and order['type'] in ["limit"]
and not order.get('ft_order_type')): and not order.get('ft_order_type')):
pair = order['symbol'] pair = order['symbol']
if self._is_dry_limit_order_filled(pair, order['side'], order['price']): if self._dry_is_price_crossed(pair, order['side'], order['price'], orderbook):
order.update({ order.update({
'status': 'closed', 'status': 'closed',
'filled': order['amount'], 'filled': order['amount'],
@ -992,10 +1024,10 @@ class Exchange:
# Order handling # Order handling
def _lev_prep(self, pair: str, leverage: float, side: BuySell): def _lev_prep(self, pair: str, leverage: float, side: BuySell, accept_fail: bool = False):
if self.trading_mode != TradingMode.SPOT: if self.trading_mode != TradingMode.SPOT:
self.set_margin_mode(pair, self.margin_mode) self.set_margin_mode(pair, self.margin_mode, accept_fail)
self._set_leverage(leverage, pair) self._set_leverage(leverage, pair, accept_fail)
def _get_params( def _get_params(
self, self,
@ -1007,12 +1039,18 @@ class Exchange:
) -> Dict: ) -> Dict:
params = self._params.copy() params = self._params.copy()
if time_in_force != 'GTC' and ordertype != 'market': if time_in_force != 'GTC' and ordertype != 'market':
param = self._ft_has.get('time_in_force_parameter', '') params.update({'timeInForce': time_in_force.upper()})
params.update({param: time_in_force.upper()})
if reduceOnly: if reduceOnly:
params.update({'reduceOnly': True}) params.update({'reduceOnly': True})
return params return params
def _order_needs_price(self, ordertype: str) -> bool:
return (
ordertype != 'market'
or self._api.options.get("createMarketBuyOrderRequiresPrice", False)
or self._ft_has.get('marketOrderRequiresPrice', False)
)
def create_order( def create_order(
self, self,
*, *,
@ -1035,8 +1073,7 @@ class Exchange:
try: try:
# Set the precision for amount and price(rate) as accepted by the exchange # Set the precision for amount and price(rate) as accepted by the exchange
amount = self.amount_to_precision(pair, self._amount_to_contracts(pair, amount)) amount = self.amount_to_precision(pair, self._amount_to_contracts(pair, amount))
needs_price = (ordertype != 'market' needs_price = self._order_needs_price(ordertype)
or self._api.options.get("createMarketBuyOrderRequiresPrice", False))
rate_for_order = self.price_to_precision(pair, rate) if needs_price else None rate_for_order = self.price_to_precision(pair, rate) if needs_price else None
if not reduceOnly: if not reduceOnly:
@ -1060,7 +1097,7 @@ class Exchange:
f'Tried to {side} amount {amount} at rate {rate}.' f'Tried to {side} amount {amount} at rate {rate}.'
f'Message: {e}') from e f'Message: {e}') from e
except ccxt.InvalidOrder as e: except ccxt.InvalidOrder as e:
raise ExchangeError( raise InvalidOrderException(
f'Could not create {ordertype} {side} order on market {pair}. ' f'Could not create {ordertype} {side} order on market {pair}. '
f'Tried to {side} amount {amount} at rate {rate}. ' f'Tried to {side} amount {amount} at rate {rate}. '
f'Message: {e}') from e f'Message: {e}') from e
@ -1079,11 +1116,11 @@ class Exchange:
""" """
if not self._ft_has.get('stoploss_on_exchange'): if not self._ft_has.get('stoploss_on_exchange'):
raise OperationalException(f"stoploss is not implemented for {self.name}.") raise OperationalException(f"stoploss is not implemented for {self.name}.")
price_param = self._ft_has['stop_price_param']
return ( return (
order.get('stopPrice', None) is None order.get(price_param, None) is None
or ((side == "sell" and stop_loss > float(order['stopPrice'])) or or ((side == "sell" and stop_loss > float(order[price_param])) or
(side == "buy" and stop_loss < float(order['stopPrice']))) (side == "buy" and stop_loss < float(order[price_param])))
) )
def _get_stop_order_type(self, user_order_type) -> Tuple[str, str]: def _get_stop_order_type(self, user_order_type) -> Tuple[str, str]:
@ -1110,19 +1147,26 @@ class Exchange:
"sell" else (stop_price >= limit_rate)) "sell" else (stop_price >= limit_rate))
# Ensure rate is less than stop price # Ensure rate is less than stop price
if bad_stop_price: if bad_stop_price:
raise OperationalException( # This can for example happen if the stop / liquidation price is set to 0
'In stoploss limit order, stop price should be more than limit price') # Which is possible if a market-order closes right away.
# The InvalidOrderException will bubble up to exit_positions, where it will be
# handled gracefully.
raise InvalidOrderException(
"In stoploss limit order, stop price should be more than limit price. "
f"Stop price: {stop_price}, Limit price: {limit_rate}, "
f"Limit Price pct: {limit_price_pct}"
)
return limit_rate return limit_rate
def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> Dict: def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> Dict:
params = self._params.copy() params = self._params.copy()
# Verify if stopPrice works for your exchange! # Verify if stopPrice works for your exchange, else configure stop_price_param
params.update({'stopPrice': stop_price}) params.update({self._ft_has['stop_price_param']: stop_price})
return params return params
@retrier(retries=0) @retrier(retries=0)
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict, def create_stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict,
side: BuySell, leverage: float) -> Dict: side: BuySell, leverage: float) -> Dict:
""" """
creates a stoploss order. creates a stoploss order.
requires `_ft_has['stoploss_order_types']` to be set as a dict mapping limit and market requires `_ft_has['stoploss_order_types']` to be set as a dict mapping limit and market
@ -1143,12 +1187,12 @@ class Exchange:
user_order_type = order_types.get('stoploss', 'market') user_order_type = order_types.get('stoploss', 'market')
ordertype, user_order_type = self._get_stop_order_type(user_order_type) ordertype, user_order_type = self._get_stop_order_type(user_order_type)
round_mode = ROUND_DOWN if side == 'buy' else ROUND_UP
stop_price_norm = self.price_to_precision(pair, stop_price) stop_price_norm = self.price_to_precision(pair, stop_price, rounding_mode=round_mode)
limit_rate = None limit_rate = None
if user_order_type == 'limit': if user_order_type == 'limit':
limit_rate = self._get_stop_limit_rate(stop_price, order_types, side) limit_rate = self._get_stop_limit_rate(stop_price, order_types, side)
limit_rate = self.price_to_precision(pair, limit_rate) limit_rate = self.price_to_precision(pair, limit_rate, rounding_mode=round_mode)
if self._config['dry_run']: if self._config['dry_run']:
dry_order = self.create_dry_run_order( dry_order = self.create_dry_run_order(
@ -1167,10 +1211,14 @@ class Exchange:
stop_price=stop_price_norm) stop_price=stop_price_norm)
if self.trading_mode == TradingMode.FUTURES: if self.trading_mode == TradingMode.FUTURES:
params['reduceOnly'] = True params['reduceOnly'] = True
if 'stoploss_price_type' in order_types and 'stop_price_type_field' in self._ft_has:
price_type = self._ft_has['stop_price_type_value_mapping'][
order_types.get('stoploss_price_type', PriceType.LAST)]
params[self._ft_has['stop_price_type_field']] = price_type
amount = self.amount_to_precision(pair, self._amount_to_contracts(pair, amount)) amount = self.amount_to_precision(pair, self._amount_to_contracts(pair, amount))
self._lev_prep(pair, leverage, side) self._lev_prep(pair, leverage, side, accept_fail=True)
order = self._api.create_order(symbol=pair, type=ordertype, side=side, order = self._api.create_order(symbol=pair, type=ordertype, side=side,
amount=amount, price=limit_rate, params=params) amount=amount, price=limit_rate, params=params)
self._log_exchange_response('create_stoploss_order', order) self._log_exchange_response('create_stoploss_order', order)
@ -1357,7 +1405,7 @@ class Exchange:
raise OperationalException(e) from e raise OperationalException(e) from e
@retrier @retrier
def fetch_positions(self, pair: str = None) -> List[Dict]: def fetch_positions(self, pair: Optional[str] = None) -> List[Dict]:
""" """
Fetch positions from the exchange. Fetch positions from the exchange.
If no pair is given, all positions are returned. If no pair is given, all positions are returned.
@ -1497,7 +1545,7 @@ class Exchange:
return result return result
@retrier @retrier
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict: def fetch_l2_order_book(self, pair: str, limit: int = 100) -> OrderBook:
""" """
Get L2 order book from exchange. Get L2 order book from exchange.
Can be limited to a certain amount (if supported). Can be limited to a certain amount (if supported).
@ -1540,7 +1588,7 @@ class Exchange:
def get_rate(self, pair: str, refresh: bool, def get_rate(self, pair: str, refresh: bool,
side: EntryExit, is_short: bool, side: EntryExit, is_short: bool,
order_book: Optional[dict] = None, ticker: Optional[Ticker] = None) -> float: order_book: Optional[OrderBook] = None, ticker: Optional[Ticker] = None) -> float:
""" """
Calculates bid/ask target Calculates bid/ask target
bid rate - between current ask price and last price bid rate - between current ask price and last price
@ -1578,7 +1626,8 @@ class Exchange:
logger.debug('order_book %s', order_book) logger.debug('order_book %s', order_book)
# top 1 = index 0 # top 1 = index 0
try: try:
rate = order_book[f"{price_side}s"][order_book_top - 1][0] obside: OBLiteral = 'bids' if price_side == 'bid' else 'asks'
rate = order_book[obside][order_book_top - 1][0]
except (IndexError, KeyError) as e: except (IndexError, KeyError) as e:
logger.warning( logger.warning(
f"{pair} - {name} Price at location {order_book_top} from orderbook " f"{pair} - {name} Price at location {order_book_top} from orderbook "
@ -1705,7 +1754,7 @@ class Exchange:
return self._config['fee'] return self._config['fee']
# validate that markets are loaded before trying to get fee # validate that markets are loaded before trying to get fee
if self._api.markets is None or len(self._api.markets) == 0: if self._api.markets is None or len(self._api.markets) == 0:
self._api.load_markets() self._api.load_markets(params={})
return self._api.calculate_fee(symbol=symbol, type=type, side=side, amount=amount, return self._api.calculate_fee(symbol=symbol, type=type, side=side, amount=amount,
price=price, takerOrMaker=taker_or_maker)['rate'] price=price, takerOrMaker=taker_or_maker)['rate']
@ -1801,7 +1850,7 @@ class Exchange:
def get_historic_ohlcv(self, pair: str, timeframe: str, def get_historic_ohlcv(self, pair: str, timeframe: str,
since_ms: int, candle_type: CandleType, since_ms: int, candle_type: CandleType,
is_new_pair: bool = False, is_new_pair: bool = False,
until_ms: int = None) -> List: until_ms: Optional[int] = None) -> List:
""" """
Get candle history using asyncio and returns the list of candles. Get candle history using asyncio and returns the list of candles.
Handles all async work for this. Handles all async work for this.
@ -1813,32 +1862,18 @@ class Exchange:
:param candle_type: '', mark, index, premiumIndex, or funding_rate :param candle_type: '', mark, index, premiumIndex, or funding_rate
:return: List with candle (OHLCV) data :return: List with candle (OHLCV) data
""" """
pair, _, _, data = self.loop.run_until_complete( pair, _, _, data, _ = self.loop.run_until_complete(
self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe, self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe,
since_ms=since_ms, until_ms=until_ms, since_ms=since_ms, until_ms=until_ms,
is_new_pair=is_new_pair, candle_type=candle_type)) is_new_pair=is_new_pair, candle_type=candle_type))
logger.info(f"Downloaded data for {pair} with length {len(data)}.") logger.info(f"Downloaded data for {pair} with length {len(data)}.")
return data return data
def get_historic_ohlcv_as_df(self, pair: str, timeframe: str,
since_ms: int, candle_type: CandleType) -> DataFrame:
"""
Minimal wrapper around get_historic_ohlcv - converting the result into a dataframe
:param pair: Pair to download
:param timeframe: Timeframe to get data for
:param since_ms: Timestamp in milliseconds to get history from
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: OHLCV DataFrame
"""
ticks = self.get_historic_ohlcv(pair, timeframe, since_ms=since_ms, candle_type=candle_type)
return ohlcv_to_dataframe(ticks, timeframe, pair=pair, fill_missing=True,
drop_incomplete=self._ohlcv_partial_candle)
async def _async_get_historic_ohlcv(self, pair: str, timeframe: str, async def _async_get_historic_ohlcv(self, pair: str, timeframe: str,
since_ms: int, candle_type: CandleType, since_ms: int, candle_type: CandleType,
is_new_pair: bool = False, raise_: bool = False, is_new_pair: bool = False, raise_: bool = False,
until_ms: Optional[int] = None until_ms: Optional[int] = None
) -> Tuple[str, str, str, List]: ) -> OHLCVResponse:
""" """
Download historic ohlcv Download historic ohlcv
:param is_new_pair: used by binance subclass to allow "fast" new pair downloading :param is_new_pair: used by binance subclass to allow "fast" new pair downloading
@ -1869,15 +1904,16 @@ class Exchange:
continue continue
else: else:
# Deconstruct tuple if it's not an exception # Deconstruct tuple if it's not an exception
p, _, c, new_data = res p, _, c, new_data, _ = res
if p == pair and c == candle_type: if p == pair and c == candle_type:
data.extend(new_data) data.extend(new_data)
# Sort data again after extending the result - above calls return in "async order" # Sort data again after extending the result - above calls return in "async order"
data = sorted(data, key=lambda x: x[0]) data = sorted(data, key=lambda x: x[0])
return pair, timeframe, candle_type, data return pair, timeframe, candle_type, data, self._ohlcv_partial_candle
def _build_coroutine(self, pair: str, timeframe: str, candle_type: CandleType, def _build_coroutine(
since_ms: Optional[int], cache: bool) -> Coroutine: self, pair: str, timeframe: str, candle_type: CandleType,
since_ms: Optional[int], cache: bool) -> Coroutine[Any, Any, OHLCVResponse]:
not_all_data = cache and self.required_candle_call_count > 1 not_all_data = cache and self.required_candle_call_count > 1
if cache and (pair, timeframe, candle_type) in self._klines: if cache and (pair, timeframe, candle_type) in self._klines:
candle_limit = self.ohlcv_candle_limit(timeframe, candle_type) candle_limit = self.ohlcv_candle_limit(timeframe, candle_type)
@ -1914,7 +1950,7 @@ class Exchange:
""" """
Build Coroutines to execute as part of refresh_latest_ohlcv Build Coroutines to execute as part of refresh_latest_ohlcv
""" """
input_coroutines = [] input_coroutines: List[Coroutine[Any, Any, OHLCVResponse]] = []
cached_pairs = [] cached_pairs = []
for pair, timeframe, candle_type in set(pair_list): for pair, timeframe, candle_type in set(pair_list):
if (timeframe not in self.timeframes if (timeframe not in self.timeframes
@ -1943,7 +1979,8 @@ class Exchange:
cache: bool, drop_incomplete: bool) -> DataFrame: cache: bool, drop_incomplete: bool) -> DataFrame:
# keeping last candle time as last refreshed time of the pair # keeping last candle time as last refreshed time of the pair
if ticks and cache: if ticks and cache:
self._pairs_last_refresh_time[(pair, timeframe, c_type)] = ticks[-1][0] // 1000 idx = -2 if drop_incomplete and len(ticks) > 1 else -1
self._pairs_last_refresh_time[(pair, timeframe, c_type)] = ticks[idx][0] // 1000
# keeping parsed dataframe in cache # keeping parsed dataframe in cache
ohlcv_df = ohlcv_to_dataframe(ticks, timeframe, pair=pair, fill_missing=True, ohlcv_df = ohlcv_to_dataframe(ticks, timeframe, pair=pair, fill_missing=True,
drop_incomplete=drop_incomplete) drop_incomplete=drop_incomplete)
@ -1978,7 +2015,6 @@ class Exchange:
:return: Dict of [{(pair, timeframe): Dataframe}] :return: Dict of [{(pair, timeframe): Dataframe}]
""" """
logger.debug("Refreshing candle (OHLCV) data for %d pairs", len(pair_list)) logger.debug("Refreshing candle (OHLCV) data for %d pairs", len(pair_list))
drop_incomplete = self._ohlcv_partial_candle if drop_incomplete is None else drop_incomplete
# Gather coroutines to run # Gather coroutines to run
input_coroutines, cached_pairs = self._build_ohlcv_dl_jobs(pair_list, since_ms, cache) input_coroutines, cached_pairs = self._build_ohlcv_dl_jobs(pair_list, since_ms, cache)
@ -1996,10 +2032,11 @@ class Exchange:
if isinstance(res, Exception): if isinstance(res, Exception):
logger.warning(f"Async code raised an exception: {repr(res)}") logger.warning(f"Async code raised an exception: {repr(res)}")
continue continue
# Deconstruct tuple (has 4 elements) # Deconstruct tuple (has 5 elements)
pair, timeframe, c_type, ticks = res pair, timeframe, c_type, ticks, drop_hint = res
drop_incomplete_ = drop_hint if drop_incomplete is None else drop_incomplete
ohlcv_df = self._process_ohlcv_df( ohlcv_df = self._process_ohlcv_df(
pair, timeframe, c_type, ticks, cache, drop_incomplete) pair, timeframe, c_type, ticks, cache, drop_incomplete_)
results_df[(pair, timeframe, c_type)] = ohlcv_df results_df[(pair, timeframe, c_type)] = ohlcv_df
@ -2016,7 +2053,9 @@ class Exchange:
# Timeframe in seconds # Timeframe in seconds
interval_in_sec = timeframe_to_seconds(timeframe) interval_in_sec = timeframe_to_seconds(timeframe)
plr = self._pairs_last_refresh_time.get((pair, timeframe, candle_type), 0) + interval_in_sec plr = self._pairs_last_refresh_time.get((pair, timeframe, candle_type), 0) + interval_in_sec
return plr < arrow.utcnow().int_timestamp # current,active candle open date
now = int(timeframe_to_prev_date(timeframe).timestamp())
return plr < now
@retrier_async @retrier_async
async def _async_get_candle_history( async def _async_get_candle_history(
@ -2025,7 +2064,7 @@ class Exchange:
timeframe: str, timeframe: str,
candle_type: CandleType, candle_type: CandleType,
since_ms: Optional[int] = None, since_ms: Optional[int] = None,
) -> Tuple[str, str, str, List]: ) -> OHLCVResponse:
""" """
Asynchronously get candle history data using fetch_ohlcv Asynchronously get candle history data using fetch_ohlcv
:param candle_type: '', mark, index, premiumIndex, or funding_rate :param candle_type: '', mark, index, premiumIndex, or funding_rate
@ -2035,8 +2074,8 @@ class Exchange:
# Fetch OHLCV asynchronously # Fetch OHLCV asynchronously
s = '(' + arrow.get(since_ms // 1000).isoformat() + ') ' if since_ms is not None else '' s = '(' + arrow.get(since_ms // 1000).isoformat() + ') ' if since_ms is not None else ''
logger.debug( logger.debug(
"Fetching pair %s, interval %s, since %s %s...", "Fetching pair %s, %s, interval %s, since %s %s...",
pair, timeframe, since_ms, s pair, candle_type, timeframe, since_ms, s
) )
params = deepcopy(self._ft_has.get('ohlcv_params', {})) params = deepcopy(self._ft_has.get('ohlcv_params', {}))
candle_limit = self.ohlcv_candle_limit( candle_limit = self.ohlcv_candle_limit(
@ -2050,11 +2089,12 @@ class Exchange:
limit=candle_limit, params=params) limit=candle_limit, params=params)
else: else:
# Funding rate # Funding rate
data = await self._api_async.fetch_funding_rate_history( data = await self._fetch_funding_rate_history(
pair, since=since_ms, pair=pair,
limit=candle_limit) timeframe=timeframe,
# Convert funding rate to candle pattern limit=candle_limit,
data = [[x['timestamp'], x['fundingRate'], 0, 0, 0, 0] for x in data] since_ms=since_ms,
)
# Some exchanges sort OHLCV in ASC order and others in DESC. # Some exchanges sort OHLCV in ASC order and others in DESC.
# Ex: Bittrex returns the list of OHLCV in ASC order (oldest first, newest last) # Ex: Bittrex returns the list of OHLCV in ASC order (oldest first, newest last)
# while GDAX returns the list of OHLCV in DESC order (newest first, oldest last) # while GDAX returns the list of OHLCV in DESC order (newest first, oldest last)
@ -2064,9 +2104,9 @@ class Exchange:
data = sorted(data, key=lambda x: x[0]) data = sorted(data, key=lambda x: x[0])
except IndexError: except IndexError:
logger.exception("Error loading %s. Result was %s.", pair, data) logger.exception("Error loading %s. Result was %s.", pair, data)
return pair, timeframe, candle_type, [] return pair, timeframe, candle_type, [], self._ohlcv_partial_candle
logger.debug("Done fetching pair %s, interval %s ...", pair, timeframe) logger.debug("Done fetching pair %s, interval %s ...", pair, timeframe)
return pair, timeframe, candle_type, data return pair, timeframe, candle_type, data, self._ohlcv_partial_candle
except ccxt.NotSupported as e: except ccxt.NotSupported as e:
raise OperationalException( raise OperationalException(
@ -2082,6 +2122,24 @@ class Exchange:
raise OperationalException(f'Could not fetch historical candle (OHLCV) data ' raise OperationalException(f'Could not fetch historical candle (OHLCV) data '
f'for pair {pair}. Message: {e}') from e f'for pair {pair}. Message: {e}') from e
async def _fetch_funding_rate_history(
self,
pair: str,
timeframe: str,
limit: int,
since_ms: Optional[int] = None,
) -> List[List]:
"""
Fetch funding rate history - used to selectively override this by subclasses.
"""
# Funding rate
data = await self._api_async.fetch_funding_rate_history(
pair, since=since_ms,
limit=limit)
# Convert funding rate to candle pattern
data = [[x['timestamp'], x['fundingRate'], 0, 0, 0, 0] for x in data]
return data
# Fetch historic trades # Fetch historic trades
@retrier_async @retrier_async
@ -2485,7 +2543,7 @@ class Exchange:
self, self,
leverage: float, leverage: float,
pair: Optional[str] = None, pair: Optional[str] = None,
trading_mode: Optional[TradingMode] = None accept_fail: bool = False,
): ):
""" """
Set's the leverage before making a trade, in order to not Set's the leverage before making a trade, in order to not
@ -2494,12 +2552,18 @@ class Exchange:
if self._config['dry_run'] or not self.exchange_has("setLeverage"): if self._config['dry_run'] or not self.exchange_has("setLeverage"):
# Some exchanges only support one margin_mode type # Some exchanges only support one margin_mode type
return return
if self._ft_has.get('floor_leverage', False) is True:
# Rounding for binance ...
leverage = floor(leverage)
try: try:
res = self._api.set_leverage(symbol=pair, leverage=leverage) res = self._api.set_leverage(symbol=pair, leverage=leverage)
self._log_exchange_response('set_leverage', res) self._log_exchange_response('set_leverage', res)
except ccxt.DDoSProtection as e: except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e raise DDosProtection(e) from e
except (ccxt.BadRequest, ccxt.InsufficientFunds) as e:
if not accept_fail:
raise TemporaryError(
f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e: except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError( raise TemporaryError(
f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e
@ -2521,7 +2585,8 @@ class Exchange:
return open_date.minute > 0 or open_date.second > 0 return open_date.minute > 0 or open_date.second > 0
@retrier @retrier
def set_margin_mode(self, pair: str, margin_mode: MarginMode, params: dict = {}): def set_margin_mode(self, pair: str, margin_mode: MarginMode, accept_fail: bool = False,
params: dict = {}):
""" """
Set's the margin mode on the exchange to cross or isolated for a specific pair Set's the margin mode on the exchange to cross or isolated for a specific pair
:param pair: base/quote currency pair (e.g. "ADA/USDT") :param pair: base/quote currency pair (e.g. "ADA/USDT")
@ -2535,6 +2600,10 @@ class Exchange:
self._log_exchange_response('set_margin_mode', res) self._log_exchange_response('set_margin_mode', res)
except ccxt.DDoSProtection as e: except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e raise DDosProtection(e) from e
except ccxt.BadRequest as e:
if not accept_fail:
raise TemporaryError(
f'Could not set margin mode due to {e.__class__.__name__}. Message: {e}') from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e: except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError( raise TemporaryError(
f'Could not set margin mode due to {e.__class__.__name__}. Message: {e}') from e f'Could not set margin mode due to {e.__class__.__name__}. Message: {e}') from e
@ -2668,7 +2737,7 @@ class Exchange:
:param amount: Trade amount :param amount: Trade amount
:param open_date: Open date of the trade :param open_date: Open date of the trade
:return: funding fee since open_date :return: funding fee since open_date
:raies: ExchangeError if something goes wrong. :raises: ExchangeError if something goes wrong.
""" """
if self.trading_mode == TradingMode.FUTURES: if self.trading_mode == TradingMode.FUTURES:
if self._config['dry_run']: if self._config['dry_run']:
@ -2688,6 +2757,7 @@ class Exchange:
is_short: bool, is_short: bool,
amount: float, # Absolute value of position size amount: float, # Absolute value of position size
stake_amount: float, stake_amount: float,
leverage: float,
wallet_balance: float, wallet_balance: float,
mm_ex_1: float = 0.0, # (Binance) Cross only mm_ex_1: float = 0.0, # (Binance) Cross only
upnl_ex_1: float = 0.0, # (Binance) Cross only upnl_ex_1: float = 0.0, # (Binance) Cross only
@ -2701,14 +2771,15 @@ class Exchange:
raise OperationalException( raise OperationalException(
f"{self.name} does not support {self.margin_mode} {self.trading_mode}") f"{self.name} does not support {self.margin_mode} {self.trading_mode}")
isolated_liq = None liquidation_price = None
if self._config['dry_run'] or not self.exchange_has("fetchPositions"): if self._config['dry_run'] or not self.exchange_has("fetchPositions"):
isolated_liq = self.dry_run_liquidation_price( liquidation_price = self.dry_run_liquidation_price(
pair=pair, pair=pair,
open_rate=open_rate, open_rate=open_rate,
is_short=is_short, is_short=is_short,
amount=amount, amount=amount,
leverage=leverage,
stake_amount=stake_amount, stake_amount=stake_amount,
wallet_balance=wallet_balance, wallet_balance=wallet_balance,
mm_ex_1=mm_ex_1, mm_ex_1=mm_ex_1,
@ -2718,16 +2789,16 @@ class Exchange:
positions = self.fetch_positions(pair) positions = self.fetch_positions(pair)
if len(positions) > 0: if len(positions) > 0:
pos = positions[0] pos = positions[0]
isolated_liq = pos['liquidationPrice'] liquidation_price = pos['liquidationPrice']
if isolated_liq: if liquidation_price is not None:
buffer_amount = abs(open_rate - isolated_liq) * self.liquidation_buffer buffer_amount = abs(open_rate - liquidation_price) * self.liquidation_buffer
isolated_liq = ( liquidation_price_buffer = (
isolated_liq - buffer_amount liquidation_price - buffer_amount
if is_short else if is_short else
isolated_liq + buffer_amount liquidation_price + buffer_amount
) )
return isolated_liq return max(liquidation_price_buffer, 0.0)
else: else:
return None return None
@ -2738,6 +2809,7 @@ class Exchange:
is_short: bool, is_short: bool,
amount: float, amount: float,
stake_amount: float, stake_amount: float,
leverage: float,
wallet_balance: float, # Or margin balance wallet_balance: float, # Or margin balance
mm_ex_1: float = 0.0, # (Binance) Cross only mm_ex_1: float = 0.0, # (Binance) Cross only
upnl_ex_1: float = 0.0, # (Binance) Cross only upnl_ex_1: float = 0.0, # (Binance) Cross only
@ -2745,22 +2817,28 @@ class Exchange:
""" """
Important: Must be fetching data from cached values as this is used by backtesting! Important: Must be fetching data from cached values as this is used by backtesting!
PERPETUAL: PERPETUAL:
gateio: https://www.gate.io/help/futures/perpetual/22160/calculation-of-liquidation-price gate: https://www.gate.io/help/futures/futures/27724/liquidation-price-bankruptcy-price
> Liquidation Price = (Entry Price ± Margin / Contract Multiplier / Size) /
[ 1 ± (Maintenance Margin Ratio + Taker Rate)]
Wherein, "+" or "-" depends on whether the contract goes long or short:
"-" for long, and "+" for short.
okex: https://www.okex.com/support/hc/en-us/articles/ okex: https://www.okex.com/support/hc/en-us/articles/
360053909592-VI-Introduction-to-the-isolated-mode-of-Single-Multi-currency-Portfolio-margin 360053909592-VI-Introduction-to-the-isolated-mode-of-Single-Multi-currency-Portfolio-margin
:param exchange_name: :param pair: Pair to calculate liquidation price for
:param open_rate: Entry price of position :param open_rate: Entry price of position
:param is_short: True if the trade is a short, false otherwise :param is_short: True if the trade is a short, false otherwise
:param amount: Absolute value of position size incl. leverage (in base currency) :param amount: Absolute value of position size incl. leverage (in base currency)
:param stake_amount: Stake amount - Collateral in settle currency. :param stake_amount: Stake amount - Collateral in settle currency.
:param leverage: Leverage used for this position.
:param trading_mode: SPOT, MARGIN, FUTURES, etc. :param trading_mode: SPOT, MARGIN, FUTURES, etc.
:param margin_mode: Either ISOLATED or CROSS :param margin_mode: Either ISOLATED or CROSS
:param wallet_balance: Amount of margin_mode in the wallet being used to trade :param wallet_balance: Amount of margin_mode in the wallet being used to trade
Cross-Margin Mode: crossWalletBalance Cross-Margin Mode: crossWalletBalance
Isolated-Margin Mode: isolatedWalletBalance Isolated-Margin Mode: isolatedWalletBalance
# * Not required by Gateio or OKX # * Not required by Gate or OKX
:param mm_ex_1: :param mm_ex_1:
:param upnl_ex_1: :param upnl_ex_1:
""" """
@ -2789,7 +2867,7 @@ class Exchange:
def get_maintenance_ratio_and_amt( def get_maintenance_ratio_and_amt(
self, self,
pair: str, pair: str,
nominal_value: float = 0.0, nominal_value: float,
) -> Tuple[float, Optional[float]]: ) -> Tuple[float, Optional[float]]:
""" """
Important: Must be fetching data from cached values as this is used by backtesting! Important: Must be fetching data from cached values as this is used by backtesting!

View File

@ -2,11 +2,12 @@
Exchange support utils Exchange support utils
""" """
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from math import ceil from math import ceil, floor
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
import ccxt import ccxt
from ccxt import ROUND_DOWN, ROUND_UP, TICK_SIZE, TRUNCATE, decimal_to_precision from ccxt import (DECIMAL_PLACES, ROUND, ROUND_DOWN, ROUND_UP, SIGNIFICANT_DIGITS, TICK_SIZE,
TRUNCATE, decimal_to_precision)
from freqtrade.exchange.common import BAD_EXCHANGES, EXCHANGE_HAS_OPTIONAL, EXCHANGE_HAS_REQUIRED from freqtrade.exchange.common import BAD_EXCHANGES, EXCHANGE_HAS_OPTIONAL, EXCHANGE_HAS_REQUIRED
from freqtrade.util import FtPrecise from freqtrade.util import FtPrecise
@ -15,18 +16,19 @@ from freqtrade.util import FtPrecise
CcxtModuleType = Any CcxtModuleType = Any
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool: def is_exchange_known_ccxt(
exchange_name: str, ccxt_module: Optional[CcxtModuleType] = None) -> bool:
return exchange_name in ccxt_exchanges(ccxt_module) return exchange_name in ccxt_exchanges(ccxt_module)
def ccxt_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]: def ccxt_exchanges(ccxt_module: Optional[CcxtModuleType] = None) -> List[str]:
""" """
Return the list of all exchanges known to ccxt Return the list of all exchanges known to ccxt
""" """
return ccxt_module.exchanges if ccxt_module is not None else ccxt.exchanges return ccxt_module.exchanges if ccxt_module is not None else ccxt.exchanges
def available_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]: def available_exchanges(ccxt_module: Optional[CcxtModuleType] = None) -> List[str]:
""" """
Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list
""" """
@ -86,7 +88,7 @@ def timeframe_to_msecs(timeframe: str) -> int:
return ccxt.Exchange.parse_timeframe(timeframe) * 1000 return ccxt.Exchange.parse_timeframe(timeframe) * 1000
def timeframe_to_prev_date(timeframe: str, date: datetime = None) -> datetime: def timeframe_to_prev_date(timeframe: str, date: Optional[datetime] = None) -> datetime:
""" """
Use Timeframe and determine the candle start date for this date. Use Timeframe and determine the candle start date for this date.
Does not round when given a candle start date. Does not round when given a candle start date.
@ -102,7 +104,7 @@ def timeframe_to_prev_date(timeframe: str, date: datetime = None) -> datetime:
return datetime.fromtimestamp(new_timestamp, tz=timezone.utc) return datetime.fromtimestamp(new_timestamp, tz=timezone.utc)
def timeframe_to_next_date(timeframe: str, date: datetime = None) -> datetime: def timeframe_to_next_date(timeframe: str, date: Optional[datetime] = None) -> datetime:
""" """
Use Timeframe and determine next candle. Use Timeframe and determine next candle.
:param timeframe: timeframe in string format (e.g. "5m") :param timeframe: timeframe in string format (e.g. "5m")
@ -218,35 +220,51 @@ def amount_to_contract_precision(
return amount return amount
def price_to_precision(price: float, price_precision: Optional[float], def price_to_precision(
precisionMode: Optional[int]) -> float: price: float,
price_precision: Optional[float],
precisionMode: Optional[int],
*,
rounding_mode: int = ROUND,
) -> float:
""" """
Returns the price rounded up to the precision the Exchange accepts. Returns the price rounded to the precision the Exchange accepts.
Partial Re-implementation of ccxt internal method decimal_to_precision(), Partial Re-implementation of ccxt internal method decimal_to_precision(),
which does not support rounding up which does not support rounding up.
For stoploss calculations, must use ROUND_UP for longs, and ROUND_DOWN for shorts.
TODO: If ccxt supports ROUND_UP for decimal_to_precision(), we could remove this and TODO: If ccxt supports ROUND_UP for decimal_to_precision(), we could remove this and
align with amount_to_precision(). align with amount_to_precision().
!!! Rounds up
:param price: price to convert :param price: price to convert
:param price_precision: price precision to use. Used from markets[pair]['precision']['price'] :param price_precision: price precision to use. Used from markets[pair]['precision']['price']
:param precisionMode: precision mode to use. Should be used from precisionMode :param precisionMode: precision mode to use. Should be used from precisionMode
one of ccxt's DECIMAL_PLACES, SIGNIFICANT_DIGITS, or TICK_SIZE one of ccxt's DECIMAL_PLACES, SIGNIFICANT_DIGITS, or TICK_SIZE
:param rounding_mode: rounding mode to use. Defaults to ROUND
:return: price rounded up to the precision the Exchange accepts :return: price rounded up to the precision the Exchange accepts
""" """
if price_precision is not None and precisionMode is not None: if price_precision is not None and precisionMode is not None:
# price = float(decimal_to_precision(price, rounding_mode=ROUND,
# precision=price_precision,
# counting_mode=self.precisionMode,
# ))
if precisionMode == TICK_SIZE: if precisionMode == TICK_SIZE:
if rounding_mode == ROUND:
ticks = price / price_precision
rounded_ticks = round(ticks)
return rounded_ticks * price_precision
precision = FtPrecise(price_precision) precision = FtPrecise(price_precision)
price_str = FtPrecise(price) price_str = FtPrecise(price)
missing = price_str % precision missing = price_str % precision
if not missing == FtPrecise("0"): if not missing == FtPrecise("0"):
price = round(float(str(price_str - missing + precision)), 14) return round(float(str(price_str - missing + precision)), 14)
else: return price
symbol_prec = price_precision elif precisionMode in (SIGNIFICANT_DIGITS, DECIMAL_PLACES):
big_price = price * pow(10, symbol_prec) ndigits = round(price_precision)
price = ceil(big_price) / pow(10, symbol_prec) if rounding_mode == ROUND:
return round(price, ndigits)
ticks = price * (10**ndigits)
if rounding_mode == ROUND_UP:
return ceil(ticks) / (10**ndigits)
if rounding_mode == TRUNCATE:
return int(ticks) / (10**ndigits)
if rounding_mode == ROUND_DOWN:
return floor(ticks) / (10**ndigits)
raise ValueError(f"Unknown rounding_mode {rounding_mode}")
raise ValueError(f"Unknown precisionMode {precisionMode}")
return price return price

View File

@ -4,8 +4,7 @@ from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
from freqtrade.constants import BuySell from freqtrade.constants import BuySell
from freqtrade.enums import MarginMode, TradingMode from freqtrade.enums import MarginMode, PriceType, TradingMode
from freqtrade.exceptions import OperationalException
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.misc import safe_value_fallback2 from freqtrade.misc import safe_value_fallback2
@ -13,7 +12,7 @@ from freqtrade.misc import safe_value_fallback2
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Gateio(Exchange): class Gate(Exchange):
""" """
Gate.io exchange class. Contains adjustments needed for Freqtrade to work Gate.io exchange class. Contains adjustments needed for Freqtrade to work
with this exchange. with this exchange.
@ -28,12 +27,21 @@ class Gateio(Exchange):
"order_time_in_force": ['GTC', 'IOC'], "order_time_in_force": ['GTC', 'IOC'],
"stoploss_order_types": {"limit": "limit"}, "stoploss_order_types": {"limit": "limit"},
"stoploss_on_exchange": True, "stoploss_on_exchange": True,
"marketOrderRequiresPrice": True,
} }
_ft_has_futures: Dict = { _ft_has_futures: Dict = {
"needs_trading_fees": True, "needs_trading_fees": True,
"marketOrderRequiresPrice": False,
"tickers_have_bid_ask": False,
"fee_cost_in_contracts": False, # Set explicitly to false for clarity "fee_cost_in_contracts": False, # Set explicitly to false for clarity
"order_props_in_contracts": ['amount', 'filled', 'remaining'], "order_props_in_contracts": ['amount', 'filled', 'remaining'],
"stop_price_type_field": "price_type",
"stop_price_type_value_mapping": {
PriceType.LAST: 0,
PriceType.MARK: 1,
PriceType.INDEX: 2,
},
} }
_supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [
@ -43,13 +51,6 @@ class Gateio(Exchange):
(TradingMode.FUTURES, MarginMode.ISOLATED) (TradingMode.FUTURES, MarginMode.ISOLATED)
] ]
def validate_ordertypes(self, order_types: Dict) -> None:
if self.trading_mode != TradingMode.FUTURES:
if any(v == 'market' for k, v in order_types.items()):
raise OperationalException(
f'Exchange {self.name} does not support market orders.')
def _get_params( def _get_params(
self, self,
side: BuySell, side: BuySell,
@ -67,8 +68,7 @@ class Gateio(Exchange):
) )
if ordertype == 'market' and self.trading_mode == TradingMode.FUTURES: if ordertype == 'market' and self.trading_mode == TradingMode.FUTURES:
params['type'] = 'market' params['type'] = 'market'
param = self._ft_has.get('time_in_force_parameter', '') params.update({'timeInForce': 'IOC'})
params.update({param: 'IOC'})
return params return params
def get_trades_for_order(self, order_id: str, pair: str, since: datetime, def get_trades_for_order(self, order_id: str, pair: str, since: datetime,
@ -77,7 +77,7 @@ class Gateio(Exchange):
if self.trading_mode == TradingMode.FUTURES: if self.trading_mode == TradingMode.FUTURES:
# Futures usually don't contain fees in the response. # Futures usually don't contain fees in the response.
# As such, futures orders on gateio will not contain a fee, which causes # As such, futures orders on gate will not contain a fee, which causes
# a repeated "update fee" cycle and wrong calculations. # a repeated "update fee" cycle and wrong calculations.
# Therefore we patch the response with fees if it's not available. # Therefore we patch the response with fees if it's not available.
# An alternative also contianing fees would be # An alternative also contianing fees would be

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