Compare commits
589 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f00a1d0d2 | |||
| 9a37d7bfbb | |||
| c9c08906e5 | |||
| 5c02ce934d | |||
| 260512d678 | |||
| 8b1b16cb08 | |||
| cacd52db1c | |||
| 4e809947c7 | |||
| 89c4aa23f3 | |||
| 1bd043a912 | |||
| 3ce23f99de | |||
| c5fa5c5c69 | |||
| 21d0b60168 | |||
| ba3925cdcd | |||
| 9cf6d47a43 | |||
| e01993b9c1 | |||
| c354a76ae2 | |||
| f296213088 | |||
| d80dbc1644 | |||
| 91ee8652ef | |||
| 75dfc95221 | |||
| 05fe35ce57 | |||
| 95e36013db | |||
| c5c96d9610 | |||
| ad9a7279be | |||
| dafb2fda7b | |||
| 04fea4ac29 | |||
| 896250fe88 | |||
| 8485abc9b8 | |||
| 2013a2edda | |||
| 11eb0c0802 | |||
| 78709a9d76 | |||
| f55a90d98c | |||
| 4b3ff02d49 | |||
| ea52deb98e | |||
| 7b33242aa0 | |||
| 46ee092119 | |||
| 931cd2e7ba | |||
| b6899264a8 | |||
| ca47882fa9 | |||
| c21ce5ef94 | |||
| 9baa6eebbe | |||
| 0feec257e3 | |||
| 802d42cc00 | |||
| f546146d40 | |||
| d2c4bd1b50 | |||
| 5e5495e050 | |||
| 51f3f0d65a | |||
| 0019867da8 | |||
| 335e632bbc | |||
| d0ac462dd3 | |||
| fc113f7bbf | |||
| 4f6b1b6fd0 | |||
| 006d2305af | |||
| 5c9f140c5d | |||
| c6f3b00819 | |||
| 1780d2db23 | |||
| 78d602f7b4 | |||
| 4823f66c4e | |||
| a3c19d10f7 | |||
| ebb318a0f0 | |||
| 35d6e6e832 | |||
| 37bc93e0d3 | |||
| 2cd30b0604 | |||
| 2f30cda9d7 | |||
| 9e1c760222 | |||
| 53884cae2f | |||
| 1b16b450b7 | |||
| 18ba3241ce | |||
| 6f8ad595b7 | |||
| 5479f204b5 | |||
| c54b94b5a4 | |||
| 5ed590d862 | |||
| 3f5ed399b5 | |||
| a9a686c64e | |||
| 978ca8f852 | |||
| ea30f906f9 | |||
| 811112f0ce | |||
| 5ebffb27aa | |||
| 0cb676a677 | |||
| 6a6dce323d | |||
| 0d62fab367 | |||
| a1b4a4dbfb | |||
| 092da6aee5 | |||
| 13c63c0bf5 | |||
| aa38a36b56 | |||
| e9847d9549 | |||
| 0beb76ce48 | |||
| 21d723b35d | |||
| f002ce67b1 | |||
| 5fdc8acbe9 | |||
| 1811f9581f | |||
| 66235f3198 | |||
| 6c8b8f642a | |||
| 6905b8059d | |||
| 1143aba671 | |||
| 278bd0e97d | |||
| d5b296c75c | |||
| c63fba2e57 | |||
| c8d74baaa1 | |||
| a9ebff3965 | |||
| 8859b9009a | |||
| d4aee7e433 | |||
| f0908a1043 | |||
| cf6bf1b7b5 | |||
| 84e9251fcd | |||
| 5800002d42 | |||
| 6a98c19dab | |||
| 025707d9ad | |||
| 4540e2ceea | |||
| eb3e8b82f9 | |||
| 98da54ae82 | |||
| fa5210aa4b | |||
| 289e53ed5a | |||
| 8c62816972 | |||
| c0d40a03aa | |||
| 551831c901 | |||
| 67850fd2a2 | |||
| 715ef21da0 | |||
| b8defa5d45 | |||
| 6d3dac828a | |||
| 968a9a3750 | |||
| 03b5cdb240 | |||
| 7dc0d5d146 | |||
| c20f511418 | |||
| 484b3ff2f3 | |||
| 5d25adfc42 | |||
| 1099fd2525 | |||
| 293989f019 | |||
| 57d1e24275 | |||
| e52b5aef45 | |||
| 28517085ca | |||
| a16d2a1ef9 | |||
| 13c86452e9 | |||
| fe18731057 | |||
| e26529b695 | |||
| bac6219cc1 | |||
| 0ed3bdc747 | |||
| 8af0631ff0 | |||
| 2e3d276304 | |||
| bd5630a104 | |||
| b406219515 | |||
| 31d3a19836 | |||
| 83b372a32d | |||
| 51e0b204b6 | |||
| c9ed79d2c8 | |||
| 043574f558 | |||
| fc5680d95c | |||
| eabb7c98ce | |||
| 6848f9197e | |||
| 6d2c30abca | |||
| 93bde7dc46 | |||
| 97e2e0a405 | |||
| 12206f028b | |||
| 4c7944ac77 | |||
| d4ced7b416 | |||
| 451eef5c99 | |||
| ae8f059de0 | |||
| 878bd7cbc7 | |||
| 6d017c9a6c | |||
| 4c3d9b8c70 | |||
| 23a4260859 | |||
| d15d08a2d5 | |||
| 6aeab16ce4 | |||
| 46538d9a5b | |||
| f0f48395c5 | |||
| b3a1442a69 | |||
| bbafb1dabd | |||
| 645a9159e4 | |||
| 2d3ff2f8ca | |||
| 5919736904 | |||
| 732610e200 | |||
| 309985503d | |||
| 072ed705fc | |||
| 3689b52309 | |||
| 01fbf31405 | |||
| 00f687f3f5 | |||
| 96849fcafe | |||
| 80d5b6e24c | |||
| f33fd98c83 | |||
| c7636734de | |||
| 994e61fe42 | |||
| 359eba462b | |||
| 38e48c0c5e | |||
| 1e187e0945 | |||
| e4fc5df1cf | |||
| cde886b884 | |||
| 9f4e167455 | |||
| f5e6504e22 | |||
| 0ec1066b34 | |||
| 62d4da3b94 | |||
| 253950deb6 | |||
| ed92d6beb9 | |||
| ebb362d9fa | |||
| f23fad420e | |||
| aaf23221ff | |||
| 156c1a99a9 | |||
| cb55ef5c59 | |||
| 6540fbb8e7 | |||
| 412392aea9 | |||
| e6030b7f59 | |||
| c1c968666e | |||
| f8d6363d19 | |||
| acc69e0d2e | |||
| 5110d0bdde | |||
| 597cc0592b | |||
| 01b0a8fa42 | |||
| cf6b7a847b | |||
| 4897080827 | |||
| 3ca8e0fb5c | |||
| 40f4ff04c2 | |||
| 3bd911982f | |||
| 730383ab18 | |||
| b70f10dca6 | |||
| 17009ac59f | |||
| 07fbf2b467 | |||
| 3f0be5e41f | |||
| 2845568f61 | |||
| e3229935f6 | |||
| b1ee115b77 | |||
| d6060f04bc | |||
| 1ae5310d2f | |||
| 417a0817a7 | |||
| 41a82eff21 | |||
| d41acc77f7 | |||
| 271fc6b585 | |||
| 262f4ffa4c | |||
| 338c1c5424 | |||
| 8ca25b1757 | |||
| 68e54248fd | |||
| e792bafe21 | |||
| fe95581acd | |||
| 7f831f8a9c | |||
| 3fb7382cc4 | |||
| 83f70b3c27 | |||
| e6e14ab67f | |||
| 37792e7d86 | |||
| a63ea6adb8 | |||
| 06a8f3d097 | |||
| e76b9bb64a | |||
| 606dbe5db1 | |||
| 81e4e0d301 | |||
| a3e97527d1 | |||
| 7137461891 | |||
| 10e7d279f0 | |||
| 971cb94ce4 | |||
| 19526f1df2 | |||
| 9c73c8671e | |||
| 0f5427f4a0 | |||
| a013793b2f | |||
| 1a77f1b203 | |||
| faf552837a | |||
| 4b2d099258 | |||
| 4e6ea1d2ba | |||
| 197623839d | |||
| 6d8fa76708 | |||
| d7eb49d5d0 | |||
| 659509e085 | |||
| 2b729c2527 | |||
| 38151423b8 | |||
| 2f990b773d | |||
| 20d253dd41 | |||
| 6e2165b5e5 | |||
| 6860904bb9 | |||
| 450dc23374 | |||
| d781f09b46 | |||
| dbde8332f7 | |||
| f5f1785b17 | |||
| 7d01928df0 | |||
| 31f712749b | |||
| bcdf83100f | |||
| dc88ea0ed9 | |||
| 543457a1ef | |||
| 5d781d0114 | |||
| 45b1dabe0a | |||
| ffea373f86 | |||
| ba650de562 | |||
| 39233ff240 | |||
| 8950423418 | |||
| 760a2b9ff7 | |||
| a13f488b84 | |||
| 09b1582704 | |||
| 61ab49a124 | |||
| 1a95b04d79 | |||
| 691a6b0a72 | |||
| 1d0a902251 | |||
| 1de9f5a2fb | |||
| 7a5342cc93 | |||
| 52c73eabeb | |||
| 6eba5eedbe | |||
| 02de1f0a1e | |||
| 3453bdf607 | |||
| 3b55e577c2 | |||
| 8e031a01e6 | |||
| ac2723c3a0 | |||
| 1536c09df3 | |||
| bfe9aac16b | |||
| fade66afd9 | |||
| f63484d0b0 | |||
| 3543e96ec5 | |||
| c83ea0db4f | |||
| ad256367be | |||
| 73b427370b | |||
| ca7234e33f | |||
| cd7b267171 | |||
| 1770a68457 | |||
| 57fd455adf | |||
| 61ecaa4c41 | |||
| 682c4137b4 | |||
| 759c18df3d | |||
| 04fda255de | |||
| 26f23c10b5 | |||
| 001baa07b1 | |||
| 72724037af | |||
| 1bd60c2afb | |||
| c0a1911f22 | |||
| f4920f199c | |||
| 6b8968ed0f | |||
| 85a88d3594 | |||
| b5e17735a6 | |||
| 67beeb6f26 | |||
| f94acc9173 | |||
| a7ac957399 | |||
| b337b075ab | |||
| 3152e97b2f | |||
| 77e8a53572 | |||
| 4eea0cca08 | |||
| 8274a6c3a9 | |||
| f0a5b95ec0 | |||
| e4dd3b2821 | |||
| 7698ee9f3d | |||
| c5127ba522 | |||
| 024d2db2e2 | |||
| f2498df99b | |||
| 37ce645bad | |||
| d4188a093b | |||
| bc3342b4d2 | |||
| 64cf284c07 | |||
| 15b0cc28f8 | |||
| a647ceb753 | |||
| 54840a3f7e | |||
| 2b1ef1bf59 | |||
| 757439a594 | |||
| 73dccb0780 | |||
| aa7aac3a14 | |||
| 2015ccc727 | |||
| 47301830b6 | |||
| b7b280de96 | |||
| 7edc2e8c94 | |||
| 972e25a6a7 | |||
| 649db69314 | |||
| d0fb4cdc37 | |||
| efabcef330 | |||
| a4e6ac0c7f | |||
| 0ce9149ddd | |||
| 2750643e07 | |||
| b92535deea | |||
| 2fa0503993 | |||
| 3932470190 | |||
| d901f4b10b | |||
| 8269384077 | |||
| b364153d02 | |||
| 916d8324cb | |||
| 60309b9e57 | |||
| a05d142af6 | |||
| 1feb11bac0 | |||
| 93936c9946 | |||
| ce78039ea8 | |||
| 1db871e42d | |||
| 1513ba9af9 | |||
| 22b88249ff | |||
| 18f73af6e6 | |||
| b8c835e24e | |||
| 2f392b483c | |||
| 220480327c | |||
| 2c6ff3f018 | |||
| 56a8fb4aae | |||
| 3f782fc482 | |||
| d02e5f2b90 | |||
| 92fd9411e5 | |||
| 650cdf5eb3 | |||
| 060a1543e9 | |||
| 50402c5cdc | |||
| 0835414f24 | |||
| 6449074658 | |||
| b8d558a455 | |||
| 4017b010f4 | |||
| 7e178cb032 | |||
| e17936c407 | |||
| f437d4a55b | |||
| a731b73457 | |||
| b5be462dd1 | |||
| b55e7bcf4e | |||
| d1e71544af | |||
| 6e1367fa94 | |||
| 58452ebc7c | |||
| 7b1dd61ae4 | |||
| 1321991fca | |||
| 8ae8b615b2 | |||
| 1c96dfd58f | |||
| f98efdbe07 | |||
| e67c2eefff | |||
| 2ea19f2ab0 | |||
| 44a6d2ead7 | |||
| 5fa314e4a8 | |||
| 89a8adcbcf | |||
| 57f216e9c7 | |||
| 927a771f2e | |||
| 3a1fffeeb7 | |||
| 9a5622fe33 | |||
| ec51820074 | |||
| 4425e0cd40 | |||
| 97a830b4f0 | |||
| cb28498890 | |||
| 1747114b57 | |||
| 1056b2562e | |||
| 64f680ed86 | |||
| 028c60ce5a | |||
| d27ee227cb | |||
| 81c49136d1 | |||
| 4297207226 | |||
| 3877fb46de | |||
| 22707b8664 | |||
| d2c380c83b | |||
| bc516db3f8 | |||
| 5c0cf8f228 | |||
| b753231d3c | |||
| af728f8224 | |||
| 5000927939 | |||
| 89274bfcdb | |||
| ef86b4113d | |||
| 38ff755533 | |||
| 70ec376657 | |||
| 1a506dc4b4 | |||
| 47451dd989 | |||
| 705849db3d | |||
| 14d3096a22 | |||
| 0340d36af2 | |||
| ad7816d51e | |||
| 73127c8179 | |||
| 72889e2edb | |||
| 0f17b04b2f | |||
| 179a5ba6ed | |||
| ed65b012b8 | |||
| 625629b9db | |||
| 9fa9f0860c | |||
| 5970881bb8 | |||
| bed93429cd | |||
| 3af9089d51 | |||
| 3aed562806 | |||
| 7f32ce498b | |||
| 9e89ba6eed | |||
| 82309c3f47 | |||
| d5613cf471 | |||
| 73f91eab15 | |||
| 35fb598017 | |||
| 40b9a836eb | |||
| 7189c0ff35 | |||
| 0eb206c7b3 | |||
| 728d2c9bcb | |||
| f22feb7dee | |||
| c6bf0e1843 | |||
| 68836cb7be | |||
| 706955e5fc | |||
| 9aec10b0f3 | |||
| b6b817e051 | |||
| 40107b9380 | |||
| 8804850170 | |||
| d246933c28 | |||
| 777ff1938e | |||
| 2846d9478e | |||
| 5d494eac51 | |||
| e26c3cbe5a | |||
| 81a5056e1b | |||
| 1876656afc | |||
| 889ab7ea00 | |||
| 2d4b02f7e5 | |||
| c5a339eaf3 | |||
| 1e50a2da53 | |||
| 7d1c2d3a1b | |||
| a9f9b73a3a | |||
| 236df5be6f | |||
| 6ea83ba0e7 | |||
| 992c2f9e3e | |||
| 5e74700e31 | |||
| 4a225cab23 | |||
| 524ceebcbb | |||
| f93c906614 | |||
| b32ba68a6e | |||
| 649aff8076 | |||
| a3efba019f | |||
| ff4230af8a | |||
| d1014ce3ce | |||
| 3bad6d3341 | |||
| 7526fd0e0d | |||
| a2ec085dab | |||
| cce7702e9c | |||
| 1cf7f4f9d8 | |||
| 1328df772b | |||
| 68dea691c2 | |||
| f214942ff1 | |||
| 91866c1165 | |||
| f73cbed843 | |||
| 5ad817f59e | |||
| 4a8f487b68 | |||
| d1b553cecc | |||
| 1a2f261ee2 | |||
| cfd4926f47 | |||
| 36593ec593 | |||
| dc5f646f24 | |||
| d7e4965cde | |||
| e22bf5c681 | |||
| 007ab1b796 | |||
| c748ac2aa2 | |||
| c091426c44 | |||
| ab28e43050 | |||
| 74a18bdb11 | |||
| 367b9fa7f6 | |||
| 8269333d9c | |||
| d83f222a13 | |||
| 2ba9172526 | |||
| 465af62c16 | |||
| 231a145716 | |||
| 4cabbe4d52 | |||
| 72c87b7cbd | |||
| 3da6006a44 | |||
| 6f48b82297 | |||
| ac51b41fdf | |||
| 4b0b306c44 | |||
| fd0acc074c | |||
| 39c37980d5 | |||
| 6dc2547177 | |||
| d1224367e5 | |||
| c88a92b4f9 | |||
| ffab6c3c50 | |||
| cb7e04bfb0 | |||
| c6a7b84684 | |||
| 97afb4a56a | |||
| 886c15a7fb | |||
| e34e84c5c6 | |||
| 4cac68d774 | |||
| a792744c0d | |||
| 384ed3fafb | |||
| 80ea476497 | |||
| 8ddbf4ba08 | |||
| 041d93a254 | |||
| 167f264bc4 | |||
| 5c036f5fcc | |||
| 964ed8099c | |||
| 71b169616f | |||
| d824755597 | |||
| 8e41699348 | |||
| a580ba1903 | |||
| edcb3696f1 | |||
| f1f07a1764 | |||
| 5139ea4e1c | |||
| fdf9d4da81 | |||
| 65267b2bb7 | |||
| 420bb720c1 | |||
| bfbb6404e6 | |||
| 6ffc88b3b3 | |||
| 54501b5c16 | |||
| d7ef5e8bd2 | |||
| c7e64360cd | |||
| 55b66ca5e6 | |||
| 1fc6cf4c89 | |||
| 918e7c4bf8 | |||
| cfc406709c | |||
| 9f55dac605 | |||
| 00a6575fb4 | |||
| c6eb63ab77 | |||
| db63d433f7 | |||
| 635af046bf | |||
| 86381955a3 | |||
| 3cfa366ec9 | |||
| baa5b1a58e | |||
| 5be0a9c069 | |||
| 8978da7c20 | |||
| b3bbb92358 | |||
| 06ac40fdbb | |||
| d38d8167d8 | |||
| 5684d0de0b | |||
| a2f887aabb | |||
| f72e708627 | |||
| 781d8501cb | |||
| 015f1055a7 | |||
| 2466cf85a1 | |||
| e6ddeef07f | |||
| 614b85e833 |
+15
-8
@@ -2,7 +2,7 @@ version: 2
|
||||
updates:
|
||||
- package-ecosystem: docker
|
||||
cooldown:
|
||||
default-days: 4
|
||||
default-days: 7
|
||||
directories:
|
||||
- "/"
|
||||
- "/docker"
|
||||
@@ -16,7 +16,7 @@ updates:
|
||||
- package-ecosystem: devcontainers
|
||||
directory: "/"
|
||||
cooldown:
|
||||
default-days: 4
|
||||
default-days: 7
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
@@ -24,13 +24,13 @@ updates:
|
||||
- package-ecosystem: pip
|
||||
directory: "/"
|
||||
cooldown:
|
||||
default-days: 4
|
||||
default-days: 7
|
||||
exclude:
|
||||
- ccxt
|
||||
schedule:
|
||||
interval: weekly
|
||||
time: "03:00"
|
||||
timezone: "Etc/UTC"
|
||||
interval: "cron"
|
||||
# Monday at 03:00
|
||||
cronjob: "0 3 * * 1"
|
||||
open-pull-requests-limit: 15
|
||||
target-branch: develop
|
||||
groups:
|
||||
@@ -51,8 +51,15 @@ updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
cooldown:
|
||||
default-days: 4
|
||||
default-days: 7
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
interval: "cron"
|
||||
# Monday at 03:00
|
||||
cronjob: "0 3 * * 1"
|
||||
open-pull-requests-limit: 10
|
||||
target-branch: develop
|
||||
groups:
|
||||
actions:
|
||||
patterns:
|
||||
# Combine updates for github provided actions
|
||||
- "actions/*"
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
environment:
|
||||
name: develop
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
run: python build_helpers/binance_update_lev_tiers.py
|
||||
|
||||
|
||||
- uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
- uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
|
||||
with:
|
||||
token: ${{ secrets.REPO_SCOPED_TOKEN }}
|
||||
add-paths: freqtrade/exchange/binance_leverage_tiers.json
|
||||
|
||||
+45
-36
@@ -25,10 +25,10 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ "ubuntu-22.04", "ubuntu-24.04", "macos-14", "macos-15" , "windows-2022", "windows-2025" ]
|
||||
python-version: ["3.11", "3.12", "3.13"]
|
||||
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d # v7.1.0
|
||||
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
|
||||
with:
|
||||
activate-environment: true
|
||||
enable-cache: true
|
||||
@@ -74,29 +74,31 @@ jobs:
|
||||
run: |
|
||||
pytest --random-order --cov=freqtrade --cov=freqtrade_client --cov-config=.coveragerc
|
||||
|
||||
- name: Coveralls
|
||||
- uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||
if: (runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-24.04')
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Cleanup codecov dirty state files
|
||||
if: (runner.os == 'Linux' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-24.04')
|
||||
env:
|
||||
# Coveralls token. Not used as secret due to github not providing secrets to forked repositories
|
||||
COVERALLS_REPO_TOKEN: 6D1m0xupS3FgutfuGao8keFf9Hc0FpIXu
|
||||
run: |
|
||||
# Allow failure for coveralls
|
||||
uv pip install coveralls
|
||||
coveralls || true
|
||||
# See https://github.com/codecov/codecov-action/issues/1851
|
||||
rm -rf codecov codecov.SHA256SUM codecov.SHA256SUM.sig
|
||||
|
||||
- name: Run json schema extract
|
||||
# This should be kept before the repository check to ensure that the schema is up-to-date
|
||||
# This must be kept before the repository check to ensure that the schema is up-to-date
|
||||
run: |
|
||||
python build_helpers/extract_config_json_schema.py
|
||||
|
||||
- name: Run command docs partials extract
|
||||
# This should be kept before the repository check to ensure that the docs are up-to-date
|
||||
# This must be kept before the repository check to ensure that the docs are up-to-date
|
||||
if: ${{ (matrix.python-version == '3.13') }}
|
||||
run: |
|
||||
python build_helpers/create_command_partials.py
|
||||
|
||||
- name: Check for repository changes - *nix
|
||||
# TODO: python 3.13 slightly changed the output of argparse.
|
||||
if: ${{ (matrix.python-version != '3.13') && (runner.os != 'Windows') }}
|
||||
if: ${{ (runner.os != 'Windows') }}
|
||||
run: |
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
echo "Repository is dirty, changes detected:"
|
||||
@@ -108,7 +110,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Check for repository changes - Windows
|
||||
if: ${{ runner.os == 'Windows' && (matrix.python-version != '3.13') }}
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
run: |
|
||||
if (git status --porcelain) {
|
||||
Write-Host "Repository is dirty, changes detected:"
|
||||
@@ -157,6 +159,7 @@ jobs:
|
||||
shell: powershell
|
||||
run: |
|
||||
$PSVersionTable
|
||||
Get-PSRepository | Format-List *
|
||||
Set-PSRepository psgallery -InstallationPolicy trusted
|
||||
Install-Module -Name Pester -RequiredVersion 5.3.1 -Confirm:$false -Force -SkipPublisherCheck
|
||||
$Error.clear()
|
||||
@@ -175,7 +178,7 @@ jobs:
|
||||
name: "Mypy Version Check"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -193,7 +196,7 @@ jobs:
|
||||
name: "Pre-commit checks"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -206,7 +209,7 @@ jobs:
|
||||
name: "Documentation build"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -238,7 +241,7 @@ jobs:
|
||||
name: "Tests and Linting - Online tests"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -248,7 +251,7 @@ jobs:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d # v7.1.0
|
||||
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
|
||||
with:
|
||||
activate-environment: true
|
||||
enable-cache: true
|
||||
@@ -273,10 +276,7 @@ jobs:
|
||||
# Notify only once - when CI completes (and after deploy) in case it's successful
|
||||
notify-complete:
|
||||
needs: [
|
||||
tests,
|
||||
docs-check,
|
||||
mypy-version-check,
|
||||
pre-commit,
|
||||
build,
|
||||
build-linux-online
|
||||
]
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -304,12 +304,24 @@ jobs:
|
||||
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
build:
|
||||
if: always()
|
||||
name: "Build"
|
||||
needs: [ tests, docs-check, mypy-version-check, pre-commit ]
|
||||
needs: [
|
||||
tests,
|
||||
docs-check,
|
||||
mypy-version-check,
|
||||
pre-commit,
|
||||
]
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
|
||||
with:
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -324,7 +336,7 @@ jobs:
|
||||
python -m build --sdist --wheel
|
||||
|
||||
- name: Upload artifacts 📦
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: freqtrade-build
|
||||
path: |
|
||||
@@ -337,7 +349,7 @@ jobs:
|
||||
python -m build --sdist --wheel ft_client
|
||||
|
||||
- name: Upload artifacts 📦
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: freqtrade-client-build
|
||||
path: |
|
||||
@@ -356,12 +368,12 @@ jobs:
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download artifact 📦
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: freqtrade*-build
|
||||
path: dist
|
||||
@@ -385,12 +397,12 @@ jobs:
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download artifact 📦
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: freqtrade*-build
|
||||
path: dist
|
||||
@@ -403,10 +415,7 @@ jobs:
|
||||
docker-build:
|
||||
name: "Docker Build and Deploy"
|
||||
needs: [
|
||||
tests,
|
||||
docs-check,
|
||||
mypy-version-check,
|
||||
pre-commit
|
||||
build,
|
||||
]
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade'
|
||||
uses: ./.github/workflows/docker-build.yml
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
name: Deploy Docs through mike
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: true
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
packages: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Login to GitHub Container Registry
|
||||
|
||||
@@ -33,10 +33,21 @@ jobs:
|
||||
if: github.repository == 'freqtrade/freqtrade'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Visualize disk usage before build
|
||||
run: df -h
|
||||
|
||||
- name: Cleanup some disk space
|
||||
run: |
|
||||
docker system prune -a --force || true
|
||||
docker builder prune -af || true
|
||||
|
||||
- name: Visualize disk usage after cleanup
|
||||
run: df -h
|
||||
|
||||
- name: Set docker tag names
|
||||
id: tags
|
||||
uses: ./.github/actions/docker-tags
|
||||
@@ -48,13 +59,13 @@ jobs:
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
with:
|
||||
cache-image: false
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f #v3.12.0
|
||||
|
||||
- name: Available platforms
|
||||
run: echo ${PLATFORMS}
|
||||
@@ -142,6 +153,9 @@ jobs:
|
||||
run: |
|
||||
docker images
|
||||
|
||||
- name: Visualize disk usage after build
|
||||
run: df -h
|
||||
|
||||
deploy-arm:
|
||||
name: "Deploy Docker ARM64"
|
||||
permissions:
|
||||
@@ -152,7 +166,7 @@ jobs:
|
||||
if: github.repository == 'freqtrade/freqtrade'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -276,6 +290,7 @@ jobs:
|
||||
docker buildx imagetools create \
|
||||
--tag ${GHCR_IMAGE_NAME}:${TAG} \
|
||||
--tag ${GHCR_IMAGE_NAME}:latest \
|
||||
--tag ${IMAGE_NAME}:latest \
|
||||
${IMAGE_NAME}:${TAG}
|
||||
|
||||
- name: Docker images
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
dockerHubDescription:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
auto-update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Run auto-update
|
||||
run: pre-commit autoupdate
|
||||
|
||||
- uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
- uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
|
||||
with:
|
||||
token: ${{ secrets.REPO_SCOPED_TOKEN }}
|
||||
add-paths: .pre-commit-config.yaml
|
||||
|
||||
@@ -14,6 +14,7 @@ permissions: {}
|
||||
|
||||
jobs:
|
||||
zizmor:
|
||||
name: Run zizmor 🌈
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
@@ -21,9 +22,9 @@ jobs:
|
||||
# actions: read # only needed for private repos
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v6.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run zizmor 🌈
|
||||
uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0
|
||||
uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0
|
||||
|
||||
@@ -21,7 +21,7 @@ repos:
|
||||
# stages: [push]
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: "v1.18.2"
|
||||
rev: "v1.19.1"
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: build_helpers
|
||||
@@ -30,9 +30,9 @@ repos:
|
||||
- types-filelock==3.2.7
|
||||
- types-requests==2.32.4.20250913
|
||||
- types-tabulate==0.9.0.20241207
|
||||
- types-python-dateutil==2.9.0.20251008
|
||||
- scipy-stubs==1.16.2.4
|
||||
- SQLAlchemy==2.0.44
|
||||
- types-python-dateutil==2.9.0.20251115
|
||||
- scipy-stubs==1.16.3.3
|
||||
- SQLAlchemy==2.0.45
|
||||
# stages: [push]
|
||||
|
||||
- repo: https://github.com/pycqa/isort
|
||||
@@ -44,7 +44,7 @@ repos:
|
||||
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: 'v0.14.2'
|
||||
rev: 'v0.14.10'
|
||||
hooks:
|
||||
- id: ruff
|
||||
- id: ruff-format
|
||||
@@ -83,6 +83,6 @@ repos:
|
||||
|
||||
# Ensure github actions remain safe
|
||||
- repo: https://github.com/woodruffw/zizmor-pre-commit
|
||||
rev: v1.16.0
|
||||
rev: v1.19.0
|
||||
hooks:
|
||||
- id: zizmor
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM python:3.13.8-slim-bookworm AS base
|
||||
FROM python:3.13.11-slim-bookworm AS base
|
||||
|
||||
# Setup env
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 
|
||||
|
||||
[](https://github.com/freqtrade/freqtrade/actions/)
|
||||
[](https://github.com/freqtrade/freqtrade/actions/workflows/ci.yml)
|
||||
[](https://doi.org/10.21105/joss.04864)
|
||||
[](https://coveralls.io/github/freqtrade/freqtrade?branch=develop)
|
||||
[](https://www.freqtrade.io)
|
||||
@@ -15,7 +15,7 @@ This software is for educational purposes only. Do not risk money which
|
||||
you are afraid to lose. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS
|
||||
AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
|
||||
|
||||
Always start by running a trading bot in Dry-run and do not engage money
|
||||
Always start by running a trading bot in Dry-Run and do not engage money
|
||||
before you understand how it works and what profit/loss you should
|
||||
expect.
|
||||
|
||||
@@ -24,7 +24,7 @@ hesitate to read the source code and understand the mechanism of this bot.
|
||||
|
||||
## Supported Exchange marketplaces
|
||||
|
||||
Please read the [exchange specific notes](docs/exchanges.md) to learn about eventual, special configurations needed for each exchange.
|
||||
Please read the [exchange-specific notes](docs/exchanges.md) to learn about special configurations that maybe needed for each exchange.
|
||||
|
||||
- [X] [Binance](https://www.binance.com/)
|
||||
- [X] [BingX](https://bingx.com/invite/0EM9RX)
|
||||
|
||||
@@ -1,53 +1,105 @@
|
||||
import os
|
||||
import subprocess # noqa: S404, RUF100
|
||||
import sys
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
subcommands = [
|
||||
"trade",
|
||||
"create-userdir",
|
||||
"new-config",
|
||||
"show-config",
|
||||
"new-strategy",
|
||||
"download-data",
|
||||
"convert-data",
|
||||
"convert-trade-data",
|
||||
"trades-to-ohlcv",
|
||||
"list-data",
|
||||
"backtesting",
|
||||
"backtesting-show",
|
||||
"backtesting-analysis",
|
||||
"edge",
|
||||
"hyperopt",
|
||||
"hyperopt-list",
|
||||
"hyperopt-show",
|
||||
"list-exchanges",
|
||||
"list-markets",
|
||||
"list-pairs",
|
||||
"list-strategies",
|
||||
"list-hyperoptloss",
|
||||
"list-freqaimodels",
|
||||
"list-timeframes",
|
||||
"show-trades",
|
||||
"test-pairlist",
|
||||
"convert-db",
|
||||
"install-ui",
|
||||
"plot-dataframe",
|
||||
"plot-profit",
|
||||
"webserver",
|
||||
"strategy-updater",
|
||||
"lookahead-analysis",
|
||||
"recursive-analysis",
|
||||
]
|
||||
|
||||
result = subprocess.run(["freqtrade", "--help"], capture_output=True, text=True)
|
||||
|
||||
with Path("docs/commands/main.md").open("w") as f:
|
||||
f.write(f"```\n{result.stdout}\n```\n")
|
||||
def _write_partial_file(filename: str, content: str):
|
||||
with Path(filename).open("w") as f:
|
||||
f.write(f"``` output\n{content}\n```\n")
|
||||
|
||||
|
||||
for command in subcommands:
|
||||
print(f"Running for {command}")
|
||||
result = subprocess.run(["freqtrade", command, "--help"], capture_output=True, text=True)
|
||||
def _get_help_output(parser) -> str:
|
||||
"""Capture the help output from a parser."""
|
||||
output = StringIO()
|
||||
parser.print_help(file=output)
|
||||
return output.getvalue()
|
||||
|
||||
with Path(f"docs/commands/{command}.md").open("w") as f:
|
||||
f.write(f"```\n{result.stdout}\n```\n")
|
||||
|
||||
def extract_command_partials():
|
||||
# Set terminal width to 80 columns for consistent output formatting
|
||||
os.environ["COLUMNS"] = "80"
|
||||
|
||||
# Import Arguments here to avoid circular imports and ensure COLUMNS is set
|
||||
from freqtrade.commands.arguments import Arguments
|
||||
|
||||
subcommands = [
|
||||
"trade",
|
||||
"create-userdir",
|
||||
"new-config",
|
||||
"show-config",
|
||||
"new-strategy",
|
||||
"download-data",
|
||||
"convert-data",
|
||||
"convert-trade-data",
|
||||
"trades-to-ohlcv",
|
||||
"list-data",
|
||||
"backtesting",
|
||||
"backtesting-show",
|
||||
"backtesting-analysis",
|
||||
"edge",
|
||||
"hyperopt",
|
||||
"hyperopt-list",
|
||||
"hyperopt-show",
|
||||
"list-exchanges",
|
||||
"list-markets",
|
||||
"list-pairs",
|
||||
"list-strategies",
|
||||
"list-hyperoptloss",
|
||||
"list-freqaimodels",
|
||||
"list-timeframes",
|
||||
"show-trades",
|
||||
"test-pairlist",
|
||||
"convert-db",
|
||||
"install-ui",
|
||||
"plot-dataframe",
|
||||
"plot-profit",
|
||||
"webserver",
|
||||
"strategy-updater",
|
||||
"lookahead-analysis",
|
||||
"recursive-analysis",
|
||||
]
|
||||
|
||||
# Build the Arguments class to get the parser with all subcommands
|
||||
args = Arguments(None)
|
||||
args._build_subcommands()
|
||||
|
||||
# Get main help output
|
||||
main_help = _get_help_output(args.parser)
|
||||
_write_partial_file("docs/commands/main.md", main_help)
|
||||
|
||||
# Get subparsers from the main parser
|
||||
# The subparsers are stored in _subparsers._group_actions[0].choices
|
||||
subparsers_action = None
|
||||
for action in args.parser._subparsers._group_actions:
|
||||
if hasattr(action, "choices"):
|
||||
subparsers_action = action
|
||||
break
|
||||
|
||||
if subparsers_action is None:
|
||||
raise RuntimeError("Could not find subparsers in the main parser")
|
||||
|
||||
for command in subcommands:
|
||||
print(f"Running for {command}")
|
||||
if command in subparsers_action.choices:
|
||||
subparser = subparsers_action.choices[command]
|
||||
help_output = _get_help_output(subparser)
|
||||
_write_partial_file(f"docs/commands/{command}.md", help_output)
|
||||
else:
|
||||
print(f" Warning: subcommand '{command}' not found in parser")
|
||||
|
||||
# freqtrade-client still uses subprocess as requested
|
||||
print("Running for freqtrade-client")
|
||||
result_client = subprocess.run(["freqtrade-client", "--show"], capture_output=True, text=True)
|
||||
|
||||
_write_partial_file("docs/commands/freqtrade-client.md", result_client.stdout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if sys.version_info < (3, 13): # pragma: no cover
|
||||
sys.exit(
|
||||
"argparse output changed in Python 3.13+. "
|
||||
"To keep command partials up to date, please run this script with Python 3.13+."
|
||||
)
|
||||
extract_command_partials()
|
||||
|
||||
BIN
Binary file not shown.
@@ -273,6 +273,68 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"backtest_cache": {
|
||||
"description": "Load a cached backtest result no older than specified age.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"day",
|
||||
"week",
|
||||
"month"
|
||||
]
|
||||
},
|
||||
"hyperopt_path": {
|
||||
"description": "Specify additional lookup path for Hyperopt Loss functions.",
|
||||
"type": "string"
|
||||
},
|
||||
"epochs": {
|
||||
"description": "Number of training epochs for Hyperopt.",
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"early_stop": {
|
||||
"description": "Early stop hyperopt if no improvement after <epochs>. Set to 0 to disable.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"spaces": {
|
||||
"description": "Hyperopt parameter spaces to optimize. Default is the default set andincludes all spaces except for 'trailing', 'protection', and 'trades'.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": [
|
||||
"default"
|
||||
]
|
||||
},
|
||||
"analyze_per_epoch": {
|
||||
"description": "Perform analysis after each epoch in Hyperopt.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"print_all": {
|
||||
"description": "Print all hyperopt trials, not just the best ones.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"hyperopt_jobs": {
|
||||
"description": "The number of concurrently running jobs for hyperoptimization (hyperopt worker processes). If -1 (default), all CPUs are used, for -2, all CPUs but one are used, etc. If 1 is given, no parallel computing is used.",
|
||||
"type": "integer",
|
||||
"default": -1
|
||||
},
|
||||
"hyperopt_random_state": {
|
||||
"description": "Random state for hyperopt trials.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"hyperopt_min_trades": {
|
||||
"description": "Minimum number of trades per epoch for hyperopt.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"hyperopt_loss": {
|
||||
"description": "The class name of the hyperopt loss function class (IHyperOptLoss). Different functions can generate completely different results, since the target for optimization is different. Built-in Hyperopt-loss-functions are: ShortTradeDurHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss, SharpeHyperOptLossDaily, SortinoHyperOptLoss, SortinoHyperOptLossDaily, CalmarHyperOptLoss, MaxDrawDownHyperOptLoss, MaxDrawDownRelativeHyperOptLoss, MaxDrawDownPerPairHyperOptLoss, ProfitDrawDownHyperOptLoss, MultiMetricHyperOptLoss",
|
||||
"type": "string"
|
||||
},
|
||||
"bot_name": {
|
||||
"description": "Name of the trading bot. Passed via API to a client.",
|
||||
"type": "string"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM python:3.11.13-slim-bookworm AS base
|
||||
FROM python:3.11.14-slim-bookworm AS base
|
||||
|
||||
# Setup env
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade backtesting-analysis [-h] [-v] [--no-color] [--logfile FILE]
|
||||
[-V] [-c PATH] [-d PATH]
|
||||
[--userdir PATH]
|
||||
@@ -15,13 +15,13 @@ usage: freqtrade backtesting-analysis [-h] [-v] [--no-color] [--logfile FILE]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--backtest-filename PATH, --export-filename PATH
|
||||
--backtest-filename, --export-filename PATH
|
||||
Use this filename for backtest results.Example:
|
||||
`--backtest-
|
||||
filename=backtest_results_2020-09-27_16-20-48.json`.
|
||||
Assumes either `user_data/backtest_results/` or
|
||||
`--export-directory` as base directory.
|
||||
--backtest-directory PATH, --export-directory PATH
|
||||
--backtest-directory, --export-directory PATH
|
||||
Directory to use for backtest results. Example:
|
||||
`--export-directory=user_data/backtest_results/`.
|
||||
--analysis-groups {0,1,2,3,4,5} [{0,1,2,3,4,5} ...]
|
||||
@@ -54,21 +54,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade backtesting-show [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--backtest-filename PATH]
|
||||
@@ -8,13 +8,13 @@ usage: freqtrade backtesting-show [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--backtest-filename PATH, --export-filename PATH
|
||||
--backtest-filename, --export-filename PATH
|
||||
Use this filename for backtest results.Example:
|
||||
`--backtest-
|
||||
filename=backtest_results_2020-09-27_16-20-48.json`.
|
||||
Assumes either `user_data/backtest_results/` or
|
||||
`--export-directory` as base directory.
|
||||
--backtest-directory PATH, --export-directory PATH
|
||||
--backtest-directory, --export-directory PATH
|
||||
Directory to use for backtest results. Example:
|
||||
`--export-directory=user_data/backtest_results/`.
|
||||
--show-pair-list Show backtesting pairlist sorted by profit.
|
||||
@@ -26,21 +26,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade backtesting [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH] [-s NAME]
|
||||
[--strategy-path PATH]
|
||||
@@ -23,7 +23,7 @@ usage: freqtrade backtesting [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-i TIMEFRAME, --timeframe TIMEFRAME
|
||||
-i, --timeframe TIMEFRAME
|
||||
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
|
||||
--timerange TIMERANGE
|
||||
Specify what timerange of data to use.
|
||||
@@ -38,12 +38,14 @@ options:
|
||||
setting.
|
||||
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
|
||||
entry and exit).
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--eps, --enable-position-stacking
|
||||
Allow buying the same pair multiple times (position
|
||||
stacking).
|
||||
stacking). Only applicable to backtesting and
|
||||
hyperopt. Results archived by this cannot be
|
||||
reproduced in dry/live trading.
|
||||
--enable-protections, --enableprotections
|
||||
Enable protections for backtesting. Will slow
|
||||
backtesting down by a considerable amount, but will
|
||||
@@ -53,7 +55,7 @@ options:
|
||||
pairlist will be generated for each new candle if
|
||||
you're using a pairlist handler that supports this
|
||||
feature, for example, ShuffleFilter.
|
||||
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
|
||||
--dry-run-wallet, --starting-balance DRY_RUN_WALLET
|
||||
Starting balance, used for backtesting / hyperopt and
|
||||
dry-runs.
|
||||
--timeframe-detail TIMEFRAME_DETAIL
|
||||
@@ -68,13 +70,13 @@ options:
|
||||
becomes `backtest-data-SampleStrategy.json`
|
||||
--export {none,trades,signals}
|
||||
Export backtest results (default: trades).
|
||||
--backtest-filename PATH, --export-filename PATH
|
||||
--backtest-filename, --export-filename PATH
|
||||
Use this filename for backtest results.Example:
|
||||
`--backtest-
|
||||
filename=backtest_results_2020-09-27_16-20-48.json`.
|
||||
Assumes either `user_data/backtest_results/` or
|
||||
`--export-directory` as base directory.
|
||||
--backtest-directory PATH, --export-directory PATH
|
||||
--backtest-directory, --export-directory PATH
|
||||
Directory to use for backtest results. Example:
|
||||
`--export-directory=user_data/backtest_results/`.
|
||||
--breakdown {day,week,month,year,weekday} [{day,week,month,year,weekday} ...]
|
||||
@@ -91,26 +93,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade convert-data [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[-p PAIRS [PAIRS ...]] --format-from
|
||||
{json,jsongz,feather,parquet} --format-to
|
||||
{json,jsongz,feather,parquet} [--erase]
|
||||
[--exchange EXCHANGE]
|
||||
[-p PAIRS [PAIRS ...]]
|
||||
--format-from {json,jsongz,feather,parquet}
|
||||
--format-to {json,jsongz,feather,parquet}
|
||||
[--erase] [--exchange EXCHANGE]
|
||||
[-t TIMEFRAMES [TIMEFRAMES ...]]
|
||||
[--trading-mode {spot,margin,futures}]
|
||||
[--candle-types {spot,futures,mark,index,premiumIndex,funding_rate} [{spot,futures,mark,index,premiumIndex,funding_rate} ...]]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--format-from {json,jsongz,feather,parquet}
|
||||
@@ -21,10 +21,10 @@ options:
|
||||
--erase Clean all existing data for the selected
|
||||
exchange/pairs/timeframes.
|
||||
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
|
||||
-t TIMEFRAMES [TIMEFRAMES ...], --timeframes TIMEFRAMES [TIMEFRAMES ...]
|
||||
-t, --timeframes TIMEFRAMES [TIMEFRAMES ...]
|
||||
Specify which tickers to download. Space-separated
|
||||
list. Default: `1m 5m`.
|
||||
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
--candle-types {spot,futures,mark,index,premiumIndex,funding_rate} [{spot,futures,mark,index,premiumIndex,funding_rate} ...]
|
||||
Select candle type to convert. Defaults to all
|
||||
@@ -34,21 +34,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade convert-db [-h] [--db-url PATH] [--db-url-from PATH]
|
||||
|
||||
options:
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade convert-trade-data [-h] [-v] [--no-color] [--logfile FILE]
|
||||
[-V] [-c PATH] [-d PATH] [--userdir PATH]
|
||||
[-p PAIRS [PAIRS ...]] --format-from
|
||||
{json,jsongz,feather,parquet,kraken_csv}
|
||||
[-p PAIRS [PAIRS ...]]
|
||||
--format-from {json,jsongz,feather,parquet,kraken_csv}
|
||||
--format-to {json,jsongz,feather,parquet}
|
||||
[--erase] [--exchange EXCHANGE]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--format-from {json,jsongz,feather,parquet,kraken_csv}
|
||||
@@ -23,21 +23,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade create-userdir [-h] [--userdir PATH] [--reset]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
--reset Reset sample files to their original state.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade download-data [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[-p PAIRS [PAIRS ...]] [--pairs-file FILE]
|
||||
@@ -11,11 +11,12 @@ usage: freqtrade download-data [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[--data-format-ohlcv {json,jsongz,feather,parquet}]
|
||||
[--data-format-trades {json,jsongz,feather,parquet}]
|
||||
[--trading-mode {spot,margin,futures}]
|
||||
[--candle-types {spot,futures,mark,index,premiumIndex,funding_rate} [{spot,futures,mark,index,premiumIndex,funding_rate} ...]]
|
||||
[--prepend]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--pairs-file FILE File containing a list of pairs. Takes precedence over
|
||||
@@ -37,7 +38,7 @@ options:
|
||||
OHLCV (e.g. Kraken). If not provided, use `trades-to-
|
||||
ohlcv` to convert trades data to OHLCV data.
|
||||
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
|
||||
-t TIMEFRAMES [TIMEFRAMES ...], --timeframes TIMEFRAMES [TIMEFRAMES ...]
|
||||
-t, --timeframes TIMEFRAMES [TIMEFRAMES ...]
|
||||
Specify which tickers to download. Space-separated
|
||||
list. Default: `1m 5m`.
|
||||
--erase Clean all existing data for the selected
|
||||
@@ -48,29 +49,33 @@ options:
|
||||
--data-format-trades {json,jsongz,feather,parquet}
|
||||
Storage format for downloaded trades data. (default:
|
||||
`feather`).
|
||||
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
--candle-types {spot,futures,mark,index,premiumIndex,funding_rate} [{spot,futures,mark,index,premiumIndex,funding_rate} ...]
|
||||
Select candle type to download. Defaults to the
|
||||
necessary candles for the selected trading mode (e.g.
|
||||
'spot' or ('futures', 'funding_rate' and 'mark') for
|
||||
futures).
|
||||
--prepend Allow data prepending. (Data-appending is disabled)
|
||||
|
||||
Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
+8
-10
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade edge [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH]
|
||||
[-d PATH] [--userdir PATH] [-s NAME]
|
||||
[--strategy-path PATH] [--recursive-strategy-search]
|
||||
@@ -10,7 +10,7 @@ usage: freqtrade edge [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-i TIMEFRAME, --timeframe TIMEFRAME
|
||||
-i, --timeframe TIMEFRAME
|
||||
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
|
||||
--timerange TIMERANGE
|
||||
Specify what timerange of data to use.
|
||||
@@ -25,7 +25,7 @@ options:
|
||||
setting.
|
||||
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
|
||||
entry and exit).
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
|
||||
@@ -33,26 +33,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
``` output
|
||||
Possible commands:
|
||||
|
||||
available_pairs
|
||||
Return available pair (backtest data) based on timeframe / stake_currency selection
|
||||
|
||||
:param timeframe: Only pairs with this timeframe available.
|
||||
:param stake_currency: Only pairs that include this stake currency.
|
||||
|
||||
balance
|
||||
Get the account balance.
|
||||
|
||||
blacklist
|
||||
Show the current blacklist.
|
||||
|
||||
: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
|
||||
Return the amount of open trades.
|
||||
|
||||
daily
|
||||
Return the profits for each day, and amount of trades.
|
||||
|
||||
delete_lock
|
||||
Delete (disable) lock from the database.
|
||||
|
||||
:param lock_id: ID for the lock to delete
|
||||
|
||||
delete_trade
|
||||
Delete trade from the database.
|
||||
Tries to close open orders. Requires manual handling of this asset on the exchange.
|
||||
|
||||
:param trade_id: Deletes the trade with this ID from the database.
|
||||
|
||||
entries
|
||||
Returns List of dicts containing all Trades, based on buy tag performance
|
||||
Can either be average for all pairs or a specific pair provided
|
||||
|
||||
exits
|
||||
Returns List of dicts containing all Trades, based on exit reason performance
|
||||
Can either be average for all pairs or a specific pair provided
|
||||
|
||||
forcebuy
|
||||
Buy an asset.
|
||||
|
||||
:param pair: Pair to buy (ETH/BTC)
|
||||
:param price: Optional - price to buy
|
||||
|
||||
forceenter
|
||||
Force entering a trade
|
||||
|
||||
:param pair: Pair to buy (ETH/BTC)
|
||||
:param side: 'long' or 'short'
|
||||
:param price: Optional - price to buy
|
||||
:param order_type: Optional keyword argument - 'limit' or 'market'
|
||||
:param stake_amount: Optional keyword argument - stake amount (as float)
|
||||
:param leverage: Optional keyword argument - leverage (as float)
|
||||
:param enter_tag: Optional keyword argument - entry tag (as string, default: 'force_enter')
|
||||
|
||||
forceexit
|
||||
Force-exit a trade.
|
||||
|
||||
:param tradeid: Id of the trade (can be received via status command)
|
||||
:param ordertype: Order type to use (must be market or limit)
|
||||
:param amount: Amount to sell. Full sell if not given
|
||||
|
||||
health
|
||||
Provides a quick health check of the running bot.
|
||||
|
||||
list_custom_data
|
||||
List custom-data of the running bot for a specific trade.
|
||||
|
||||
:param trade_id: ID of the trade
|
||||
:param key: str, optional - Key of the custom-data
|
||||
|
||||
list_open_trades_custom_data
|
||||
List open trades custom-data of the running bot.
|
||||
|
||||
:param key: str, optional - Key of the custom-data
|
||||
:param limit: limit of trades
|
||||
:param offset: trades offset for pagination
|
||||
|
||||
lock_add
|
||||
Lock pair
|
||||
|
||||
:param pair: Pair to lock
|
||||
:param until: Lock until this date (format "2024-03-30 16:00:00Z")
|
||||
:param side: Side to lock (long, short, *)
|
||||
:param reason: Reason for the lock
|
||||
|
||||
locks
|
||||
Return current locks
|
||||
|
||||
logs
|
||||
Show latest logs.
|
||||
|
||||
:param limit: Limits log messages to the last <limit> logs. No limit to get the entire log.
|
||||
|
||||
mix_tags
|
||||
Returns List of dicts containing all Trades, based on entry_tag + exit_reason performance
|
||||
Can either be average for all pairs or a specific pair provided
|
||||
|
||||
monthly
|
||||
Return the profits for each month, and amount of trades.
|
||||
|
||||
pair_candles
|
||||
Return live dataframe for <pair><timeframe>.
|
||||
|
||||
:param pair: Pair to get data for
|
||||
:param timeframe: Only pairs with this timeframe available.
|
||||
:param limit: Limit result to the last n candles.
|
||||
:param columns: List of dataframe columns to return. Empty list will return OHLCV.
|
||||
|
||||
pair_history
|
||||
Return historic, analyzed dataframe
|
||||
|
||||
:param pair: Pair to get data for
|
||||
:param timeframe: Only pairs with this timeframe available.
|
||||
:param strategy: Strategy to analyze and get values for
|
||||
:param freqaimodel: FreqAI model to use for analysis
|
||||
:param timerange: Timerange to get data for (same format than --timerange endpoints)
|
||||
|
||||
pairlists_available
|
||||
Lists available pairlist providers
|
||||
|
||||
performance
|
||||
Return the performance of the different coins.
|
||||
|
||||
ping
|
||||
simple ping
|
||||
|
||||
plot_config
|
||||
Return plot configuration if the strategy defines one.
|
||||
|
||||
profit
|
||||
Return the profit summary.
|
||||
|
||||
reload_config
|
||||
Reload configuration.
|
||||
|
||||
show_config
|
||||
Returns part of the configuration, relevant for trading operations.
|
||||
|
||||
start
|
||||
Start the bot if it's in the stopped state.
|
||||
|
||||
stats
|
||||
Return the stats report (durations, sell-reasons).
|
||||
|
||||
status
|
||||
Get the status of open trades.
|
||||
|
||||
stop
|
||||
Stop the bot. Use `start` to restart.
|
||||
|
||||
stopbuy
|
||||
Stop buying (but handle sells gracefully). Use `reload_config` to reset.
|
||||
|
||||
strategies
|
||||
Lists available strategies
|
||||
|
||||
strategy
|
||||
Get strategy details
|
||||
|
||||
:param strategy: Strategy class name
|
||||
|
||||
sysinfo
|
||||
Provides system information (CPU, RAM usage)
|
||||
|
||||
trade
|
||||
Return specific trade
|
||||
|
||||
:param trade_id: Specify which trade to get.
|
||||
|
||||
trades
|
||||
Return trades history, sorted by id (or by latest timestamp if order_by_id=False)
|
||||
|
||||
:param limit: Limits trades to the X last trades. Max 500 trades.
|
||||
:param offset: Offset by this amount of trades.
|
||||
:param order_by_id: Sort trades by id (default: True). If False, sorts by latest timestamp.
|
||||
|
||||
version
|
||||
Return the version of the bot.
|
||||
|
||||
weekly
|
||||
Return the profits for each week, and amount of trades.
|
||||
|
||||
whitelist
|
||||
Show the current whitelist.
|
||||
|
||||
|
||||
```
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade hyperopt-list [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH] [--best]
|
||||
[--profitable] [--min-trades INT]
|
||||
@@ -44,21 +44,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade hyperopt-show [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH] [--best]
|
||||
[--profitable] [-n INT] [--print-json]
|
||||
@@ -10,7 +10,7 @@ options:
|
||||
-h, --help show this help message and exit
|
||||
--best Select only best epochs.
|
||||
--profitable Select only profitable epochs.
|
||||
-n INT, --index INT Specify the index of the epoch to print details for.
|
||||
-n, --index INT Specify the index of the epoch to print details for.
|
||||
--print-json Print output in JSON format.
|
||||
--hyperopt-filename FILENAME
|
||||
Hyperopt result filename.Example: `--hyperopt-
|
||||
@@ -26,21 +26,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
+26
-23
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade hyperopt [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH] [-s NAME]
|
||||
[--strategy-path PATH] [--recursive-strategy-search]
|
||||
@@ -11,16 +11,15 @@ usage: freqtrade hyperopt [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[--eps] [--enable-protections]
|
||||
[--dry-run-wallet DRY_RUN_WALLET]
|
||||
[--timeframe-detail TIMEFRAME_DETAIL] [-e INT]
|
||||
[--spaces {all,buy,sell,roi,stoploss,trailing,protection,trades,default} [{all,buy,sell,roi,stoploss,trailing,protection,trades,default} ...]]
|
||||
[--print-all] [--print-json] [-j JOBS]
|
||||
[--random-state INT] [--min-trades INT]
|
||||
[--hyperopt-loss NAME] [--disable-param-export]
|
||||
[--ignore-missing-spaces] [--analyze-per-epoch]
|
||||
[--early-stop INT]
|
||||
[--spaces SPACES [SPACES ...]] [--print-all]
|
||||
[--print-json] [-j JOBS] [--random-state INT]
|
||||
[--min-trades INT] [--hyperopt-loss NAME]
|
||||
[--disable-param-export] [--ignore-missing-spaces]
|
||||
[--analyze-per-epoch] [--early-stop INT]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-i TIMEFRAME, --timeframe TIMEFRAME
|
||||
-i, --timeframe TIMEFRAME
|
||||
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
|
||||
--timerange TIMERANGE
|
||||
Specify what timerange of data to use.
|
||||
@@ -35,31 +34,37 @@ options:
|
||||
setting.
|
||||
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
|
||||
entry and exit).
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--hyperopt-path PATH Specify additional lookup path for Hyperopt Loss
|
||||
functions.
|
||||
--eps, --enable-position-stacking
|
||||
Allow buying the same pair multiple times (position
|
||||
stacking).
|
||||
stacking). Only applicable to backtesting and
|
||||
hyperopt. Results archived by this cannot be
|
||||
reproduced in dry/live trading.
|
||||
--enable-protections, --enableprotections
|
||||
Enable protections for backtesting. Will slow
|
||||
backtesting down by a considerable amount, but will
|
||||
include configured protections
|
||||
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
|
||||
--dry-run-wallet, --starting-balance DRY_RUN_WALLET
|
||||
Starting balance, used for backtesting / hyperopt and
|
||||
dry-runs.
|
||||
--timeframe-detail TIMEFRAME_DETAIL
|
||||
Specify detail timeframe for backtesting (`1m`, `5m`,
|
||||
`30m`, `1h`, `1d`).
|
||||
-e INT, --epochs INT Specify number of epochs (default: 100).
|
||||
--spaces {all,buy,sell,roi,stoploss,trailing,protection,trades,default} [{all,buy,sell,roi,stoploss,trailing,protection,trades,default} ...]
|
||||
-e, --epochs INT Specify number of epochs (default: 100).
|
||||
--spaces SPACES [SPACES ...]
|
||||
Specify which parameters to hyperopt. Space-separated
|
||||
list.
|
||||
list. Available builtin options (custom spaces will
|
||||
not be listed here): default, all, buy, sell, enter,
|
||||
exit, roi, stoploss, trailing, protection, trades.
|
||||
Default: `default` - which includes all spaces except
|
||||
for 'trailing', 'protection', and 'trades'.
|
||||
--print-all Print all results, not only the best ones.
|
||||
--print-json Print output in JSON format.
|
||||
-j JOBS, --job-workers JOBS
|
||||
-j, --job-workers JOBS
|
||||
The number of concurrently running jobs for
|
||||
hyperoptimization (hyperopt worker processes). If -1
|
||||
(default), all CPUs are used, for -2, all CPUs but one
|
||||
@@ -69,7 +74,7 @@ options:
|
||||
reproducible hyperopt results.
|
||||
--min-trades INT Set minimal desired number of trades for evaluations
|
||||
in the hyperopt optimization path (default: 1).
|
||||
--hyperopt-loss NAME, --hyperoptloss NAME
|
||||
--hyperopt-loss, --hyperoptloss NAME
|
||||
Specify the class name of the hyperopt loss function
|
||||
class (IHyperOptLoss). Different functions can
|
||||
generate completely different results, since the
|
||||
@@ -95,26 +100,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade install-ui [-h] [--erase] [--prerelease]
|
||||
[--ui-version UI_VERSION]
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-data [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--exchange EXCHANGE]
|
||||
@@ -18,10 +18,10 @@ options:
|
||||
Storage format for downloaded trades data. (default:
|
||||
`feather`).
|
||||
--trades Work on trades data instead of OHLCV data.
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
--show-timerange Show timerange available for available data. (May take
|
||||
a while to calculate).
|
||||
@@ -30,21 +30,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-exchanges [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH] [-1] [-a]
|
||||
[--trading-mode {spot,margin,futures}]
|
||||
@@ -8,7 +8,7 @@ options:
|
||||
-h, --help show this help message and exit
|
||||
-1, --one-column Print output in one column.
|
||||
-a, --all Print all exchanges known to the ccxt library.
|
||||
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
--dex-exchanges Print only DEX exchanges.
|
||||
|
||||
@@ -16,21 +16,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-freqaimodels [-h] [-v] [--no-color] [--logfile FILE]
|
||||
[-V] [-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--freqaimodel-path PATH] [-1]
|
||||
@@ -13,21 +13,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-hyperoptloss [-h] [-v] [--no-color] [--logfile FILE]
|
||||
[-V] [-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--hyperopt-path PATH] [-1]
|
||||
@@ -13,21 +13,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-markets [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--exchange EXCHANGE] [--print-list]
|
||||
@@ -21,28 +21,27 @@ options:
|
||||
Specify quote currency(-ies). Space-separated list.
|
||||
-a, --all Print all pairs or market symbols. By default only
|
||||
active ones are shown.
|
||||
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
|
||||
Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-pairs [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--exchange EXCHANGE] [--print-list]
|
||||
@@ -21,28 +21,27 @@ options:
|
||||
Specify quote currency(-ies). Space-separated list.
|
||||
-a, --all Print all pairs or market symbols. By default only
|
||||
active ones are shown.
|
||||
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
|
||||
Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-strategies [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--strategy-path PATH] [-1]
|
||||
@@ -16,21 +16,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade list-timeframes [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--exchange EXCHANGE] [-1]
|
||||
[--trading-mode {spot,margin,futures}]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
|
||||
-1, --one-column Print output in one column.
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
|
||||
Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE]
|
||||
[-V] [-c PATH] [-d PATH] [--userdir PATH]
|
||||
[-s NAME] [--strategy-path PATH]
|
||||
@@ -26,7 +26,7 @@ usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-i TIMEFRAME, --timeframe TIMEFRAME
|
||||
-i, --timeframe TIMEFRAME
|
||||
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
|
||||
--timerange TIMERANGE
|
||||
Specify what timerange of data to use.
|
||||
@@ -41,7 +41,7 @@ options:
|
||||
setting.
|
||||
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
|
||||
entry and exit).
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--enable-protections, --enableprotections
|
||||
@@ -53,7 +53,7 @@ options:
|
||||
pairlist will be generated for each new candle if
|
||||
you're using a pairlist handler that supports this
|
||||
feature, for example, ShuffleFilter.
|
||||
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
|
||||
--dry-run-wallet, --starting-balance DRY_RUN_WALLET
|
||||
Starting balance, used for backtesting / hyperopt and
|
||||
dry-runs.
|
||||
--timeframe-detail TIMEFRAME_DETAIL
|
||||
@@ -68,13 +68,13 @@ options:
|
||||
becomes `backtest-data-SampleStrategy.json`
|
||||
--export {none,trades,signals}
|
||||
Export backtest results (default: trades).
|
||||
--backtest-filename PATH, --export-filename PATH
|
||||
--backtest-filename, --export-filename PATH
|
||||
Use this filename for backtest results.Example:
|
||||
`--backtest-
|
||||
filename=backtest_results_2020-09-27_16-20-48.json`.
|
||||
Assumes either `user_data/backtest_results/` or
|
||||
`--export-directory` as base directory.
|
||||
--backtest-directory PATH, --export-directory PATH
|
||||
--backtest-directory, --export-directory PATH
|
||||
Directory to use for backtest results. Example:
|
||||
`--export-directory=user_data/backtest_results/`.
|
||||
--freqai-backtest-live-models
|
||||
@@ -93,26 +93,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade [-h] [-V]
|
||||
{trade,create-userdir,new-config,show-config,new-strategy,download-data,convert-data,convert-trade-data,trades-to-ohlcv,list-data,backtesting,backtesting-show,backtesting-analysis,edge,hyperopt,hyperopt-list,hyperopt-show,list-exchanges,list-markets,list-pairs,list-strategies,list-hyperoptloss,list-freqaimodels,list-timeframes,show-trades,test-pairlist,convert-db,install-ui,plot-dataframe,plot-profit,webserver,strategy-updater,lookahead-analysis,recursive-analysis}
|
||||
...
|
||||
{trade,create-userdir,new-config,show-config,new-strategy,download-data,convert-data,convert-trade-data,trades-to-ohlcv,list-data,backtesting,backtesting-show,backtesting-analysis,edge,hyperopt,hyperopt-list,hyperopt-show,list-exchanges,list-markets,list-pairs,list-strategies,list-hyperoptloss,list-freqaimodels,list-timeframes,show-trades,test-pairlist,convert-db,install-ui,plot-dataframe,plot-profit,webserver,strategy-updater,lookahead-analysis,recursive-analysis} ...
|
||||
|
||||
Free, open source crypto trading bot
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade new-config [-h] [-c PATH]
|
||||
|
||||
options:
|
||||
-h, --help show this help message 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.
|
||||
-h, --help show this help message and exit
|
||||
-c, --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.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade new-strategy [-h] [--userdir PATH] [-s NAME]
|
||||
[--strategy-path PATH]
|
||||
[--template {full,minimal,advanced}]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--template {full,minimal,advanced}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade plot-dataframe [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH] [-s NAME]
|
||||
[--strategy-path PATH]
|
||||
@@ -16,7 +16,7 @@ usage: freqtrade plot-dataframe [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--indicators1 INDICATORS1 [INDICATORS1 ...]
|
||||
@@ -38,7 +38,7 @@ options:
|
||||
(backtest file)) Default: file
|
||||
--export {none,trades,signals}
|
||||
Export backtest results (default: trades).
|
||||
--backtest-filename PATH, --export-filename PATH
|
||||
--backtest-filename, --export-filename PATH
|
||||
Use this filename for backtest results.Example:
|
||||
`--backtest-
|
||||
filename=backtest_results_2020-09-27_16-20-48.json`.
|
||||
@@ -46,7 +46,7 @@ options:
|
||||
`--export-directory` as base directory.
|
||||
--timerange TIMERANGE
|
||||
Specify what timerange of data to use.
|
||||
-i TIMEFRAME, --timeframe TIMEFRAME
|
||||
-i, --timeframe TIMEFRAME
|
||||
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
|
||||
--no-trades Skip using trades from backtesting file and DB.
|
||||
|
||||
@@ -54,26 +54,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade plot-profit [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH] [-s NAME]
|
||||
[--strategy-path PATH]
|
||||
@@ -12,14 +12,14 @@ usage: freqtrade plot-profit [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--timerange TIMERANGE
|
||||
Specify what timerange of data to use.
|
||||
--export {none,trades,signals}
|
||||
Export backtest results (default: trades).
|
||||
--backtest-filename PATH, --export-filename PATH
|
||||
--backtest-filename, --export-filename PATH
|
||||
Use this filename for backtest results.Example:
|
||||
`--backtest-
|
||||
filename=backtest_results_2020-09-27_16-20-48.json`.
|
||||
@@ -32,7 +32,7 @@ options:
|
||||
--trade-source {DB,file}
|
||||
Specify the source for trades (Can be DB or file
|
||||
(backtest file)) Default: file
|
||||
-i TIMEFRAME, --timeframe TIMEFRAME
|
||||
-i, --timeframe TIMEFRAME
|
||||
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
|
||||
--auto-open Automatically open generated plot.
|
||||
|
||||
@@ -40,26 +40,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade recursive-analysis [-h] [-v] [--no-color] [--logfile FILE]
|
||||
[-V] [-c PATH] [-d PATH] [--userdir PATH]
|
||||
[-s NAME] [--strategy-path PATH]
|
||||
@@ -12,14 +12,14 @@ usage: freqtrade recursive-analysis [-h] [-v] [--no-color] [--logfile FILE]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-i TIMEFRAME, --timeframe TIMEFRAME
|
||||
-i, --timeframe TIMEFRAME
|
||||
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
|
||||
--timerange TIMERANGE
|
||||
Specify what timerange of data to use.
|
||||
--data-format-ohlcv {json,jsongz,feather,parquet}
|
||||
Storage format for downloaded candle (OHLCV) data.
|
||||
(default: `feather`).
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
--startup-candle STARTUP_CANDLE [STARTUP_CANDLE ...]
|
||||
@@ -30,26 +30,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade show-config [-h] [--userdir PATH] [-c PATH]
|
||||
[--show-sensitive]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
-c PATH, --config PATH
|
||||
Specify configuration file (default:
|
||||
-c, --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.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade show-trades [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--db-url PATH]
|
||||
@@ -19,21 +19,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade strategy-updater [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
|
||||
@@ -23,21 +23,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade test-pairlist [-h] [--userdir PATH] [-v] [-c PATH]
|
||||
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
|
||||
[-1] [--print-json] [--exchange EXCHANGE]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
-c PATH, --config PATH
|
||||
Specify configuration file (default:
|
||||
-c, --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.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade trade [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH]
|
||||
[-d PATH] [--userdir PATH] [-s NAME]
|
||||
[--strategy-path PATH] [--recursive-strategy-search]
|
||||
@@ -15,7 +15,7 @@ options:
|
||||
--sd-notify Notify systemd service manager.
|
||||
--dry-run Enforce dry-run for trading (removes Exchange secrets
|
||||
and simulates trades).
|
||||
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
|
||||
--dry-run-wallet, --starting-balance DRY_RUN_WALLET
|
||||
Starting balance, used for backtesting / hyperopt and
|
||||
dry-runs.
|
||||
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
|
||||
@@ -25,26 +25,24 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
Strategy arguments:
|
||||
-s NAME, --strategy NAME
|
||||
Specify strategy class name which will be used by the
|
||||
-s, --strategy NAME Specify strategy class name which will be used by the
|
||||
bot.
|
||||
--strategy-path PATH Specify additional strategy lookup path.
|
||||
--recursive-strategy-search
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade trades-to-ohlcv [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
[-p PAIRS [PAIRS ...]]
|
||||
@@ -10,10 +10,10 @@ usage: freqtrade trades-to-ohlcv [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
|
||||
-p, --pairs PAIRS [PAIRS ...]
|
||||
Limit command to these pairs. Pairs are space-
|
||||
separated.
|
||||
-t TIMEFRAMES [TIMEFRAMES ...], --timeframes TIMEFRAMES [TIMEFRAMES ...]
|
||||
-t, --timeframes TIMEFRAMES [TIMEFRAMES ...]
|
||||
Specify which tickers to download. Space-separated
|
||||
list. Default: `1m 5m`.
|
||||
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
|
||||
@@ -23,28 +23,27 @@ options:
|
||||
--data-format-trades {json,jsongz,feather,parquet}
|
||||
Storage format for downloaded trades data. (default:
|
||||
`feather`).
|
||||
--trading-mode {spot,margin,futures}, --tradingmode {spot,margin,futures}
|
||||
--trading-mode, --tradingmode {spot,margin,futures}
|
||||
Select Trading mode
|
||||
|
||||
Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
```
|
||||
``` output
|
||||
usage: freqtrade webserver [-h] [-v] [--no-color] [--logfile FILE] [-V]
|
||||
[-c PATH] [-d PATH] [--userdir PATH]
|
||||
|
||||
@@ -9,21 +9,20 @@ Common arguments:
|
||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||
--no-color Disable colorization of hyperopt results. May be
|
||||
useful if you are redirecting output to a file.
|
||||
--logfile FILE, --log-file FILE
|
||||
--logfile, --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:
|
||||
-c, --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
|
||||
-d, --datadir, --data-dir PATH
|
||||
Path to the base directory of the exchange with
|
||||
historical backtesting data. To see futures data, use
|
||||
trading-mode additionally.
|
||||
--userdir PATH, --user-data-dir PATH
|
||||
--userdir, --user-data-dir PATH
|
||||
Path to userdata directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -675,7 +675,7 @@ Should you experience problems you suspect are caused by websockets, you can dis
|
||||
Should you be required to use a proxy, please refer to the [proxy section](#using-a-proxy-with-freqtrade) for more information.
|
||||
|
||||
!!! Info "Rollout"
|
||||
We're implementing this out slowly, ensuring stability of your bots.
|
||||
We're rolling this out slowly, ensuring stability of your bots.
|
||||
Currently, usage is limited to ohlcv data streams.
|
||||
It's also limited to a few exchanges, with new exchanges being added on an ongoing basis.
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ freqtrade download-data --exchange binance --pairs ".*/USDT"
|
||||
* Given starting points are ignored if data is already available, downloading only missing data up to today.
|
||||
* Use `--timeframes` to specify what timeframe download the historical candle (OHLCV) data for. Default is `--timeframes 1m 5m` which will download 1-minute and 5-minute data.
|
||||
* To use exchange, timeframe and list of pairs as defined in your configuration file, use the `-c/--config` option. With this, the script uses the whitelist defined in the config as the list of currency pairs to download data for and does not require the pairs.json file. You can combine `-c/--config` with most other options.
|
||||
* When downloading futures data (`--trading-mode futures` or a configuration specifying futures mode), freqtrade will automatically download the necessary candle types (e.g. `mark` and `funding_rate` candles) unless specified otherwise via `--candle-types`.
|
||||
|
||||
??? Note "Permission denied errors"
|
||||
If your configuration directory `user_data` was made by docker, you may get the following error:
|
||||
|
||||
@@ -98,3 +98,50 @@ Please use configuration based [log setup](advanced-setup.md#advanced-logging) i
|
||||
|
||||
The edge module has been deprecated in 2023.9 and removed in 2025.6.
|
||||
All functionalities of edge have been removed, and having edge configured will result in an error.
|
||||
|
||||
## Adjustment to dynamic funding rate handling
|
||||
|
||||
With version 2025.12, the handling of dynamic funding rates has been adjusted to also support dynamic funding rates down to 1h funding intervals.
|
||||
As a consequence, the mark and funding rate timeframes have been changed to 1h for every supported futures exchange.
|
||||
|
||||
As the timeframe for both mark and funding_fee candles has changed (usually from 8h to 1h) - already downloaded data will have to be adjusted or partially re-downloaded.
|
||||
You can either re-download everything (`freqtrade download-data [...] --erase` - :warning: can take a long time) - or download the updated data selectively.
|
||||
|
||||
### Strategy
|
||||
|
||||
Most strategies should not need adjustments to continue to work as expected - however, strategies using `@informative("8h", candle_type="funding_rate")` or similar will have to switch the timeframe to 1h.
|
||||
The same is true for `dp.get_pair_dataframe(metadata["pair"], "8h", candle_type="funding_rate")` - which will need to be switched to 1h.
|
||||
|
||||
freqtrade will auto-adjust the timeframe and return `funding_rates` despite the wrongly given timeframe. It'll issue a warning - and may still break your strategy.
|
||||
|
||||
### Selective data re-download
|
||||
|
||||
The script below should serve as an example - you may need to adjust the timeframe and exchange to your needs!
|
||||
|
||||
``` bash
|
||||
# Cleanup no longer needed data
|
||||
rm user_data/data/<exchange>/futures/*-mark-*
|
||||
rm user_data/data/<exchange>/futures/*-funding_rate-*
|
||||
|
||||
# download new data (only required once to fix the mark and funding fee data)
|
||||
freqtrade download-data -t 1h --trading-mode futures --candle-types funding_rate mark [...] --timerange <full timerange you've got other data for>
|
||||
|
||||
```
|
||||
|
||||
The result of the above will be that your funding_rates and mark data will have the 1h timeframe.
|
||||
you can verify this with `freqtrade list-data --exchange <yourexchange> --show`.
|
||||
|
||||
!!! Note "Additional arguments"
|
||||
Additional arguments to the above commands may be necessary, like configuration files or explicit user_data if they deviate from the default.
|
||||
|
||||
**Hyperliquid** is a special case now - which will no longer require 1h mark data - but will use regular candles instead (this data never existed and is identical to 1h futures candles). As we don't support download-data for hyperliquid (they don't provide historic data) - there won't be actions necessary for hyperliquid users.
|
||||
|
||||
## Catboost models in freqAI
|
||||
|
||||
CatBoost models have been removed with version 2025.12 and are no longer actively supported.
|
||||
If you have existing bots using CatBoost models, you can still use them in your custom models by copy/pasting them from the git history (as linked below) and installing the Catboost library manually.
|
||||
We do however recommend switching to other supported model libraries like LightGBM or XGBoost for better support and future compatibility.
|
||||
|
||||
* [CatboostRegressor](https://github.com/freqtrade/freqtrade/blob/c6f3b0081927e161a16b116cc47fb663f7831d30/freqtrade/freqai/prediction_models/CatboostRegressor.py)
|
||||
* [CatboostClassifier](https://github.com/freqtrade/freqtrade/blob/c6f3b0081927e161a16b116cc47fb663f7831d30/freqtrade/freqai/prediction_models/CatboostClassifier.py)
|
||||
* [CatboostClassifierMultiTarget](https://github.com/freqtrade/freqtrade/blob/c6f3b0081927e161a16b116cc47fb663f7831d30/freqtrade/freqai/prediction_models/CatboostClassifierMultiTarget.py)
|
||||
|
||||
+12
-3
@@ -26,10 +26,19 @@ Alternatively (e.g. if your system is not supported by the setup.sh script), fol
|
||||
|
||||
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.
|
||||
This avoids a lot of waiting for CI already, as some basic formatting checks are done locally on your machine.
|
||||
Run the following command to install the git hook scripts:
|
||||
|
||||
Before opening a pull request, please familiarize yourself with our [Contributing Guidelines](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md).
|
||||
``` bash
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
These pre-commit scripts check your changes automatically before each commit.
|
||||
If any formatting issues are found, the commit will fail and will prompt for fixes.
|
||||
This reduces unnecessary CI failures, reduces maintenance burden, and improves code quality.
|
||||
|
||||
You can run the checks manually when necessary with `pre-commit run -a`.
|
||||
|
||||
Before opening a pull request, please also familiarize yourself with our [Contributing Guidelines](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md).
|
||||
|
||||
### Devcontainer setup
|
||||
|
||||
|
||||
+7
-3
@@ -407,11 +407,12 @@ To use these with Freqtrade, you will need to use the following configuration pa
|
||||
``` json
|
||||
"exchange": {
|
||||
"name": "hyperliquid",
|
||||
"walletAddress": "your_vault_address", // Vault or subaccount address
|
||||
"privateKey": "your_api_private_key",
|
||||
"walletAddress": "your_master_wallet_address", // Your master wallet address (not the API wallet address and not the vault/subaccount address).
|
||||
"privateKey": "your_api_private_key", // API wallet private key (see https://app.hyperliquid.xyz/API). You'll only need the private key.
|
||||
"ccxt_config": {
|
||||
"options": {
|
||||
"vaultAddress": "your_vault_address" // Optional, only if you want to use a vault or subaccount
|
||||
"vaultAddress": "your_vault_address", // Optional, only if you want to use a vault ...
|
||||
"subAccountAddress": "your_subaccount_address" // OR optional, only if you want to use a subaccount
|
||||
}
|
||||
},
|
||||
// ...
|
||||
@@ -420,6 +421,9 @@ To use these with Freqtrade, you will need to use the following configuration pa
|
||||
|
||||
Your balance and trades will now be used from your vault / subaccount - and no longer from your main account.
|
||||
|
||||
!!! Note
|
||||
You can only use either a vault or a subaccount - not both at the same time.
|
||||
|
||||
### Historic Hyperliquid data
|
||||
|
||||
The Hyperliquid API does not provide historic data beyond the single call to fetch current data, so downloading data is not possible, as the downloaded data would not constitute proper historic data.
|
||||
|
||||
@@ -200,15 +200,15 @@ If this value is set, FreqAI will initially use the predictions from the trainin
|
||||
|
||||
## Using different prediction models
|
||||
|
||||
FreqAI has multiple example prediction model libraries that are ready to be used as is via the flag `--freqaimodel`. These libraries include `CatBoost`, `LightGBM`, and `XGBoost` regression, classification, and multi-target models, and can be found in `freqai/prediction_models/`.
|
||||
FreqAI has multiple example prediction model libraries that are ready to be used as is via the flag `--freqaimodel`. These libraries include `LightGBM`, and `XGBoost` regression, classification, and multi-target models, and can be found in `freqai/prediction_models/`.
|
||||
|
||||
Regression and classification models differ in what targets they predict - a regression model will predict a target of continuous values, for example what price BTC will be at tomorrow, whilst a classifier will predict a target of discrete values, for example if the price of BTC will go up tomorrow or not. This means that you have to specify your targets differently depending on which model type you are using (see details [below](#setting-model-targets)).
|
||||
|
||||
All of the aforementioned model libraries implement gradient boosted decision tree algorithms. They all work on the principle of ensemble learning, where predictions from multiple simple learners are combined to get a final prediction that is more stable and generalized. The simple learners in this case are decision trees. Gradient boosting refers to the method of learning, where each simple learner is built in sequence - the subsequent learner is used to improve on the error from the previous learner. If you want to learn more about the different model libraries you can find the information in their respective docs:
|
||||
|
||||
* CatBoost: https://catboost.ai/en/docs/
|
||||
* LightGBM: https://lightgbm.readthedocs.io/en/v3.3.2/#
|
||||
* XGBoost: https://xgboost.readthedocs.io/en/stable/#
|
||||
* LightGBM: <https://lightgbm.readthedocs.io/en/v3.3.2/#>
|
||||
* XGBoost: <https://xgboost.readthedocs.io/en/stable/#>
|
||||
* CatBoost: <https://catboost.ai/en/docs/> (No longer actively supported since 2025.12)
|
||||
|
||||
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.
|
||||
|
||||
@@ -219,7 +219,7 @@ Make sure to use unique names to avoid overriding built-in models.
|
||||
|
||||
#### Regressors
|
||||
|
||||
If you are using a regressor, you need to specify a target that has continuous values. FreqAI includes a variety of regressors, such as the `CatboostRegressor`via the flag `--freqaimodel CatboostRegressor`. An example of how you could set a regression target for predicting the price 100 candles into the future would be
|
||||
If you are using a regressor, you need to specify a target that has continuous values. FreqAI includes a variety of regressors, such as the `LightGBMRegressor`via the flag `--freqaimodel LightGBMRegressor`. An example of how you could set a regression target for predicting the price 100 candles into the future would be
|
||||
|
||||
```python
|
||||
df['&s-close_price'] = df['close'].shift(-100)
|
||||
@@ -229,7 +229,7 @@ If you want to predict multiple targets, you need to define multiple labels usin
|
||||
|
||||
#### Classifiers
|
||||
|
||||
If you are using a classifier, you need to specify a target that has discrete values. FreqAI includes a variety of classifiers, such as the `CatboostClassifier` via the flag `--freqaimodel CatboostClassifier`. If you elects to use a classifier, the classes need to be set using strings. For example, if you want to predict if the price 100 candles into the future goes up or down you would set
|
||||
If you are using a classifier, you need to specify a target that has discrete values. FreqAI includes a variety of classifiers, such as the `LightGBMClassifier` via the flag `--freqaimodel LightGBMClassifier`. If you elects to use a classifier, the classes need to be set using strings. For example, if you want to predict if the price 100 candles into the future goes up or down you would set
|
||||
|
||||
```python
|
||||
df['&s-up_or_down'] = np.where( df["close"].shift(-100) > df["close"], 'up', 'down')
|
||||
|
||||
@@ -107,7 +107,6 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
|
||||
| `n_steps` | An alternative way of setting `n_epochs` - the number of training iterations to run. Iteration here refer to the number of times we call `optimizer.step()`. Ignored if `n_epochs` is set. A simplified version of the function: <br><br> n_epochs = n_steps / (n_obs / batch_size) <br><br> The motivation here is that `n_steps` is easier to optimize and keep stable across different n_obs - the number of data points. <br> <br> **Datatype:** int. optional. <br> Default: `None`.
|
||||
| `batch_size` | The size of the batches to use during training. <br><br> **Datatype:** int. <br> Default: `64`.
|
||||
|
||||
|
||||
### Additional parameters
|
||||
|
||||
| Parameter | Description |
|
||||
@@ -116,3 +115,4 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
|
||||
| `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 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.override_exchange_check` | Override the exchange check to force FreqAI to use exchanges that may not have enough historic data. Turn this to True if you know your FreqAI model and strategy do not require historical data. <br> **Datatype:** Boolean. <br> Default: `False`.
|
||||
|
||||
+21
-9
@@ -46,10 +46,17 @@ Depending on the space you want to optimize, only some of the below are required
|
||||
|
||||
* define parameters with `space='buy'` - for entry signal optimization
|
||||
* define parameters with `space='sell'` - for exit signal optimization
|
||||
* define parameters with `space='enter'` - for entry signal optimization
|
||||
* define parameters with `space='exit'` - for exit signal optimization
|
||||
* define parameters with `space='protection'` - for protection optimization
|
||||
* define parameters with `space='random_spacename'` - for better control over which parameters are optimized together
|
||||
|
||||
Pick the space name that suits the parameter best. We recommend to use either `buy` / `sell` or `enter` / `exit` for clarity (however there's no technical limitation in this regard).
|
||||
|
||||
!!! Note
|
||||
`populate_indicators` needs to create all indicators any of the spaces may use, otherwise hyperopt will not work.
|
||||
|
||||
|
||||
Rarely you may also need to create a [nested class](advanced-hyperopt.md#overriding-pre-defined-spaces) named `HyperOpt` and implement
|
||||
|
||||
* `roi_space` - for custom ROI optimization (if you need the ranges for the ROI parameters in the optimization hyperspace that differ from default)
|
||||
@@ -79,15 +86,15 @@ Based on the loss function result, hyperopt will determine the next set of param
|
||||
|
||||
### Configure your Guards and Triggers
|
||||
|
||||
There are two places you need to change in your strategy file to add a new buy hyperopt for testing:
|
||||
There are two places you need to change in your strategy file to add a new hyperopt parameter for optimization:
|
||||
|
||||
* Define the parameters at the class level hyperopt shall be optimizing.
|
||||
* Within `populate_entry_trend()` - use defined parameter values instead of raw constants.
|
||||
|
||||
There you have two different types of indicators: 1. `guards` and 2. `triggers`.
|
||||
|
||||
1. Guards are conditions like "never buy if ADX < 10", or never buy if current price is over EMA10.
|
||||
2. Triggers are ones that actually trigger buy in specific moment, like "buy when EMA5 crosses over EMA10" or "buy when close price touches lower Bollinger band".
|
||||
1. Guards are conditions like "never enter if ADX < 10", or never enter if current price is over EMA10.
|
||||
2. Triggers are ones that actually trigger entry in specific moment, like "enter when EMA5 crosses over EMA10" or "enter when close price touches lower Bollinger band".
|
||||
|
||||
!!! Hint "Guards and Triggers"
|
||||
Technically, there is no difference between Guards and Triggers.
|
||||
@@ -160,9 +167,11 @@ We use these to either enable or disable the ADX and RSI guards.
|
||||
The last one we call `trigger` and use it to decide which buy trigger we want to use.
|
||||
|
||||
!!! Note "Parameter space assignment"
|
||||
Parameters must either be assigned to a variable named `buy_*` or `sell_*` - or contain `space='buy'` | `space='sell'` to be assigned to a space correctly.
|
||||
If no parameter is available for a space, you'll receive the error that no space was found when running hyperopt.
|
||||
- Parameters must either be assigned to a variable named `buy_*`, `sell_*`, `enter_*` or `exit_*` or `protection_*` - or contain have a space assigned explicitly via parameter (`space='buy'`, `space='sell'`, `space='protection'`).
|
||||
- Parameters with conflicting assignments (e.g. `buy_adx = IntParameter(4, 24, default=14, space='sell')`) will use the explicit space assignment.
|
||||
- If no parameter is available for a space, you'll receive the error that no space was found when running hyperopt.
|
||||
Parameters with unclear space (e.g. `adx_period = IntParameter(4, 24, default=14)` - no explicit nor implicit space) will not be detected and will therefore be ignored.
|
||||
Spaces can also be custom named (e.g. `space='my_custom_space'`), with the only limitation that the space name cannot be `all`, `default` - and must result in a valid python identifier.
|
||||
|
||||
So let's write the buy strategy using these values:
|
||||
|
||||
@@ -520,21 +529,24 @@ freqtrade hyperopt --strategy <strategyname> --timerange 20210101-20210201
|
||||
### Running Hyperopt with Smaller Search Space
|
||||
|
||||
Use the `--spaces` option to limit the search space used by hyperopt.
|
||||
Letting Hyperopt optimize everything is a huuuuge search space.
|
||||
Often it might make more sense to start by just searching for initial buy algorithm.
|
||||
Or maybe you just want to optimize your stoploss or roi table for that awesome new buy strategy you have.
|
||||
Letting Hyperopt optimize everything is often a huuuuge search space.
|
||||
Often it might make more sense to start by just searching for initial entry algorithm.
|
||||
Or maybe you just want to optimize your stoploss or roi table for that awesome new strategy you have.
|
||||
|
||||
Legal values are:
|
||||
|
||||
* `all`: optimize everything
|
||||
* `all`: optimize everything (including custom spaces)
|
||||
* `buy`: just search for a new buy strategy
|
||||
* `sell`: just search for a new sell strategy
|
||||
* `enter`: just search for a new entry logic
|
||||
* `exit`: just search for a new entry logic
|
||||
* `roi`: just optimize the minimal profit table for your strategy
|
||||
* `stoploss`: search for the best stoploss value
|
||||
* `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)
|
||||
* `default`: `all` except `trailing`, `trades` and `protection`
|
||||
* `custom_space_name`: any custom space used by any parameter in your strategy
|
||||
* space-separated list of any of the above values for example `--spaces roi stoploss`
|
||||
|
||||
The default Hyperopt Search Space, used when no `--space` command line option is specified, does not include the `trailing` hyperspace. We recommend you to run optimization for the `trailing` hyperspace separately, when the best parameters for other hyperspaces were found, validated and pasted into your custom strategy.
|
||||
|
||||
@@ -367,7 +367,7 @@ The optional `bearer_token` will be included in the requests Authorization Heade
|
||||
|
||||
#### MarketCapPairList
|
||||
|
||||
`MarketCapPairList` employs sorting/filtering of pairs by their marketcap rank based of CoinGecko. The returned pairlist will be sorted based of their marketcap ranks.
|
||||
`MarketCapPairList` employs sorting/filtering of pairs by their marketcap rank based of CoinGecko. The returned pairlist will be sorted based of their marketcap ranks if used in whitelist `mode`.
|
||||
|
||||
```json
|
||||
"pairlists": [
|
||||
@@ -376,16 +376,21 @@ The optional `bearer_token` will be included in the requests Authorization Heade
|
||||
"number_assets": 20,
|
||||
"max_rank": 50,
|
||||
"refresh_period": 86400,
|
||||
"mode": "whitelist",
|
||||
"categories": ["layer-1"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
`number_assets` defines the maximum number of pairs returned by the pairlist. `max_rank` will determine the maximum rank used in creating/filtering the pairlist. It's expected that some coins within the top `max_rank` marketcap will not be included in the resulting pairlist since not all pairs will have active trading pairs in your preferred market/stake/exchange combination.
|
||||
`number_assets` defines the maximum number of pairs returned by the pairlist if used in whitelist `mode`. In blacklist `mode`, this setting will be ignored.
|
||||
|
||||
`max_rank` will determine the maximum rank used in creating/filtering the pairlist. It's expected that some coins within the top `max_rank` marketcap will not be included in the resulting pairlist since not all pairs will have active trading pairs in your preferred market/stake/exchange combination.
|
||||
While using a `max_rank` bigger than 250 is supported, it's not recommended, as it'll cause multiple API calls to CoinGecko, which can lead to rate limit issues.
|
||||
|
||||
The `refresh_period` setting defines the interval (in seconds) at which the marketcap rank data will be refreshed. The default is 86,400 seconds (1 day). The pairlist cache (`refresh_period`) applies to both generating pairlists (when in the first position in the list) and filtering instances (when not in the first position in the list).
|
||||
|
||||
The `mode` setting defines whether the plugin will filters in (whitelist `mode`) or filters out (blacklist `mode`) top marketcap ranked coins. By default, the plugin will be in whitelist mode.
|
||||
|
||||
The `categories` setting specifies the [coingecko categories](https://www.coingecko.com/en/categories) from which to select coins from. The default is an empty list `[]`, meaning no category filtering is applied.
|
||||
If an incorrect category string is chosen, the plugin will print the available categories from CoinGecko and fail. The category should be the ID of the category, for example, for `https://www.coingecko.com/en/categories/layer-1`, the category ID would be `layer-1`. You can pass multiple categories such as `["layer-1", "meme-token"]` to select from several categories.
|
||||
|
||||
@@ -412,7 +417,7 @@ This filter allows freqtrade to ignore pairs until they have been listed for at
|
||||
Removes pairs that will be delisted on the exchange maximum `max_days_from_now` days from now (defaults to `0` which remove all future delisted pairs no matter how far from now). Currently this filter only supports following exchanges:
|
||||
|
||||
!!! Note "Available exchanges"
|
||||
Delist filter is only available on Binance, where Binance Futures will work for both dry and live modes, while Binance Spot is limited to live mode (for technical reasons).
|
||||
Delist filter is available on Bybit Futures, Bitget Futures and Binance, where Binance Futures will work for both dry and live modes, while Binance Spot is limited to live mode (for technical reasons).
|
||||
|
||||
!!! Warning "Backtesting"
|
||||
`DelistFilter` does not support backtesting mode.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
[](https://github.com/freqtrade/freqtrade/actions/)
|
||||
[](https://github.com/freqtrade/freqtrade/actions/workflows/ci.yml)
|
||||
[](https://doi.org/10.21105/joss.04864)
|
||||
[](https://coveralls.io/github/freqtrade/freqtrade?branch=develop)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
markdown==3.9
|
||||
markdown==3.10
|
||||
mkdocs==1.6.1
|
||||
mkdocs-material==9.6.22
|
||||
mkdocs-material==9.7.0
|
||||
mdx_truly_sane_lists==1.3
|
||||
pymdown-extensions==10.16.1
|
||||
pymdown-extensions==10.19.1
|
||||
jinja2==3.1.6
|
||||
mike==2.1.3
|
||||
|
||||
+4
-172
@@ -150,184 +150,16 @@ This method will work for all arguments - check the "show" command for a list of
|
||||
|
||||
For a full list of available commands, please refer to the list below.
|
||||
|
||||
#### Freqtrade client- available commands
|
||||
|
||||
Possible commands can be listed from the rest-client script using the `help` command.
|
||||
|
||||
``` bash
|
||||
freqtrade-client help
|
||||
```
|
||||
|
||||
``` output
|
||||
Possible commands:
|
||||
--8<-- "commands/freqtrade-client.md"
|
||||
|
||||
available_pairs
|
||||
Return available pair (backtest data) based on timeframe / stake_currency selection
|
||||
|
||||
:param timeframe: Only pairs with this timeframe available.
|
||||
:param stake_currency: Only pairs that include this timeframe
|
||||
|
||||
balance
|
||||
Get the account balance.
|
||||
|
||||
blacklist
|
||||
Show the current blacklist.
|
||||
|
||||
: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
|
||||
Return the amount of open trades.
|
||||
|
||||
daily
|
||||
Return the profits for each day, and amount of trades.
|
||||
|
||||
delete_lock
|
||||
Delete (disable) lock from the database.
|
||||
|
||||
:param lock_id: ID for the lock to delete
|
||||
|
||||
delete_trade
|
||||
Delete trade from the database.
|
||||
Tries to close open orders. Requires manual handling of this asset on the exchange.
|
||||
|
||||
:param trade_id: Deletes the trade with this ID from the database.
|
||||
|
||||
forcebuy
|
||||
Buy an asset.
|
||||
|
||||
:param pair: Pair to buy (ETH/BTC)
|
||||
:param price: Optional - price to buy
|
||||
|
||||
forceenter
|
||||
Force entering a trade
|
||||
|
||||
:param pair: Pair to buy (ETH/BTC)
|
||||
:param side: 'long' or 'short'
|
||||
:param price: Optional - price to buy
|
||||
|
||||
forceexit
|
||||
Force-exit a trade.
|
||||
|
||||
:param tradeid: Id of the trade (can be received via status command)
|
||||
:param ordertype: Order type to use (must be market or limit)
|
||||
:param amount: Amount to sell. Full sell if not given
|
||||
|
||||
health
|
||||
Provides a quick health check of the running bot.
|
||||
|
||||
lock_add
|
||||
Manually lock a specific pair
|
||||
|
||||
:param pair: Pair to lock
|
||||
:param until: Lock until this date (format "2024-03-30 16:00:00Z")
|
||||
:param side: Side to lock (long, short, *)
|
||||
:param reason: Reason for the lock
|
||||
|
||||
locks
|
||||
Return current locks
|
||||
|
||||
logs
|
||||
Show latest logs.
|
||||
|
||||
:param limit: Limits log messages to the last <limit> logs. No limit to get the entire log.
|
||||
|
||||
pair_candles
|
||||
Return live dataframe for <pair><timeframe>.
|
||||
|
||||
:param pair: Pair to get data for
|
||||
:param timeframe: Only pairs with this timeframe available.
|
||||
:param limit: Limit result to the last n candles.
|
||||
|
||||
pair_history
|
||||
Return historic, analyzed dataframe
|
||||
|
||||
:param pair: Pair to get data for
|
||||
:param timeframe: Only pairs with this timeframe available.
|
||||
:param strategy: Strategy to analyze and get values for
|
||||
:param timerange: Timerange to get data for (same format than --timerange endpoints)
|
||||
|
||||
performance
|
||||
Return the performance of the different coins.
|
||||
|
||||
ping
|
||||
simple ping
|
||||
|
||||
plot_config
|
||||
Return plot configuration if the strategy defines one.
|
||||
|
||||
profit
|
||||
Return the profit summary.
|
||||
|
||||
reload_config
|
||||
Reload configuration.
|
||||
|
||||
show_config
|
||||
Returns part of the configuration, relevant for trading operations.
|
||||
|
||||
start
|
||||
Start the bot if it's in the stopped state.
|
||||
|
||||
pause
|
||||
Pause the bot if it's in the running state. If triggered on stopped state will handle open positions.
|
||||
|
||||
stats
|
||||
Return the stats report (durations, sell-reasons).
|
||||
|
||||
status
|
||||
Get the status of open trades.
|
||||
|
||||
stop
|
||||
Stop the bot. Use `start` to restart.
|
||||
|
||||
stopbuy
|
||||
Stop buying (but handle sells gracefully). Use `reload_config` to reset.
|
||||
|
||||
strategies
|
||||
Lists available strategies
|
||||
|
||||
strategy
|
||||
Get strategy details
|
||||
|
||||
:param strategy: Strategy class name
|
||||
|
||||
sysinfo
|
||||
Provides system information (CPU, RAM usage)
|
||||
|
||||
trade
|
||||
Return specific trade
|
||||
|
||||
:param trade_id: Specify which trade to get.
|
||||
|
||||
trades
|
||||
Return trades history, sorted by id
|
||||
|
||||
:param limit: Limits trades to the X last trades. Max 500 trades.
|
||||
:param offset: Offset by this amount of trades.
|
||||
|
||||
list_open_trades_custom_data
|
||||
Return a dict containing open trades custom-datas
|
||||
|
||||
:param key: str, optional - Key of the custom-data
|
||||
:param limit: Limits trades to X trades.
|
||||
:param offset: Offset by this amount of trades.
|
||||
|
||||
list_custom_data
|
||||
Return a dict containing custom-datas of a specified trade
|
||||
|
||||
:param trade_id: int - ID of the trade
|
||||
:param key: str, optional - Key of the custom-data
|
||||
|
||||
version
|
||||
Return the version of the bot.
|
||||
|
||||
whitelist
|
||||
Show the current whitelist.
|
||||
|
||||
|
||||
```
|
||||
|
||||
### Available endpoints
|
||||
|
||||
@@ -359,7 +191,7 @@ All endpoints in the below table need to be prefixed with the base URL of the AP
|
||||
| `/locks/<lockid>` | DELETE | Deletes (disables) the lock by id.<br/>*Params:*<br/>- `lockid` (`int`)
|
||||
| `/profit` | GET | Display a summary of your profit/loss from close trades and some stats about your performance.
|
||||
| `/forceexit` | POST | Instantly exits the given trade (ignoring `minimum_roi`), using the given order type ("market" or "limit", uses your config setting if not specified), and the chosen amount (full sell if not specified). If `all` is supplied as the `tradeid`, then all currently open trades will be forced to exit.<br/>*Params:*<br/>- `<tradeid>` (`int` or `str`)<br/>- `<ordertype>` (`str`)<br/>- `[amount]` (`float`)
|
||||
| `/forceenter` | POST | Instantly enters the given pair. Side is optional and is either `long` or `short` (default is `long`). Rate is optional. (`force_entry_enable` must be set to True)<br/>*Params:*<br/>- `<pair>` (`str`)<br/>- `<side>` (`str`)<br/>- `[rate]` (`float`)
|
||||
| `/forceenter` | POST | Instantly enters the given pair. Side is optional and is either `long` or `short` (default is `long`). Price, stake amount, entry tag and leverage are optional. Order type is optional and is either `market` or `long` (default using the value set in config). (`force_entry_enable` must be set to True)<br/>*Params:*<br/>- `<pair>` (`str`)<br/>- `<side>` (`str`)<br/>- `[price]` (`float`)<br/>- `[ordertype]` (`str`)<br/>- `[stakeamount]` (`float`)<br/>- `[entry_tag]` (`str`)<br/>- `[leverage]` (`float`)
|
||||
| `/performance` | GET | Show performance of each finished trade grouped by pair.
|
||||
| `/balance` | GET | Show account balance per currency.
|
||||
| `/daily` | GET | Shows profit or loss per day, over the last n days (n defaults to 7).<br/>*Params:*<br/>- `timescale` (`int`)
|
||||
|
||||
+6
-1
@@ -31,9 +31,14 @@ The Order-type will be ignored if only one mode is available.
|
||||
--8<-- "includes/exchange-features.md"
|
||||
|
||||
!!! Note "Tight stoploss"
|
||||
<ins>Do not set too low/tight stoploss value when using stop loss on exchange!</ins>
|
||||
Do not set too low/tight stoploss value when using stop loss on exchange!
|
||||
If set to low/tight you will have greater risk of missing fill on the order and stoploss will not work.
|
||||
|
||||
!!! Warning "Loose stoploss"
|
||||
Using stoploss on exchange with a very wide stoploss (e.g. -1) may fail to place the stoploss order on exchange due to exchange limitations.
|
||||
In that case, the bot will fallback to using the `emergency_exit` order type to place a market order as placing the stoploss order failed.
|
||||
Freqtrade currently does not implement a limitation to avoid this situation, so please ensure your stoploss values are within reasonable limits for your exchange or disable stoploss on exchange.
|
||||
|
||||
### stoploss_on_exchange and stoploss_on_exchange_limit_ratio
|
||||
|
||||
Enable or Disable stop loss on exchange.
|
||||
|
||||
@@ -634,7 +634,7 @@ class AwesomeStrategy(IStrategy):
|
||||
|
||||
## Custom order price rules
|
||||
|
||||
By default, freqtrade use the orderbook to automatically set an order price([Relevant documentation](configuration.md#prices-used-for-orders)), you also have the option to create custom order prices based on your strategy.
|
||||
By default, freqtrade use the orderbook to automatically set an order price ([Relevant documentation](configuration.md#prices-used-for-orders)), you also have the option to create custom order prices based on your strategy.
|
||||
|
||||
You can use this feature by creating a `custom_entry_price()` function in your strategy file to customize entry prices and `custom_exit_price()` for exits.
|
||||
|
||||
@@ -644,7 +644,7 @@ Each of these methods are called right before placing an order on the exchange.
|
||||
If your custom pricing function return None or an invalid value, price will fall back to `proposed_rate`, which is based on the regular pricing configuration.
|
||||
|
||||
!!! Note
|
||||
Using custom_entry_price, the Trade object will be available as soon as the first entry order associated with the trade is created, for the first entry, `trade` parameter value will be `None`.
|
||||
When using `custom_entry_price()`, the Trade object will be available as soon as the first entry order associated with the trade is created, for the first entry, `trade` parameter value will be `None`.
|
||||
|
||||
### Custom order entry and exit price example
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Freqtrade bot"""
|
||||
|
||||
__version__ = "2025.10"
|
||||
__version__ = "2025.12"
|
||||
|
||||
if "dev" in __version__:
|
||||
from pathlib import Path
|
||||
|
||||
@@ -3,6 +3,7 @@ This module contains the argument manager class
|
||||
"""
|
||||
|
||||
from argparse import ArgumentParser, Namespace, _ArgumentGroup
|
||||
from copy import deepcopy
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
@@ -104,7 +105,7 @@ ARGS_BACKTEST_SHOW = [
|
||||
|
||||
ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all", "trading_mode", "dex_exchanges"]
|
||||
|
||||
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
|
||||
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column", "trading_mode"]
|
||||
|
||||
ARGS_LIST_PAIRS = [
|
||||
"exchange",
|
||||
@@ -174,6 +175,7 @@ ARGS_DOWNLOAD_DATA = [
|
||||
"dataformat_ohlcv",
|
||||
"dataformat_trades",
|
||||
"trading_mode",
|
||||
"candle_types",
|
||||
"prepend_data",
|
||||
]
|
||||
|
||||
@@ -348,7 +350,11 @@ class Arguments:
|
||||
def _build_args(self, optionlist: list[str], parser: ArgumentParser | _ArgumentGroup) -> None:
|
||||
for val in optionlist:
|
||||
opt = AVAILABLE_CLI_OPTIONS[val]
|
||||
parser.add_argument(*opt.cli, dest=val, **opt.kwargs)
|
||||
options = deepcopy(opt.kwargs)
|
||||
help_text = options.pop("help", None)
|
||||
if opt.fthelp and isinstance(opt.fthelp, dict) and hasattr(parser, "prog"):
|
||||
help_text = opt.fthelp.get(parser.prog, help_text)
|
||||
parser.add_argument(*opt.cli, dest=val, help=help_text, **options)
|
||||
|
||||
def _build_subcommands(self) -> None:
|
||||
"""
|
||||
|
||||
@@ -5,7 +5,10 @@ Definition of cli arguments used in arguments.py
|
||||
from argparse import ArgumentTypeError
|
||||
|
||||
from freqtrade import constants
|
||||
from freqtrade.constants import HYPEROPT_LOSS_BUILTIN
|
||||
from freqtrade.constants import (
|
||||
HYPEROPT_BUILTIN_SPACE_OPTIONS,
|
||||
HYPEROPT_LOSS_BUILTIN,
|
||||
)
|
||||
from freqtrade.enums import CandleType
|
||||
|
||||
|
||||
@@ -35,8 +38,14 @@ def check_int_nonzero(value: str) -> int:
|
||||
|
||||
class Arg:
|
||||
# Optional CLI arguments
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args, fthelp: dict[str, str] | None = None, **kwargs):
|
||||
"""
|
||||
CLI Arguments - used to build subcommand parsers consistently.
|
||||
:param fthelp: dict - fthelp per command - should be "freqtrade <command>": help_text
|
||||
If not provided or not found, 'help' from kwargs is used instead.
|
||||
"""
|
||||
self.cli = args
|
||||
self.fthelp = fthelp
|
||||
self.kwargs = kwargs
|
||||
|
||||
|
||||
@@ -171,7 +180,11 @@ AVAILABLE_CLI_OPTIONS = {
|
||||
"position_stacking": Arg(
|
||||
"--eps",
|
||||
"--enable-position-stacking",
|
||||
help="Allow buying the same pair multiple times (position stacking).",
|
||||
help=(
|
||||
"Allow buying the same pair multiple times (position stacking). "
|
||||
"Only applicable to backtesting and hyperopt. "
|
||||
"Results archived by this cannot be reproduced in dry/live trading."
|
||||
),
|
||||
action="store_true",
|
||||
default=False,
|
||||
),
|
||||
@@ -278,26 +291,18 @@ AVAILABLE_CLI_OPTIONS = {
|
||||
),
|
||||
"spaces": Arg(
|
||||
"--spaces",
|
||||
help="Specify which parameters to hyperopt. Space-separated list.",
|
||||
choices=[
|
||||
"all",
|
||||
"buy",
|
||||
"sell",
|
||||
"roi",
|
||||
"stoploss",
|
||||
"trailing",
|
||||
"protection",
|
||||
"trades",
|
||||
"default",
|
||||
],
|
||||
help=(
|
||||
"Specify which parameters to hyperopt. Space-separated list. "
|
||||
"Available builtin options (custom spaces will not be listed here): "
|
||||
f"{', '.join(HYPEROPT_BUILTIN_SPACE_OPTIONS)}. Default: `default` - "
|
||||
"which includes all spaces except for 'trailing', 'protection', and 'trades'."
|
||||
),
|
||||
nargs="+",
|
||||
default="default",
|
||||
),
|
||||
"analyze_per_epoch": Arg(
|
||||
"--analyze-per-epoch",
|
||||
help="Run populate_indicators once per epoch.",
|
||||
action="store_true",
|
||||
default=False,
|
||||
),
|
||||
"print_all": Arg(
|
||||
"--print-all",
|
||||
@@ -427,6 +432,14 @@ AVAILABLE_CLI_OPTIONS = {
|
||||
),
|
||||
"candle_types": Arg(
|
||||
"--candle-types",
|
||||
fthelp={
|
||||
"freqtrade download-data": (
|
||||
"Select candle type to download. "
|
||||
"Defaults to the necessary candles for the selected trading mode "
|
||||
"(e.g. 'spot' or ('futures', 'funding_rate' and 'mark') for futures)."
|
||||
),
|
||||
"_": "Select candle type to convert. Defaults to all available types.",
|
||||
},
|
||||
help="Select candle type to convert. Defaults to all available types.",
|
||||
choices=[c.value for c in CandleType],
|
||||
nargs="+",
|
||||
|
||||
@@ -101,7 +101,7 @@ def _print_objs_tabular(objs: list, print_colorized: bool) -> None:
|
||||
names = [s["name"] for s in objs]
|
||||
objs_to_print: list[dict[str, Text | str]] = [
|
||||
{
|
||||
"name": Text(s["name"] if s["name"] else "--"),
|
||||
"Strategy name": Text(s["name"] if s["name"] else "--"),
|
||||
"location": s["location_rel"],
|
||||
"status": (
|
||||
Text("LOAD FAILED", style="bold red")
|
||||
@@ -115,11 +115,19 @@ def _print_objs_tabular(objs: list, print_colorized: bool) -> None:
|
||||
]
|
||||
for idx, s in enumerate(objs):
|
||||
if "hyperoptable" in s:
|
||||
custom_params = [
|
||||
f"{space}: {len(params)}"
|
||||
for space, params in s["hyperoptable"].items()
|
||||
if space not in ["buy", "sell", "protection"]
|
||||
]
|
||||
hyp = s["hyperoptable"]
|
||||
objs_to_print[idx].update(
|
||||
{
|
||||
"hyperoptable": "Yes" if s["hyperoptable"]["count"] > 0 else "No",
|
||||
"buy-Params": str(len(s["hyperoptable"].get("buy", []))),
|
||||
"sell-Params": str(len(s["hyperoptable"].get("sell", []))),
|
||||
"hyperoptable": "Yes" if len(hyp) > 0 else "No",
|
||||
"buy-Params": str(len(hyp.get("buy", []))),
|
||||
"sell-Params": str(len(hyp.get("sell", []))),
|
||||
"protection-Params": str(len(hyp.get("protection", []))),
|
||||
"custom-Params": ", ".join(custom_params) if custom_params else "",
|
||||
}
|
||||
)
|
||||
table = Table()
|
||||
@@ -140,6 +148,7 @@ def start_list_strategies(args: dict[str, Any]) -> None:
|
||||
"""
|
||||
from freqtrade.configuration import setup_utils_configuration
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
from freqtrade.strategy.hyper import detect_all_parameters
|
||||
|
||||
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
|
||||
|
||||
@@ -153,9 +162,9 @@ def start_list_strategies(args: dict[str, Any]) -> None:
|
||||
strategy_objs = sorted(strategy_objs, key=lambda x: x["name"])
|
||||
for obj in strategy_objs:
|
||||
if obj["class"]:
|
||||
obj["hyperoptable"] = obj["class"].detect_all_parameters()
|
||||
obj["hyperoptable"] = detect_all_parameters(obj["class"])
|
||||
else:
|
||||
obj["hyperoptable"] = {"count": 0}
|
||||
obj["hyperoptable"] = {}
|
||||
|
||||
if args["print_one_column"]:
|
||||
print("\n".join([s["name"] for s in strategy_objs]))
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
# Required json-schema for user specified config
|
||||
|
||||
|
||||
from freqtrade.constants import (
|
||||
AVAILABLE_DATAHANDLERS,
|
||||
AVAILABLE_PAIRLISTS,
|
||||
BACKTEST_BREAKDOWNS,
|
||||
BACKTEST_CACHE_AGE,
|
||||
DRY_RUN_WALLET,
|
||||
EXPORT_OPTIONS,
|
||||
HYPEROPT_LOSS_BUILTIN,
|
||||
MARGIN_MODES,
|
||||
ORDERTIF_POSSIBILITIES,
|
||||
ORDERTYPE_POSSIBILITIES,
|
||||
@@ -228,6 +231,76 @@ CONF_SCHEMA = {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "enum": BACKTEST_BREAKDOWNS},
|
||||
},
|
||||
"backtest_cache": {
|
||||
"description": "Load a cached backtest result no older than specified age.",
|
||||
"type": "string",
|
||||
"enum": BACKTEST_CACHE_AGE,
|
||||
},
|
||||
# Hyperopt
|
||||
"hyperopt_path": {
|
||||
"description": "Specify additional lookup path for Hyperopt Loss functions.",
|
||||
"type": "string",
|
||||
},
|
||||
"epochs": {
|
||||
"description": "Number of training epochs for Hyperopt.",
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
},
|
||||
"early_stop": {
|
||||
"description": (
|
||||
"Early stop hyperopt if no improvement after <epochs>. Set to 0 to disable."
|
||||
),
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
},
|
||||
"spaces": {
|
||||
"description": (
|
||||
"Hyperopt parameter spaces to optimize. Default is the default set and"
|
||||
"includes all spaces except for 'trailing', 'protection', and 'trades'."
|
||||
),
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"default": ["default"],
|
||||
},
|
||||
"analyze_per_epoch": {
|
||||
"description": "Perform analysis after each epoch in Hyperopt.",
|
||||
"type": "boolean",
|
||||
},
|
||||
"print_all": {
|
||||
"description": "Print all hyperopt trials, not just the best ones.",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
},
|
||||
"hyperopt_jobs": {
|
||||
"description": (
|
||||
"The number of concurrently running jobs for hyperoptimization "
|
||||
"(hyperopt worker processes). "
|
||||
"If -1 (default), all CPUs are used, for -2, all CPUs but one are used, etc. "
|
||||
"If 1 is given, no parallel computing is used."
|
||||
),
|
||||
"type": "integer",
|
||||
"default": -1,
|
||||
},
|
||||
"hyperopt_random_state": {
|
||||
"description": "Random state for hyperopt trials.",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
},
|
||||
"hyperopt_min_trades": {
|
||||
"description": "Minimum number of trades per epoch for hyperopt.",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
},
|
||||
"hyperopt_loss": {
|
||||
"description": (
|
||||
"The class name of the hyperopt loss function class (IHyperOptLoss). "
|
||||
"Different functions can generate completely different results, "
|
||||
"since the target for optimization is different. "
|
||||
f"Built-in Hyperopt-loss-functions are: {', '.join(HYPEROPT_LOSS_BUILTIN)}"
|
||||
),
|
||||
"type": "string",
|
||||
},
|
||||
# end hyperopt
|
||||
"bot_name": {
|
||||
"description": "Name of the trading bot. Passed via API to a client.",
|
||||
"type": "string",
|
||||
|
||||
@@ -41,6 +41,19 @@ HYPEROPT_LOSS_BUILTIN = [
|
||||
"ProfitDrawDownHyperOptLoss",
|
||||
"MultiMetricHyperOptLoss",
|
||||
]
|
||||
HYPEROPT_BUILTIN_SPACES = [
|
||||
"buy",
|
||||
"sell",
|
||||
"enter",
|
||||
"exit",
|
||||
"roi",
|
||||
"stoploss",
|
||||
"trailing",
|
||||
"protection",
|
||||
"trades",
|
||||
]
|
||||
HYPEROPT_BUILTIN_SPACE_OPTIONS = ["default", "all"] + HYPEROPT_BUILTIN_SPACES
|
||||
|
||||
AVAILABLE_PAIRLISTS = [
|
||||
"StaticPairList",
|
||||
"VolumePairList",
|
||||
|
||||
@@ -38,7 +38,8 @@ def ohlcv_to_dataframe(
|
||||
cols = DEFAULT_DATAFRAME_COLUMNS
|
||||
df = DataFrame(ohlcv, columns=cols)
|
||||
|
||||
df["date"] = to_datetime(df["date"], unit="ms", utc=True)
|
||||
# Floor date to seconds to account for exchange imprecisions
|
||||
df["date"] = to_datetime(df["date"], unit="ms", utc=True).dt.floor("s")
|
||||
|
||||
# Some exchanges return int values for Volume and even for OHLC.
|
||||
# Convert them since TA-LIB indicators used in the strategy assume floats
|
||||
|
||||
@@ -348,6 +348,22 @@ class DataProvider:
|
||||
)
|
||||
return total_candles
|
||||
|
||||
def __fix_funding_rate_timeframe(
|
||||
self, pair: str, timeframe: str | None, candle_type: str
|
||||
) -> str | None:
|
||||
if (
|
||||
candle_type == CandleType.FUNDING_RATE
|
||||
and (ff_tf := self.get_funding_rate_timeframe()) != timeframe
|
||||
):
|
||||
# TODO: does this message make sense? might be pointless as funding fees don't
|
||||
# have a timeframe
|
||||
logger.warning(
|
||||
f"{pair}, {timeframe} requested - funding rate timeframe not matching {ff_tf}."
|
||||
)
|
||||
return ff_tf
|
||||
|
||||
return timeframe
|
||||
|
||||
def get_pair_dataframe(
|
||||
self, pair: str, timeframe: str | None = None, candle_type: str = ""
|
||||
) -> DataFrame:
|
||||
@@ -361,6 +377,7 @@ class DataProvider:
|
||||
:return: Dataframe for this pair
|
||||
:param candle_type: '', mark, index, premiumIndex, or funding_rate
|
||||
"""
|
||||
timeframe = self.__fix_funding_rate_timeframe(pair, timeframe, candle_type)
|
||||
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
|
||||
# Get live OHLCV data.
|
||||
data = self.ohlcv(pair=pair, timeframe=timeframe, candle_type=candle_type)
|
||||
@@ -620,3 +637,12 @@ class DataProvider:
|
||||
except ExchangeError:
|
||||
logger.warning(f"Could not fetch market data for {pair}. Assuming no delisting.")
|
||||
return None
|
||||
|
||||
def get_funding_rate_timeframe(self) -> str:
|
||||
"""
|
||||
Get the funding rate timeframe from exchange options
|
||||
:return: Timeframe string
|
||||
"""
|
||||
if self._exchange is None:
|
||||
raise OperationalException(NO_EXCHANGE_EXCEPTION)
|
||||
return self._exchange.get_option("funding_fee_timeframe")
|
||||
|
||||
@@ -397,6 +397,9 @@ class IDataHandler(ABC):
|
||||
pairdf = self._ohlcv_load(
|
||||
pair, timeframe, timerange=timerange_startup, candle_type=candle_type
|
||||
)
|
||||
if not pairdf.empty and candle_type == CandleType.FUNDING_RATE:
|
||||
# Funding rate data is sometimes off by a couple of ms - floor to seconds
|
||||
pairdf["date"] = pairdf["date"].dt.floor("s")
|
||||
if self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data):
|
||||
return pairdf
|
||||
else:
|
||||
@@ -508,8 +511,15 @@ class IDataHandler(ABC):
|
||||
Applies to bybit and okx, where funding-fee and mark candles have different timeframes.
|
||||
"""
|
||||
paircombs = self.ohlcv_get_available_data(self._datadir, TradingMode.FUTURES)
|
||||
ff_timeframe_s = timeframe_to_seconds(ff_timeframe)
|
||||
|
||||
funding_rate_combs = [
|
||||
f for f in paircombs if f[2] == CandleType.FUNDING_RATE and f[1] != ff_timeframe
|
||||
f
|
||||
for f in paircombs
|
||||
if f[2] == CandleType.FUNDING_RATE
|
||||
and f[1] != ff_timeframe
|
||||
# Only allow smaller timeframes to move from smaller to larger timeframes
|
||||
and timeframe_to_seconds(f[1]) < ff_timeframe_s
|
||||
]
|
||||
|
||||
if funding_rate_combs:
|
||||
|
||||
@@ -308,11 +308,15 @@ def _download_pair_history(
|
||||
candle_type=candle_type,
|
||||
until_ms=until_ms if until_ms else None,
|
||||
)
|
||||
logger.info(f"Downloaded data for {pair} with length {len(new_dataframe)}.")
|
||||
logger.info(
|
||||
f"Downloaded data for {pair}, {timeframe}, {candle_type} with length "
|
||||
f"{len(new_dataframe)}."
|
||||
)
|
||||
else:
|
||||
new_dataframe = pair_candles
|
||||
logger.info(
|
||||
f"Downloaded data for {pair} with length {len(new_dataframe)}. Parallel Method."
|
||||
f"Downloaded data for {pair}, {timeframe}, {candle_type} with length "
|
||||
f"{len(new_dataframe)}. Parallel Method."
|
||||
)
|
||||
|
||||
if data.empty:
|
||||
@@ -349,6 +353,7 @@ def _download_pair_history(
|
||||
|
||||
def refresh_backtest_ohlcv_data(
|
||||
exchange: Exchange,
|
||||
*,
|
||||
pairs: list[str],
|
||||
timeframes: list[str],
|
||||
datadir: Path,
|
||||
@@ -359,6 +364,7 @@ def refresh_backtest_ohlcv_data(
|
||||
data_format: str | None = None,
|
||||
prepend: bool = False,
|
||||
progress_tracker: CustomProgress | None = None,
|
||||
candle_types: list[CandleType] | None = None,
|
||||
no_parallel_download: bool = False,
|
||||
) -> list[str]:
|
||||
"""
|
||||
@@ -371,10 +377,44 @@ def refresh_backtest_ohlcv_data(
|
||||
pairs_not_available = []
|
||||
fast_candles: dict[PairWithTimeframe, DataFrame] = {}
|
||||
data_handler = get_datahandler(datadir, data_format)
|
||||
candle_type = CandleType.get_default(trading_mode)
|
||||
def_candletype = CandleType.SPOT if trading_mode != "futures" else CandleType.FUTURES
|
||||
if trading_mode != "futures":
|
||||
# Ignore user passed candle types for non-futures trading
|
||||
timeframes_with_candletype = [(tf, def_candletype) for tf in timeframes]
|
||||
else:
|
||||
# Filter out SPOT candle type for futures trading
|
||||
candle_types = (
|
||||
[ct for ct in candle_types if ct != CandleType.SPOT] if candle_types else None
|
||||
)
|
||||
fr_candle_type = CandleType.from_string(exchange.get_option("mark_ohlcv_price"))
|
||||
tf_funding_rate = exchange.get_option("funding_fee_timeframe")
|
||||
tf_mark = exchange.get_option("mark_ohlcv_timeframe")
|
||||
|
||||
if candle_types:
|
||||
for ct in candle_types:
|
||||
exchange.verify_candle_type_support(ct)
|
||||
timeframes_with_candletype = [
|
||||
(tf, ct)
|
||||
for ct in candle_types
|
||||
for tf in timeframes
|
||||
if ct != CandleType.FUNDING_RATE
|
||||
]
|
||||
else:
|
||||
# Default behavior
|
||||
timeframes_with_candletype = [(tf, def_candletype) for tf in timeframes]
|
||||
timeframes_with_candletype.append((tf_mark, fr_candle_type))
|
||||
if not candle_types or CandleType.FUNDING_RATE in candle_types:
|
||||
# All exchanges need FundingRate for futures trading.
|
||||
# The timeframe is aligned to the mark-price timeframe.
|
||||
timeframes_with_candletype.append((tf_funding_rate, CandleType.FUNDING_RATE))
|
||||
# Deduplicate list ...
|
||||
timeframes_with_candletype = list(dict.fromkeys(timeframes_with_candletype))
|
||||
logger.debug(
|
||||
"Downloading %s.", ", ".join(f'"{tf} {ct}"' for tf, ct in timeframes_with_candletype)
|
||||
)
|
||||
|
||||
with progress_tracker as progress:
|
||||
tf_length = len(timeframes) if trading_mode != "futures" else len(timeframes) + 2
|
||||
timeframe_task = progress.add_task("Timeframe", total=tf_length)
|
||||
timeframe_task = progress.add_task("Timeframe", total=len(timeframes_with_candletype))
|
||||
pair_task = progress.add_task("Downloading data...", total=len(pairs))
|
||||
|
||||
for pair in pairs:
|
||||
@@ -385,11 +425,13 @@ def refresh_backtest_ohlcv_data(
|
||||
pairs_not_available.append(f"{pair}: Pair not available on exchange.")
|
||||
logger.info(f"Skipping pair {pair}...")
|
||||
continue
|
||||
for timeframe in timeframes:
|
||||
for timeframe, candle_type in timeframes_with_candletype:
|
||||
# Get fast candles via parallel method on first loop through per timeframe
|
||||
# and candle type. Downloads all the pairs in the list and stores them.
|
||||
# Also skips if only 1 pair/timeframe combination is scheduled for download.
|
||||
if (
|
||||
not no_parallel_download
|
||||
and (len(pairs) + len(timeframes)) > 2
|
||||
and exchange.get_option("download_data_parallel_quick", True)
|
||||
and (
|
||||
((pair, timeframe, candle_type) not in fast_candles)
|
||||
@@ -410,7 +452,7 @@ def refresh_backtest_ohlcv_data(
|
||||
# get the already downloaded pair candles if they exist
|
||||
pair_candles = fast_candles.pop((pair, timeframe, candle_type), None)
|
||||
|
||||
progress.update(timeframe_task, description=f"Timeframe {timeframe}")
|
||||
progress.update(timeframe_task, description=f"Timeframe {timeframe} {candle_type}")
|
||||
logger.debug(f"Downloading pair {pair}, {candle_type}, interval {timeframe}.")
|
||||
_download_pair_history(
|
||||
pair=pair,
|
||||
@@ -426,33 +468,6 @@ def refresh_backtest_ohlcv_data(
|
||||
pair_candles=pair_candles, # optional pass of dataframe of parallel candles
|
||||
)
|
||||
progress.update(timeframe_task, advance=1)
|
||||
if trading_mode == "futures":
|
||||
# Predefined candletype (and timeframe) depending on exchange
|
||||
# Downloads what is necessary to backtest based on futures data.
|
||||
tf_mark = exchange.get_option("mark_ohlcv_timeframe")
|
||||
tf_funding_rate = exchange.get_option("funding_fee_timeframe")
|
||||
|
||||
fr_candle_type = CandleType.from_string(exchange.get_option("mark_ohlcv_price"))
|
||||
# All exchanges need FundingRate for futures trading.
|
||||
# The timeframe is aligned to the mark-price timeframe.
|
||||
combs = ((CandleType.FUNDING_RATE, tf_funding_rate), (fr_candle_type, tf_mark))
|
||||
for candle_type_f, tf in combs:
|
||||
logger.debug(f"Downloading pair {pair}, {candle_type_f}, interval {tf}.")
|
||||
_download_pair_history(
|
||||
pair=pair,
|
||||
datadir=datadir,
|
||||
exchange=exchange,
|
||||
timerange=timerange,
|
||||
data_handler=data_handler,
|
||||
timeframe=str(tf),
|
||||
new_pairs_days=new_pairs_days,
|
||||
candle_type=candle_type_f,
|
||||
erase=erase,
|
||||
prepend=prepend,
|
||||
)
|
||||
progress.update(
|
||||
timeframe_task, advance=1, description=f"Timeframe {candle_type_f}, {tf}"
|
||||
)
|
||||
|
||||
progress.update(pair_task, advance=1)
|
||||
progress.update(timeframe_task, description="Timeframe")
|
||||
@@ -474,7 +489,7 @@ def _download_all_pairs_history_parallel(
|
||||
:return: Candle pairs with timeframes
|
||||
"""
|
||||
candles: dict[PairWithTimeframe, DataFrame] = {}
|
||||
since = 0
|
||||
since: int | None = None
|
||||
if timerange:
|
||||
if timerange.starttype == "date":
|
||||
since = timerange.startts * 1000
|
||||
@@ -482,10 +497,12 @@ def _download_all_pairs_history_parallel(
|
||||
candle_limit = exchange.ohlcv_candle_limit(timeframe, candle_type)
|
||||
one_call_min_time_dt = dt_ts(date_minus_candles(timeframe, candle_limit))
|
||||
# check if we can get all candles in one go, if so then we can download them in parallel
|
||||
if since > one_call_min_time_dt:
|
||||
if since is None or since > one_call_min_time_dt:
|
||||
logger.info(
|
||||
f"Downloading parallel candles for {timeframe} for all pairs "
|
||||
f"since {format_ms_time(since)}"
|
||||
f"Downloading parallel candles for {timeframe} for all pairs"
|
||||
f" since {format_ms_time(since)}"
|
||||
if since
|
||||
else "."
|
||||
)
|
||||
needed_pairs: ListPairsWithTimeframes = [
|
||||
(p, timeframe, candle_type) for p in [p for p in pairs]
|
||||
@@ -693,6 +710,9 @@ def download_data(
|
||||
"""
|
||||
Download data function. Used from both cli and API.
|
||||
"""
|
||||
exchange.validate_trading_mode_and_margin_mode(
|
||||
config.get("trading_mode", TradingMode.SPOT), None, allow_none_margin_mode=True
|
||||
)
|
||||
timerange = TimeRange()
|
||||
if "days" in config and config["days"] is not None:
|
||||
time_since = (datetime.now() - timedelta(days=config["days"])).strftime("%Y%m%d")
|
||||
@@ -793,6 +813,7 @@ def download_data(
|
||||
trading_mode=config.get("trading_mode", "spot"),
|
||||
prepend=config.get("prepend_data", False),
|
||||
progress_tracker=progress_tracker,
|
||||
candle_types=config.get("candle_types"),
|
||||
no_parallel_download=config.get("no_parallel_download", False),
|
||||
)
|
||||
finally:
|
||||
|
||||
@@ -74,9 +74,10 @@ def combined_dataframes_with_rel_mean(
|
||||
df_comb = combine_dataframes_by_column(data, column)
|
||||
# Trim dataframes to the given timeframe
|
||||
df_comb = df_comb.iloc[(df_comb.index >= fromdt) & (df_comb.index < todt)]
|
||||
rel_mean = df_comb.pct_change().mean(axis=1).fillna(0).cumsum()
|
||||
df_comb["count"] = df_comb.count(axis=1)
|
||||
df_comb["mean"] = df_comb.mean(axis=1)
|
||||
df_comb["rel_mean"] = df_comb["mean"].pct_change().fillna(0).cumsum()
|
||||
df_comb["rel_mean"] = rel_mean
|
||||
return df_comb[["mean", "rel_mean", "count"]]
|
||||
|
||||
|
||||
@@ -143,6 +144,20 @@ def _calc_drawdown_series(
|
||||
max_drawdown_df["drawdown_relative"] = (
|
||||
max_drawdown_df["high_value"] - max_drawdown_df["cumulative"]
|
||||
) / max_drawdown_df["high_value"]
|
||||
|
||||
# Add zero row at start to account for edge-cases with no winning / losing trades - so high/low
|
||||
# will be 0.0 in such cases.
|
||||
zero_row = pd.DataFrame(
|
||||
{
|
||||
"cumulative": [0.0],
|
||||
"high_value": [0.0],
|
||||
"drawdown": [0.0],
|
||||
"drawdown_relative": [0.0],
|
||||
"date": [profit_results.loc[0, date_col]],
|
||||
}
|
||||
)
|
||||
|
||||
max_drawdown_df = pd.concat([zero_row, max_drawdown_df], ignore_index=True)
|
||||
return max_drawdown_df
|
||||
|
||||
|
||||
@@ -215,6 +230,7 @@ def calculate_max_drawdown(
|
||||
max_drawdown_df = _calc_drawdown_series(
|
||||
profit_results, date_col=date_col, value_col=value_col, starting_balance=starting_balance
|
||||
)
|
||||
# max_drawdown_df has an extra zero row at the start
|
||||
|
||||
# Calculate maximum drawdown
|
||||
idxmin = (
|
||||
@@ -223,15 +239,15 @@ def calculate_max_drawdown(
|
||||
else max_drawdown_df["drawdown"].idxmin()
|
||||
)
|
||||
high_idx = max_drawdown_df.iloc[: idxmin + 1]["high_value"].idxmax()
|
||||
high_date = profit_results.loc[high_idx, date_col]
|
||||
low_date = profit_results.loc[idxmin, date_col]
|
||||
high_val = max_drawdown_df.loc[high_idx, "cumulative"]
|
||||
low_val = max_drawdown_df.loc[idxmin, "cumulative"]
|
||||
max_drawdown_rel = max_drawdown_df.loc[idxmin, "drawdown_relative"]
|
||||
high_date = profit_results.at[max(high_idx - 1, 0), date_col]
|
||||
low_date = profit_results.at[max(idxmin - 1, 0), date_col]
|
||||
high_val = max_drawdown_df.at[high_idx, "cumulative"]
|
||||
low_val = max_drawdown_df.at[idxmin, "cumulative"]
|
||||
max_drawdown_rel = max_drawdown_df.at[idxmin, "drawdown_relative"]
|
||||
|
||||
# Calculate current drawdown
|
||||
current_high_idx = max_drawdown_df["high_value"].iloc[:-1].idxmax()
|
||||
current_high_date = profit_results.loc[current_high_idx, date_col]
|
||||
current_high_date = profit_results.at[max(current_high_idx - 1, 0), date_col]
|
||||
current_high_value = max_drawdown_df.iloc[-1]["high_value"]
|
||||
current_cumulative = max_drawdown_df.iloc[-1]["cumulative"]
|
||||
current_drawdown_abs = current_high_value - current_cumulative
|
||||
|
||||
@@ -4,7 +4,7 @@ from freqtrade.exchange.common import MAP_EXCHANGE_CHILDCLASS
|
||||
from freqtrade.exchange.exchange import Exchange
|
||||
|
||||
# isort: on
|
||||
from freqtrade.exchange.binance import Binance
|
||||
from freqtrade.exchange.binance import Binance, Binanceus, Binanceusdm
|
||||
from freqtrade.exchange.bingx import Bingx
|
||||
from freqtrade.exchange.bitget import Bitget
|
||||
from freqtrade.exchange.bitmart import Bitmart
|
||||
|
||||
@@ -5,7 +5,6 @@ from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
import ccxt
|
||||
from cachetools import TTLCache
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
|
||||
@@ -21,6 +20,7 @@ from freqtrade.exchange.common import retrier
|
||||
from freqtrade.exchange.exchange_types import FtHas, Tickers
|
||||
from freqtrade.exchange.exchange_utils_timeframe import timeframe_to_msecs
|
||||
from freqtrade.misc import deep_merge_dicts, json_load
|
||||
from freqtrade.util import FtTTLCache
|
||||
from freqtrade.util.datetime_helpers import dt_from_ts, dt_ts
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ class Binance(Exchange):
|
||||
"funding_fee_candle_limit": 1000,
|
||||
"stoploss_order_types": {"limit": "stop", "market": "stop_market"},
|
||||
"stoploss_blocks_assets": False, # Stoploss orders do not block assets
|
||||
"stoploss_query_requires_stop_flag": True,
|
||||
"stoploss_algo_order_info_id": "actualOrderId",
|
||||
"tickers_have_price": False,
|
||||
"floor_leverage": True,
|
||||
"fetch_orders_limit_minutes": 7 * 1440, # "fetch_orders" is limited to 7 days
|
||||
@@ -76,7 +78,7 @@ class Binance(Exchange):
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self._spot_delist_schedule_cache: TTLCache = TTLCache(maxsize=100, ttl=300)
|
||||
self._spot_delist_schedule_cache: FtTTLCache = FtTTLCache(maxsize=100, ttl=300)
|
||||
|
||||
def get_proxy_coin(self) -> str:
|
||||
"""
|
||||
@@ -544,3 +546,26 @@ class Binance(Exchange):
|
||||
cache[ft_symbol] = delist_dt
|
||||
|
||||
return cache.get(pair, None)
|
||||
|
||||
|
||||
class Binanceusdm(Binance):
|
||||
"""Binacne USDM Exchange
|
||||
Same as Binance - only futures trading is supported (via ccxt).
|
||||
|
||||
Not actually necessary, binance should be preferred.
|
||||
"""
|
||||
|
||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||
(TradingMode.FUTURES, MarginMode.CROSS),
|
||||
(TradingMode.FUTURES, MarginMode.ISOLATED),
|
||||
]
|
||||
|
||||
|
||||
class Binanceus(Binance):
|
||||
"""Binance US exchange class.
|
||||
Minimal adjustment to disable futures trading for the US subsidiary of Binance
|
||||
"""
|
||||
|
||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||
(TradingMode.SPOT, MarginMode.NONE),
|
||||
]
|
||||
|
||||
+11913
-11043
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import ccxt
|
||||
|
||||
from freqtrade.constants import BuySell
|
||||
from freqtrade.enums import CandleType, MarginMode, TradingMode
|
||||
from freqtrade.enums import OPTIMIZE_MODES, CandleType, MarginMode, TradingMode
|
||||
from freqtrade.exceptions import (
|
||||
DDosProtection,
|
||||
OperationalException,
|
||||
@@ -14,7 +14,7 @@ from freqtrade.exceptions import (
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.exchange.common import API_RETRY_COUNT, retrier
|
||||
from freqtrade.exchange.exchange_types import CcxtOrder, FtHas
|
||||
from freqtrade.util.datetime_helpers import dt_now, dt_ts
|
||||
from freqtrade.util import dt_from_ts, dt_now, dt_ts
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -31,12 +31,13 @@ class Bitget(Exchange):
|
||||
"stop_price_prop": "stopPrice",
|
||||
"stoploss_blocks_assets": False, # Stoploss orders do not block assets
|
||||
"stoploss_order_types": {"limit": "limit", "market": "market"},
|
||||
"stoploss_query_requires_stop_flag": True,
|
||||
"ohlcv_candle_limit": 200, # 200 for historical candles, 1000 for recent ones.
|
||||
"order_time_in_force": ["GTC", "FOK", "IOC", "PO"],
|
||||
}
|
||||
_ft_has_futures: FtHas = {
|
||||
"mark_ohlcv_timeframe": "4h",
|
||||
"funding_fee_candle_limit": 100,
|
||||
"has_delisting": True,
|
||||
}
|
||||
|
||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||
@@ -128,9 +129,6 @@ class Bitget(Exchange):
|
||||
|
||||
return self._fetch_stop_order_fallback(order_id, pair)
|
||||
|
||||
def cancel_stoploss_order(self, order_id: str, pair: str, params: dict | None = None) -> dict:
|
||||
return self.cancel_order(order_id=order_id, pair=pair, params={"stop": True})
|
||||
|
||||
@retrier
|
||||
def additional_exchange_init(self) -> None:
|
||||
"""
|
||||
@@ -236,3 +234,35 @@ class Bitget(Exchange):
|
||||
raise OperationalException(
|
||||
"Freqtrade currently only supports isolated futures for bitget"
|
||||
)
|
||||
|
||||
def check_delisting_time(self, pair: str) -> datetime | None:
|
||||
"""
|
||||
Check if the pair gonna be delisted.
|
||||
By default, it returns None.
|
||||
:param pair: Market symbol
|
||||
:return: Datetime if the pair gonna be delisted, None otherwise
|
||||
"""
|
||||
if self._config["runmode"] in OPTIMIZE_MODES:
|
||||
return None
|
||||
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
return self._check_delisting_futures(pair)
|
||||
return None
|
||||
|
||||
def _check_delisting_futures(self, pair: str) -> datetime | None:
|
||||
delivery_time = self.markets.get(pair, {}).get("info", {}).get("limitOpenTime", None)
|
||||
if delivery_time:
|
||||
if isinstance(delivery_time, str) and (delivery_time != ""):
|
||||
delivery_time = int(delivery_time)
|
||||
|
||||
if not isinstance(delivery_time, int) or delivery_time <= 0:
|
||||
return None
|
||||
|
||||
max_delivery = dt_ts() + (
|
||||
14 * 24 * 60 * 60 * 1000
|
||||
) # Assume exchange don't announce delisting more than 14 days in advance
|
||||
|
||||
if delivery_time < max_delivery:
|
||||
return dt_from_ts(delivery_time)
|
||||
|
||||
return None
|
||||
|
||||
@@ -4,12 +4,13 @@ from datetime import datetime, timedelta
|
||||
import ccxt
|
||||
|
||||
from freqtrade.constants import BuySell
|
||||
from freqtrade.enums import MarginMode, PriceType, TradingMode
|
||||
from freqtrade.enums import OPTIMIZE_MODES, MarginMode, PriceType, TradingMode
|
||||
from freqtrade.exceptions import DDosProtection, ExchangeError, OperationalException, TemporaryError
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.exchange.common import retrier
|
||||
from freqtrade.exchange.exchange_types import CcxtOrder, FtHas
|
||||
from freqtrade.misc import deep_merge_dicts
|
||||
from freqtrade.util import dt_from_ts, dt_ts
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -37,8 +38,6 @@ class Bybit(Exchange):
|
||||
}
|
||||
_ft_has_futures: FtHas = {
|
||||
"ohlcv_has_history": True,
|
||||
"mark_ohlcv_timeframe": "4h",
|
||||
"funding_fee_timeframe": "8h",
|
||||
"funding_fee_candle_limit": 200,
|
||||
"stoploss_on_exchange": True,
|
||||
"stoploss_order_types": {"limit": "limit", "market": "market"},
|
||||
@@ -54,6 +53,7 @@ class Bybit(Exchange):
|
||||
"exchange_has_overrides": {
|
||||
"fetchOrder": True,
|
||||
},
|
||||
"has_delisting": True,
|
||||
}
|
||||
|
||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||
@@ -294,3 +294,35 @@ class Bybit(Exchange):
|
||||
|
||||
self.cache_leverage_tiers(tiers, self._config["stake_currency"])
|
||||
return tiers
|
||||
|
||||
def check_delisting_time(self, pair: str) -> datetime | None:
|
||||
"""
|
||||
Check if the pair gonna be delisted.
|
||||
By default, it returns None.
|
||||
:param pair: Market symbol
|
||||
:return: Datetime if the pair gonna be delisted, None otherwise
|
||||
"""
|
||||
if self._config["runmode"] in OPTIMIZE_MODES:
|
||||
return None
|
||||
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
return self._check_delisting_futures(pair)
|
||||
return None
|
||||
|
||||
def _check_delisting_futures(self, pair: str) -> datetime | None:
|
||||
delivery_time = self.markets.get(pair, {}).get("info", {}).get("deliveryTime", 0)
|
||||
if delivery_time:
|
||||
if isinstance(delivery_time, str) and (delivery_time != ""):
|
||||
delivery_time = int(delivery_time)
|
||||
|
||||
if not isinstance(delivery_time, int) or delivery_time <= 0:
|
||||
return None
|
||||
|
||||
max_delivery = dt_ts() + (
|
||||
14 * 24 * 60 * 60 * 1000
|
||||
) # Assume exchange don't announce delisting more than 14 days in advance
|
||||
|
||||
if delivery_time < max_delivery:
|
||||
return dt_from_ts(delivery_time)
|
||||
|
||||
return None
|
||||
|
||||
@@ -45,8 +45,6 @@ BAD_EXCHANGES = {
|
||||
}
|
||||
|
||||
MAP_EXCHANGE_CHILDCLASS = {
|
||||
"binanceus": "binance",
|
||||
"binanceusdm": "binance",
|
||||
"okex": "okx",
|
||||
"gateio": "gate",
|
||||
"huboi": "htx",
|
||||
@@ -54,6 +52,8 @@ MAP_EXCHANGE_CHILDCLASS = {
|
||||
|
||||
SUPPORTED_EXCHANGES = [
|
||||
"binance",
|
||||
"binanceus",
|
||||
"binanceusdm",
|
||||
"bingx",
|
||||
"bitmart",
|
||||
"bitget",
|
||||
@@ -97,6 +97,9 @@ EXCHANGE_HAS_OPTIONAL = [
|
||||
# 'fetchLeverageTiers', # Futures initialization
|
||||
# 'fetchMarketLeverageTiers', # Futures initialization
|
||||
# 'fetchOpenOrders', 'fetchClosedOrders', # 'fetchOrders', # Refinding balance...
|
||||
# "fetchPremiumIndexOHLCV", # Futures additional data
|
||||
# "fetchMarkOHLCV", # Futures additional data
|
||||
# "fetchIndexOHLCV", # Futures additional data
|
||||
# ccxt.pro
|
||||
"watchOHLCV",
|
||||
]
|
||||
|
||||
+192
-57
@@ -16,7 +16,6 @@ from typing import Any, Literal, TypeGuard, TypeVar
|
||||
|
||||
import ccxt
|
||||
import ccxt.pro as ccxt_pro
|
||||
from cachetools import TTLCache
|
||||
from ccxt import TICK_SIZE
|
||||
from dateutil import parser
|
||||
from pandas import DataFrame, concat
|
||||
@@ -105,11 +104,11 @@ from freqtrade.misc import (
|
||||
deep_merge_dicts,
|
||||
file_dump_json,
|
||||
file_load_json,
|
||||
safe_value_fallback,
|
||||
safe_value_fallback2,
|
||||
)
|
||||
from freqtrade.util import dt_from_ts, dt_now
|
||||
from freqtrade.util import FtTTLCache, PeriodicCache, dt_from_ts, dt_now
|
||||
from freqtrade.util.datetime_helpers import dt_humanize_delta, dt_ts, format_ms_time
|
||||
from freqtrade.util.periodic_cache import PeriodicCache
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -133,6 +132,7 @@ class Exchange:
|
||||
"stop_price_prop": "stopLossPrice", # Used for stoploss_on_exchange response parsing
|
||||
"stoploss_order_types": {},
|
||||
"stoploss_blocks_assets": True, # By default stoploss orders block assets
|
||||
"stoploss_query_requires_stop_flag": False, # Require "stop": True" to fetch stop orders
|
||||
"order_time_in_force": ["GTC"],
|
||||
"ohlcv_params": {},
|
||||
"ohlcv_has_history": True, # Some exchanges (Kraken) don't provide history via ohlcv
|
||||
@@ -154,8 +154,8 @@ class Exchange:
|
||||
"l2_limit_range_required": True, # Allow Empty L2 limit (kucoin)
|
||||
"l2_limit_upper": None, # Upper limit for L2 limit
|
||||
"mark_ohlcv_price": "mark",
|
||||
"mark_ohlcv_timeframe": "8h",
|
||||
"funding_fee_timeframe": "8h",
|
||||
"mark_ohlcv_timeframe": "1h",
|
||||
"funding_fee_timeframe": "1h",
|
||||
"ccxt_futures_name": "swap",
|
||||
"needs_trading_fees": False, # use fetch_trading_fees to cache fees
|
||||
"order_props_in_contracts": ["amount", "filled", "remaining"],
|
||||
@@ -230,13 +230,13 @@ class Exchange:
|
||||
|
||||
self._cache_lock = Lock()
|
||||
# Cache for 10 minutes ...
|
||||
self._fetch_tickers_cache: TTLCache = TTLCache(maxsize=4, ttl=60 * 10)
|
||||
self._fetch_tickers_cache: FtTTLCache = FtTTLCache(maxsize=4, ttl=60 * 10)
|
||||
# Cache values for 300 to avoid frequent polling of the exchange for prices
|
||||
# Caching only applies to RPC methods, so prices for open trades are still
|
||||
# refreshed once every iteration.
|
||||
# Shouldn't be too high either, as it'll freeze UI updates in case of open orders.
|
||||
self._exit_rate_cache: TTLCache = TTLCache(maxsize=100, ttl=300)
|
||||
self._entry_rate_cache: TTLCache = TTLCache(maxsize=100, ttl=300)
|
||||
self._exit_rate_cache: FtTTLCache = FtTTLCache(maxsize=100, ttl=300)
|
||||
self._entry_rate_cache: FtTTLCache = FtTTLCache(maxsize=100, ttl=300)
|
||||
|
||||
# Holds candles
|
||||
self._klines: dict[PairWithTimeframe, DataFrame] = {}
|
||||
@@ -430,7 +430,15 @@ class Exchange:
|
||||
|
||||
@property
|
||||
def timeframes(self) -> list[str]:
|
||||
return list((self._api.timeframes or {}).keys())
|
||||
market_type = (
|
||||
"spot"
|
||||
if self.trading_mode != TradingMode.FUTURES
|
||||
else self._ft_has["ccxt_futures_name"]
|
||||
)
|
||||
timeframes = self._api.options.get("timeframes", {}).get(market_type)
|
||||
if timeframes is None:
|
||||
timeframes = self._api.timeframes
|
||||
return list((timeframes or {}).keys())
|
||||
|
||||
@property
|
||||
def markets(self) -> dict[str, Any]:
|
||||
@@ -701,7 +709,7 @@ class Exchange:
|
||||
self._markets = self._api_async.markets
|
||||
self._api.set_markets_from_exchange(self._api_async)
|
||||
# Assign options array, as it contains some temporary information from the exchange.
|
||||
# TODO: investigate with ccxt if it's safe to remove `.options`
|
||||
# ccxt does not implicitly copy options over in set_markets_from_exchange
|
||||
self._api.options = self._api_async.options
|
||||
if self._exchange_ws:
|
||||
# Set markets to avoid reloading on websocket api
|
||||
@@ -871,19 +879,20 @@ class Exchange:
|
||||
# Only allow 5 calls per pair to somewhat limit the impact
|
||||
raise ConfigurationError(
|
||||
f"This strategy requires {startup_candles} candles to start, "
|
||||
"which is more than 5x "
|
||||
f"which is more than 5x ({candle_limit * 5 - 1} candles) "
|
||||
f"the amount of candles {self.name} provides for {timeframe}."
|
||||
)
|
||||
elif required_candle_call_count > 1:
|
||||
raise ConfigurationError(
|
||||
f"This strategy requires {startup_candles} candles to start, which is more than "
|
||||
f"This strategy requires {startup_candles} candles to start, "
|
||||
f"which is more than ({candle_limit - 1} candles) "
|
||||
f"the amount of candles {self.name} provides for {timeframe}."
|
||||
)
|
||||
if required_candle_call_count > 1:
|
||||
logger.warning(
|
||||
f"Using {required_candle_call_count} calls to get OHLCV. "
|
||||
f"This can result in slower operations for the bot. Please check "
|
||||
f"if you really need {startup_candles} candles for your strategy"
|
||||
f"if you really need {startup_candles} candles for your strategy."
|
||||
)
|
||||
return required_candle_call_count
|
||||
|
||||
@@ -891,6 +900,7 @@ class Exchange:
|
||||
self,
|
||||
trading_mode: TradingMode,
|
||||
margin_mode: MarginMode | None, # Only None when trading_mode = TradingMode.SPOT
|
||||
allow_none_margin_mode: bool = False,
|
||||
):
|
||||
"""
|
||||
Checks if freqtrade can perform trades using the configured
|
||||
@@ -898,7 +908,18 @@ class Exchange:
|
||||
Throws OperationalException:
|
||||
If the trading_mode/margin_mode type are not supported by freqtrade on this exchange
|
||||
"""
|
||||
if trading_mode != TradingMode.SPOT and (
|
||||
if trading_mode == TradingMode.SPOT:
|
||||
return
|
||||
if allow_none_margin_mode and margin_mode is None:
|
||||
# Verify trading mode independent of margin mode
|
||||
if not any(
|
||||
trading_mode == pair[0] for pair in self._supported_trading_mode_margin_pairs
|
||||
):
|
||||
raise ConfigurationError(
|
||||
f"Freqtrade does not support '{trading_mode}' on {self.name}."
|
||||
)
|
||||
|
||||
if not allow_none_margin_mode and (
|
||||
(trading_mode, margin_mode) not in self._supported_trading_mode_margin_pairs
|
||||
):
|
||||
mm_value = margin_mode and margin_mode.value
|
||||
@@ -1101,6 +1122,7 @@ class Exchange:
|
||||
leverage: float,
|
||||
params: dict | None = None,
|
||||
stop_loss: bool = False,
|
||||
stop_price: float | None = None,
|
||||
) -> CcxtOrder:
|
||||
now = dt_now()
|
||||
order_id = f"dry_run_{side}_{pair}_{now.timestamp()}"
|
||||
@@ -1127,7 +1149,7 @@ class Exchange:
|
||||
}
|
||||
if stop_loss:
|
||||
dry_order["info"] = {"stopPrice": dry_order["price"]}
|
||||
dry_order[self._ft_has["stop_price_prop"]] = dry_order["price"]
|
||||
dry_order[self._ft_has["stop_price_prop"]] = stop_price or dry_order["price"]
|
||||
# Workaround to avoid filling stoploss orders immediately
|
||||
dry_order["ft_order_type"] = "stoploss"
|
||||
orderbook: OrderBook | None = None
|
||||
@@ -1145,7 +1167,11 @@ class Exchange:
|
||||
|
||||
if dry_order["type"] == "market" and not dry_order.get("ft_order_type"):
|
||||
# Update market order pricing
|
||||
average = self.get_dry_market_fill_price(pair, side, amount, rate, orderbook)
|
||||
slippage = 0.05
|
||||
worst_rate = rate * ((1 + slippage) if side == "buy" else (1 - slippage))
|
||||
average = self.get_dry_market_fill_price(
|
||||
pair, side, amount, rate, worst_rate, orderbook
|
||||
)
|
||||
dry_order.update(
|
||||
{
|
||||
"average": average,
|
||||
@@ -1185,7 +1211,13 @@ class Exchange:
|
||||
return dry_order
|
||||
|
||||
def get_dry_market_fill_price(
|
||||
self, pair: str, side: str, amount: float, rate: float, orderbook: OrderBook | None
|
||||
self,
|
||||
pair: str,
|
||||
side: str,
|
||||
amount: float,
|
||||
rate: float,
|
||||
worst_rate: float,
|
||||
orderbook: OrderBook | None,
|
||||
) -> float:
|
||||
"""
|
||||
Get the market order fill price based on orderbook interpolation
|
||||
@@ -1194,8 +1226,6 @@ class Exchange:
|
||||
if not orderbook:
|
||||
orderbook = self.fetch_l2_order_book(pair, 20)
|
||||
ob_type: OBLiteral = "asks" if side == "buy" else "bids"
|
||||
slippage = 0.05
|
||||
max_slippage_val = rate * ((1 + slippage) if side == "buy" else (1 - slippage))
|
||||
|
||||
remaining_amount = amount
|
||||
filled_value = 0.0
|
||||
@@ -1219,11 +1249,10 @@ class Exchange:
|
||||
forecast_avg_filled_price = max(filled_value, 0) / amount
|
||||
# Limit max. slippage to specified value
|
||||
if side == "buy":
|
||||
forecast_avg_filled_price = min(forecast_avg_filled_price, max_slippage_val)
|
||||
forecast_avg_filled_price = min(forecast_avg_filled_price, worst_rate)
|
||||
|
||||
else:
|
||||
forecast_avg_filled_price = max(forecast_avg_filled_price, max_slippage_val)
|
||||
|
||||
forecast_avg_filled_price = max(forecast_avg_filled_price, worst_rate)
|
||||
return self.price_to_precision(pair, forecast_avg_filled_price)
|
||||
|
||||
return rate
|
||||
@@ -1235,13 +1264,15 @@ class Exchange:
|
||||
limit: float,
|
||||
orderbook: OrderBook | None = None,
|
||||
offset: float = 0.0,
|
||||
is_stop: bool = False,
|
||||
) -> bool:
|
||||
if not self.exchange_has("fetchL2OrderBook"):
|
||||
return True
|
||||
# True unless checking a stoploss order
|
||||
return not is_stop
|
||||
if not orderbook:
|
||||
orderbook = self.fetch_l2_order_book(pair, 1)
|
||||
try:
|
||||
if side == "buy":
|
||||
if (side == "buy" and not is_stop) or (side == "sell" and is_stop):
|
||||
price = orderbook["asks"][0][0]
|
||||
if limit * (1 - offset) >= price:
|
||||
return True
|
||||
@@ -1260,6 +1291,38 @@ class Exchange:
|
||||
"""
|
||||
Check dry-run limit order fill and update fee (if it filled).
|
||||
"""
|
||||
if order["status"] != "closed" and order.get("ft_order_type") == "stoploss":
|
||||
pair = order["symbol"]
|
||||
if not orderbook and self.exchange_has("fetchL2OrderBook"):
|
||||
orderbook = self.fetch_l2_order_book(pair, 20)
|
||||
price = safe_value_fallback(order, self._ft_has["stop_price_prop"], "price")
|
||||
crossed = self._dry_is_price_crossed(
|
||||
pair, order["side"], price, orderbook, is_stop=True
|
||||
)
|
||||
if crossed:
|
||||
average = self.get_dry_market_fill_price(
|
||||
pair,
|
||||
order["side"],
|
||||
order["amount"],
|
||||
price,
|
||||
worst_rate=order["price"],
|
||||
orderbook=orderbook,
|
||||
)
|
||||
order.update(
|
||||
{
|
||||
"status": "closed",
|
||||
"filled": order["amount"],
|
||||
"remaining": 0,
|
||||
"average": average,
|
||||
"cost": order["amount"] * average,
|
||||
}
|
||||
)
|
||||
self.add_dry_order_fee(
|
||||
pair,
|
||||
order,
|
||||
"taker" if immediate else "maker",
|
||||
)
|
||||
return order
|
||||
if (
|
||||
order["status"] != "closed"
|
||||
and order["type"] in ["limit"]
|
||||
@@ -1283,7 +1346,7 @@ class Exchange:
|
||||
|
||||
return order
|
||||
|
||||
def fetch_dry_run_order(self, order_id) -> CcxtOrder:
|
||||
def fetch_dry_run_order(self, order_id: str) -> CcxtOrder:
|
||||
"""
|
||||
Return dry-run order
|
||||
Only call if running in dry-run mode.
|
||||
@@ -1295,11 +1358,12 @@ class Exchange:
|
||||
except KeyError as e:
|
||||
from freqtrade.persistence import Order
|
||||
|
||||
order = Order.order_by_id(order_id)
|
||||
if order:
|
||||
ccxt_order = order.to_ccxt_object(self._ft_has["stop_price_prop"])
|
||||
self._dry_run_open_orders[order_id] = ccxt_order
|
||||
return ccxt_order
|
||||
order_obj = Order.order_by_id(order_id)
|
||||
if order_obj:
|
||||
order = order_obj.to_ccxt_object(self._ft_has["stop_price_prop"])
|
||||
order = self.check_dry_limit_order_filled(order)
|
||||
self._dry_run_open_orders[order_id] = order
|
||||
return order
|
||||
# Gracefully handle errors with dry-run orders.
|
||||
raise InvalidOrderException(
|
||||
f"Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}"
|
||||
@@ -1343,8 +1407,9 @@ class Exchange:
|
||||
amount: float,
|
||||
rate: float,
|
||||
leverage: float,
|
||||
reduceOnly: bool = False,
|
||||
time_in_force: str = "GTC",
|
||||
reduceOnly: bool = False,
|
||||
initial_order: bool = True,
|
||||
) -> CcxtOrder:
|
||||
if self._config["dry_run"]:
|
||||
dry_order = self.create_dry_run_order(
|
||||
@@ -1361,7 +1426,7 @@ class Exchange:
|
||||
rate_for_order = self.price_to_precision(pair, rate) if needs_price else None
|
||||
|
||||
if not reduceOnly:
|
||||
self._lev_prep(pair, leverage, side)
|
||||
self._lev_prep(pair, leverage, side, accept_fail=not initial_order)
|
||||
|
||||
order = self._api.create_order(
|
||||
pair,
|
||||
@@ -1498,8 +1563,9 @@ class Exchange:
|
||||
ordertype,
|
||||
side,
|
||||
amount,
|
||||
stop_price_norm,
|
||||
limit_rate or stop_price_norm,
|
||||
stop_loss=True,
|
||||
stop_price=stop_price_norm,
|
||||
leverage=leverage,
|
||||
)
|
||||
return dry_order
|
||||
@@ -1623,7 +1689,24 @@ class Exchange:
|
||||
def fetch_stoploss_order(
|
||||
self, order_id: str, pair: str, params: dict | None = None
|
||||
) -> CcxtOrder:
|
||||
return self.fetch_order(order_id, pair, params)
|
||||
if self.get_option("stoploss_query_requires_stop_flag"):
|
||||
params = params or {}
|
||||
params["stop"] = True
|
||||
order = self.fetch_order(order_id, pair, params)
|
||||
val = self.get_option("stoploss_algo_order_info_id")
|
||||
if val and order.get("status", "open") == "closed":
|
||||
if new_orderid := order.get("info", {}).get(val):
|
||||
# Fetch real order, which was placed by the algo order.
|
||||
actual_order = self.fetch_order(order_id=new_orderid, pair=pair, params=None)
|
||||
actual_order["id_stop"] = actual_order["id"]
|
||||
actual_order["id"] = order_id
|
||||
actual_order["type"] = "stoploss"
|
||||
actual_order["stopPrice"] = order.get("stopPrice")
|
||||
actual_order["status_stop"] = "triggered"
|
||||
|
||||
return actual_order
|
||||
|
||||
return order
|
||||
|
||||
def fetch_order_or_stoploss_order(
|
||||
self, order_id: str, pair: str, stoploss_order: bool = False
|
||||
@@ -1677,6 +1760,9 @@ class Exchange:
|
||||
raise OperationalException(e) from e
|
||||
|
||||
def cancel_stoploss_order(self, order_id: str, pair: str, params: dict | None = None) -> dict:
|
||||
if self.get_option("stoploss_query_requires_stop_flag"):
|
||||
params = params or {}
|
||||
params["stop"] = True
|
||||
return self.cancel_order(order_id, pair, params)
|
||||
|
||||
def is_cancel_order_result_suitable(self, corder) -> TypeGuard[CcxtOrder]:
|
||||
@@ -1750,7 +1836,7 @@ class Exchange:
|
||||
balances.pop("total", None)
|
||||
balances.pop("used", None)
|
||||
|
||||
self._log_exchange_response("fetch_balances", balances)
|
||||
self._log_exchange_response("fetch_balance", balances)
|
||||
return balances
|
||||
except ccxt.DDoSProtection as e:
|
||||
raise DDosProtection(e) from e
|
||||
@@ -1771,9 +1857,9 @@ class Exchange:
|
||||
if self._config["dry_run"] or self.trading_mode != TradingMode.FUTURES:
|
||||
return []
|
||||
try:
|
||||
symbols = []
|
||||
symbols = None
|
||||
if pair:
|
||||
symbols.append(pair)
|
||||
symbols = [pair]
|
||||
positions: list[CcxtPosition] = self._api.fetch_positions(symbols)
|
||||
self._log_exchange_response("fetch_positions", positions)
|
||||
return positions
|
||||
@@ -2143,7 +2229,9 @@ class Exchange:
|
||||
name = side.capitalize()
|
||||
strat_name = "entry_pricing" if side == "entry" else "exit_pricing"
|
||||
|
||||
cache_rate: TTLCache = self._entry_rate_cache if side == "entry" else self._exit_rate_cache
|
||||
cache_rate: FtTTLCache = (
|
||||
self._entry_rate_cache if side == "entry" else self._exit_rate_cache
|
||||
)
|
||||
if not refresh:
|
||||
with self._cache_lock:
|
||||
rate = cache_rate.get(pair)
|
||||
@@ -2625,24 +2713,25 @@ class Exchange:
|
||||
input_coroutines: list[Coroutine[Any, Any, OHLCVResponse]] = []
|
||||
cached_pairs = []
|
||||
for pair, timeframe, candle_type in set(pair_list):
|
||||
invalid_funding = (
|
||||
candle_type == CandleType.FUNDING_RATE
|
||||
and timeframe != self.get_option("funding_fee_timeframe")
|
||||
)
|
||||
if candle_type == CandleType.FUNDING_RATE and timeframe != (
|
||||
ff_tf := self.get_option("funding_fee_timeframe")
|
||||
):
|
||||
# TODO: does this message make sense? would docs be better?
|
||||
# if any, this should be cached to avoid log spam!
|
||||
logger.warning(
|
||||
f"Wrong funding rate timeframe {timeframe} for pair {pair}, "
|
||||
f"downloading {ff_tf} instead."
|
||||
)
|
||||
timeframe = ff_tf
|
||||
invalid_timeframe = timeframe not in self.timeframes and candle_type in (
|
||||
CandleType.SPOT,
|
||||
CandleType.FUTURES,
|
||||
)
|
||||
if invalid_timeframe or invalid_funding:
|
||||
timeframes_ = (
|
||||
", ".join(self.timeframes)
|
||||
if candle_type != CandleType.FUNDING_RATE
|
||||
else self.get_option("funding_fee_timeframe")
|
||||
)
|
||||
if invalid_timeframe:
|
||||
logger.warning(
|
||||
f"Cannot download ({pair}, {timeframe}, {candle_type}) combination as this "
|
||||
f"timeframe is not available on {self.name}. Available timeframes are "
|
||||
f"{timeframes_}."
|
||||
f"{', '.join(self.timeframes)}."
|
||||
)
|
||||
continue
|
||||
|
||||
@@ -2679,7 +2768,11 @@ class Exchange:
|
||||
has_cache = cache and (pair, timeframe, c_type) in self._klines
|
||||
# in case of existing cache, fill_missing happens after concatenation
|
||||
ohlcv_df = ohlcv_to_dataframe(
|
||||
ticks, timeframe, pair=pair, fill_missing=not has_cache, drop_incomplete=drop_incomplete
|
||||
ticks,
|
||||
timeframe,
|
||||
pair=pair,
|
||||
fill_missing=not has_cache and c_type != CandleType.FUNDING_RATE,
|
||||
drop_incomplete=drop_incomplete,
|
||||
)
|
||||
# keeping parsed dataframe in cache
|
||||
if cache:
|
||||
@@ -2690,7 +2783,7 @@ class Exchange:
|
||||
concat([old, ohlcv_df], axis=0),
|
||||
timeframe,
|
||||
pair,
|
||||
fill_missing=True,
|
||||
fill_missing=c_type != CandleType.FUNDING_RATE,
|
||||
drop_incomplete=False,
|
||||
)
|
||||
candle_limit = self.ohlcv_candle_limit(timeframe, self._config["candle_type_def"])
|
||||
@@ -2825,9 +2918,10 @@ class Exchange:
|
||||
timeframe, candle_type=candle_type, since_ms=since_ms
|
||||
)
|
||||
|
||||
if candle_type and candle_type not in (CandleType.SPOT, CandleType.FUTURES):
|
||||
params.update({"price": candle_type.value})
|
||||
if candle_type != CandleType.FUNDING_RATE:
|
||||
if candle_type and candle_type not in (CandleType.SPOT, CandleType.FUTURES):
|
||||
self.verify_candle_type_support(candle_type)
|
||||
params.update({"price": str(candle_type)})
|
||||
data = await self._api_async.fetch_ohlcv(
|
||||
pair, timeframe=timeframe, since=since_ms, limit=candle_limit, params=params
|
||||
)
|
||||
@@ -2892,6 +2986,38 @@ class Exchange:
|
||||
data = [[x["timestamp"], x["fundingRate"], 0, 0, 0, 0] for x in data]
|
||||
return data
|
||||
|
||||
def check_candle_type_support(self, candle_type: CandleType) -> bool:
|
||||
"""
|
||||
Check that the exchange supports the given candle type.
|
||||
:param candle_type: CandleType to verify
|
||||
:return: True if supported, False otherwise
|
||||
"""
|
||||
if candle_type == CandleType.FUNDING_RATE:
|
||||
if not self.exchange_has("fetchFundingRateHistory"):
|
||||
return False
|
||||
elif candle_type not in (CandleType.SPOT, CandleType.FUTURES):
|
||||
mapping = {
|
||||
CandleType.MARK: "fetchMarkOHLCV",
|
||||
CandleType.INDEX: "fetchIndexOHLCV",
|
||||
CandleType.PREMIUMINDEX: "fetchPremiumIndexOHLCV",
|
||||
CandleType.FUNDING_RATE: "fetchFundingRateHistory",
|
||||
}
|
||||
_method = mapping.get(candle_type, "fetchOHLCV")
|
||||
if not self.exchange_has(_method):
|
||||
return False
|
||||
return True
|
||||
|
||||
def verify_candle_type_support(self, candle_type: CandleType) -> None:
|
||||
"""
|
||||
Verify that the exchange supports the given candle type.
|
||||
:param candle_type: CandleType to verify
|
||||
:raises OperationalException: if the candle type is not supported
|
||||
"""
|
||||
if not self.check_candle_type_support(candle_type):
|
||||
raise OperationalException(
|
||||
f"Exchange {self._api.name} does not support fetching {candle_type} candles."
|
||||
)
|
||||
|
||||
# fetch Trade data stuff
|
||||
|
||||
def needed_candle_for_trades_ms(self, timeframe: str, candle_type: CandleType) -> int:
|
||||
@@ -3719,10 +3845,11 @@ class Exchange:
|
||||
:param mark_rates: Dataframe containing Mark rates (Type mark_ohlcv_price)
|
||||
:param futures_funding_rate: Fake funding rate to use if funding_rates are not available
|
||||
"""
|
||||
relevant_cols = ["date", "open_mark", "open_fund"]
|
||||
if futures_funding_rate is None:
|
||||
return mark_rates.merge(
|
||||
funding_rates, on="date", how="inner", suffixes=["_mark", "_fund"]
|
||||
)
|
||||
)[relevant_cols]
|
||||
else:
|
||||
if len(funding_rates) == 0:
|
||||
# No funding rate candles - full fillup with fallback variable
|
||||
@@ -3735,15 +3862,23 @@ class Exchange:
|
||||
"low": "low_mark",
|
||||
"volume": "volume_mark",
|
||||
}
|
||||
)
|
||||
)[relevant_cols]
|
||||
|
||||
else:
|
||||
# Fill up missing funding_rate candles with fallback value
|
||||
combined = mark_rates.merge(
|
||||
funding_rates, on="date", how="left", suffixes=["_mark", "_fund"]
|
||||
)
|
||||
combined["open_fund"] = combined["open_fund"].fillna(futures_funding_rate)
|
||||
return combined
|
||||
# Fill only leading missing funding rates so gaps stay untouched
|
||||
first_valid_idx = combined["open_fund"].first_valid_index()
|
||||
if first_valid_idx is None:
|
||||
combined["open_fund"] = futures_funding_rate
|
||||
else:
|
||||
is_leading_na = (combined.index <= first_valid_idx) & combined[
|
||||
"open_fund"
|
||||
].isna()
|
||||
combined.loc[is_leading_na, "open_fund"] = futures_funding_rate
|
||||
return combined[relevant_cols].dropna()
|
||||
|
||||
def calculate_funding_fees(
|
||||
self,
|
||||
|
||||
@@ -19,6 +19,8 @@ class FtHas(TypedDict, total=False):
|
||||
stop_price_type_value_mapping: dict
|
||||
stoploss_order_types: dict[str, str]
|
||||
stoploss_blocks_assets: bool
|
||||
stoploss_query_requires_stop_flag: bool
|
||||
stoploss_algo_order_info_id: str
|
||||
# ohlcv
|
||||
ohlcv_params: dict
|
||||
ohlcv_candle_limit: int
|
||||
|
||||
@@ -30,6 +30,8 @@ class Gate(Exchange):
|
||||
"stoploss_order_types": {"limit": "limit"},
|
||||
"stop_price_param": "stopPrice",
|
||||
"stop_price_prop": "stopPrice",
|
||||
"stoploss_query_requires_stop_flag": True,
|
||||
"stoploss_algo_order_info_id": "fired_order_id",
|
||||
"l2_limit_upper": 1000,
|
||||
"marketOrderRequiresPrice": True,
|
||||
"trades_has_history": False, # Endpoint would support this - but ccxt doesn't.
|
||||
@@ -42,6 +44,7 @@ class Gate(Exchange):
|
||||
"stop_price_type_field": "price_type",
|
||||
"l2_limit_upper": 300,
|
||||
"stoploss_blocks_assets": False,
|
||||
"stoploss_algo_order_info_id": "trade_id",
|
||||
"stop_price_type_value_mapping": {
|
||||
PriceType.LAST: 0,
|
||||
PriceType.MARK: 1,
|
||||
@@ -132,25 +135,3 @@ class Gate(Exchange):
|
||||
|
||||
def get_order_id_conditional(self, order: CcxtOrder) -> str:
|
||||
return safe_value_fallback2(order, order, "id_stop", "id")
|
||||
|
||||
def fetch_stoploss_order(
|
||||
self, order_id: str, pair: str, params: dict | None = None
|
||||
) -> CcxtOrder:
|
||||
order = self.fetch_order(order_id=order_id, pair=pair, params={"stop": True})
|
||||
if order.get("status", "open") == "closed":
|
||||
# Places a real order - which we need to fetch explicitly.
|
||||
val = "trade_id" if self.trading_mode == TradingMode.FUTURES else "fired_order_id"
|
||||
|
||||
if new_orderid := order.get("info", {}).get(val):
|
||||
order1 = self.fetch_order(order_id=new_orderid, pair=pair, params=params)
|
||||
order1["id_stop"] = order1["id"]
|
||||
order1["id"] = order_id
|
||||
order1["type"] = "stoploss"
|
||||
order1["stopPrice"] = order.get("stopPrice")
|
||||
order1["status_stop"] = "triggered"
|
||||
|
||||
return order1
|
||||
return order
|
||||
|
||||
def cancel_stoploss_order(self, order_id: str, pair: str, params: dict | None = None) -> dict:
|
||||
return self.cancel_order(order_id=order_id, pair=pair, params={"stop": True})
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import logging
|
||||
from copy import deepcopy
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from freqtrade.constants import BuySell
|
||||
from freqtrade.enums import MarginMode, TradingMode
|
||||
@@ -36,9 +37,9 @@ class Hyperliquid(Exchange):
|
||||
"stoploss_order_types": {"limit": "limit"},
|
||||
"stoploss_blocks_assets": False,
|
||||
"stop_price_prop": "stopPrice",
|
||||
"funding_fee_timeframe": "1h",
|
||||
"funding_fee_candle_limit": 500,
|
||||
"uses_leverage_tiers": False,
|
||||
"mark_ohlcv_price": "futures",
|
||||
}
|
||||
|
||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||
@@ -56,6 +57,13 @@ class Hyperliquid(Exchange):
|
||||
config.update(super()._ccxt_config)
|
||||
return config
|
||||
|
||||
def market_is_tradable(self, market: dict[str, Any]) -> bool:
|
||||
parent_check = super().market_is_tradable(market)
|
||||
|
||||
# Exclude hip3 markets for now - which have the format XYZ:GOOGL/USDT:USDT -
|
||||
# and XYZ:GOOGL as base
|
||||
return parent_check and ":" not in market["base"]
|
||||
|
||||
def get_max_leverage(self, pair: str, stake_amount: float | None) -> float:
|
||||
# There are no leverage tiers
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
|
||||
@@ -35,7 +35,6 @@ class Kraken(Exchange):
|
||||
"trades_pagination_arg": "since",
|
||||
"trades_pagination_overlap": False,
|
||||
"trades_has_history": True,
|
||||
"mark_ohlcv_timeframe": "4h",
|
||||
}
|
||||
|
||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||
@@ -82,7 +81,7 @@ class Kraken(Exchange):
|
||||
balances.pop("free", None)
|
||||
balances.pop("total", None)
|
||||
balances.pop("used", None)
|
||||
self._log_exchange_response("fetch_balances", balances)
|
||||
self._log_exchange_response("fetch_balance", balances)
|
||||
|
||||
# Consolidate balances
|
||||
balances = self.consolidate_balances(balances)
|
||||
@@ -104,7 +103,7 @@ class Kraken(Exchange):
|
||||
balances[bal]["used"] = sum(order[1] for order in order_list if order[0] == bal)
|
||||
balances[bal]["free"] = balances[bal]["total"] - balances[bal]["used"]
|
||||
|
||||
self._log_exchange_response("fetch_balances2", balances)
|
||||
self._log_exchange_response("fetch_balance2", balances)
|
||||
return balances
|
||||
except ccxt.DDoSProtection as e:
|
||||
raise DDosProtection(e) from e
|
||||
|
||||
@@ -44,8 +44,9 @@ class Kucoin(Exchange):
|
||||
amount: float,
|
||||
rate: float,
|
||||
leverage: float,
|
||||
reduceOnly: bool = False,
|
||||
time_in_force: str = "GTC",
|
||||
reduceOnly: bool = False,
|
||||
initial_order: bool = True,
|
||||
) -> CcxtOrder:
|
||||
res = super().create_order(
|
||||
pair=pair,
|
||||
@@ -56,6 +57,7 @@ class Kucoin(Exchange):
|
||||
leverage=leverage,
|
||||
reduceOnly=reduceOnly,
|
||||
time_in_force=time_in_force,
|
||||
initial_order=initial_order,
|
||||
)
|
||||
# Kucoin returns only the order-id.
|
||||
# ccxt returns status = 'closed' at the moment - which is information ccxt invented.
|
||||
|
||||
@@ -29,10 +29,9 @@ class Okx(Exchange):
|
||||
|
||||
_ft_has: FtHas = {
|
||||
"ohlcv_candle_limit": 100, # Warning, special case with data prior to X months
|
||||
"mark_ohlcv_timeframe": "4h",
|
||||
"funding_fee_timeframe": "8h",
|
||||
"stoploss_order_types": {"limit": "limit"},
|
||||
"stoploss_on_exchange": True,
|
||||
"stoploss_query_requires_stop_flag": True,
|
||||
"trades_has_history": False, # Endpoint doesn't have a "since" parameter
|
||||
"ws_enabled": True,
|
||||
}
|
||||
@@ -41,8 +40,8 @@ class Okx(Exchange):
|
||||
"stop_price_type_field": "slTriggerPxType",
|
||||
"stop_price_type_value_mapping": {
|
||||
PriceType.LAST: "last",
|
||||
PriceType.MARK: "index",
|
||||
PriceType.INDEX: "mark",
|
||||
PriceType.MARK: "mark",
|
||||
PriceType.INDEX: "index",
|
||||
},
|
||||
"stoploss_blocks_assets": False,
|
||||
"ws_enabled": True,
|
||||
@@ -265,16 +264,6 @@ class Okx(Exchange):
|
||||
return safe_value_fallback2(order, order, "id_stop", "id")
|
||||
return order["id"]
|
||||
|
||||
def cancel_stoploss_order(self, order_id: str, pair: str, params: dict | None = None) -> dict:
|
||||
params1 = {"stop": True}
|
||||
# 'ordType': 'conditional'
|
||||
#
|
||||
return self.cancel_order(
|
||||
order_id=order_id,
|
||||
pair=pair,
|
||||
params=params1,
|
||||
)
|
||||
|
||||
def _fetch_orders_emulate(self, pair: str, since_ms: int) -> list[CcxtOrder]:
|
||||
orders = []
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class BaseClassifierModel(IFreqaiModel):
|
||||
"""
|
||||
Base class for regression type models (e.g. Catboost, LightGBM, XGboost etc.).
|
||||
User *must* inherit from this class and set fit(). See example scripts
|
||||
such as prediction_models/CatboostClassifier.py for guidance.
|
||||
such as prediction_models/XGBoostClassifier.py for guidance.
|
||||
"""
|
||||
|
||||
def train(self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
|
||||
@@ -18,7 +18,7 @@ class BaseRegressionModel(IFreqaiModel):
|
||||
"""
|
||||
Base class for regression type models (e.g. Catboost, LightGBM, XGboost etc.).
|
||||
User *must* inherit from this class and set fit(). See example scripts
|
||||
such as prediction_models/CatboostRegressor.py for guidance.
|
||||
such as prediction_models/XGBoostRegressor.py for guidance.
|
||||
"""
|
||||
|
||||
def train(self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
|
||||
@@ -948,7 +948,7 @@ class IFreqaiModel(ABC):
|
||||
return dk
|
||||
|
||||
# Following methods which are overridden by user made prediction models.
|
||||
# See freqai/prediction_models/CatboostPredictionModel.py for an example.
|
||||
# See freqai/prediction_models/XGBoostRegressor.py for an example.
|
||||
|
||||
@abstractmethod
|
||||
def train(self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
@@ -964,7 +964,7 @@ class IFreqaiModel(ABC):
|
||||
def fit(self, data_dictionary: dict[str, Any], dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
"""
|
||||
Most regressors use the same function names and arguments e.g. user
|
||||
can drop in LGBMRegressor in place of CatBoostRegressor and all data
|
||||
can drop in LGBMRegressor in place of XGBoostRegressor and all data
|
||||
management will be properly handled by Freqai.
|
||||
:param data_dictionary: Dict = the dictionary constructed by DataHandler to hold
|
||||
all the training and test data/labels.
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from catboost import CatBoostClassifier, Pool
|
||||
|
||||
from freqtrade.freqai.base_models.BaseClassifierModel import BaseClassifierModel
|
||||
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CatboostClassifier(BaseClassifierModel):
|
||||
"""
|
||||
User created prediction model. The class inherits IFreqaiModel, which
|
||||
means it has full access to all Frequency AI functionality. Typically,
|
||||
users would use this to override the common `fit()`, `train()`, or
|
||||
`predict()` methods to add their custom data handling tools or change
|
||||
various aspects of the training that cannot be configured via the
|
||||
top level config.json file.
|
||||
"""
|
||||
|
||||
def fit(self, data_dictionary: dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
"""
|
||||
User sets up the training and test data to fit their desired model here
|
||||
:param data_dictionary: the dictionary holding all data for train, test,
|
||||
labels, weights
|
||||
:param dk: The datakitchen object for the current coin/model
|
||||
"""
|
||||
|
||||
train_data = Pool(
|
||||
data=data_dictionary["train_features"],
|
||||
label=data_dictionary["train_labels"],
|
||||
weight=data_dictionary["train_weights"],
|
||||
)
|
||||
if self.freqai_info.get("data_split_parameters", {}).get("test_size", 0.1) == 0:
|
||||
test_data = None
|
||||
else:
|
||||
test_data = Pool(
|
||||
data=data_dictionary["test_features"],
|
||||
label=data_dictionary["test_labels"],
|
||||
weight=data_dictionary["test_weights"],
|
||||
)
|
||||
|
||||
cbr = CatBoostClassifier(
|
||||
allow_writing_files=True,
|
||||
loss_function="MultiClass",
|
||||
train_dir=Path(dk.data_path),
|
||||
**self.model_training_parameters,
|
||||
)
|
||||
|
||||
init_model = self.get_init_model(dk.pair)
|
||||
|
||||
cbr.fit(
|
||||
X=train_data,
|
||||
eval_set=test_data,
|
||||
init_model=init_model,
|
||||
)
|
||||
|
||||
return cbr
|
||||
@@ -1,79 +0,0 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from catboost import CatBoostClassifier, Pool
|
||||
|
||||
from freqtrade.freqai.base_models.BaseClassifierModel import BaseClassifierModel
|
||||
from freqtrade.freqai.base_models.FreqaiMultiOutputClassifier import FreqaiMultiOutputClassifier
|
||||
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CatboostClassifierMultiTarget(BaseClassifierModel):
|
||||
"""
|
||||
User created prediction model. The class inherits IFreqaiModel, which
|
||||
means it has full access to all Frequency AI functionality. Typically,
|
||||
users would use this to override the common `fit()`, `train()`, or
|
||||
`predict()` methods to add their custom data handling tools or change
|
||||
various aspects of the training that cannot be configured via the
|
||||
top level config.json file.
|
||||
"""
|
||||
|
||||
def fit(self, data_dictionary: dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
"""
|
||||
User sets up the training and test data to fit their desired model here
|
||||
:param data_dictionary: the dictionary holding all data for train, test,
|
||||
labels, weights
|
||||
:param dk: The datakitchen object for the current coin/model
|
||||
"""
|
||||
|
||||
cbc = CatBoostClassifier(
|
||||
allow_writing_files=True,
|
||||
loss_function="MultiClass",
|
||||
train_dir=Path(dk.data_path),
|
||||
**self.model_training_parameters,
|
||||
)
|
||||
|
||||
X = data_dictionary["train_features"]
|
||||
y = data_dictionary["train_labels"]
|
||||
|
||||
sample_weight = data_dictionary["train_weights"]
|
||||
|
||||
eval_sets = [None] * y.shape[1]
|
||||
|
||||
if self.freqai_info.get("data_split_parameters", {}).get("test_size", 0.1) != 0:
|
||||
eval_sets = [None] * data_dictionary["test_labels"].shape[1]
|
||||
|
||||
for i in range(data_dictionary["test_labels"].shape[1]):
|
||||
eval_sets[i] = Pool(
|
||||
data=data_dictionary["test_features"],
|
||||
label=data_dictionary["test_labels"].iloc[:, i],
|
||||
weight=data_dictionary["test_weights"],
|
||||
)
|
||||
|
||||
init_model = self.get_init_model(dk.pair)
|
||||
|
||||
if init_model:
|
||||
init_models = init_model.estimators_
|
||||
else:
|
||||
init_models = [None] * y.shape[1]
|
||||
|
||||
fit_params = []
|
||||
for i in range(len(eval_sets)):
|
||||
fit_params.append(
|
||||
{
|
||||
"eval_set": eval_sets[i],
|
||||
"init_model": init_models[i],
|
||||
}
|
||||
)
|
||||
|
||||
model = FreqaiMultiOutputClassifier(estimator=cbc)
|
||||
thread_training = self.freqai_info.get("multitarget_parallel_training", False)
|
||||
if thread_training:
|
||||
model.n_jobs = y.shape[1]
|
||||
model.fit(X=X, y=y, sample_weight=sample_weight, fit_params=fit_params)
|
||||
|
||||
return model
|
||||
@@ -1,60 +0,0 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from catboost import CatBoostRegressor, Pool
|
||||
|
||||
from freqtrade.freqai.base_models.BaseRegressionModel import BaseRegressionModel
|
||||
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CatboostRegressor(BaseRegressionModel):
|
||||
"""
|
||||
User created prediction model. The class inherits IFreqaiModel, which
|
||||
means it has full access to all Frequency AI functionality. Typically,
|
||||
users would use this to override the common `fit()`, `train()`, or
|
||||
`predict()` methods to add their custom data handling tools or change
|
||||
various aspects of the training that cannot be configured via the
|
||||
top level config.json file.
|
||||
"""
|
||||
|
||||
def fit(self, data_dictionary: dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
"""
|
||||
User sets up the training and test data to fit their desired model here
|
||||
:param data_dictionary: the dictionary holding all data for train, test,
|
||||
labels, weights
|
||||
:param dk: The datakitchen object for the current coin/model
|
||||
"""
|
||||
|
||||
train_data = Pool(
|
||||
data=data_dictionary["train_features"],
|
||||
label=data_dictionary["train_labels"],
|
||||
weight=data_dictionary["train_weights"],
|
||||
)
|
||||
if self.freqai_info.get("data_split_parameters", {}).get("test_size", 0.1) == 0:
|
||||
test_data = None
|
||||
else:
|
||||
test_data = Pool(
|
||||
data=data_dictionary["test_features"],
|
||||
label=data_dictionary["test_labels"],
|
||||
weight=data_dictionary["test_weights"],
|
||||
)
|
||||
|
||||
init_model = self.get_init_model(dk.pair)
|
||||
|
||||
model = CatBoostRegressor(
|
||||
allow_writing_files=True,
|
||||
train_dir=Path(dk.data_path),
|
||||
**self.model_training_parameters,
|
||||
)
|
||||
|
||||
model.fit(
|
||||
X=train_data,
|
||||
eval_set=test_data,
|
||||
init_model=init_model,
|
||||
)
|
||||
|
||||
return model
|
||||
@@ -1,78 +0,0 @@
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from catboost import CatBoostRegressor, Pool
|
||||
|
||||
from freqtrade.freqai.base_models.BaseRegressionModel import BaseRegressionModel
|
||||
from freqtrade.freqai.base_models.FreqaiMultiOutputRegressor import FreqaiMultiOutputRegressor
|
||||
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CatboostRegressorMultiTarget(BaseRegressionModel):
|
||||
"""
|
||||
User created prediction model. The class inherits IFreqaiModel, which
|
||||
means it has full access to all Frequency AI functionality. Typically,
|
||||
users would use this to override the common `fit()`, `train()`, or
|
||||
`predict()` methods to add their custom data handling tools or change
|
||||
various aspects of the training that cannot be configured via the
|
||||
top level config.json file.
|
||||
"""
|
||||
|
||||
def fit(self, data_dictionary: dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
|
||||
"""
|
||||
User sets up the training and test data to fit their desired model here
|
||||
:param data_dictionary: the dictionary holding all data for train, test,
|
||||
labels, weights
|
||||
:param dk: The datakitchen object for the current coin/model
|
||||
"""
|
||||
|
||||
cbr = CatBoostRegressor(
|
||||
allow_writing_files=True,
|
||||
train_dir=Path(dk.data_path),
|
||||
**self.model_training_parameters,
|
||||
)
|
||||
|
||||
X = data_dictionary["train_features"]
|
||||
y = data_dictionary["train_labels"]
|
||||
|
||||
sample_weight = data_dictionary["train_weights"]
|
||||
|
||||
eval_sets = [None] * y.shape[1]
|
||||
|
||||
if self.freqai_info.get("data_split_parameters", {}).get("test_size", 0.1) != 0:
|
||||
eval_sets = [None] * data_dictionary["test_labels"].shape[1]
|
||||
|
||||
for i in range(data_dictionary["test_labels"].shape[1]):
|
||||
eval_sets[i] = Pool(
|
||||
data=data_dictionary["test_features"],
|
||||
label=data_dictionary["test_labels"].iloc[:, i],
|
||||
weight=data_dictionary["test_weights"],
|
||||
)
|
||||
|
||||
init_model = self.get_init_model(dk.pair)
|
||||
|
||||
if init_model:
|
||||
init_models = init_model.estimators_
|
||||
else:
|
||||
init_models = [None] * y.shape[1]
|
||||
|
||||
fit_params = []
|
||||
for i in range(len(eval_sets)):
|
||||
fit_params.append(
|
||||
{
|
||||
"eval_set": eval_sets[i],
|
||||
"init_model": init_models[i],
|
||||
}
|
||||
)
|
||||
|
||||
model = FreqaiMultiOutputRegressor(estimator=cbr)
|
||||
thread_training = self.freqai_info.get("multitarget_parallel_training", False)
|
||||
if thread_training:
|
||||
model.n_jobs = y.shape[1]
|
||||
model.fit(X=X, y=y, sample_weight=sample_weight, fit_params=fit_params)
|
||||
|
||||
return model
|
||||
@@ -97,7 +97,7 @@ def plot_feature_importance(
|
||||
"""
|
||||
Plot Best and worst features by importance for a single sub-train.
|
||||
:param model: Any = A model which was `fit` using a common library
|
||||
such as catboost or lightgbm
|
||||
such as XGBoost or lightgbm
|
||||
:param pair: str = pair e.g. BTC/USD
|
||||
:param dk: FreqaiDataKitchen = non-persistent data container for current coin/loop
|
||||
:param count_max: int = the amount of features to be loaded per column
|
||||
@@ -115,6 +115,8 @@ def plot_feature_importance(
|
||||
for label in models:
|
||||
mdl = models[label]
|
||||
if "catboost.core" in str(mdl.__class__):
|
||||
# CatBoost is no longer actively supported since 2025.12
|
||||
# However users can still use it in their custom models
|
||||
feature_importance = mdl.get_feature_importance()
|
||||
elif "lightgbm.sklearn" in str(mdl.__class__):
|
||||
feature_importance = mdl.feature_importances_
|
||||
|
||||
+44
-26
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Freqtrade is the main module of this bot. It contains the class Freqtrade()
|
||||
Freqtrade is the main module of this bot. It contains the FreqtradeBot class.
|
||||
"""
|
||||
|
||||
import logging
|
||||
@@ -63,7 +63,7 @@ from freqtrade.rpc.rpc_types import (
|
||||
from freqtrade.strategy.interface import IStrategy
|
||||
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
|
||||
from freqtrade.util import FtPrecise, MeasureTime, PeriodicCache, dt_from_ts, dt_now
|
||||
from freqtrade.util.migrations.binance_mig import migrate_binance_futures_names
|
||||
from freqtrade.util.migrations import migrate_live_content
|
||||
from freqtrade.wallets import Wallets
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
Called on startup and after reloading the bot - triggers notifications and
|
||||
performs startup tasks
|
||||
"""
|
||||
migrate_binance_futures_names(self.config)
|
||||
migrate_live_content(self.config, self.exchange)
|
||||
set_startup_time()
|
||||
|
||||
self.rpc.startup_messages(self.config, self.pairlists, self.protections)
|
||||
@@ -937,6 +937,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
reduceOnly=False,
|
||||
time_in_force=time_in_force,
|
||||
leverage=leverage,
|
||||
initial_order=trade is None,
|
||||
)
|
||||
order_obj = Order.parse_from_ccxt_object(order, pair, side, amount, enter_limit_requested)
|
||||
order_obj.ft_order_tag = enter_tag
|
||||
@@ -1063,7 +1064,16 @@ class FreqtradeBot(LoggingMixin):
|
||||
|
||||
return True
|
||||
|
||||
def cancel_stoploss_on_exchange(self, trade: Trade) -> Trade:
|
||||
def cancel_stoploss_on_exchange(self, trade: Trade, allow_nonblocking: bool = False) -> Trade:
|
||||
"""
|
||||
Cancels on exchange stoploss orders for the given trade.
|
||||
:param trade: Trade for which to cancel stoploss order
|
||||
:param allow_nonblocking: If True, will skip cancelling stoploss on exchange
|
||||
if the exchange supports blocking stoploss orders.
|
||||
"""
|
||||
if allow_nonblocking and not self.exchange.get_option("stoploss_blocks_assets", True):
|
||||
logger.info(f"Skipping cancelling stoploss on exchange for {trade}.")
|
||||
return trade
|
||||
# First cancelling stoploss on exchange ...
|
||||
for oslo in trade.open_sl_orders:
|
||||
try:
|
||||
@@ -2002,14 +2012,14 @@ class FreqtradeBot(LoggingMixin):
|
||||
|
||||
def _safe_exit_amount(self, trade: Trade, pair: str, amount: float) -> float:
|
||||
"""
|
||||
Get sellable amount.
|
||||
Get exitable amount.
|
||||
Should be trade.amount - but will fall back to the available amount if necessary.
|
||||
This should cover cases where get_real_amount() was not able to update the amount
|
||||
for whatever reason.
|
||||
:param trade: Trade we're working with
|
||||
:param pair: Pair we're trying to sell
|
||||
:param pair: Pair we're trying to exit
|
||||
:param amount: amount we expect to be available
|
||||
:return: amount to sell
|
||||
:return: amount to exit
|
||||
:raise: DependencyException: if available balance is not within 2% of the available amount.
|
||||
"""
|
||||
# Update wallets to ensure amounts tied up in a stoploss is now free!
|
||||
@@ -2045,11 +2055,12 @@ class FreqtradeBot(LoggingMixin):
|
||||
exit_tag: str | None = None,
|
||||
ordertype: str | None = None,
|
||||
sub_trade_amt: float | None = None,
|
||||
skip_custom_exit_price: bool = False,
|
||||
) -> bool:
|
||||
"""
|
||||
Executes a trade exit for the given trade and limit
|
||||
:param trade: Trade instance
|
||||
:param limit: limit rate for the sell order
|
||||
:param limit: limit rate for the exit order
|
||||
:param exit_check: CheckTuple with signal and reason
|
||||
:return: True if it succeeds False
|
||||
"""
|
||||
@@ -2071,29 +2082,33 @@ class FreqtradeBot(LoggingMixin):
|
||||
):
|
||||
exit_type = "stoploss"
|
||||
|
||||
order_type = (
|
||||
(ordertype or self.strategy.order_types[exit_type])
|
||||
if exit_check.exit_type != ExitType.EMERGENCY_EXIT
|
||||
else self.strategy.order_types.get("emergency_exit", "market")
|
||||
)
|
||||
|
||||
# set custom_exit_price if available
|
||||
proposed_limit_rate = limit
|
||||
custom_exit_price = limit
|
||||
|
||||
current_profit = trade.calc_profit_ratio(limit)
|
||||
custom_exit_price = strategy_safe_wrapper(
|
||||
self.strategy.custom_exit_price, default_retval=proposed_limit_rate
|
||||
)(
|
||||
pair=trade.pair,
|
||||
trade=trade,
|
||||
current_time=datetime.now(UTC),
|
||||
proposed_rate=proposed_limit_rate,
|
||||
current_profit=current_profit,
|
||||
exit_tag=exit_reason,
|
||||
)
|
||||
if order_type == "limit" and not skip_custom_exit_price:
|
||||
custom_exit_price = strategy_safe_wrapper(
|
||||
self.strategy.custom_exit_price, default_retval=proposed_limit_rate
|
||||
)(
|
||||
pair=trade.pair,
|
||||
trade=trade,
|
||||
current_time=datetime.now(UTC),
|
||||
proposed_rate=proposed_limit_rate,
|
||||
current_profit=current_profit,
|
||||
exit_tag=exit_reason,
|
||||
)
|
||||
|
||||
limit = self.get_valid_price(custom_exit_price, proposed_limit_rate)
|
||||
|
||||
# First cancelling stoploss on exchange ...
|
||||
trade = self.cancel_stoploss_on_exchange(trade)
|
||||
|
||||
order_type = ordertype or self.strategy.order_types[exit_type]
|
||||
if exit_check.exit_type == ExitType.EMERGENCY_EXIT:
|
||||
# Emergency sells (default to market!)
|
||||
order_type = self.strategy.order_types.get("emergency_exit", "market")
|
||||
trade = self.cancel_stoploss_on_exchange(trade, allow_nonblocking=True)
|
||||
|
||||
amount = self._safe_exit_amount(trade, trade.pair, sub_trade_amt or trade.amount)
|
||||
time_in_force = self.strategy.order_time_in_force["exit"]
|
||||
@@ -2121,7 +2136,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
return False
|
||||
|
||||
try:
|
||||
# Execute sell and update trade record
|
||||
# Execute exit and update trade record
|
||||
order = self.exchange.create_order(
|
||||
pair=trade.pair,
|
||||
ordertype=order_type,
|
||||
@@ -2131,6 +2146,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
leverage=trade.leverage,
|
||||
reduceOnly=self.trading_mode == TradingMode.FUTURES,
|
||||
time_in_force=time_in_force,
|
||||
initial_order=False,
|
||||
)
|
||||
except InsufficientFundsError as e:
|
||||
logger.warning(f"Unable to place order {e}.")
|
||||
@@ -2148,7 +2164,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
trade.exit_reason = exit_reason
|
||||
|
||||
self._notify_exit(trade, order_type, sub_trade=bool(sub_trade_amt), order=order_obj)
|
||||
# In case of market sell orders the order can be closed immediately
|
||||
# In case of market exit orders the order can be closed immediately
|
||||
if order.get("status", "unknown") in ("closed", "expired"):
|
||||
self.update_trade_state(trade, order_obj.order_id, order)
|
||||
Trade.commit()
|
||||
@@ -2378,6 +2394,8 @@ class FreqtradeBot(LoggingMixin):
|
||||
self.strategy.ft_stoploss_adjust(
|
||||
current_rate, trade, datetime.now(UTC), profit, 0, after_fill=True
|
||||
)
|
||||
if not trade.is_open:
|
||||
self.cancel_stoploss_on_exchange(trade)
|
||||
# Updating wallets when order is closed
|
||||
self.wallets.update()
|
||||
return trade
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
from cachetools import TTLCache, cached
|
||||
from cachetools import cached
|
||||
|
||||
from freqtrade.util import FtTTLCache
|
||||
|
||||
|
||||
class LoggingMixin:
|
||||
@@ -18,7 +20,7 @@ class LoggingMixin:
|
||||
"""
|
||||
self.logger = logger
|
||||
self.refresh_period = refresh_period
|
||||
self._log_cache: TTLCache = TTLCache(maxsize=1024, ttl=self.refresh_period)
|
||||
self._log_cache: FtTTLCache = FtTTLCache(maxsize=1024, ttl=self.refresh_period)
|
||||
|
||||
def log_once(self, message: str, logmethod: Callable, force_show: bool = False) -> None:
|
||||
"""
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user