Compare commits
861 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c86484b152 | |||
| a33eb51f36 | |||
| 373cd8141c | |||
| 360f294f45 | |||
| a64ab2629b | |||
| 5d88923e03 | |||
| 84cbb1eb01 | |||
| 1c764d622d | |||
| fb6627335b | |||
| 436d3b1bbc | |||
| 308c80c7b2 | |||
| a4a69bd16d | |||
| 9bd68dd63a | |||
| 670cfa2087 | |||
| 7a69cfa62b | |||
| 142dd3fd25 | |||
| d102d3cac8 | |||
| 2b7bcdb594 | |||
| 9ccbf15080 | |||
| 16717f06e9 | |||
| 7d77e16271 | |||
| f501619434 | |||
| 7c9a618c72 | |||
| 16374ef7f1 | |||
| bb4d2f8f1a | |||
| 52fc180c75 | |||
| 87b313cd53 | |||
| 74c88f77c0 | |||
| 6cb459f37b | |||
| 00848c9a96 | |||
| e8adf01b18 | |||
| d28fce7ed8 | |||
| 390d504cf2 | |||
| 1799aa33f9 | |||
| dcff1c4317 | |||
| 121bdab8fe | |||
| 9a48feea35 | |||
| 0955ccadfe | |||
| c778e44e80 | |||
| 18933a6e20 | |||
| 182bdaceb5 | |||
| 6ae4394628 | |||
| 1bdb1539b1 | |||
| 2765277cd0 | |||
| 085a9be186 | |||
| e279c0333f | |||
| 5e7246d23b | |||
| fe86163730 | |||
| b5d467c943 | |||
| c9fd8a619a | |||
| 690080e180 | |||
| 583431e9d5 | |||
| 4b82f82d9c | |||
| 63d6001415 | |||
| ad6cf90037 | |||
| 558c65a85c | |||
| 8cb72e1fa3 | |||
| 4870d45b04 | |||
| 4436acea68 | |||
| e8eb6d7018 | |||
| f1a6e61dbd | |||
| 4abb871c16 | |||
| a6eccaec69 | |||
| 1747724206 | |||
| 616900330b | |||
| bbe5e22730 | |||
| 8b396ae3a2 | |||
| 7f511cbe82 | |||
| 12f5b9bc5b | |||
| d152e3e47d | |||
| 39908c60e2 | |||
| 74a1e48a1c | |||
| b507aebf1c | |||
| ad293c28d0 | |||
| e4c7b5511a | |||
| 85fd070899 | |||
| e658490593 | |||
| 621e78e7ce | |||
| fc5801a0b7 | |||
| 22cd1357f8 | |||
| ead68e0a51 | |||
| 80b87d2592 | |||
| 0ac43042cc | |||
| 590a69ca42 | |||
| e44a36cedd | |||
| 131ab77085 | |||
| ba07de8d00 | |||
| 6ee34aa482 | |||
| d5686d548c | |||
| 4917a0abe5 | |||
| 93f2cf5db7 | |||
| 38a470098f | |||
| b0eb5c77ec | |||
| 0d5bd94f43 | |||
| 735284dccd | |||
| deb0dd80c8 | |||
| 12f815e157 | |||
| 059636f1ea | |||
| 793ca9c3da | |||
| 323a28c0bc | |||
| 77567f6315 | |||
| dda448c10d | |||
| b7df0de33c | |||
| a89ef23407 | |||
| b90538f47d | |||
| ee6b7f2f95 | |||
| b4aa6231e0 | |||
| 6bd57cc3b5 | |||
| 26db014782 | |||
| 8e3ca302b0 | |||
| 14aeb56ff9 | |||
| 9cbb8ec1c2 | |||
| faa5c4be39 | |||
| 45b6ec95a4 | |||
| 91b921cc88 | |||
| 123897ea89 | |||
| 31cf2dd46d | |||
| 06a53924d7 | |||
| 993771c5d3 | |||
| f08f19d1cb | |||
| 515912f14d | |||
| df8465a9f3 | |||
| 1333cb3181 | |||
| 18fa981690 | |||
| 60425e6237 | |||
| 3b5f1d52cd | |||
| 519721b58b | |||
| 3ae7823983 | |||
| 7182e6960e | |||
| 8596042065 | |||
| c2e92250b5 | |||
| d2ed5c6736 | |||
| 8e023a7bf3 | |||
| b3711fdf6c | |||
| 681876e0e5 | |||
| c3502991d3 | |||
| 6cc22fcf74 | |||
| 2f011e5421 | |||
| 4322acbbb8 | |||
| 50cba51008 | |||
| 7498f20baa | |||
| a1b3e59491 | |||
| 4fcbce2ce5 | |||
| 22699ee6ed | |||
| aec5450036 | |||
| 2c5a150a7b | |||
| f845dc71b1 | |||
| 61274252af | |||
| 00d903cb3f | |||
| 29f235441b | |||
| 872b59c9cd | |||
| be7f5f4e26 | |||
| 82c1f096de | |||
| ed7887c426 | |||
| e58f7b0344 | |||
| 32eaae5dcf | |||
| 38c74e5d1a | |||
| e89a31c6d1 | |||
| 3eb8de633c | |||
| 0ee3e4304f | |||
| 228dfe8ab2 | |||
| bfcc2aa153 | |||
| 39e2ecb6a2 | |||
| 0fcfd933ea | |||
| b9a4918d61 | |||
| 0d7127bb6a | |||
| cfd048e74e | |||
| c911332da3 | |||
| 43a849d45d | |||
| 3ad502b073 | |||
| 6d4ad393d5 | |||
| 69cc238700 | |||
| 9a9b4e15f3 | |||
| fcab9460fb | |||
| 58130572a9 | |||
| f82d2fe796 | |||
| 577464c12d | |||
| 00bd3e5a5c | |||
| bc2be74b36 | |||
| 3543437fc5 | |||
| 4b278941b8 | |||
| 8a33b71351 | |||
| a09ca38de2 | |||
| 4d4fee9874 | |||
| f2dfe1788a | |||
| 0e82c0458a | |||
| 2ec2626277 | |||
| 04f4f327df | |||
| 34ad58e2da | |||
| f78aa7b39a | |||
| a174461952 | |||
| 6c164683b7 | |||
| 9cdd8659ec | |||
| 795df94817 | |||
| 40f87c0d30 | |||
| 1380940565 | |||
| 595309c9ed | |||
| 78dde7d1bc | |||
| 2a0da08413 | |||
| fd7aff6063 | |||
| c41584a548 | |||
| 1e6d832f71 | |||
| 6f2ba13b0c | |||
| 78141c7216 | |||
| 8e91fea11f | |||
| 0f8c6d456e | |||
| 2a1b3ae7ba | |||
| 0a94a6d332 | |||
| 75a3651493 | |||
| 0dad2b36ab | |||
| 70834b6491 | |||
| 31269c7ce0 | |||
| 9f00a1d0d2 | |||
| f0a5bbe511 | |||
| 863124d67e | |||
| 6d1e4d8f45 | |||
| 5f12c81768 | |||
| 9a37d7bfbb | |||
| c9c08906e5 | |||
| 31341afcef | |||
| 383b305b74 | |||
| 84244e7ca7 | |||
| cc06e9baec | |||
| d5ac8a5b0b | |||
| 00a4a743d2 | |||
| 650cb1ef8c | |||
| 76ea4ea14f | |||
| 90502a6ac0 | |||
| f9fe909847 | |||
| 7085103e43 | |||
| c5ee96b66a | |||
| d454a10dea | |||
| e3d03f586d | |||
| e8d748535f | |||
| 1cdb386374 | |||
| 8205cb25b8 | |||
| 511b817e84 | |||
| de94170424 | |||
| 6e9b60c0b0 | |||
| b8cf38cb6f | |||
| b394705545 | |||
| 9b99c5b3f3 | |||
| e77e901df1 | |||
| b26c37af62 | |||
| 414fe81b27 | |||
| 00de8077f7 | |||
| 1dde1ad0ed | |||
| 2708343a2d | |||
| 61eb3306dd | |||
| e71329c82b | |||
| dc4adccaaf | |||
| 45b9c8c53f | |||
| 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 | |||
| bcd033bd0d | |||
| 092da6aee5 | |||
| 13c63c0bf5 | |||
| aa38a36b56 | |||
| ce8732b0cd | |||
| bcf6c244b0 | |||
| 9023ca4f56 | |||
| e9847d9549 | |||
| 0beb76ce48 | |||
| 21d723b35d | |||
| f002ce67b1 | |||
| 5fdc8acbe9 | |||
| 1811f9581f | |||
| 66235f3198 | |||
| 6c8b8f642a | |||
| 29b7cbbb12 | |||
| b2d5343a4e | |||
| 6905b8059d | |||
| 301aff141a | |||
| 245ca4bc2a | |||
| f32d25daac | |||
| 1143aba671 | |||
| 278bd0e97d | |||
| d5b296c75c | |||
| c63fba2e57 | |||
| c8d74baaa1 | |||
| a9ebff3965 | |||
| 8859b9009a | |||
| d4aee7e433 | |||
| f0908a1043 | |||
| cf6bf1b7b5 | |||
| 84e9251fcd | |||
| 5800002d42 | |||
| 6a98c19dab | |||
| 025707d9ad | |||
| 4540e2ceea | |||
| eb3e8b82f9 | |||
| 98da54ae82 | |||
| fa5210aa4b | |||
| 289e53ed5a | |||
| 789f4aa4f8 | |||
| 2045fa6427 | |||
| 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 | |||
| 922d5893f8 | |||
| e6e14ab67f | |||
| 37792e7d86 | |||
| a63ea6adb8 | |||
| 06a8f3d097 | |||
| e76b9bb64a | |||
| 606dbe5db1 | |||
| 81e4e0d301 | |||
| a3e97527d1 | |||
| 3ebc7bfcfc | |||
| c892b07eef | |||
| 7a23da4deb | |||
| 670999abda | |||
| e2b5e209f6 | |||
| 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 | |||
| 645f70e216 | |||
| b59db3c690 | |||
| bfe9aac16b | |||
| fade66afd9 | |||
| f63484d0b0 | |||
| 3543e96ec5 | |||
| c83ea0db4f | |||
| ad256367be | |||
| 73b427370b | |||
| ca7234e33f | |||
| cd7b267171 | |||
| 1770a68457 | |||
| 57fd455adf | |||
| 61ecaa4c41 | |||
| 682c4137b4 | |||
| 759c18df3d | |||
| 6cef73947c | |||
| 33dbe32e5c | |||
| 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 | |||
| 8caf7a888e | |||
| 033050e6cf | |||
| 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 |
@@ -46,8 +46,9 @@ runs:
|
||||
id: tags
|
||||
env:
|
||||
BRANCH_NAME_INPUT: ${{ github.event.inputs.branch_name }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
if [ "${EVENT_NAME}" = "workflow_dispatch" ]; then
|
||||
BRANCH_NAME="${BRANCH_NAME_INPUT}"
|
||||
else
|
||||
BRANCH_NAME="${GITHUB_REF##*/}"
|
||||
|
||||
+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/*"
|
||||
|
||||
@@ -6,20 +6,25 @@ on:
|
||||
# on demand
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
auto-update:
|
||||
name: "Auto Update Binance Leverage Tiers"
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: develop
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
@@ -34,7 +39,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
|
||||
|
||||
+58
-50
@@ -16,8 +16,8 @@ on:
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}"
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
repository-projects: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: "Tests and Linting"
|
||||
@@ -25,20 +25,20 @@ 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d # v7.1.0
|
||||
uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
|
||||
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,12 +178,12 @@ jobs:
|
||||
name: "Mypy Version Check"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 #v6.1.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
@@ -193,11 +196,11 @@ jobs:
|
||||
name: "Pre-commit checks"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
|
||||
@@ -206,7 +209,7 @@ jobs:
|
||||
name: "Documentation build"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -215,7 +218,7 @@ jobs:
|
||||
./tests/test_docs.sh
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
@@ -238,17 +241,17 @@ jobs:
|
||||
name: "Tests and Linting - Online tests"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d # v7.1.0
|
||||
uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
|
||||
with:
|
||||
activate-environment: true
|
||||
enable-cache: true
|
||||
@@ -272,18 +275,14 @@ jobs:
|
||||
|
||||
# Notify only once - when CI completes (and after deploy) in case it's successful
|
||||
notify-complete:
|
||||
name: "Notify CI Completion"
|
||||
needs: [
|
||||
tests,
|
||||
docs-check,
|
||||
mypy-version-check,
|
||||
pre-commit,
|
||||
build,
|
||||
build-linux-online
|
||||
]
|
||||
runs-on: ubuntu-22.04
|
||||
# Discord notification can't handle schedule events
|
||||
if: github.event_name != 'schedule' && github.repository == 'freqtrade/freqtrade'
|
||||
permissions:
|
||||
repository-projects: read
|
||||
steps:
|
||||
|
||||
- name: Check user permission
|
||||
@@ -304,17 +303,29 @@ 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
@@ -324,7 +335,7 @@ jobs:
|
||||
python -m build --sdist --wheel
|
||||
|
||||
- name: Upload artifacts 📦
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.1.0
|
||||
with:
|
||||
name: freqtrade-build
|
||||
path: |
|
||||
@@ -337,7 +348,7 @@ jobs:
|
||||
python -m build --sdist --wheel ft_client
|
||||
|
||||
- name: Upload artifacts 📦
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.1.0
|
||||
with:
|
||||
name: freqtrade-client-build
|
||||
path: |
|
||||
@@ -353,15 +364,15 @@ jobs:
|
||||
name: testpypi
|
||||
url: https://test.pypi.org/p/freqtrade
|
||||
permissions:
|
||||
id-token: write
|
||||
id-token: write # Needed for pypa/gh-action-pypi-publish
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download artifact 📦
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
with:
|
||||
pattern: freqtrade*-build
|
||||
path: dist
|
||||
@@ -382,15 +393,15 @@ jobs:
|
||||
name: pypi
|
||||
url: https://pypi.org/p/freqtrade
|
||||
permissions:
|
||||
id-token: write
|
||||
id-token: write # Needed for pypa/gh-action-pypi-publish
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download artifact 📦
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
with:
|
||||
pattern: freqtrade*-build
|
||||
path: dist
|
||||
@@ -403,15 +414,12 @@ 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
|
||||
permissions:
|
||||
packages: write
|
||||
packages: write # Needed to push package versions
|
||||
contents: read
|
||||
secrets:
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
@@ -425,6 +433,6 @@ jobs:
|
||||
# Only run on push, schedule, or release events
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule') && github.repository == 'freqtrade/freqtrade'
|
||||
permissions:
|
||||
packages: write
|
||||
packages: write # Needed to delete package versions
|
||||
with:
|
||||
package_name: 'freqtrade'
|
||||
|
||||
@@ -11,6 +11,9 @@ on:
|
||||
# disable permissions for all of the available permissions
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-docs:
|
||||
@@ -19,12 +22,12 @@ jobs:
|
||||
name: Deploy Docs through mike
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: true
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
|
||||
@@ -17,14 +17,17 @@ concurrency:
|
||||
group: "${{ github.workflow }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: "Build and Push Devcontainer Image"
|
||||
permissions:
|
||||
packages: write
|
||||
packages: write # Needed to push package versions
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Login to GitHub Container Registry
|
||||
@@ -40,3 +43,14 @@ jobs:
|
||||
imageName: ghcr.io/${{ github.repository }}-devcontainer
|
||||
cacheFrom: ghcr.io/${{ github.repository }}-devcontainer
|
||||
push: always
|
||||
|
||||
|
||||
packages-cleanup:
|
||||
name: "Docker Package Cleanup"
|
||||
uses: ./.github/workflows/packages-cleanup.yml
|
||||
# Only run on push, schedule, or release events
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule') && github.repository == 'freqtrade/freqtrade'
|
||||
permissions:
|
||||
packages: write # Needed to delete package versions
|
||||
with:
|
||||
package_name: 'freqtrade-devcontainer'
|
||||
|
||||
@@ -17,6 +17,10 @@ on:
|
||||
default: 'develop'
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -33,10 +37,21 @@ jobs:
|
||||
if: github.repository == 'freqtrade/freqtrade'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
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 +63,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,17 +157,20 @@ jobs:
|
||||
run: |
|
||||
docker images
|
||||
|
||||
- name: Visualize disk usage after build
|
||||
run: df -h
|
||||
|
||||
deploy-arm:
|
||||
name: "Deploy Docker ARM64"
|
||||
permissions:
|
||||
packages: write
|
||||
packages: write # Needed to push package versions
|
||||
needs: [ deploy-docker ]
|
||||
# Only run on 64bit machines
|
||||
runs-on: [self-hosted, linux, ARM64]
|
||||
if: github.repository == 'freqtrade/freqtrade'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -276,6 +294,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
|
||||
|
||||
@@ -4,14 +4,19 @@ on:
|
||||
branches:
|
||||
- stable
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
|
||||
# disable permissions for all of the available permissions
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
dockerHubDescription:
|
||||
name: "Update Docker Hub Description"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -25,20 +25,26 @@ on:
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
PACKAGE_NAME: "freqtrade"
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
deploy-docker:
|
||||
name: "Delete Packages"
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.repository == 'freqtrade/freqtrade'
|
||||
permissions:
|
||||
packages: write
|
||||
packages: write # Needed to delete package versions
|
||||
|
||||
steps:
|
||||
- name: "Delete untagged Package Versions"
|
||||
uses: actions/delete-package-versions@v5
|
||||
uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0
|
||||
with:
|
||||
package-name: ${{ inputs.package_name || env.PACKAGE_NAME }}
|
||||
package-type: 'container'
|
||||
|
||||
@@ -9,15 +9,20 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
auto-update:
|
||||
name: Auto-update pre-commit hooks
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
@@ -28,7 +33,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
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
name: GitHub Actions Security Analysis with zizmor 🌈
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- stable
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- stable
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
zizmor:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
# contents: read # only needed for private repos
|
||||
# actions: read # only needed for private repos
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run zizmor 🌈
|
||||
uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0
|
||||
@@ -0,0 +1,34 @@
|
||||
name: GitHub Actions Security Analysis with zizmor 🌈
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- stable
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- stable
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
zizmor:
|
||||
name: Run zizmor 🌈
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
|
||||
# contents: read # Only needed for private repos. Needed to clone the repo.
|
||||
# actions: read # Only needed for private repos. Needed for upload-sarif to read workflow run info.
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run zizmor 🌈
|
||||
uses: zizmorcore/zizmor-action@135698455da5c3b3e55f73f4419e481ab68cdd95 # v0.4.1
|
||||
@@ -21,18 +21,18 @@ 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
|
||||
additional_dependencies:
|
||||
- types-cachetools==6.2.0.20251022
|
||||
- types-filelock==3.2.7
|
||||
- types-requests==2.32.4.20250913
|
||||
- types-requests==2.32.4.20260107
|
||||
- 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.17.0.1
|
||||
- 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.14'
|
||||
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.22.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-trixie 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,9 @@ 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.
|
||||
|
||||
### Supported Spot Exchanges
|
||||
|
||||
- [X] [Binance](https://www.binance.com/)
|
||||
- [X] [BingX](https://bingx.com/invite/0EM9RX)
|
||||
@@ -39,7 +41,7 @@ Please read the [exchange specific notes](docs/exchanges.md) to learn about even
|
||||
- [X] [MyOKX](https://okx.com/) (OKX EEA)
|
||||
- [ ] [potentially many others](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
|
||||
|
||||
### Supported Futures Exchanges (experimental)
|
||||
### Supported Futures Exchanges
|
||||
|
||||
- [X] [Binance](https://www.binance.com/)
|
||||
- [X] [Bitget](https://www.bitget.com/)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -41,7 +41,7 @@ ranging from the simplest (0) to the most detailed per pair, per buy and per sel
|
||||
* 1: profit summaries grouped by enter_tag
|
||||
* 2: profit summaries grouped by enter_tag and exit_tag
|
||||
* 3: profit summaries grouped by pair and enter_tag
|
||||
* 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large)
|
||||
* 4: profit summaries grouped by pair, enter_tag and exit_tag (this can get quite large)
|
||||
* 5: profit summaries grouped by exit_tag
|
||||
|
||||
More options are available by running with the `-h` option.
|
||||
@@ -52,11 +52,10 @@ By default, `backtesting-analysis` processes the most recent backtest results in
|
||||
If you want to analyze results from an earlier backtest, use the `--backtest-filename` option to specify the desired file. This lets you revisit and re-analyze historical backtest outputs at any time by providing the filename of the relevant backtest result:
|
||||
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --timeframe <tf> --strategy <strategy_name> --timerange <timerange> --export signals --backtest-filename backtest-result-2025-03-05_20-38-34.zip
|
||||
freqtrade backtesting -c <config.json> --strategy <strategy_name> --timerange <timerange> --export signals --backtest-filename backtest-result-2025-03-05_20-38-34.zip
|
||||
```
|
||||
|
||||
You should see some output similar to below in the logs with the name of the timestamped
|
||||
filename that was exported:
|
||||
You should see some output similar to below in the logs with the name of the timestamped filename that was exported:
|
||||
|
||||
```
|
||||
2022-06-14 16:28:32,698 - freqtrade.misc - INFO - dumping json to "mystrat_backtest-2022-06-14_16-28-32.json"
|
||||
@@ -64,14 +63,14 @@ filename that was exported:
|
||||
|
||||
You can then use that filename in `backtesting-analysis`:
|
||||
|
||||
```
|
||||
freqtrade backtesting-analysis -c <config.json> --backtest-filename=mystrat_backtest-2022-06-14_16-28-32.json
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --backtest-filename=backtest-result-2025-03-05_20-38-34.zip
|
||||
```
|
||||
|
||||
To use a result from a different results directory, you can use `--backtest-directory` to specify the directory
|
||||
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --backtest-directory custom_results/ --backtest-filename mystrat_backtest-2022-06-14_16-28-32.json
|
||||
freqtrade backtesting-analysis -c <config.json> --backtest-directory custom_results/ --backtest-filename backtest-result-2025-03-05_20-38-34.zip
|
||||
```
|
||||
|
||||
### Tuning the buy tags and sell tags to display
|
||||
@@ -85,7 +84,7 @@ To show only certain buy and sell tags in the displayed output, use the followin
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 2 --enter-reason-list enter_tag_a enter_tag_b --exit-reason-list roi custom_exit_tag_a stop_loss
|
||||
```
|
||||
|
||||
@@ -96,7 +95,7 @@ values present on signal candles to allow fine-grained investigation and tuning
|
||||
indicators. To print out a column for a given set of indicators, use the `--indicator-list`
|
||||
option:
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 2 --enter-reason-list enter_tag_a enter_tag_b --exit-reason-list roi custom_exit_tag_a stop_loss --indicator-list rsi rsi_1h bb_lowerband ema_9 macd macdsignal
|
||||
```
|
||||
|
||||
@@ -108,24 +107,24 @@ output.
|
||||
The indicator values will be displayed for both entry and exit points. If `--indicator-list all` is specified,
|
||||
only the indicators at the entry point will be shown to avoid excessively large lists, which could occur depending on the strategy.
|
||||
|
||||
There are a range of candle and trade-related fields that are included in the analysis so are
|
||||
There are a range of candle and trade-related fields that are included in the analysis so are
|
||||
automatically accessible by including them on the indicator-list, and these include:
|
||||
|
||||
- **open_date :** trade open datetime
|
||||
- **close_date :** trade close datetime
|
||||
- **min_rate :** minimum price seen throughout the position
|
||||
- **max_rate :** maximum price seen throughout the position
|
||||
- **open :** signal candle open price
|
||||
- **close :** signal candle close price
|
||||
- **high :** signal candle high price
|
||||
- **low :** signal candle low price
|
||||
- **volume :** signal candle volume
|
||||
- **profit_ratio :** trade profit ratio
|
||||
- **profit_abs :** absolute profit return of the trade
|
||||
* **open_date :** trade open datetime
|
||||
* **close_date :** trade close datetime
|
||||
* **min_rate :** minimum price seen throughout the position
|
||||
* **max_rate :** maximum price seen throughout the position
|
||||
* **open :** signal candle open price
|
||||
* **close :** signal candle close price
|
||||
* **high :** signal candle high price
|
||||
* **low :** signal candle low price
|
||||
* **volume :** signal candle volume
|
||||
* **profit_ratio :** trade profit ratio
|
||||
* **profit_abs :** absolute profit return of the trade
|
||||
|
||||
#### Sample Output for Indicator Values
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c user_data/config.json --analysis-groups 0 --indicator-list chikou_span tenkan_sen
|
||||
```
|
||||
|
||||
@@ -158,13 +157,13 @@ The `--indicator-list` option, by default, displays indicator values for both en
|
||||
|
||||
Example: Display indicator values at entry signals:
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c user_data/config.json --analysis-groups 0 --indicator-list chikou_span tenkan_sen --entry-only
|
||||
```
|
||||
|
||||
Example: Display indicator values at exit signals:
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c user_data/config.json --analysis-groups 0 --indicator-list chikou_span tenkan_sen --exit-only
|
||||
```
|
||||
|
||||
@@ -181,7 +180,7 @@ To show only trades between dates within your backtested timerange, supply the u
|
||||
|
||||
For example, if your backtest timerange was `20220101-20221231` but you only want to output trades in January:
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --timerange 20220101-20220201
|
||||
```
|
||||
|
||||
@@ -189,7 +188,7 @@ freqtrade backtesting-analysis -c <config.json> --timerange 20220101-20220201
|
||||
|
||||
Use the `--rejected-signals` option to print out rejected signals.
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --rejected-signals
|
||||
```
|
||||
|
||||
@@ -198,13 +197,13 @@ freqtrade backtesting-analysis -c <config.json> --rejected-signals
|
||||
Some of the tabular outputs can become large, so printing them out to the terminal is not preferable.
|
||||
Use the `--analysis-to-csv` option to disable printing out of tables to standard out and write them to CSV files.
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --analysis-to-csv
|
||||
```
|
||||
|
||||
By default this will write one file per output table you specified in the `backtesting-analysis` command, e.g.
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --analysis-to-csv --rejected-signals --analysis-groups 0 1
|
||||
```
|
||||
|
||||
@@ -216,6 +215,6 @@ This will write to `user_data/backtest_results`:
|
||||
|
||||
To override where the files will be written, also specify the `--analysis-csv-path` option.
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
freqtrade backtesting-analysis -c <config.json> --analysis-to-csv --analysis-csv-path another/data/path/
|
||||
```
|
||||
|
||||
@@ -133,7 +133,7 @@ class MyAwesomeStrategy(IStrategy):
|
||||
]
|
||||
|
||||
# Define a custom max_open_trades space
|
||||
def max_open_trades_space(self) -> List[Dimension]:
|
||||
def max_open_trades_space() -> List[Dimension]:
|
||||
return [
|
||||
Integer(-1, 10, name='max_open_trades'),
|
||||
]
|
||||
@@ -142,7 +142,7 @@ class MyAwesomeStrategy(IStrategy):
|
||||
!!! Note
|
||||
All overrides are optional and can be mixed/matched as necessary.
|
||||
|
||||
### Dynamic parameters
|
||||
## Dynamic parameters
|
||||
|
||||
Parameters can also be defined dynamically, but must be available to the instance once the [`bot_start()` callback](strategy-callbacks.md#bot-start) has been called.
|
||||
|
||||
@@ -159,7 +159,7 @@ class MyAwesomeStrategy(IStrategy):
|
||||
!!! Warning
|
||||
Parameters created this way will not show up in the `list-strategies` parameter count.
|
||||
|
||||
### Overriding Base estimator
|
||||
## Overriding Base estimator
|
||||
|
||||
You can define your own optuna sampler for Hyperopt by implementing `generate_estimator()` in the Hyperopt subclass.
|
||||
|
||||
@@ -208,7 +208,6 @@ Some research will be necessary to find additional Samplers (from optunahub) for
|
||||
|
||||
Obviously the same approach will work for all other Samplers optuna supports.
|
||||
|
||||
|
||||
## Space options
|
||||
|
||||
For the additional spaces, scikit-optimize (in combination with Freqtrade) provides the following space types:
|
||||
|
||||
@@ -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)
|
||||
|
||||
+14
-6
@@ -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
|
||||
|
||||
@@ -423,7 +432,6 @@ freqtrade download-data --timerange 20250625-20250801 --config tests/testdata/co
|
||||
freqtrade backtesting --config tests/testdata/config.tests.usdt.json -s SampleStrategy --userdir user_data_bttest/ --cache none --timerange 20250701-20250801
|
||||
```
|
||||
|
||||
|
||||
## Continuous integration
|
||||
|
||||
This documents some decisions taken for the CI Pipeline.
|
||||
@@ -455,10 +463,10 @@ git checkout -b new_release <commitid>
|
||||
Determine if crucial bugfixes have been made between this commit and the current state, and eventually cherry-pick these.
|
||||
|
||||
* Merge the release branch (stable) into this branch.
|
||||
* Edit `freqtrade/__init__.py` and add the version matching the current date (for example `2019.7` for July 2019). Minor versions can be `2019.7.1` should we need to do a second release that month. Version numbers must follow allowed versions from PEP0440 to avoid failures pushing to pypi.
|
||||
* Edit `freqtrade/__init__.py` and add the version matching the current date (for example `2025.7` for July 2025). Minor versions can be `2025.7.1` should we need to do a second release that month. Version numbers must follow allowed versions from PEP0440 to avoid failures pushing to pypi.
|
||||
* Commit this part.
|
||||
* Push that branch to the remote and create a PR against the **stable branch**.
|
||||
* Update develop version to next version following the pattern `2019.8-dev`.
|
||||
* Update develop version to next version following the pattern `2025.8-dev`.
|
||||
|
||||
### Create changelog from git commits
|
||||
|
||||
|
||||
+37
-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,10 +421,43 @@ 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.
|
||||
|
||||
### HIP-3 DEXes
|
||||
|
||||
Hyperliquid supports HIP-3 decentralized exchanges (DEXes), which are independent exchanges built on top of the Hyperliquid infrastructure.
|
||||
These DEXes operate similarly to the main Hyperliquid exchange but are community-created and managed.
|
||||
|
||||
To trade on HIP-3 DEXes with Freqtrade, you need to add them to your configuration using the `hip3_dexes` parameter:
|
||||
|
||||
```json
|
||||
"exchange": {
|
||||
"name": "hyperliquid",
|
||||
"walletAddress": "your_master_wallet_address",
|
||||
"privateKey": "your_api_private_key",
|
||||
"hip3_dexes": ["dex_name_1", "dex_name_2"]
|
||||
}
|
||||
```
|
||||
|
||||
Replace `"dex_name_1"` and `"dex_name_2"` with the actual names of the HIP-3 DEXes you want to trade on (e.g. `vntl` and `xyz`).
|
||||
|
||||
!!! Warning "Performance and Rate Limit Impact"
|
||||
Each HIP-3 DEX you add significantly impacts bot performance and rate limits.
|
||||
|
||||
* **Additional API Calls**: For each HIP-3 DEX configured, Freqtrade needs to make additional API calls.
|
||||
* **Rate Limit Pressure**: Additional API calls contribute to Hyperliquid's strict rate limits. With multiple DEXes, you may hit rate limits faster, or rather, slow down bot operations due to enforced delays.
|
||||
|
||||
Please only add HIP-3 DEXes that you actively trade on. Monitor your logs for rate limit warnings or signs of slowed operations, and adjust your configuration accordingly.
|
||||
Different HIP-3 DEXes may also use different quote currencies - so make sure to only add DEXes that are compatible with your stake currency to avoid unnecessary delays.
|
||||
|
||||
!!! Note
|
||||
HIP-3 DEXes share the same wallet and free amount of collateral as your main Hyperliquid account. Trades on different DEXes will affect your overall account balance and margin.
|
||||
|
||||
## Bitvavo
|
||||
|
||||
If your account is required to use an operatorId, you can set it in the configuration file as follows:
|
||||
|
||||
+8
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
## Supported Markets
|
||||
|
||||
Freqtrade supports spot trading, as well as (isolated) futures trading for some selected exchanges. Please refer to the [documentation start page](index.md#supported-futures-exchanges-experimental) for an up-to-date list of supported exchanges.
|
||||
Freqtrade supports spot trading, as well as futures trading for some selected exchanges. Please refer to the [documentation start page](index.md#supported-futures-exchanges-experimental) for an up-to-date list of supported exchanges.
|
||||
|
||||
### Can my bot open short positions?
|
||||
|
||||
@@ -29,6 +29,13 @@ You can however use the [`adjust_trade_position()` callback](strategy-callbacks.
|
||||
|
||||
Backtesting provides an option for this in `--eps` - however this is only there to highlight "hidden" signals, and will not work in live.
|
||||
|
||||
### Does freqtrade support sandbox accounts?
|
||||
|
||||
No, but you can use dry-run mode to simulate trading without risking real funds.
|
||||
|
||||
Sandbox markets are separate, simulated markets - which are not suitable to test your strategy in a realistic environment.
|
||||
These markets usually have different order books, liquidity and trading behaviour (usually with very few participants) - which makes them unsuitable for realistic tests of your strategy.
|
||||
|
||||
### The bot does not start
|
||||
|
||||
Running the bot with `freqtrade trade --config config.json` shows the output `freqtrade: command not found`.
|
||||
|
||||
@@ -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,28 +1,28 @@
|
||||
## Highlighted changes
|
||||
# Highlighted changes
|
||||
|
||||
- ...
|
||||
|
||||
### How to update
|
||||
## How to update
|
||||
|
||||
As always, you can update your bot using one of the following commands:
|
||||
|
||||
#### docker-compose
|
||||
### docker-compose
|
||||
|
||||
```bash
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
#### Installation via setup script
|
||||
### Installation via setup script
|
||||
|
||||
```
|
||||
``` bash
|
||||
# Deactivate venv and run
|
||||
./setup.sh --update
|
||||
```
|
||||
|
||||
#### Plain native installation
|
||||
### Plain native installation
|
||||
|
||||
```
|
||||
``` bash
|
||||
git pull
|
||||
pip install -U -r requirements.txt
|
||||
```
|
||||
|
||||
+4
-2
@@ -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)
|
||||
|
||||
@@ -37,6 +37,8 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is
|
||||
|
||||
Please read the [exchange specific notes](exchanges.md) to learn about eventual, special configurations needed for each exchange.
|
||||
|
||||
### Supported Spot Exchanges
|
||||
|
||||
- [X] [Binance](https://www.binance.com/)
|
||||
- [X] [BingX](https://bingx.com/invite/0EM9RX)
|
||||
- [X] [Bitget](https://www.bitget.com/)
|
||||
@@ -50,7 +52,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual,
|
||||
- [X] [MyOKX](https://okx.com/) (OKX EEA)
|
||||
- [ ] [potentially many others through <img alt="ccxt" width="30px" src="assets/ccxt-logo.svg" />](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
|
||||
|
||||
### Supported Futures Exchanges (experimental)
|
||||
### Supported Futures Exchanges
|
||||
|
||||
- [X] [Binance](https://www.binance.com/)
|
||||
- [X] [Bitget](https://www.bitget.com/)
|
||||
|
||||
+57
-18
@@ -9,15 +9,25 @@ The freqtrade documentation describes various ways to install freqtrade
|
||||
* [Manual Installation](#manual-installation)
|
||||
* [Installation with Conda](#installation-with-conda)
|
||||
|
||||
Please consider using the prebuilt [docker images](docker_quickstart.md) to get started quickly while evaluating how freqtrade works.
|
||||
Please consider using the prebuilt [docker images](docker_quickstart.md) to get started quickly.
|
||||
|
||||
!!! Note "Updating"
|
||||
Keeping freqtrade updated is important to [ensure ongoing compatibility](updating.md#why-update) with exchange API's.
|
||||
Please refer to the [updating guide](updating.md) for details on how to update your installation.
|
||||
|
||||
!!! Note "Windows users"
|
||||
We **strongly** recommend that Windows users use [Docker](docker_quickstart.md) as this will work much easier and smoother (also more secure).
|
||||
|
||||
If that is not possible, try using the Windows Linux subsystem (WSL) - for which the Ubuntu/Linux instructions will work.
|
||||
If you really want to install freqtrade natively on Windows, best use the [`./setup.ps1` installation script](#use-setupps1-windows).
|
||||
|
||||
Please also make sure to use the 64bit version of Python, as 32bit versions have severe memory limitations, which can negatively impact your experience with backtesting/hyperopt.
|
||||
|
||||
------
|
||||
|
||||
## Information
|
||||
|
||||
For Windows installation, please use the [windows installation guide](windows_installation.md).
|
||||
|
||||
The easiest way to install and run Freqtrade is to clone the bot Github repository and then run the `./setup.sh` script, if it's available for your platform.
|
||||
The easiest way to install and run Freqtrade is to clone the bot Github repository and then run the `./setup.sh` (`./setup.ps1` for Windows) script, if it's available for your platform.
|
||||
|
||||
!!! Note "Version considerations"
|
||||
When cloning the repository the default working branch has the name `develop`. This branch contains all last features (can be considered as relatively stable, thanks to automated tests).
|
||||
@@ -152,20 +162,9 @@ If you are on Debian, Ubuntu or MacOS, freqtrade provides the script to install
|
||||
./setup.sh -i
|
||||
```
|
||||
|
||||
### Activate your virtual environment
|
||||
#### Other options of /setup.sh script
|
||||
|
||||
Each time you open a new terminal, you must run `source .venv/bin/activate` to activate your virtual environment.
|
||||
|
||||
```bash
|
||||
# activate virtual environment
|
||||
source ./.venv/bin/activate
|
||||
```
|
||||
|
||||
[You are now ready](#you-are-ready) to run the bot.
|
||||
|
||||
### Other options of /setup.sh script
|
||||
|
||||
You can as well update, configure and reset the codebase of your bot with `./script.sh`
|
||||
You can also update, configure and reset the codebase of your bot with `./setup.sh`
|
||||
|
||||
```bash
|
||||
# --update, Command git pull to update.
|
||||
@@ -194,6 +193,34 @@ This option will pull the last version of your current branch and update your vi
|
||||
This option will hard reset your branch (only if you are on either `stable` or `develop`) and recreate your virtualenv.
|
||||
```
|
||||
|
||||
#### Activate your virtual environment
|
||||
|
||||
Each time you open a new terminal, you must run `source .venv/bin/activate` to activate your virtual environment.
|
||||
|
||||
```bash
|
||||
# activate virtual environment
|
||||
source ./.venv/bin/activate
|
||||
```
|
||||
|
||||
### Use ./setup.ps1 (Windows)
|
||||
|
||||
The script will ask you a few questions to determine which parts should be installed.
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy -ExecutionPolicy Bypass
|
||||
cd freqtrade
|
||||
. .\setup.ps1
|
||||
```
|
||||
|
||||
#### Activate your virtual environment (Windows)
|
||||
|
||||
```powershell
|
||||
# activate virtual environment
|
||||
. .\.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
[You are now ready](#you-are-ready) to run the bot.
|
||||
|
||||
-----
|
||||
|
||||
## Manual Installation
|
||||
@@ -337,7 +364,7 @@ conda deactivate
|
||||
|
||||
Happy trading!
|
||||
|
||||
-----
|
||||
------
|
||||
|
||||
## You are ready
|
||||
|
||||
@@ -394,3 +421,15 @@ open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10
|
||||
```
|
||||
|
||||
If this file is inexistent, then you're probably on a different version of MacOS, so you may need to consult the internet for specific resolution details.
|
||||
|
||||
### Windows Installation error
|
||||
|
||||
```bash
|
||||
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
|
||||
```
|
||||
|
||||
Unfortunately, many packages requiring compilation don't provide a pre-built wheel. It is therefore mandatory to have a C/C++ compiler installed and available for your python environment to use.
|
||||
|
||||
You can download the Visual C++ build tools from [the Visual Studio website](https://visualstudio.microsoft.com/visual-cpp-build-tools/) and install "Desktop development with C++" in it's default configuration. Unfortunately, this is a heavy download / dependency so you might want to consider WSL2 or [docker compose](docker_quickstart.md) first.
|
||||
|
||||

|
||||
|
||||
+1
-4
@@ -1,8 +1,5 @@
|
||||
# Trading with Leverage
|
||||
|
||||
!!! Warning "Beta feature"
|
||||
This feature is still in it's testing phase. Should you notice something you think is wrong please let us know via Discord or via Github Issue.
|
||||
|
||||
!!! Note "Multiple bots on one account"
|
||||
You can't run 2 bots on the same account with leverage. For leveraged / margin trading, freqtrade assumes it's the only user of the account, and all liquidation levels are calculated based on this assumption.
|
||||
|
||||
@@ -55,7 +52,7 @@ Perpetual swaps (also known as Perpetual Futures) are contracts traded at a pric
|
||||
In addition to the gains/losses from the change in price of the futures contract, traders also exchange _funding fees_, which are gains/losses worth an amount that is derived from the difference in price between the futures contract and the underlying asset. The difference in price between a futures contract and the underlying asset varies between exchanges.
|
||||
|
||||
To trade in futures markets, you'll have to set `trading_mode` to "futures".
|
||||
You will also have to pick a "margin mode" (explanation below) - with freqtrade currently only supporting isolated margin.
|
||||
You will also have to pick a "margin mode" (explanation below).
|
||||
|
||||
``` json
|
||||
"trading_mode": "futures",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
markdown==3.9
|
||||
markdown==3.10
|
||||
mkdocs==1.6.1
|
||||
mkdocs-material==9.6.22
|
||||
mkdocs-material==9.7.1
|
||||
mdx_truly_sane_lists==1.3
|
||||
pymdown-extensions==10.16.1
|
||||
pymdown-extensions==10.20
|
||||
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
|
||||
|
||||
@@ -1292,6 +1292,22 @@ Currently two types of annotations are supported, `area` and `line`.
|
||||
}
|
||||
```
|
||||
|
||||
#### Point
|
||||
|
||||
``` json
|
||||
{
|
||||
"type": "point", // Type of the annotation, currently only "point" is supported
|
||||
"x": "2024-01-01 15:00:00", // Start date of the point
|
||||
"y": 94000.2, // Price / y axis value
|
||||
"color": "",
|
||||
"z_level": 5, // z-level, higher values are drawn on top of lower values. Positions relative to the Chart elements need to be set in freqUI.
|
||||
"label": "some label",
|
||||
"size": 2, // Optional, line width in pixels. Defaults to 10
|
||||
"symbol": "circle", // Optional, can be "circle", "rect", "roundRect", "triangle", "pin", "arrow", "none".
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
The below example will mark the chart with areas for the hours 8 and 15, with a grey color, highlighting the market open and close hours.
|
||||
This is obviously a very basic example.
|
||||
|
||||
|
||||
+14
-3
@@ -6,6 +6,12 @@ To update your freqtrade installation, please use one of the below methods, corr
|
||||
Breaking changes / changed behavior will be documented in the changelog that is posted alongside every release.
|
||||
For the develop branch, please follow PR's to avoid being surprised by changes.
|
||||
|
||||
## Why update?
|
||||
|
||||
Keeping your bot updated not only ensures that you have the latest features and improvements, but is a requirement to keep your bot running smoothly.
|
||||
Freqtrade is heavily dependent on the underlying exchange API's, which change pretty frequently if considered across exchanges.
|
||||
To ensure ongoing compatibility, please make sure to update your bot regularly.
|
||||
|
||||
## Docker
|
||||
|
||||
!!! Note "Legacy installations using the `master` image"
|
||||
@@ -38,7 +44,12 @@ pip install -e .
|
||||
freqtrade install-ui
|
||||
```
|
||||
|
||||
### Problems updating
|
||||
## Problems updating
|
||||
|
||||
Update-problems usually come missing dependencies (you didn't follow the above instructions) - or from updated dependencies, which fail to install (for example TA-lib).
|
||||
Please refer to the corresponding installation sections (common problems linked below)
|
||||
Update-problems usually come missing dependencies (you didn't follow the above instructions) - or from dependencies which fail to install.
|
||||
We try to make sure that heavy dependencies have wheels available for major platforms, but sometimes this is not possible.
|
||||
|
||||
Please refer to the corresponding installation sections (common problem sections linked below).
|
||||
|
||||
[Common installation problems](installation.md#troubleshooting)
|
||||
[Common installation problems - windows](installation.md#windows-installation-error)
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# Windows installation
|
||||
|
||||
We **strongly** recommend that Windows users use [Docker](docker_quickstart.md) as this will work much easier and smoother (also more secure).
|
||||
|
||||
If that is not possible, try using the Windows Linux subsystem (WSL) - for which the Ubuntu instructions should work.
|
||||
Otherwise, please follow the instructions below.
|
||||
|
||||
All instructions assume that python 3.11+ is installed and available.
|
||||
|
||||
## Clone the git repository
|
||||
|
||||
First of all clone the repository by running:
|
||||
|
||||
``` powershell
|
||||
git clone https://github.com/freqtrade/freqtrade.git
|
||||
```
|
||||
|
||||
Now, choose your installation method, either automatically via script (recommended) or manually following the corresponding instructions.
|
||||
|
||||
## Install freqtrade automatically
|
||||
|
||||
### Run the installation script
|
||||
|
||||
The script will ask you a few questions to determine which parts should be installed.
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy -ExecutionPolicy Bypass
|
||||
cd freqtrade
|
||||
. .\setup.ps1
|
||||
```
|
||||
|
||||
## Install freqtrade manually
|
||||
|
||||
!!! Note "64bit Python version"
|
||||
Please make sure to use 64bit Windows and 64bit Python to avoid problems with backtesting or hyperopt due to the memory constraints 32bit applications have under Windows.
|
||||
32bit python versions are no longer supported under Windows.
|
||||
|
||||
!!! Hint
|
||||
Using the [Anaconda Distribution](https://www.anaconda.com/distribution/) under Windows can greatly help with installation problems. Check out the [Anaconda installation section](installation.md#installation-with-conda) in the documentation for more information.
|
||||
|
||||
|
||||
### Error during installation on Windows
|
||||
|
||||
``` bash
|
||||
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
|
||||
```
|
||||
|
||||
Unfortunately, many packages requiring compilation don't provide a pre-built wheel. It is therefore mandatory to have a C/C++ compiler installed and available for your python environment to use.
|
||||
|
||||
You can download the Visual C++ build tools from [here](https://visualstudio.microsoft.com/visual-cpp-build-tools/) and install "Desktop development with C++" in it's default configuration. Unfortunately, this is a heavy download / dependency so you might want to consider WSL2 or [docker compose](docker_quickstart.md) first.
|
||||
|
||||

|
||||
|
||||
---
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Freqtrade bot"""
|
||||
|
||||
__version__ = "2025.10"
|
||||
__version__ = "2026.1"
|
||||
|
||||
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
|
||||
@@ -102,9 +103,15 @@ ARGS_BACKTEST_SHOW = [
|
||||
"backtest_breakdown",
|
||||
]
|
||||
|
||||
ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all", "trading_mode", "dex_exchanges"]
|
||||
ARGS_LIST_EXCHANGES = [
|
||||
"print_one_column",
|
||||
"list_exchanges_all",
|
||||
"trading_mode",
|
||||
"dex_exchanges",
|
||||
"list_exchanges_futures_options",
|
||||
]
|
||||
|
||||
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
|
||||
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column", "trading_mode"]
|
||||
|
||||
ARGS_LIST_PAIRS = [
|
||||
"exchange",
|
||||
@@ -174,6 +181,7 @@ ARGS_DOWNLOAD_DATA = [
|
||||
"dataformat_ohlcv",
|
||||
"dataformat_trades",
|
||||
"trading_mode",
|
||||
"candle_types",
|
||||
"prepend_data",
|
||||
]
|
||||
|
||||
@@ -348,7 +356,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:
|
||||
"""
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
Definition of cli arguments used in arguments.py
|
||||
"""
|
||||
|
||||
from argparse import ArgumentTypeError
|
||||
from argparse import SUPPRESS, 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",
|
||||
@@ -383,6 +388,13 @@ AVAILABLE_CLI_OPTIONS = {
|
||||
help="Print only DEX exchanges.",
|
||||
action="store_true",
|
||||
),
|
||||
"list_exchanges_futures_options": Arg(
|
||||
"--ccxt-show-futures-options-exchanges",
|
||||
help=SUPPRESS,
|
||||
# Show compatibility with ccxt for futures functionality
|
||||
# Doesn't show in help as it's an internal/debug option.
|
||||
action="store_true",
|
||||
),
|
||||
# List pairs / markets
|
||||
"list_pairs_all": Arg(
|
||||
"-a",
|
||||
@@ -427,6 +439,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="+",
|
||||
|
||||
@@ -38,13 +38,15 @@ def start_list_exchanges(args: dict[str, Any]) -> None:
|
||||
else:
|
||||
available_exchanges = [e for e in available_exchanges if e["valid"] is not False]
|
||||
title = f"Exchanges available for Freqtrade ({len(available_exchanges)} exchanges):"
|
||||
|
||||
show_fut_reasons = args.get("list_exchanges_futures_options", False)
|
||||
table = Table(title=title)
|
||||
|
||||
table.add_column("Exchange Name")
|
||||
table.add_column("Class Name")
|
||||
table.add_column("Markets")
|
||||
table.add_column("Reason")
|
||||
if show_fut_reasons:
|
||||
table.add_column("Futures Reason")
|
||||
|
||||
trading_mode = args.get("trading_mode", None)
|
||||
dex_only = args.get("dex_exchanges", False)
|
||||
@@ -78,12 +80,14 @@ def start_list_exchanges(args: dict[str, Any]) -> None:
|
||||
if exchange["dex"]:
|
||||
trade_modes = Text("DEX: ") + trade_modes
|
||||
trade_modes.stylize("bold", 0, 3)
|
||||
futcol = [] if not show_fut_reasons else [exchange["comment_futures"]]
|
||||
|
||||
table.add_row(
|
||||
name,
|
||||
classname,
|
||||
trade_modes,
|
||||
exchange["comment"],
|
||||
*futcol,
|
||||
style=None if exchange["valid"] else "red",
|
||||
)
|
||||
# table.add_row(*[exchange[header] for header in headers])
|
||||
@@ -101,7 +105,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 +119,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 +152,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 +166,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",
|
||||
|
||||
@@ -30,7 +30,7 @@ def log_config_error_range(path: str, errmsg: str) -> str:
|
||||
offsetlist = re.findall(r"(?<=Parse\serror\sat\soffset\s)\d+", errmsg)
|
||||
if offsetlist:
|
||||
offset = int(offsetlist[0])
|
||||
text = Path(path).read_text()
|
||||
text = Path(path).read_text(encoding="utf-8")
|
||||
# Fetch an offset of 80 characters around the error line
|
||||
subtext = text[offset - min(80, offset) : offset + 80]
|
||||
segments = subtext.split("\n")
|
||||
|
||||
@@ -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:
|
||||
|
||||
+35
-10
@@ -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
|
||||
@@ -318,7 +334,10 @@ def calculate_expectancy(trades: pd.DataFrame) -> tuple[float, float]:
|
||||
|
||||
|
||||
def calculate_sortino(
|
||||
trades: pd.DataFrame, min_date: datetime, max_date: datetime, starting_balance: float
|
||||
trades: pd.DataFrame,
|
||||
min_date: datetime | None,
|
||||
max_date: datetime | None,
|
||||
starting_balance: float,
|
||||
) -> float:
|
||||
"""
|
||||
Calculate sortino
|
||||
@@ -346,7 +365,10 @@ def calculate_sortino(
|
||||
|
||||
|
||||
def calculate_sharpe(
|
||||
trades: pd.DataFrame, min_date: datetime, max_date: datetime, starting_balance: float
|
||||
trades: pd.DataFrame,
|
||||
min_date: datetime | None,
|
||||
max_date: datetime | None,
|
||||
starting_balance: float,
|
||||
) -> float:
|
||||
"""
|
||||
Calculate sharpe
|
||||
@@ -373,7 +395,10 @@ def calculate_sharpe(
|
||||
|
||||
|
||||
def calculate_calmar(
|
||||
trades: pd.DataFrame, min_date: datetime, max_date: datetime, starting_balance: float
|
||||
trades: pd.DataFrame,
|
||||
min_date: datetime | None,
|
||||
max_date: datetime | None,
|
||||
starting_balance: float,
|
||||
) -> float:
|
||||
"""
|
||||
Calculate calmar
|
||||
|
||||
@@ -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
|
||||
@@ -66,6 +68,7 @@ class Binance(Exchange):
|
||||
"BFUSD": "USDT",
|
||||
},
|
||||
}
|
||||
_can_use_data_download_fast = True
|
||||
|
||||
_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
|
||||
(TradingMode.SPOT, MarginMode.NONE),
|
||||
@@ -76,7 +79,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:
|
||||
"""
|
||||
@@ -179,7 +182,8 @@ class Binance(Exchange):
|
||||
return DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS)
|
||||
|
||||
if (
|
||||
self._config["exchange"].get("only_from_ccxt", False)
|
||||
not self._can_use_data_download_fast
|
||||
or self._config["exchange"].get("only_from_ccxt", False)
|
||||
or
|
||||
# only download timeframes with significant improvements,
|
||||
# otherwise fall back to rest API
|
||||
@@ -403,7 +407,10 @@ class Binance(Exchange):
|
||||
) -> tuple[str, list[list]]:
|
||||
logger.info(f"Fetching trades for {pair} from Binance, {from_id=}, {since=}, {until=}")
|
||||
|
||||
if not self._config["exchange"].get("only_from_ccxt", False):
|
||||
if (
|
||||
not self._config["exchange"].get("only_from_ccxt", False)
|
||||
and self._can_use_data_download_fast
|
||||
):
|
||||
if from_id is None or not since:
|
||||
trades = await self._api_async.fetch_trades(
|
||||
pair,
|
||||
@@ -544,3 +551,28 @@ 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),
|
||||
]
|
||||
# binance vision does not have data for binanceus
|
||||
_can_use_data_download_fast = False
|
||||
|
||||
+15032
-12687
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
|
||||
|
||||
@@ -47,14 +47,16 @@ def check_exchange(config: Config, check_for_bad: bool = True) -> bool:
|
||||
f"{', '.join(available_exchanges())}"
|
||||
)
|
||||
|
||||
valid, reason, _ = validate_exchange(exchange)
|
||||
valid, reason, _, _ = validate_exchange(exchange)
|
||||
if not valid:
|
||||
if check_for_bad:
|
||||
raise OperationalException(
|
||||
f'Exchange "{exchange}" will not work with Freqtrade. Reason: {reason}'
|
||||
f'Exchange "{exchange}" will not work with Freqtrade. Reason: {reason}.'
|
||||
)
|
||||
else:
|
||||
logger.warning(f'Exchange "{exchange}" will not work with Freqtrade. Reason: {reason}')
|
||||
logger.warning(
|
||||
f'Exchange "{exchange}" will not work with Freqtrade. Reason: {reason}.'
|
||||
)
|
||||
|
||||
if MAP_EXCHANGE_CHILDCLASS.get(exchange, exchange) in SUPPORTED_EXCHANGES:
|
||||
logger.info(
|
||||
|
||||
@@ -36,17 +36,16 @@ API_RETRY_COUNT = 4
|
||||
API_FETCH_ORDER_RETRY_COUNT = 5
|
||||
|
||||
BAD_EXCHANGES = {
|
||||
"bitmex": "Various reasons.",
|
||||
"probit": "Requires additional, regular calls to `signIn()`.",
|
||||
"poloniex": "Does not provide fetch_order endpoint to fetch both open and closed orders.",
|
||||
"kucoinfutures": "Unsupported futures exchange.",
|
||||
"poloniexfutures": "Unsupported futures exchange.",
|
||||
"binancecoinm": "Unsupported futures exchange.",
|
||||
"bitmex": "Various reasons",
|
||||
"probit": "Requires additional, regular calls to `signIn()`",
|
||||
"poloniex": "Does not provide fetch_order endpoint to fetch both open and closed orders",
|
||||
"krakenfutures": "Unsupported futures exchange",
|
||||
"kucoinfutures": "Unsupported futures exchange",
|
||||
"poloniexfutures": "Unsupported futures exchange",
|
||||
"binancecoinm": "Unsupported futures exchange",
|
||||
}
|
||||
|
||||
MAP_EXCHANGE_CHILDCLASS = {
|
||||
"binanceus": "binance",
|
||||
"binanceusdm": "binance",
|
||||
"okex": "okx",
|
||||
"gateio": "gate",
|
||||
"huboi": "htx",
|
||||
@@ -54,6 +53,8 @@ MAP_EXCHANGE_CHILDCLASS = {
|
||||
|
||||
SUPPORTED_EXCHANGES = [
|
||||
"binance",
|
||||
"binanceus",
|
||||
"binanceusdm",
|
||||
"bingx",
|
||||
"bitmart",
|
||||
"bitget",
|
||||
@@ -78,28 +79,35 @@ EXCHANGE_HAS_REQUIRED: dict[str, list[str]] = {
|
||||
"fetchOHLCV": [],
|
||||
}
|
||||
|
||||
EXCHANGE_HAS_OPTIONAL = [
|
||||
EXCHANGE_HAS_OPTIONAL: dict[str, list[str]] = {
|
||||
# Private
|
||||
"fetchMyTrades", # Trades for order - fee detection
|
||||
"createLimitOrder",
|
||||
"createMarketOrder", # Either OR for orders
|
||||
# 'setLeverage', # Margin/Futures trading
|
||||
# 'setMarginMode', # Margin/Futures trading
|
||||
# 'fetchFundingHistory', # Futures trading
|
||||
"fetchMyTrades": [], # Trades for order - fee detection
|
||||
"createLimitOrder": [],
|
||||
"createMarketOrder": [], # Either OR for orders
|
||||
# Public
|
||||
"fetchOrderBook",
|
||||
"fetchL2OrderBook",
|
||||
"fetchTicker", # OR for pricing
|
||||
"fetchTickers", # For volumepairlist?
|
||||
"fetchTrades", # Downloading trades data
|
||||
# 'fetchFundingRateHistory', # Futures trading
|
||||
# 'fetchPositions', # Futures trading
|
||||
# 'fetchLeverageTiers', # Futures initialization
|
||||
# 'fetchMarketLeverageTiers', # Futures initialization
|
||||
# 'fetchOpenOrders', 'fetchClosedOrders', # 'fetchOrders', # Refinding balance...
|
||||
"fetchOrderBook": [],
|
||||
"fetchL2OrderBook": [],
|
||||
"fetchTicker": [], # OR for pricing
|
||||
"fetchTickers": [], # For volumepairlist?
|
||||
"fetchTrades": [], # Downloading trades data
|
||||
"fetchOrders": ["fetchOpenOrders", "fetchClosedOrders"], # , # Refinding balance...
|
||||
# ccxt.pro
|
||||
"watchOHLCV",
|
||||
]
|
||||
"watchOHLCV": [],
|
||||
}
|
||||
|
||||
EXCHANGE_HAS_OPTIONAL_FUTURES: dict[str, list[str]] = {
|
||||
# private
|
||||
"setLeverage": [], # Margin/Futures trading
|
||||
"setMarginMode": [], # Margin/Futures trading
|
||||
"fetchFundingHistory": [], # Futures trading
|
||||
# Public
|
||||
"fetchFundingRateHistory": [], # Futures trading
|
||||
"fetchPositions": [], # Futures trading
|
||||
"fetchLeverageTiers": ["fetchMarketLeverageTiers"], # Futures initialization
|
||||
"fetchMarkOHLCV": [],
|
||||
"fetchIndexOHLCV": [], # Futures additional data
|
||||
"fetchPremiumIndexOHLCV": [],
|
||||
}
|
||||
|
||||
|
||||
def calculate_backoff(retrycount, max_retries):
|
||||
|
||||
+243
-84
@@ -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
|
||||
@@ -74,6 +73,7 @@ from freqtrade.exchange.exchange_types import (
|
||||
CcxtPosition,
|
||||
FtHas,
|
||||
FundingRate,
|
||||
LeverageTier,
|
||||
OHLCVResponse,
|
||||
OrderBook,
|
||||
Ticker,
|
||||
@@ -105,11 +105,10 @@ from freqtrade.misc import (
|
||||
deep_merge_dicts,
|
||||
file_dump_json,
|
||||
file_load_json,
|
||||
safe_value_fallback2,
|
||||
safe_value_fallback,
|
||||
)
|
||||
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"],
|
||||
@@ -195,29 +195,30 @@ class Exchange:
|
||||
self._exchange_ws: ExchangeWS | None = None
|
||||
self._markets: dict = {}
|
||||
self._trading_fees: dict[str, Any] = {}
|
||||
self._leverage_tiers: dict[str, list[dict]] = {}
|
||||
self._leverage_tiers: dict[str, list[LeverageTier]] = {}
|
||||
# Lock event loop. This is necessary to avoid race-conditions when using force* commands
|
||||
# Due to funding fee fetching.
|
||||
self._loop_lock = Lock()
|
||||
self.loop = self._init_async_loop()
|
||||
self._config: Config = {}
|
||||
self._config: Config = config
|
||||
|
||||
# Leverage properties
|
||||
self.trading_mode: TradingMode = TradingMode(
|
||||
config.get("trading_mode", self._supported_trading_mode_margin_pairs[0][0])
|
||||
self._config.get("trading_mode", self._supported_trading_mode_margin_pairs[0][0])
|
||||
)
|
||||
self.margin_mode: MarginMode = MarginMode(
|
||||
MarginMode(config.get("margin_mode"))
|
||||
if config.get("margin_mode")
|
||||
MarginMode(self._config.get("margin_mode"))
|
||||
if self._config.get("margin_mode")
|
||||
else self._supported_trading_mode_margin_pairs[0][1]
|
||||
)
|
||||
config["trading_mode"] = self.trading_mode
|
||||
config["margin_mode"] = self.margin_mode
|
||||
config["candle_type_def"] = CandleType.get_default(self.trading_mode)
|
||||
self._config.update(config)
|
||||
self.liquidation_buffer = config.get("liquidation_buffer", 0.05)
|
||||
self._config["trading_mode"] = self.trading_mode
|
||||
self._config["margin_mode"] = self.margin_mode
|
||||
self._config["candle_type_def"] = CandleType.get_default(self.trading_mode)
|
||||
self.liquidation_buffer = self._config.get("liquidation_buffer", 0.05)
|
||||
|
||||
exchange_conf: ExchangeConfig = exchange_config if exchange_config else config["exchange"]
|
||||
exchange_conf: ExchangeConfig = (
|
||||
exchange_config if exchange_config else self._config["exchange"]
|
||||
)
|
||||
|
||||
# Deep merge ft_has with default ft_has options
|
||||
# Must be called before ft_has is used.
|
||||
@@ -230,13 +231,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] = {}
|
||||
@@ -248,14 +249,14 @@ class Exchange:
|
||||
# Holds all open sell orders for dry_run
|
||||
self._dry_run_open_orders: dict[str, Any] = {}
|
||||
|
||||
if config["dry_run"]:
|
||||
if self._config["dry_run"]:
|
||||
logger.info("Instance is running with dry_run enabled")
|
||||
logger.info(f"Using CCXT {ccxt.__version__}")
|
||||
|
||||
# Don't remove exchange credentials for dry-run or if always_require_api_keys is set
|
||||
remove_exchange_credentials(
|
||||
exchange_conf,
|
||||
not self._ft_has["always_require_api_keys"] and config.get("dry_run", False),
|
||||
not self._ft_has["always_require_api_keys"] and self._config.get("dry_run", False),
|
||||
)
|
||||
self.log_responses = exchange_conf.get("log_responses", False)
|
||||
|
||||
@@ -296,7 +297,7 @@ class Exchange:
|
||||
if validate:
|
||||
# Initial markets load
|
||||
self.reload_markets(True, load_leverage_tiers=False)
|
||||
self.validate_config(config)
|
||||
self.validate_config(self._config)
|
||||
|
||||
if self.trading_mode != TradingMode.SPOT and load_leverage_tiers:
|
||||
self.fill_leverage_tiers()
|
||||
@@ -430,7 +431,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]:
|
||||
@@ -472,7 +481,7 @@ class Exchange:
|
||||
def _log_exchange_response(self, endpoint: str, response, *, add_info=None) -> None:
|
||||
"""Log exchange responses"""
|
||||
if self.log_responses:
|
||||
add_info_str = "" if add_info is None else f" {add_info}: "
|
||||
add_info_str = "" if add_info is None else f"{add_info}: "
|
||||
logger.info(f"API {endpoint}: {add_info_str}{response}")
|
||||
|
||||
def ohlcv_candle_limit(
|
||||
@@ -701,7 +710,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 +880,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 +901,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 +909,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 +1123,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 +1150,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 +1168,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 +1212,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 +1227,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 +1250,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 +1265,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 +1292,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 +1347,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 +1359,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 +1408,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 +1427,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 +1564,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 +1690,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 +1761,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]:
|
||||
@@ -1741,16 +1828,16 @@ class Exchange:
|
||||
return order
|
||||
|
||||
@retrier
|
||||
def get_balances(self) -> CcxtBalances:
|
||||
def get_balances(self, params: dict | None = None) -> CcxtBalances:
|
||||
try:
|
||||
balances = self._api.fetch_balance()
|
||||
balances = self._api.fetch_balance(params or {})
|
||||
# Remove additional info from ccxt results
|
||||
balances.pop("info", None)
|
||||
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, add_info=params)
|
||||
return balances
|
||||
except ccxt.DDoSProtection as e:
|
||||
raise DDosProtection(e) from e
|
||||
@@ -1762,7 +1849,9 @@ class Exchange:
|
||||
raise OperationalException(e) from e
|
||||
|
||||
@retrier
|
||||
def fetch_positions(self, pair: str | None = None) -> list[CcxtPosition]:
|
||||
def fetch_positions(
|
||||
self, pair: str | None = None, params: dict | None = None
|
||||
) -> list[CcxtPosition]:
|
||||
"""
|
||||
Fetch positions from the exchange.
|
||||
If no pair is given, all positions are returned.
|
||||
@@ -1771,10 +1860,10 @@ class Exchange:
|
||||
if self._config["dry_run"] or self.trading_mode != TradingMode.FUTURES:
|
||||
return []
|
||||
try:
|
||||
symbols = []
|
||||
symbols = None
|
||||
if pair:
|
||||
symbols.append(pair)
|
||||
positions: list[CcxtPosition] = self._api.fetch_positions(symbols)
|
||||
symbols = [pair]
|
||||
positions: list[CcxtPosition] = self._api.fetch_positions(symbols, params=params or {})
|
||||
self._log_exchange_response("fetch_positions", positions)
|
||||
return positions
|
||||
except ccxt.DDoSProtection as e:
|
||||
@@ -1974,12 +2063,13 @@ class Exchange:
|
||||
"""
|
||||
return self._config["stake_currency"]
|
||||
|
||||
def get_conversion_rate(self, coin: str, currency: str) -> float | None:
|
||||
def get_conversion_rate(self, coin: str, currency: str, *, cached=True) -> float | None:
|
||||
"""
|
||||
Quick and cached way to get conversion rate one currency to the other.
|
||||
Can then be used as "rate * amount" to convert between currencies.
|
||||
:param coin: Coin to convert
|
||||
:param currency: Currency to convert to
|
||||
:param cached: Allow cached tickers, default True
|
||||
:returns: Conversion rate from coin to currency
|
||||
:raises: ExchangeErrors
|
||||
"""
|
||||
@@ -1990,13 +2080,13 @@ class Exchange:
|
||||
currency = proxy_currency
|
||||
if coin == currency:
|
||||
return 1.0
|
||||
tickers = self.get_tickers(cached=True)
|
||||
tickers = self.get_tickers(cached=cached)
|
||||
try:
|
||||
for pair in self.get_valid_pair_combination(coin, currency):
|
||||
ticker: Ticker | None = tickers.get(pair, None)
|
||||
if not ticker:
|
||||
tickers_other: Tickers = self.get_tickers(
|
||||
cached=True,
|
||||
cached=cached,
|
||||
market_type=(
|
||||
TradingMode.SPOT
|
||||
if self.trading_mode != TradingMode.SPOT
|
||||
@@ -2005,7 +2095,7 @@ class Exchange:
|
||||
)
|
||||
ticker = tickers_other.get(pair, None)
|
||||
if ticker:
|
||||
rate: float | None = safe_value_fallback2(ticker, ticker, "last", "ask", None)
|
||||
rate: float | None = safe_value_fallback(ticker, "last", "ask", None)
|
||||
if rate and pair.startswith(currency) and not pair.endswith(currency):
|
||||
rate = 1.0 / rate
|
||||
return rate
|
||||
@@ -2143,7 +2233,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)
|
||||
@@ -2303,6 +2395,16 @@ class Exchange:
|
||||
raise OperationalException(e) from e
|
||||
|
||||
def get_order_id_conditional(self, order: CcxtOrder) -> str:
|
||||
"""
|
||||
Return order id or id_stop (for conditional orders) based on exchange settings
|
||||
|
||||
:param order: ccxt order dict
|
||||
:return: correct order id
|
||||
"""
|
||||
if self.get_option("stoploss_query_requires_stop_flag") and (
|
||||
order["type"] in ("stoploss", "stop")
|
||||
):
|
||||
return safe_value_fallback(order, "id_stop", "id")
|
||||
return order["id"]
|
||||
|
||||
@retrier
|
||||
@@ -2462,7 +2564,13 @@ class Exchange:
|
||||
)
|
||||
)
|
||||
logger.debug(f"Downloaded data for {pair} from ccxt with length {len(data)}.")
|
||||
return ohlcv_to_dataframe(data, timeframe, pair, fill_missing=False, drop_incomplete=True)
|
||||
# funding_rates are always complete, so never need to be dropped.
|
||||
drop_incomplete = (
|
||||
self._ohlcv_partial_candle if candle_type != CandleType.FUNDING_RATE else False
|
||||
)
|
||||
return ohlcv_to_dataframe(
|
||||
data, timeframe, pair, fill_missing=False, drop_incomplete=drop_incomplete
|
||||
)
|
||||
|
||||
async def _async_get_historic_ohlcv(
|
||||
self,
|
||||
@@ -2625,24 +2733,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 +2788,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 +2803,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 +2938,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 +3006,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:
|
||||
@@ -3476,7 +3622,7 @@ class Exchange:
|
||||
pair_tiers.append(self.parse_leverage_tier(tier))
|
||||
self._leverage_tiers[pair] = pair_tiers
|
||||
|
||||
def parse_leverage_tier(self, tier) -> dict:
|
||||
def parse_leverage_tier(self, tier) -> LeverageTier:
|
||||
info = tier.get("info", {})
|
||||
return {
|
||||
"minNotional": tier["minNotional"],
|
||||
@@ -3517,7 +3663,11 @@ class Exchange:
|
||||
for tier in pair_tiers:
|
||||
# Adjust notional by leverage to do a proper comparison
|
||||
min_stake = tier["minNotional"] / (prior_max_lev or tier["maxLeverage"])
|
||||
max_stake = tier["maxNotional"] / tier["maxLeverage"]
|
||||
max_stake = (
|
||||
tier["maxNotional"] / tier["maxLeverage"]
|
||||
if tier["maxNotional"] is not None
|
||||
else float("inf")
|
||||
)
|
||||
prior_max_lev = tier["maxLeverage"]
|
||||
if min_stake <= stake_amount <= max_stake:
|
||||
return tier["maxLeverage"]
|
||||
@@ -3719,10 +3869,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 +3886,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
|
||||
@@ -113,5 +115,27 @@ class CcxtPosition(TypedDict):
|
||||
|
||||
CcxtOrder = dict[str, Any]
|
||||
|
||||
|
||||
class LeverageTier(TypedDict):
|
||||
"""
|
||||
Represents a single leverage tier returned by the exchange.
|
||||
|
||||
Attributes:
|
||||
minNotional: Minimum notional value (quote currency) for which this tier applies.
|
||||
maxNotional: Maximum notional value (quote currency) for which this tier applies.
|
||||
When ``maxNotional`` is ``None``, the tier is unbounded on the upper side,
|
||||
i.e. there is no maximum notional limit for this tier
|
||||
maintenanceMarginRate: Maintenance margin rate for this tier (fraction, e.g. 0.005 for 0.5%)
|
||||
maxLeverage: Maximum leverage allowed for this tier
|
||||
maintAmt: Optional fixed maintenance margin amount, if provided by the exchange
|
||||
"""
|
||||
|
||||
minNotional: float
|
||||
maxNotional: float | None
|
||||
maintenanceMarginRate: float
|
||||
maxLeverage: float
|
||||
maintAmt: float | None
|
||||
|
||||
|
||||
# pair, timeframe, candleType, OHLCV, drop last?,
|
||||
OHLCVResponse = tuple[str, str, CandleType, list, bool]
|
||||
|
||||
@@ -22,6 +22,7 @@ from ccxt import (
|
||||
from freqtrade.exchange.common import (
|
||||
BAD_EXCHANGES,
|
||||
EXCHANGE_HAS_OPTIONAL,
|
||||
EXCHANGE_HAS_OPTIONAL_FUTURES,
|
||||
EXCHANGE_HAS_REQUIRED,
|
||||
MAP_EXCHANGE_CHILDCLASS,
|
||||
SUPPORTED_EXCHANGES,
|
||||
@@ -53,7 +54,22 @@ def available_exchanges(ccxt_module: CcxtModuleType | None = None) -> list[str]:
|
||||
return [x for x in exchanges if validate_exchange(x)[0]]
|
||||
|
||||
|
||||
def validate_exchange(exchange: str) -> tuple[bool, str, ccxt.Exchange | None]:
|
||||
def _exchange_has_helper(ex_mod: ccxt.Exchange, required: dict[str, list[str]]) -> list[str]:
|
||||
"""
|
||||
Checks availability of methods (or their replacement)s in ex_mod.has
|
||||
:param ex_mod: ccxt Exchange module
|
||||
:param required: dict of required methods, with possible replacement methods as list
|
||||
:return: list of missing required methods
|
||||
"""
|
||||
return [
|
||||
k
|
||||
for k, v in required.items()
|
||||
if ex_mod.has.get(k) is not True
|
||||
and (len(v) == 0 or not (all(ex_mod.has.get(x) for x in v)))
|
||||
]
|
||||
|
||||
|
||||
def validate_exchange(exchange: str) -> tuple[bool, str, str, ccxt.Exchange | None]:
|
||||
"""
|
||||
returns: can_use, reason, exchange_object
|
||||
with Reason including both missing and missing_opt
|
||||
@@ -64,36 +80,38 @@ def validate_exchange(exchange: str) -> tuple[bool, str, ccxt.Exchange | None]:
|
||||
ex_mod = getattr(ccxt.async_support, exchange.lower())()
|
||||
|
||||
if not ex_mod or not ex_mod.has:
|
||||
return False, "", None
|
||||
return False, "", "", None
|
||||
|
||||
result = True
|
||||
reason = ""
|
||||
missing = [
|
||||
k
|
||||
for k, v in EXCHANGE_HAS_REQUIRED.items()
|
||||
if ex_mod.has.get(k) is not True and not (all(ex_mod.has.get(x) for x in v))
|
||||
]
|
||||
reasons = []
|
||||
reasons_fut = ""
|
||||
missing = _exchange_has_helper(ex_mod, EXCHANGE_HAS_REQUIRED)
|
||||
if missing:
|
||||
result = False
|
||||
reason += f"missing: {', '.join(missing)}"
|
||||
reasons.append(f"missing: {', '.join(missing)}")
|
||||
|
||||
missing_opt = [k for k in EXCHANGE_HAS_OPTIONAL if not ex_mod.has.get(k)]
|
||||
missing_opt = _exchange_has_helper(ex_mod, EXCHANGE_HAS_OPTIONAL)
|
||||
|
||||
missing_futures = _exchange_has_helper(ex_mod, EXCHANGE_HAS_OPTIONAL_FUTURES)
|
||||
|
||||
if exchange.lower() in BAD_EXCHANGES:
|
||||
result = False
|
||||
reason = BAD_EXCHANGES.get(exchange.lower(), "")
|
||||
reasons.append(BAD_EXCHANGES.get(exchange.lower(), ""))
|
||||
|
||||
if missing_opt:
|
||||
reason += f"{'. ' if reason else ''}missing opt: {', '.join(missing_opt)}. "
|
||||
reasons.append(f"missing opt: {', '.join(missing_opt)}")
|
||||
|
||||
return result, reason, ex_mod
|
||||
if missing_futures:
|
||||
reasons_fut = f"missing futures opt: {', '.join(missing_futures)}"
|
||||
|
||||
return result, "; ".join(reasons), reasons_fut, ex_mod
|
||||
|
||||
|
||||
def _build_exchange_list_entry(
|
||||
exchange_name: str, exchangeClasses: dict[str, Any]
|
||||
) -> ValidExchangesType:
|
||||
exchange_name = exchange_name.lower()
|
||||
valid, comment, ex_mod = validate_exchange(exchange_name)
|
||||
valid, comment, comment_fut, ex_mod = validate_exchange(exchange_name)
|
||||
mapped_exchange_name = MAP_EXCHANGE_CHILDCLASS.get(exchange_name, exchange_name).lower()
|
||||
is_alias = getattr(ex_mod, "alias", False)
|
||||
result: ValidExchangesType = {
|
||||
@@ -102,6 +120,7 @@ def _build_exchange_list_entry(
|
||||
"valid": valid,
|
||||
"supported": mapped_exchange_name in SUPPORTED_EXCHANGES and not is_alias,
|
||||
"comment": comment,
|
||||
"comment_futures": comment_fut,
|
||||
"dex": getattr(ex_mod, "dex", False),
|
||||
"is_alias": is_alias,
|
||||
"alias_for": inspect.getmro(ex_mod.__class__)[1]().id
|
||||
|
||||
@@ -10,8 +10,7 @@ from freqtrade.enums import MarginMode, PriceType, TradingMode
|
||||
from freqtrade.exceptions import DDosProtection, 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 safe_value_fallback2
|
||||
from freqtrade.exchange.exchange_types import FtHas
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -30,6 +29,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 +43,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,
|
||||
@@ -129,28 +131,3 @@ class Gate(Exchange):
|
||||
"rate": pair_fees[takerOrMaker],
|
||||
}
|
||||
return trades
|
||||
|
||||
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})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user