Compare commits

...

2246 Commits

Author SHA1 Message Date
Matthias
bf53d037b5 Merge pull request #3395 from freqtrade/new_release
New release 2020.5
2020-06-01 06:24:14 +02:00
Matthias
6f870e980d Version bump Pandas to 1.0.4 2020-05-30 10:55:00 +02:00
Matthias
95780cb4a1 Version bump to 2020.5 2020-05-29 19:41:53 +02:00
Matthias
3e5eef1c0d Merge branch 'master' into new_release 2020-05-29 19:41:40 +02:00
hroff-1902
003724e400 Merge pull request #3388 from freqtrade/plotting_fixplot
[minor] Plotting should not fail if one pair didn't produce any trades
2020-05-28 21:53:26 +03:00
Matthias
7df786994d Plotting should not fail if one pair didn't produce any trades 2020-05-28 19:36:10 +02:00
hroff-1902
62ac5a9914 Merge pull request #3385 from freqtrade/3rd_issuetemplate
Add question template ...
2020-05-27 23:00:22 +03:00
hroff-1902
0234e4d293 Merge pull request #3369 from freqtrade/align_trade_outputs
Improve some api results
2020-05-27 22:56:15 +03:00
Matthias
cb40e850e9 Add question template ... 2020-05-27 19:38:21 +02:00
Matthias
04eb11bb5d Merge pull request #3377 from freqtrade/btreport_refactor
Refactor BTReport
2020-05-27 19:33:08 +02:00
Matthias
18a5787a2c Reorder typing imports
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-27 19:17:15 +02:00
Matthias
b2125bd6ee check for None to allow 0.0 profit 2020-05-27 19:15:56 +02:00
hroff-1902
e0dc7fedf5 Merge pull request #3380 from freqtrade/rpi_crosscompile
Raspberry Docker image - fix and correctly crosscompile
2020-05-27 14:31:24 +03:00
hroff-1902
a0556689ea Merge pull request #3381 from freqtrade/fix/orderbook_keyerror
Fix orderbook keyerror
2020-05-27 11:52:29 +03:00
Matthias
f4af4cc2b2 Small formatting improvement 2020-05-27 07:11:59 +02:00
Matthias
8c87fcdae3 Rename PricingException to PricingError 2020-05-26 20:35:11 +02:00
Matthias
16cd1f06b2 Rename get_order_book to fetch_l2_order_book (aligning to ccxt) 2020-05-26 20:27:35 +02:00
Matthias
d09a347853 Add tests for pricingexception 2020-05-26 20:24:44 +02:00
Matthias
7a7b26e840 Add exception handlers for orderbook logic 2020-05-26 20:14:05 +02:00
Matthias
76e4e5897f Introduce pricing exception 2020-05-26 20:08:01 +02:00
Matthias
bdf795b8b0 final cleanup - use different cache image for now 2020-05-26 19:40:27 +02:00
Matthias
3e3cce4559 Use pct instead of _perc 2020-05-26 19:25:03 +02:00
Matthias
448546b0a4 Some cleanup in script 2020-05-26 19:16:44 +02:00
Matthias
e370d635bf Merge pull request #3379 from hroff-1902/fix-3378
Fix #3378
2020-05-26 17:16:11 +02:00
Matthias
2f596f739d Use cache correctly 2020-05-26 17:14:52 +02:00
Matthias
27e0c2604c Add comment to ensure we're not accidentally removing this again 2020-05-26 16:58:29 +02:00
Matthias
500ce50153 Switch to docker experimental ... 2020-05-26 16:45:42 +02:00
Matthias
7f5feab5cf Fix notifications, build ... 2020-05-26 16:45:19 +02:00
Matthias
571d61de84 Cancel previous automatically? 2020-05-26 16:45:15 +02:00
Matthias
4fbd2deb37 Use correct image 2020-05-26 16:45:15 +02:00
Matthias
a7c0e86bfd Test rpi using buildx and dockerfile.armhf
Uses piwheels for pi image
2020-05-26 16:44:49 +02:00
hroff-1902
9f573481a8 Fix #3378 2020-05-26 13:54:45 +03:00
Matthias
18d2587800 Address feedback 2020-05-26 06:12:25 +02:00
Matthias
abf79e4ab4 Use temporary variable to clean up code 2020-05-25 20:47:48 +02:00
Matthias
6a9a8f927e Rename some methods, improve some testing 2020-05-25 20:46:31 +02:00
Matthias
462c35cf75 Move stats generation to the top 2020-05-25 20:22:22 +02:00
Matthias
46f1470e28 Fix failing test 2020-05-25 20:00:05 +02:00
Matthias
027ea64d48 Fix docstrings, extract strategy-list results 2020-05-25 19:55:02 +02:00
Matthias
db257e9f7f Rename method to be public 2020-05-25 19:50:23 +02:00
Matthias
18a2dad684 Extract data generation from generate_text_table 2020-05-25 19:35:32 +02:00
Matthias
0917b17efd Refactor result_line to return dict 2020-05-25 19:21:01 +02:00
Matthias
9c76450f59 Merge pull request #3373 from freqtrade/dependabot/pip/develop/flake8-3.8.2
Bump flake8 from 3.8.1 to 3.8.2
2020-05-25 11:48:48 +02:00
dependabot-preview[bot]
5c5dce5260 Bump flake8 from 3.8.1 to 3.8.2
Bumps [flake8](https://gitlab.com/pycqa/flake8) from 3.8.1 to 3.8.2.
- [Release notes](https://gitlab.com/pycqa/flake8/tags)
- [Commits](https://gitlab.com/pycqa/flake8/compare/3.8.1...3.8.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 09:32:33 +00:00
Matthias
8742126e99 Merge pull request #3375 from freqtrade/dependabot/pip/develop/mkdocs-material-5.2.1
Bump mkdocs-material from 5.1.7 to 5.2.1
2020-05-25 11:31:39 +02:00
Matthias
b587b58852 Merge pull request #3374 from freqtrade/dependabot/pip/develop/pytest-cov-2.9.0
Bump pytest-cov from 2.8.1 to 2.9.0
2020-05-25 11:31:12 +02:00
Matthias
9a97bd3327 Merge pull request #3376 from freqtrade/dependabot/pip/develop/ccxt-1.28.49
Bump ccxt from 1.27.91 to 1.28.49
2020-05-25 11:30:49 +02:00
hroff-1902
c22b790a36 Merge pull request #3366 from freqtrade/issue_template
Update issue template
2020-05-25 12:27:55 +03:00
dependabot-preview[bot]
1c9103a13e Bump ccxt from 1.27.91 to 1.28.49
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.27.91 to 1.28.49.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.27.91...1.28.49)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 09:04:03 +00:00
dependabot-preview[bot]
781de767ed Bump mkdocs-material from 5.1.7 to 5.2.1
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.7 to 5.2.1.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.1.7...5.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 09:02:46 +00:00
dependabot-preview[bot]
6eba718680 Bump pytest-cov from 2.8.1 to 2.9.0
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 2.8.1 to 2.9.0.
- [Release notes](https://github.com/pytest-dev/pytest-cov/releases)
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v2.8.1...v2.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-25 09:02:03 +00:00
Matthias
e1362755d2 Add test for sell_reason_stats 2020-05-25 07:14:21 +02:00
Matthias
876a9e4f44 finish refactor of sell_reason table 2020-05-25 07:08:15 +02:00
Matthias
d17300fd84 Refactor sell reason stats to return a dict 2020-05-25 07:02:24 +02:00
Matthias
9d1ad70bb7 Split optimize generation from printing 2020-05-25 06:44:51 +02:00
Matthias
8217d92ab3 UPdate version question 2020-05-25 06:24:40 +02:00
Matthias
e138f9b23c Apply suggestions from code review
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-24 20:15:10 +02:00
Matthias
aa004fa842 Fix typo in label 2020-05-24 19:20:24 +02:00
Matthias
c5480c2514 Split issue-tempaltes 2020-05-24 19:18:28 +02:00
Matthias
bbd7579aa8 Fix more tests 2020-05-24 09:07:24 +02:00
Matthias
811e23e3da Have profit return time in timestamp 2020-05-24 08:58:26 +02:00
Matthias
859b619a0b Align tests to new output 2020-05-24 08:47:10 +02:00
Matthias
110b5a2521 Add timestamp to trade output 2020-05-24 08:46:50 +02:00
Matthias
73914169e4 Update issue template 2020-05-23 19:21:14 +02:00
hroff-1902
b50d072d82 Merge pull request #3359 from freqtrade/fix_typing
Fix typing circular dependency
2020-05-23 11:56:36 +03:00
Matthias
046202fdda Fix typing circular dependency 2020-05-22 20:56:34 +02:00
Matthias
f1ab1835f1 Merge pull request #3355 from freqtrade/reorder_subcommands
Reorder subcommands
2020-05-22 17:20:24 +02:00
Matthias
073d9d3853 Update readme.md with adjusted sequence 2020-05-22 13:47:11 +02:00
Matthias
98db1d52c6 Reorder new commands 2020-05-22 07:04:36 +02:00
Matthias
43e2bce6f8 Update readme with current command list 2020-05-22 07:00:57 +02:00
Matthias
1663a67959 Reorder list-arguments 2020-05-22 07:00:09 +02:00
Matthias
33b270b81f reorder more arguments 2020-05-22 06:57:20 +02:00
Matthias
fcae48d5a0 Some reordering of subcommands 2020-05-22 06:55:20 +02:00
Matthias
74056e768a Merge pull request #3352 from hroff-1902/improve_pairlist_tests
Improve pairlist tests
2020-05-21 15:06:22 +02:00
hroff-1902
ea13071308 Merge pull request #3351 from freqtrade/fix/notradesplot
[minor] Fix crash when no trades are found in plot-profit
2020-05-21 13:14:41 +03:00
hroff-1902
cd0bf96c0e Improve pairlist tests 2020-05-21 12:52:10 +03:00
Matthias
d31a091d12 Merge pull request #3346 from hroff-1902/refactor_pairlists2
Refactor filter_pairlists()
2020-05-21 07:25:43 +02:00
Matthias
1f386c570d Don't start plotting profit without trades
plotting profit only makes sense when trades are available
2020-05-21 07:13:08 +02:00
Matthias
1a984ac677 Explicitly raise ValueError if trades are empty 2020-05-21 07:12:53 +02:00
Matthias
7bf5e5ba6d Merge pull request #3327 from freqtrade/dependabot/pip/develop/scikit-learn-0.23.0
Bump scikit-learn from 0.22.2.post1 to 0.23.0
2020-05-21 06:24:31 +02:00
hroff-1902
22bcb58716 Merge pull request #3348 from freqtrade/fix_doc_link
[minor] Fix documentation link
2020-05-20 23:40:40 +03:00
hroff-1902
ff7bcb5aae Merge pull request #3344 from freqtrade/fix_cors_policy
CORS - allow authenticated responses
2020-05-20 21:44:30 +03:00
Matthias
3b5ccf2efe Fix documentation link 2020-05-20 19:48:25 +02:00
Matthias
a11651ae67 Correctly test cors 2020-05-20 19:43:52 +02:00
hroff-1902
4f0d928145 Introduce self._enabled in pairlist handlers 2020-05-20 13:41:00 +03:00
hroff-1902
7e43574382 Refactor filter_pairlist() 2020-05-20 13:27:07 +03:00
Matthias
cd3900549c Merge pull request #3341 from hroff-1902/cleanup_get_signal
Minor: cleanup in get_signal()
2020-05-20 07:07:39 +02:00
Matthias
2fbd31f5e0 CORS - allow authenticated responses 2020-05-20 07:04:48 +02:00
Matthias
3c86043235 Merge pull request #3343 from hroff-1902/refactor_verify_blacklist
Refactor verify_blacklist()
2020-05-20 06:34:42 +02:00
Matthias
2498fa5a47 Bump scikit-learn from 0.22.2.post1 to 0.23.1 2020-05-20 06:29:17 +02:00
hroff-1902
696c7e87f2 Use proper logging (using the Filter's logger) 2020-05-19 23:51:39 +03:00
hroff-1902
e96e28df07 Refactor verify_blacklist() 2020-05-19 23:13:51 +03:00
hroff-1902
a8b1dcf3c8 Minor: cleanup in get_signal() 2020-05-19 22:20:53 +03:00
Matthias
d438af342c Merge pull request #3339 from hroff-1902/cleanup-pairlistmanager
Cleanup in pairlistmanager
2020-05-19 14:04:39 +02:00
Matthias
43862d30b9 Merge pull request #3322 from hroff-1902/pairlists-shuffle
Add ShuffleFilter
2020-05-19 14:03:20 +02:00
hroff-1902
4c4fb0c9be Cleanup in pairlistmanager 2020-05-19 03:56:31 +03:00
hroff-1902
d8352bd632 Fix tests for SpreadFilter 2020-05-18 23:48:06 +03:00
hroff-1902
30d1a85895 Adjust docs 2020-05-18 23:46:23 +03:00
hroff-1902
e1e8293a67 Merge remote-tracking branch 'upstream/develop' into pairlists-shuffle 2020-05-18 23:18:41 +03:00
Matthias
63b6f171f9 Merge pull request #3331 from freqtrade/hroff-1902-patch-1
Improve Pairlist docs
2020-05-18 22:02:18 +02:00
Matthias
76bd97d510 Merge pull request #3317 from hroff-1902/refactor-informative
Refactor informative pairs
2020-05-18 21:57:16 +02:00
hroff-1902
2c6c287c4b Address comments made in review 2020-05-18 22:24:38 +03:00
hroff-1902
115586a50f Introduce freqtrade.typing 2020-05-18 21:59:50 +03:00
Matthias
839ca28604 Merge pull request #3334 from hroff-1902/retrier-dependency-exceptions
Do not throttle with DependencyException in Exchange retrier
2020-05-18 19:49:24 +02:00
Matthias
0070bc6666 Merge pull request #3333 from hroff-1902/fix-kraken-import
Minor: correct import of retrier
2020-05-18 19:24:49 +02:00
hroff-1902
6951b20aa0 Do not throttle with DependencyException in retrier 2020-05-18 17:31:34 +03:00
hroff-1902
8bdd5e7121 Minor: correct import of retrier 2020-05-18 15:20:51 +03:00
hroff-1902
0c8aff98e0 Make flake happy 2020-05-18 15:03:36 +03:00
dependabot-preview[bot]
a0c9f7bac8 Bump scikit-learn from 0.22.2.post1 to 0.23.0
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.22.2.post1 to 0.23.0.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.22.2.post1...0.23.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 11:32:03 +00:00
Matthias
5858f3a845 Merge pull request #3328 from freqtrade/dependabot/pip/develop/joblib-0.15.1
Bump joblib from 0.14.1 to 0.15.1
2020-05-18 13:30:47 +02:00
Matthias
1ed40b77dc Merge pull request #3326 from freqtrade/dependabot/pip/develop/mkdocs-material-5.1.7
Bump mkdocs-material from 5.1.6 to 5.1.7
2020-05-18 13:30:13 +02:00
hroff-1902
6fa8750fea Merge branch 'develop' into refactor-informative 2020-05-18 14:00:09 +03:00
hroff-1902
ba26f3a73a Merge branch 'refactor-informative' of ssh://github.com/hroff-1902/freqtrade into refactor-informative 2020-05-18 13:55:09 +03:00
hroff-1902
627c5059f0 Move create_pair_list to pairlistmanager 2020-05-18 13:54:21 +03:00
hroff-1902
f54dc7affd Make flake happy 2020-05-18 13:18:05 +03:00
Matthias
20d75e4a8d Merge pull request #3325 from freqtrade/dependabot/pip/develop/flake8-3.8.1
Bump flake8 from 3.7.9 to 3.8.1
2020-05-18 11:58:08 +02:00
hroff-1902
cc28aae5cb Fix the links again 2020-05-18 12:44:20 +03:00
Matthias
3e3a0164bf Merge pull request #3329 from freqtrade/dependabot/pip/develop/ccxt-1.27.91
Bump ccxt from 1.27.49 to 1.27.91
2020-05-18 11:40:55 +02:00
Matthias
5a9a31351a Adjust empty f-strings to be non-fstrings 2020-05-18 11:40:25 +02:00
hroff-1902
d57ef6a2a6 Pairlist Section reworked 2020-05-18 12:39:52 +03:00
dependabot-preview[bot]
601cbd1231 Bump ccxt from 1.27.49 to 1.27.91
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.27.49 to 1.27.91.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.27.49...1.27.91)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 09:23:03 +00:00
Matthias
849d3cfd0c Merge pull request #3330 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.17
Bump sqlalchemy from 1.3.16 to 1.3.17
2020-05-18 11:21:40 +02:00
dependabot-preview[bot]
ff8e85f2f5 Bump sqlalchemy from 1.3.16 to 1.3.17
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.16 to 1.3.17.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 09:02:29 +00:00
hroff-1902
7d80f8d25c Fix links in docs 2020-05-18 12:02:16 +03:00
dependabot-preview[bot]
37a10d1d30 Bump joblib from 0.14.1 to 0.15.1
Bumps [joblib](https://github.com/joblib/joblib) from 0.14.1 to 0.15.1.
- [Release notes](https://github.com/joblib/joblib/releases)
- [Changelog](https://github.com/joblib/joblib/blob/master/CHANGES.rst)
- [Commits](https://github.com/joblib/joblib/compare/0.14.1...0.15.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 09:01:37 +00:00
dependabot-preview[bot]
a447efbe57 Bump mkdocs-material from 5.1.6 to 5.1.7
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.6 to 5.1.7.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.1.6...5.1.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 09:00:45 +00:00
dependabot-preview[bot]
37fd675aac Bump flake8 from 3.7.9 to 3.8.1
Bumps [flake8](https://gitlab.com/pycqa/flake8) from 3.7.9 to 3.8.1.
- [Release notes](https://gitlab.com/pycqa/flake8/tags)
- [Commits](https://gitlab.com/pycqa/flake8/compare/3.7.9...3.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-18 09:00:23 +00:00
hroff-1902
51c0639e6d Update tests/pairlist/test_pairlist.py
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-05-18 11:54:52 +03:00
hroff-1902
18e38a3fe3 Merge pull request #3323 from freqtrade/simplify_sdnotify
[minor] Simplify sd_notify usage
2020-05-18 11:29:18 +03:00
Matthias
503a8a8243 Simplify sd_notify usage 2020-05-18 07:02:57 +02:00
hroff-1902
287e8bafce Add/adjust tests 2020-05-18 02:37:03 +03:00
hroff-1902
4bfab5e222 Add ShuffleFilter 2020-05-18 02:36:40 +03:00
hroff-1902
fd7fa3116a Merge pull request #3321 from freqtrade/rpc/improve_daily
Improve daily API format
2020-05-18 01:29:28 +03:00
hroff-1902
889d07900a Merge pull request #3320 from freqtrade/fix_sell_spamming
Fix sell spamming
2020-05-17 21:54:08 +03:00
Matthias
64b8d8c7bd Use correct Return hint 2020-05-17 20:18:35 +02:00
Matthias
9d63fada24 Merge pull request #3313 from hroff-1902/refactor-pairlists
Cleanup in pairlists
2020-05-17 20:15:39 +02:00
Matthias
943a2a08f8 Improve daily API format 2020-05-17 20:12:01 +02:00
hroff-1902
16622bbfad Cosmetics in pair lists 2020-05-17 14:44:32 +03:00
hroff-1902
ae69d31095 Cosmetics in IPairList 2020-05-17 14:13:26 +03:00
hroff-1902
97c50f86e9 Cleanup pairlistmanager 2020-05-17 14:10:11 +03:00
Matthias
285bc2511e Improve testcov for default check_*_timeout methods 2020-05-17 11:23:55 +02:00
Matthias
2074d986a6 Update test to verify we're not spamming messages 2020-05-17 11:12:30 +02:00
Matthias
dd55d2eea3 Reduce spammyness of parcial cancel orders 2020-05-17 10:53:07 +02:00
Matthias
1e76bff1bd Add sell_order_status to keep track of cancellations 2020-05-17 10:52:20 +02:00
hroff-1902
ce185a3b19 Remove pairs with no ticker available when it's needed 2020-05-17 11:39:18 +03:00
hroff-1902
d457542d96 Fix PrecisionFilter 2020-05-17 11:11:49 +03:00
hroff-1902
318e435a8f Merge branch 'develop' into refactor-informative 2020-05-16 22:14:50 +03:00
hroff-1902
15ef6df950 Merge pull request #3210 from jpribyl/Cancel_open_orders_on_shutdown
Cancel open orders during shutdown
2020-05-16 21:45:02 +03:00
hroff-1902
baf5f4f29c Update freqtrade/constants.py 2020-05-16 21:28:54 +03:00
hroff-1902
5f2a871637 Add missing module 2020-05-16 17:15:58 +03:00
Matthias
fed75d8718 remove --cancel_open_orders cli switch 2020-05-16 13:23:40 +02:00
Matthias
7a11219b61 Reword some documentation strings
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-16 13:17:48 +02:00
Matthias
2a1fcc0f06 Merge branch 'develop' into pr/jpribyl/3210-1 2020-05-16 13:09:38 +02:00
Matthias
22a08768f7 Add test for cancel_open_order 2020-05-16 12:40:25 +02:00
hroff-1902
e7c11ed2cf Fix fetching timeframe (failed in backtesting) 2020-05-16 12:27:56 +03:00
hroff-1902
facaaabc1e Rename _refresh_whitelist() 2020-05-16 12:27:56 +03:00
hroff-1902
f8b01f5a43 Make flake happy 2020-05-16 12:27:56 +03:00
hroff-1902
035a12ce61 Move _create_pair_whitelist to dataprovider 2020-05-16 12:27:56 +03:00
hroff-1902
bf25746965 Introduce datatype for informative pairs 2020-05-16 12:27:56 +03:00
Matthias
c3f3242f28 Add tests for cancel_open_orders_on_exit 2020-05-16 11:05:34 +02:00
hroff-1902
1b3864ebf8 Make flake happy 2020-05-16 09:21:36 +03:00
hroff-1902
9d6a41aa7a Merge pull request #3315 from freqtrade/flask_cors
Add cors support - needed for UI
2020-05-16 09:07:38 +03:00
Matthias
61f6acb5c9 Add cors support - needed for UI 2020-05-16 07:07:24 +02:00
hroff-1902
72165a1926 Merge pull request #3238 from hroff-1902/dataprovider-add-ticker
Add ticker to dataprovider
2020-05-15 22:03:01 +03:00
hroff-1902
ac076ee0af Update docs/strategy-customization.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-05-15 21:51:33 +03:00
hroff-1902
d84cb3be77 Improve test 2020-05-15 19:19:52 +03:00
hroff-1902
06b12c0a70 Add warning to docs for ticker data 2020-05-15 18:46:28 +03:00
hroff-1902
323b491962 Add description and example for dp.ticker() to the docs 2020-05-15 16:35:48 +03:00
Matthias
788d75572b Merge pull request #3309 from freqtrade/dependabot/docker/python-3.8.3-slim-buster
Bump python from 3.8.2-slim-buster to 3.8.3-slim-buster
2020-05-15 10:14:25 +02:00
dependabot-preview[bot]
33091f95c2 Bump python from 3.8.2-slim-buster to 3.8.3-slim-buster
Bumps python from 3.8.2-slim-buster to 3.8.3-slim-buster.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-15 06:24:54 +00:00
Matthias
ba68c42aae Merge pull request #3297 from bmoulkaf/develop
Fix stoploss on binance bug
2020-05-15 08:23:18 +02:00
Matthias
a7b469e83d Add test verifying correct price reduction on limit stoploss orders 2020-05-15 08:09:53 +02:00
Matthias
92b6d3e2fa Adjust test to reflect correct behaviour 2020-05-15 08:04:14 +02:00
hroff-1902
143e6f52af Simplify SpreadFilter 2020-05-15 05:14:06 +03:00
hroff-1902
cbb2ce3708 Simplify PriceFilter 2020-05-15 04:55:28 +03:00
hroff-1902
2aa80f915d Cosmetics: improve readability 2020-05-15 04:24:18 +03:00
hroff-1902
794ed304b1 Make stoploss an attribute 2020-05-15 04:17:23 +03:00
hroff-1902
afa7a5846b Simplify PriceFilter 2020-05-15 04:05:31 +03:00
hroff-1902
f0c3a0d2f8 Simplify VolumePairList 2020-05-15 03:59:13 +03:00
hroff-1902
2924b70fd7 Cosmetics in tests/pairlist/ 2020-05-15 03:41:41 +03:00
hroff-1902
481f9ba6d6 Use list comprehension instead of filter() 2020-05-15 03:00:55 +03:00
hroff-1902
8e4ffea52b Merge pull request #3239 from freqtrade/feat/fee_handling
Improve fee handling
2020-05-14 18:48:48 +03:00
Matthias
cc3c141f89 Merge pull request #3307 from freqtrade/xmatthias-pi_docs
Add note about PI and docker
2020-05-14 16:13:58 +02:00
Matthias
fb92300cfa Update docs/docker.md
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-14 15:48:23 +02:00
hroff-1902
78b81bac48 Add test for dp.ticker() 2020-05-14 16:43:16 +03:00
Matthias
38fd361c68 Add note about PI and docker 2020-05-14 14:40:40 +02:00
hroff-1902
aae096c6ae Handle fetching ticker for non-existing pair safe way 2020-05-14 13:36:48 +03:00
hroff-1902
3079e18239 Merge branch 'develop' into dataprovider-add-ticker 2020-05-14 13:22:52 +03:00
Matthias
d957f3dd2d Merge pull request #3303 from freqtrade/hroff-1902-patch-1
Minor fix in the strategy docs
2020-05-14 06:13:59 +02:00
hroff-1902
ced812660b Minor fix in the strategy docs 2020-05-13 22:37:50 +03:00
Matthias
255ff6cd06 Should return False if it's not been cancelled empty 2020-05-13 20:52:40 +02:00
hroff-1902
b4d2433fc1 Merge pull request #3267 from GrilledChickenThighs/develop
Method for accessing current pairlist inside strategy.
2020-05-13 21:29:39 +03:00
Matthias
60f26ba501 use update_trade_state also for closed stoploss orders 2020-05-13 20:25:32 +02:00
Matthias
5f0d5a302d Merge pull request #3301 from freqtrade/hroff-1902-patch-1
minor: fix typo in configuration.md
2020-05-13 19:12:19 +02:00
hroff-1902
b3dd0a68d5 minor: fix typo in configuration.md 2020-05-13 18:51:38 +03:00
Matthias
7307ebd1f4 Merge pull request #3300 from Corfucinas/patch-1
Update doc Ta_lib
2020-05-13 15:56:15 +02:00
Pedro Torres
6ff457e391 Update doc Ta_lib
Update the document with the latest Ta_lib-0.4.18. 👍 
The requirements-common.txt has been updated previously on commit a379e68cf4
2020-05-13 20:50:11 +08:00
Paul D. Mendes
6e86a47764 updated docs 2020-05-13 14:49:16 +04:00
Matthias
d86855f2f3 Merge pull request #3129 from freqtrade/trades_to_list
convert dl-trades datadownload to list
2020-05-13 09:41:26 +02:00
bmoulkaf
fe3ea8e7ec Fix stoploss on binance bug 2020-05-13 05:15:18 +00:00
Matthias
0c3bdd66ac Update sql cheatsheet iwth current table structure 2020-05-13 06:50:52 +02:00
Paul D. Mendes
87d9388a9c Merge branch 'develop' of https://github.com/freqtrade/freqtrade into develop 2020-05-13 00:32:46 +04:00
Paul D. Mendes
63dfe3669f Updated docs for #3267 2020-05-13 00:25:57 +04:00
hroff-1902
ed7209f910 Merge pull request #3290 from freqtrade/show_forcebuy
[minor] Show forcebuy status so it's visible before calling forcebuy.
2020-05-12 15:05:56 +03:00
hroff-1902
4c9131bd64 Merge pull request #3291 from hroff-1902/minor-fix-docs2
Docs: Fix samples in strategy-advanced.md
2020-05-12 15:05:07 +03:00
hroff-1902
f1367b38a4 Docs: Fix the fix 2020-05-12 14:42:33 +03:00
Matthias
77c9334c50 Use available config object
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-12 13:39:24 +02:00
hroff-1902
e2b9c24856 Docs: Fix sample in strategy-advanced 2020-05-12 13:54:13 +03:00
Matthias
aa25461e88 Show forcebuy status so it's visible before calling forcebuy. 2020-05-12 07:20:59 +02:00
Matthias
e864db1843 Update test for dp.current_whitelist 2020-05-12 06:38:14 +02:00
Matthias
1aa1fada6a Merge pull request #3289 from prashanthsandela/patch-1
Correct log path in doc.
2020-05-12 06:17:50 +02:00
prashanthsandela
258071928f Correct log path in doc. 2020-05-11 17:21:04 -07:00
hroff-1902
caac562b6b Merge pull request #3246 from flomerz/develop
hyperopt csv export - add params
2020-05-12 00:50:25 +03:00
hroff-1902
7e9998083f Merge pull request #3287 from hroff-1902/tests-suppress-deprecationwarning
Minor: Add filterwarning for DeprecationWarning in test
2020-05-11 22:00:02 +03:00
hroff-1902
c8f3ef884b Minor: Add filterwarning for DeprecationWarning in test 2020-05-11 20:22:19 +03:00
Paul D. Mendes
41bd2c815d Merge branch 'develop' of https://github.com/GrilledChickenThighs/freqtrade into develop 2020-05-11 20:17:24 +04:00
Paul D. Mendes
9fbe135790 attached pairlist manager onto dataprovider init for unified access to dynamic whitelist 2020-05-11 20:17:03 +04:00
Paul D. Mendes
a5bfa5515c Fix flake8 mypy 2020-05-11 20:13:06 +04:00
Paul D. Mendes
bc9efc31ad Added Method for accessing current pair list on initialization for dynamic informative pairs
moved import into function to avoid circular import with hyperopt
2020-05-11 19:45:15 +04:00
Paul D. Mendes
a8f523adae attached pairlist manager onto dataprovider init for unified access to dynamic whitelist 2020-05-11 19:45:15 +04:00
Matthias
20c3d6644c Merge pull request #3283 from freqtrade/dependabot/pip/develop/ta-lib-0.4.18
Bump ta-lib from 0.4.17 to 0.4.18
2020-05-11 14:33:27 +02:00
Matthias
a379e68cf4 Add new ta-lib wheels 2020-05-11 14:02:39 +02:00
Matthias
c351b7848e Merge pull request #3286 from freqtrade/dependabot/pip/develop/mkdocs-material-5.1.6
Bump mkdocs-material from 5.1.5 to 5.1.6
2020-05-11 13:32:32 +02:00
Matthias
e0ea37829b Merge pull request #3285 from freqtrade/dependabot/pip/develop/plotly-4.7.1
Bump plotly from 4.6.0 to 4.7.1
2020-05-11 11:35:42 +02:00
Matthias
265838403e Merge pull request #3284 from freqtrade/dependabot/pip/develop/ccxt-1.27.49
Bump ccxt from 1.27.20 to 1.27.49
2020-05-11 11:29:35 +02:00
Matthias
e1d3cafd80 Merge pull request #3282 from freqtrade/dependabot/pip/develop/pytest-5.4.2
Bump pytest from 5.4.1 to 5.4.2
2020-05-11 11:21:59 +02:00
dependabot-preview[bot]
96710d42f5 Bump mkdocs-material from 5.1.5 to 5.1.6
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.5 to 5.1.6.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.1.5...5.1.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 09:13:06 +00:00
dependabot-preview[bot]
e38581c19f Bump plotly from 4.6.0 to 4.7.1
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.6.0 to 4.7.1.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.6.0...v4.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 09:12:38 +00:00
dependabot-preview[bot]
43ab814f30 Bump ccxt from 1.27.20 to 1.27.49
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.27.20 to 1.27.49.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.27.20...1.27.49)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 09:12:11 +00:00
dependabot-preview[bot]
3849b68b8f Bump ta-lib from 0.4.17 to 0.4.18
Bumps [ta-lib](https://github.com/mrjbq7/ta-lib) from 0.4.17 to 0.4.18.
- [Release notes](https://github.com/mrjbq7/ta-lib/releases)
- [Changelog](https://github.com/mrjbq7/ta-lib/blob/master/CHANGELOG)
- [Commits](https://github.com/mrjbq7/ta-lib/compare/TA_Lib-0.4.17...TA_Lib-0.4.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 09:11:22 +00:00
dependabot-preview[bot]
306eae6da3 Bump pytest from 5.4.1 to 5.4.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.4.1 to 5.4.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.4.1...5.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 09:10:48 +00:00
hroff-1902
bbb609c927 Merge pull request #3278 from freqtrade/api/jwt
API server - support JWT
2020-05-10 21:33:41 +03:00
Matthias
9eca268a49 Fix test 2020-05-10 20:00:19 +02:00
Matthias
d291ca0071 Simplify code section 2020-05-10 19:43:16 +02:00
Matthias
21c2af2b92 Load jwt_key from config 2020-05-10 19:42:06 +02:00
Matthias
c3f0b5d4eb Rename methods to match endpoints 2020-05-10 19:37:41 +02:00
hroff-1902
f64209e426 Merge pull request #3281 from freqtrade/sell_order_cancel_exception
Sell order cancel exception
2020-05-10 19:22:14 +03:00
Matthias
b163bb7650 Apply suggestions from code review
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-10 17:48:29 +02:00
Matthias
c2224ed6b7 Fix doc typos
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-10 17:47:43 +02:00
Matthias
73a1496318 Catch exception on cancel_order 2020-05-10 17:44:45 +02:00
Matthias
2406e20be2 Update docs/rest-api.md
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-10 17:36:43 +02:00
Matthias
80faa5feb1 Add test to cancel sell order 2020-05-10 16:24:00 +02:00
Matthias
d9e4f41a35 Add documentation for JWt 2020-05-10 16:14:35 +02:00
hroff-1902
a2ec18680e Merge pull request #3279 from meauxt/develop
Fix Typo in telegram Plugin
2020-05-10 12:24:15 +03:00
Mohamad Tarbin
570c51b0b0 Fix Typo in telegram Plugin 2020-05-10 05:07:49 -04:00
Matthias
f246336943 Merge pull request #3277 from hroff-1902/edge-fix-fee
Fix fee usage in Edge
2020-05-10 10:58:57 +02:00
hroff-1902
51d2b817ae Use self.fee 2020-05-10 11:51:33 +03:00
Matthias
bc64619f30 Tests for JWT implementation 2020-05-10 10:43:13 +02:00
Matthias
8139058fcc Implement token/login and token/refresh endpoints 2020-05-10 10:35:38 +02:00
Matthias
0bd2fca40b Update tests/test_integration.py
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-05-10 09:55:41 +02:00
hroff-1902
b6a2c38941 Adjust tests 2020-05-10 02:39:22 +03:00
hroff-1902
7e08fa2631 Fix usage of fee value in Edge 2020-05-10 02:22:16 +03:00
Matthias
b72997fc2b Add flask-jwt-extended dependency 2020-05-09 20:16:04 +02:00
Matthias
37439b836b Merge pull request #3275 from hroff-1902/exchange-cosmetics-2
Minor: improve exception handling in exchange
2020-05-09 19:25:35 +02:00
hroff-1902
d4362ed357 Minor: improve exception handling in exchange 2020-05-09 09:29:40 +03:00
hroff-1902
2307495f28 Update docs/configuration.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-05-08 20:10:16 +03:00
hroff-1902
18ec65e05f Merge pull request #3269 from freqtrade/improve_exceptionlogging
[minor] Improve exception handling on critical errors
2020-05-08 15:39:54 +03:00
Matthias
80d367fa08 Add test for keyboardinterrupt 2020-05-08 14:24:30 +02:00
Matthias
5272ec85ea Add additional test 2020-05-08 12:34:24 +02:00
Matthias
c560de4111 Improve exception handling on critical errors 2020-05-08 11:44:24 +02:00
hroff-1902
5b92387732 Merge pull request #3259 from freqtrade/fix/filled
Fix handling of partially or non-filled timedout orders
2020-05-07 09:58:26 +03:00
Matthias
1ba2df79c6 Ause isclose for comparison, assign filled to variable
add some comments
2020-05-07 06:51:02 +02:00
hroff-1902
06313cdddf Merge pull request #3264 from freqtrade/api_improvements
Api improvements
2020-05-07 00:05:36 +03:00
Matthias
a62d7495ca FIx typo in telegram method 2020-05-05 21:28:59 +02:00
Matthias
593d13ebdd Show new values also in Telegram 2020-05-05 21:21:20 +02:00
Matthias
e4023a6567 Add some minor things to show_config 2020-05-05 21:19:35 +02:00
hroff-1902
77d889beff Merge pull request #3262 from freqtrade/humanize_show_trades_error
Humanize show-trades error when no database is specified
2020-05-05 21:28:14 +03:00
Matthias
ffef4bc474 Humanize show-trades error when no database is specified 2020-05-05 19:48:28 +02:00
hroff-1902
1b448f57b9 Merge pull request #3242 from freqtrade/feat/trade_show
New subcommand show-trades
2020-05-05 19:26:59 +03:00
hroff-1902
0340d7bf37 Merge pull request #3249 from freqtrade/increase_rate_cache
[minor] Increase cache for rate limit to avoid delays
2020-05-05 19:08:31 +03:00
Matthias
d3a0ab8096 Change mock-status to be open when testing unfilled... 2020-05-05 07:12:49 +02:00
Matthias
981976681a Use filled, it's the safer choice when determining the filled amount. 2020-05-05 07:09:12 +02:00
Matthias
b4aeb93a18 Add test testing the different ways exchanges may return data 2020-05-05 07:07:42 +02:00
Matthias
f040c20688 Use filled in tests 2020-05-05 06:41:01 +02:00
Matthias
648723fb83 Use 30min rate cache 2020-05-05 06:32:03 +02:00
Matthias
06aee85398 Merge pull request #3253 from freqtrade/dependabot/pip/develop/progressbar2-3.51.3
Bump progressbar2 from 3.51.0 to 3.51.3
2020-05-04 15:13:21 +02:00
Matthias
3ad9df66ad Merge pull request #3252 from freqtrade/dependabot/pip/develop/pytest-asyncio-0.12.0
Bump pytest-asyncio from 0.11.0 to 0.12.0
2020-05-04 15:06:43 +02:00
Matthias
e6c83b802f Merge pull request #3256 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.7
Bump python-telegram-bot from 12.6.1 to 12.7
2020-05-04 15:03:51 +02:00
dependabot-preview[bot]
5dde6d3fac Bump python-telegram-bot from 12.6.1 to 12.7
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.6.1 to 12.7.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.6.1...v12.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 12:40:24 +00:00
Matthias
7ad6e03e5a Merge pull request #3250 from freqtrade/dependabot/pip/develop/numpy-1.18.4
Bump numpy from 1.18.3 to 1.18.4
2020-05-04 14:39:06 +02:00
Matthias
a0fe49ede6 Merge pull request #3251 from freqtrade/dependabot/pip/develop/arrow-0.15.6
Bump arrow from 0.15.5 to 0.15.6
2020-05-04 13:56:23 +02:00
Matthias
e5cc0640f6 Merge pull request #3254 from freqtrade/dependabot/pip/develop/ccxt-1.27.20
Bump ccxt from 1.27.1 to 1.27.20
2020-05-04 13:55:26 +02:00
Matthias
f7020bdc10 Merge pull request #3255 from freqtrade/dependabot/pip/develop/mkdocs-material-5.1.5
Bump mkdocs-material from 5.1.3 to 5.1.5
2020-05-04 13:46:10 +02:00
dependabot-preview[bot]
32eb1c5705 Bump mkdocs-material from 5.1.3 to 5.1.5
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.3 to 5.1.5.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.1.3...5.1.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:19:26 +00:00
dependabot-preview[bot]
611b9c88d1 Bump ccxt from 1.27.1 to 1.27.20
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.27.1 to 1.27.20.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.27.1...1.27.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:18:49 +00:00
dependabot-preview[bot]
2c352e6b82 Bump progressbar2 from 3.51.0 to 3.51.3
Bumps [progressbar2](https://github.com/WoLpH/python-progressbar) from 3.51.0 to 3.51.3.
- [Release notes](https://github.com/WoLpH/python-progressbar/releases)
- [Changelog](https://github.com/WoLpH/python-progressbar/blob/develop/CHANGES.rst)
- [Commits](https://github.com/WoLpH/python-progressbar/compare/v3.51.0...v3.51.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:18:02 +00:00
dependabot-preview[bot]
68f0b105a9 Bump pytest-asyncio from 0.11.0 to 0.12.0
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.11.0...v0.12.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:17:23 +00:00
dependabot-preview[bot]
a14e027ad4 Bump arrow from 0.15.5 to 0.15.6
Bumps [arrow](https://github.com/crsmithdev/arrow) from 0.15.5 to 0.15.6.
- [Release notes](https://github.com/crsmithdev/arrow/releases)
- [Changelog](https://github.com/crsmithdev/arrow/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/crsmithdev/arrow/compare/0.15.5...0.15.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:16:50 +00:00
dependabot-preview[bot]
f7a3bb82da Bump numpy from 1.18.3 to 1.18.4
Bumps [numpy](https://github.com/numpy/numpy) from 1.18.3 to 1.18.4.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.18.3...v1.18.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:16:28 +00:00
hroff-1902
b88724ed9e Merge pull request #3248 from freqtrade/fallback_amoutn
[minor] Improve logmessage when falling back to wallet amount
2020-05-04 05:22:20 +03:00
Matthias
b38f9ed5e7 Increase cache for rate limit to avoid delays
Helps when calling /status or /status table frequently on slowish
exchanges
2020-05-03 20:44:18 +02:00
Matthias
2a4c9bf3d3 Improve logmessage when falling back to wallet amount 2020-05-03 20:32:45 +02:00
Florian Merz
889a153731 fix PEP8 2020-05-03 17:29:56 +02:00
Florian Merz
690bb7646a hyperopt csv export - add params 2020-05-03 17:00:12 +02:00
Matthias
1c9c72937e Adjust trade-ids param 2020-05-03 15:32:09 +02:00
Matthias
e92d3867cf Fix failing test 2020-05-03 15:25:54 +02:00
Matthias
81397874eb Remove commented mock 2020-05-03 11:29:51 +02:00
Matthias
72282a2239 Add explicit test for fee_conditional 2020-05-03 11:28:29 +02:00
Matthias
58168336e1 Add test for apply_fee_conditional 2020-05-03 11:13:59 +02:00
Matthias
38c4949360 Align applying of fee when comming from orders or trades 2020-05-03 10:50:59 +02:00
Matthias
7dcef58f15 Add show-trades to documentation 2020-05-02 11:50:53 +02:00
Matthias
1066a4504b Add test for show_trades 2020-05-02 11:44:18 +02:00
Matthias
56bb5f7a11 Add show-trades command 2020-05-02 11:26:12 +02:00
Matthias
78b3d8487f Add typehint 2020-05-01 20:34:58 +02:00
Matthias
021e2b58ca Support partially cancelled orders for fee calculation 2020-05-01 20:24:26 +02:00
Matthias
737fc6d198 Fix bug when querying side 2020-05-01 20:05:13 +02:00
Matthias
71c90422ba Add explicit test for fee_updated 2020-05-01 20:02:38 +02:00
Matthias
6d620ba1f6 Verify if fee for this side has been updated 2020-05-01 19:54:16 +02:00
Matthias
6b33d5af1e Fix fee-calculation for dry-run orders 2020-05-01 19:51:35 +02:00
jpribyl
bd51cd332b Cancel all open orders after receiving /stop or ctrl+c 2020-05-01 10:36:11 -06:00
hroff-1902
0f50449196 Merge pull request #3241 from freqtrade/fix/deprecation
Use non-deprectated parameter for progressbar
2020-05-01 19:18:28 +03:00
Matthias
509f38d3aa Use non-deprectated parameter for progressbar 2020-05-01 17:59:24 +02:00
Matthias
40d4949f06 Don't handle trades if they've just been closed. 2020-05-01 17:46:01 +02:00
Matthias
7558e4bffe Split fee detection from trades from general logic 2020-05-01 16:13:07 +02:00
Matthias
371100a97c Update fee handling 2020-05-01 16:01:33 +02:00
Matthias
a2ff632647 Add update_fee method to persistence 2020-05-01 16:01:12 +02:00
Matthias
fdcc507f06 Fix integration tests 2020-05-01 15:50:02 +02:00
Matthias
b93d33a93a Fix mock order dicts 2020-05-01 15:50:02 +02:00
Matthias
db8fb39a38 don't use trade.update directly! 2020-05-01 15:50:02 +02:00
Matthias
59bafc8d02 Implement fee rate calculation 2020-05-01 15:50:02 +02:00
Matthias
45c97fde2d Use correct typehint for extract_cost_curr_rate 2020-05-01 15:50:02 +02:00
Matthias
f8f794a803 Simplify fee-related tests 2020-05-01 15:49:52 +02:00
hroff-1902
63b55658ac Add ticker to dataprovider 2020-05-01 05:11:30 +03:00
Matthias
e74ed0ba7b Add tests for fee extraction methods 2020-04-30 20:05:27 +02:00
Matthias
2e4dc6c253 Exchange should return fee dict for dry-run orders 2020-04-30 19:56:48 +02:00
Matthias
a867d40eac Move fee_methods to exchange 2020-04-30 19:33:27 +02:00
Matthias
d3b9f4d393 Add extract_cost_curr_rate 2020-04-30 19:28:36 +02:00
Matthias
6d7a3a0cc9 Extract more logic into order-has_fee 2020-04-30 07:12:08 +02:00
Matthias
b125dd3728 Extract order_has_fee method 2020-04-30 07:06:06 +02:00
Matthias
7936120afc Adapt tests to support new db fields 2020-04-30 06:58:55 +02:00
Matthias
dec1b10743 Add fee_cost and currency columns 2020-04-30 06:57:39 +02:00
Matthias
25d9001f88 Merge pull request #3234 from hroff-1902/hyperopt-use-model-queue-size
Use skopt model_queue_size instead of custom hack
2020-04-29 19:29:27 +02:00
hroff-1902
38c6ba6c08 Update setup.py
Co-Authored-By: Matthias <xmatthias@outlook.com>
2020-04-29 13:54:47 +03:00
hroff-1902
9152e76966 Add skopt version check into setup.py 2020-04-29 13:54:47 +03:00
hroff-1902
fb0dfee3eb Merge pull request #3235 from freqtrade/xmatthias-patch-1
Be clear on evaluation logic during backtesting
2020-04-29 12:08:41 +03:00
Matthias
69b44234a4 Update docs/backtesting.md
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-04-29 10:47:53 +02:00
Matthias
74281a16fd Move to the last point and clarify further 2020-04-29 10:39:55 +02:00
Matthias
1a6ddfcaeb Be clear on evaluation logic during backtesting 2020-04-29 10:37:48 +02:00
hroff-1902
726e52aaa7 Use skopt model_queue_size instead of custom hack 2020-04-29 10:49:25 +03:00
Matthias
32eaca9970 Merge pull request #3231 from hroff-1902/hyperopt-cleanup6
Cleanup in Hyperopt
2020-04-29 06:11:17 +02:00
hroff-1902
c6787d7e9f Do not use 'trials' in commands 2020-04-28 23:14:02 +03:00
hroff-1902
c26835048c Hyperopt cleanup, do not use 'trials' 2020-04-28 22:56:19 +03:00
hroff-1902
09e488a693 Merge pull request #3229 from hroff-1902/hyperopt-improve-logging
Improve hyperopt-list logging
2020-04-28 17:42:56 +03:00
hroff-1902
a01ed170f5 Improve hyperopt-list logging 2020-04-28 17:33:07 +03:00
hroff-1902
2a9653cd4e Merge pull request #3228 from freqtrade/new_release2020.4
New release 2020.4
2020-04-28 12:18:54 +03:00
Matthias
fa6fe618ac Version bump 2020.4 2020-04-28 10:55:27 +02:00
Matthias
ce3fa533ae Merge branch 'master' into new_release2020.4 2020-04-28 07:51:05 +02:00
hroff-1902
fedcf1db52 Merge pull request #3217 from freqtrade/remove_deprecation
Remove deprecated pairlist and binary
2020-04-27 19:41:54 +03:00
Matthias
3754bf46ed Change wording in deprecation messages
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-04-27 17:13:30 +02:00
hroff-1902
9ebc997e9d Merge pull request #3215 from freqtrade/backtest_use_pairlists
Backtest use pairlists
2020-04-27 13:34:06 +03:00
Matthias
5870d9dfc0 Merge pull request #3226 from freqtrade/dependabot/pip/develop/mkdocs-material-5.1.3
Bump mkdocs-material from 5.1.1 to 5.1.3
2020-04-27 11:25:48 +02:00
Matthias
73185471df Merge pull request #3225 from freqtrade/dependabot/pip/develop/pytest-asyncio-0.11.0
Bump pytest-asyncio from 0.10.0 to 0.11.0
2020-04-27 11:19:25 +02:00
Matthias
1d55514991 Merge pull request #3224 from freqtrade/dependabot/pip/develop/progressbar2-3.51.0
Bump progressbar2 from 3.50.1 to 3.51.0
2020-04-27 11:16:31 +02:00
Matthias
5b84e92b2e Merge pull request #3223 from freqtrade/dependabot/pip/develop/ccxt-1.27.1
Bump ccxt from 1.26.53 to 1.27.1
2020-04-27 11:15:16 +02:00
dependabot-preview[bot]
abbb3254b2 Bump mkdocs-material from 5.1.1 to 5.1.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.1 to 5.1.3.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.1.1...5.1.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-27 09:03:59 +00:00
dependabot-preview[bot]
52c92a19e3 Bump pytest-asyncio from 0.10.0 to 0.11.0
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.10.0 to 0.11.0.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.10.0...v0.11.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-27 09:03:30 +00:00
dependabot-preview[bot]
2122384ec1 Bump progressbar2 from 3.50.1 to 3.51.0
Bumps [progressbar2](https://github.com/WoLpH/python-progressbar) from 3.50.1 to 3.51.0.
- [Release notes](https://github.com/WoLpH/python-progressbar/releases)
- [Changelog](https://github.com/WoLpH/python-progressbar/blob/develop/CHANGES.rst)
- [Commits](https://github.com/WoLpH/python-progressbar/compare/v3.50.1...v3.51.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-27 09:02:49 +00:00
dependabot-preview[bot]
77a2ff8917 Bump ccxt from 1.26.53 to 1.27.1
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.26.53 to 1.27.1.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.26.53...1.27.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-27 09:02:21 +00:00
hroff-1902
9ed627091b Merge pull request #3216 from freqtrade/hyperopt_docs
Hyperopt should mention that a strategy is mandatory.
2020-04-27 10:13:14 +03:00
Matthias
fb8a85da01 Disallow VolumePairList from backtesting for now 2020-04-27 07:56:17 +02:00
Matthias
e928c5fdaf Update docs/hyperopt.md
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-04-27 07:15:37 +02:00
hroff-1902
485e324d36 Merge pull request #2872 from freqtrade/interface_ordertimeoutcallback
Buy order timeout callback
2020-04-25 19:02:15 +03:00
Matthias
255a43c98e Update price timeout example 2020-04-25 17:25:18 +02:00
Matthias
927a7ee330 Merge pull request #3218 from freqtrade/setup_sh
[minor] Update "final" message in setup.sh
2020-04-25 17:05:34 +02:00
Matthias
e1a347df90 Use subcommand, add 3rd line 2020-04-25 16:55:13 +02:00
Matthias
deb14e0c85 Update "final" message in setup.sh
closes #2773
2020-04-25 16:32:11 +02:00
Matthias
9fa21628d7 Deprecate keys other than quoteVolume
fixes #2981
2020-04-25 16:29:17 +02:00
Matthias
d1a24db6b7 Remove deprecated pairlist and binary 2020-04-25 16:04:10 +02:00
Matthias
a3a045dbd4 Add small section noting that a strategy file is always necessary
fix #3047
2020-04-25 15:54:46 +02:00
Matthias
e8530c36d3 Remove pairlists from hyperopt too (it holds a reference to exchange) 2020-04-25 15:46:20 +02:00
Matthias
57345476ab Document pairlists for backtesting 2020-04-25 15:39:27 +02:00
Matthias
8987859044 Enable pairlist parsing for backtesting and hyperopt 2020-04-25 15:37:13 +02:00
Matthias
1761f5af1a Merge pull request #3214 from hroff-1902/hyperopt-best-asterisk
Better handling and description of asterisk in Hyperopt output
2020-04-25 15:28:02 +02:00
hroff-1902
d9f255a6c0 Fix asterisk printing for csv output 2020-04-25 12:49:14 +03:00
hroff-1902
c230a94d55 Fix #3065 2020-04-25 11:23:54 +03:00
hroff-1902
2d994f6feb Better printing of asterisk 2020-04-24 21:57:29 +03:00
Matthias
a19ea0f46f Merge pull request #3207 from hroff-1902/hyperopt-cleanup5
Minor: Remove unused methods in hyperopt
2020-04-24 19:17:40 +02:00
hroff-1902
6e5f0869b3 Remove another unused method 2020-04-24 18:39:08 +03:00
hroff-1902
5c012d79eb Remove unused method 2020-04-24 18:14:07 +03:00
hroff-1902
c5b204ea87 Merge pull request #3205 from freqtrade/fix/ftx_dynamic_crash
fix crash with Dynamic whitelist with pairfilter on FTX
2020-04-24 15:51:38 +03:00
Matthias
9627604ec3 change wording of log message 2020-04-24 07:58:18 +02:00
Matthias
f4995780e5 Verify last is not None - to avoid crashing
fix #3117
2020-04-23 20:04:36 +02:00
Matthias
461b0ef738 Add test verifying we're not reintroducing this in the future
Tests case of FTX, which returns mostly empty ticker info
2020-04-23 20:04:14 +02:00
Matthias
e6d3e2e7d3 Merge pull request #3203 from jpribyl/update_expectancy_docs
Update wording in expectancy docs and add example
2020-04-23 19:44:02 +02:00
jpribyl
662ec1cd60 Update wording in expectancy docs and add example 2020-04-22 18:45:33 -06:00
hroff-1902
1057c4e4ba Merge pull request #3202 from freqtrade/docs/sqlhelper
Update sql cheatsheet to allow manual closing trades correctly
2020-04-22 09:01:19 +03:00
Matthias
adf0bb69b8 Update sql cheatsheet to allow manual closing trades correctly 2020-04-22 06:39:03 +02:00
hroff-1902
5138b83afd Merge pull request #3200 from freqtrade/docker_log_location
Docker log location
2020-04-21 23:43:41 +03:00
Matthias
6b53197dfc Fix documentation to use --logfile, not --logfilename (which does not
exist)
2020-04-21 20:42:58 +02:00
Matthias
87f1060abc Default docker to log into log-dir 2020-04-21 19:47:49 +02:00
Matthias
102c4cf261 Merge pull request #3197 from freqtrade/dependabot/pip/develop/ccxt-1.26.53
Bump ccxt from 1.26.32 to 1.26.53
2020-04-20 13:45:14 +02:00
Matthias
6ea671ea0e Merge pull request #3192 from freqtrade/dependabot/pip/develop/pytest-mock-3.1.0
Bump pytest-mock from 3.0.0 to 3.1.0
2020-04-20 13:44:03 +02:00
Matthias
9a34deb4ea Merge pull request #3193 from freqtrade/dependabot/pip/develop/urllib3-1.25.9
Bump urllib3 from 1.25.8 to 1.25.9
2020-04-20 13:43:18 +02:00
Matthias
cdb91f00ff Merge pull request #3195 from freqtrade/dependabot/pip/develop/questionary-1.5.2
Bump questionary from 1.5.1 to 1.5.2
2020-04-20 13:24:57 +02:00
Matthias
f35c51f69c Merge pull request #3196 from freqtrade/dependabot/pip/develop/numpy-1.18.3
Bump numpy from 1.18.2 to 1.18.3
2020-04-20 13:23:47 +02:00
Matthias
f1fb22202e Merge pull request #3194 from freqtrade/dependabot/pip/develop/mkdocs-material-5.1.1
Bump mkdocs-material from 5.1.0 to 5.1.1
2020-04-20 13:23:21 +02:00
dependabot-preview[bot]
a7249f3865 Bump ccxt from 1.26.32 to 1.26.53
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.26.32 to 1.26.53.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.26.32...1.26.53)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 09:28:19 +00:00
dependabot-preview[bot]
597f053ae3 Bump numpy from 1.18.2 to 1.18.3
Bumps [numpy](https://github.com/numpy/numpy) from 1.18.2 to 1.18.3.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.18.2...v1.18.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 09:27:37 +00:00
dependabot-preview[bot]
84d09eb96d Bump questionary from 1.5.1 to 1.5.2
Bumps [questionary](https://github.com/tmbo/questionary) from 1.5.1 to 1.5.2.
- [Release notes](https://github.com/tmbo/questionary/releases)
- [Commits](https://github.com/tmbo/questionary/compare/1.5.1...1.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 09:27:16 +00:00
dependabot-preview[bot]
d395d7ac7d Bump mkdocs-material from 5.1.0 to 5.1.1
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.1.0 to 5.1.1.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.1.0...5.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 09:26:31 +00:00
dependabot-preview[bot]
4742fc6657 Bump urllib3 from 1.25.8 to 1.25.9
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.8 to 1.25.9.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/master/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.25.8...1.25.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 09:26:09 +00:00
dependabot-preview[bot]
76dd388b3c Bump pytest-mock from 3.0.0 to 3.1.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.0.0...v3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 09:25:17 +00:00
Matthias
431b244f43 Merge branch 'develop' into interface_ordertimeoutcallback 2020-04-19 06:58:44 +02:00
hroff-1902
4bbade245c Merge pull request #3181 from freqtrade/fix/cancel_problems
Fix several cancel order problems
2020-04-18 11:16:59 +03:00
hroff-1902
def8635b6d Merge pull request #3184 from freqtrade/fix/hyperopt_randfailure
Fix random test failure in hyperopt
2020-04-18 09:49:09 +03:00
Matthias
a6bdf686ae Merge pull request #3183 from freqtrade/hroff-1902-patch-1
minor: fix typo in the docs
2020-04-18 06:56:45 +02:00
Matthias
c775d65126 Update typehint for cancel_order 2020-04-18 06:55:25 +02:00
hroff-1902
2f60d9cad4 minor: fix typo in the docs 2020-04-17 23:23:22 +03:00
hroff-1902
e3e38ba68f Merge pull request #3182 from freqtrade/hyperopt_install
document to install hyperopt dependencies
2020-04-17 23:22:18 +03:00
Matthias
506781f410 Reword hyperopt install docs 2020-04-17 20:48:27 +02:00
Matthias
0273539f06 Remove exceptionhandler, this exception is handled in
cancel_with_response
2020-04-17 19:55:53 +02:00
Matthias
55af8bf26f document to install hyperopt dependencies 2020-04-17 19:49:43 +02:00
Matthias
1069cb3616 Use cancel_order_with_result when cancelling orders after timeout 2020-04-17 17:53:56 +02:00
Matthias
5e3e0e819f Add tests for cancel_order_with_result 2020-04-17 17:53:18 +02:00
Matthias
800891a475 Add tests for cancel_order_with_result 2020-04-17 07:18:46 +02:00
Matthias
fc684b0091 Ensure deleting filled is not raising an error if filled does not exist 2020-04-17 06:59:52 +02:00
Matthias
7aba9bc62a Update freqtrade/data/converter.py
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-04-17 06:22:25 +02:00
hroff-1902
68be239a0e Merge pull request #3146 from freqtrade/buy_order_timeout_logging
Improve handling for buy order cancels
2020-04-16 23:41:45 +03:00
Matthias
1f70fcfa2d Update logmessage 2020-04-16 20:19:34 +02:00
hroff-1902
9364a9c4c4 Merge pull request #3168 from freqtrade/fix_pairlist_caching
Fix pairlist caching
2020-04-16 18:39:00 +03:00
hroff-1902
df79011aba Merge pull request #3112 from freqtrade/trade_state_updates
Trade state updates
2020-04-16 12:05:19 +03:00
Matthias
d36e2cf6ab Fix random test failure in hyperopt 2020-04-16 07:06:47 +02:00
hroff-1902
b07d61f3d9 Merge pull request #3169 from freqtrade/fix_pricefilter
Fix pricefilter
2020-04-15 20:53:59 +03:00
Matthias
05c9a9b530 Merge pull request #3172 from freqtrade/dependabot/pip/develop/ccxt-1.26.32
Bump ccxt from 1.26.12 to 1.26.32
2020-04-15 14:34:38 +02:00
Matthias
9e69287740 Merge pull request #3173 from freqtrade/dependabot/pip/develop/jinja2-2.11.2
Bump jinja2 from 2.11.1 to 2.11.2
2020-04-15 14:25:16 +02:00
dependabot-preview[bot]
16a810a0f6 Bump jinja2 from 2.11.1 to 2.11.2
Bumps [jinja2](https://github.com/pallets/jinja) from 2.11.1 to 2.11.2.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/2.11.1...2.11.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-15 12:14:53 +00:00
dependabot-preview[bot]
8314759228 Bump ccxt from 1.26.12 to 1.26.32
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.26.12 to 1.26.32.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.26.12...1.26.32)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-15 12:14:35 +00:00
hroff-1902
8b6a7e685e Merge pull request #3133 from freqtrade/backtesting_filenameexpanding
[minor] Fix filename handling with --strategy-list
2020-04-15 12:02:19 +03:00
Matthias
99f3e9ed77 Remove wrong comment 2020-04-15 07:55:15 +02:00
Matthias
33b6c7de5b Add tests for price_one_pip 2020-04-15 07:53:31 +02:00
Matthias
36e714a7b2 Add price_get_one_pip filter 2020-04-15 07:19:27 +02:00
Matthias
ac008a4758 Remove obsolete comment in tests 2020-04-15 06:58:54 +02:00
Matthias
2b7376f6f3 Implement log-filtering for all pairlists 2020-04-14 20:45:30 +02:00
Matthias
1b2bf2c9b6 Add test for cached log method 2020-04-14 20:39:54 +02:00
Matthias
ceca0a659c Simplify cached stuff to only what's needed 2020-04-14 20:25:58 +02:00
Matthias
13ee7a55c4 Fix #3166
Always call _gen_pair_whitelist if volumepairlist is not the first in
the list.
2020-04-14 20:21:30 +02:00
Matthias
5d876ca0a3 Use log-spamprevention methods 2020-04-14 20:21:10 +02:00
Matthias
7c15375f5d Add log_on_refresh - using TTL caching to avoid spamming logs 2020-04-14 20:20:36 +02:00
Matthias
cfe1e4876a Improve testcase for cancel_order_empty 2020-04-14 19:20:47 +02:00
Matthias
c8ccdbcb9a Merge pull request #3150 from freqtrade/version_docker
[minor] have version-detection fall back to freqtrade_commit
2020-04-14 15:53:05 +02:00
hroff-1902
f2b1802666 Merge pull request #3137 from freqtrade/fix_maxdrawdown
[minor] Fix maxdrawdown
2020-04-14 16:03:25 +03:00
Matthias
55a052bcf6 fix typo in comment
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-04-14 08:05:46 +02:00
Matthias
ddf37ef059 Add test to demonstrate that the dataframe is not changed 2020-04-14 08:02:42 +02:00
hroff-1902
4d80f52db4 Merge pull request #3134 from freqtrade/backtesting_memory
Backtesting memory and dataframe
2020-04-13 23:08:45 +03:00
Matthias
9239c00866 Merge pull request #3159 from freqtrade/dependabot/pip/develop/ccxt-1.26.12
Bump ccxt from 1.25.81 to 1.26.12
2020-04-13 19:25:52 +02:00
dependabot-preview[bot]
a1d2124e45 Bump ccxt from 1.25.81 to 1.26.12
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.25.81 to 1.26.12.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.25.81...1.26.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 12:29:38 +00:00
Matthias
e333716635 Merge pull request #3156 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.6.1
Bump python-telegram-bot from 12.5.1 to 12.6.1
2020-04-13 14:28:25 +02:00
Matthias
3d74bdf039 Merge pull request #3154 from freqtrade/dependabot/pip/develop/cachetools-4.1.0
Bump cachetools from 4.0.0 to 4.1.0
2020-04-13 14:28:13 +02:00
Matthias
afc48782b7 Merge pull request #3155 from freqtrade/dependabot/pip/develop/coveralls-2.0.0
Bump coveralls from 1.11.1 to 2.0.0
2020-04-13 13:47:15 +02:00
dependabot-preview[bot]
a166fc887f Bump python-telegram-bot from 12.5.1 to 12.6.1
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.5.1 to 12.6.1.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.5.1...v12.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 11:47:14 +00:00
dependabot-preview[bot]
fb0d76b94a Bump cachetools from 4.0.0 to 4.1.0
Bumps [cachetools](https://github.com/tkem/cachetools) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/tkem/cachetools/releases)
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v4.0.0...v4.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 11:47:12 +00:00
Matthias
e4ec0a9e0c Merge pull request #3158 from freqtrade/dependabot/pip/develop/mkdocs-material-5.1.0
Bump mkdocs-material from 4.6.3 to 5.1.0
2020-04-13 13:46:45 +02:00
Matthias
8885a3b866 Merge pull request #3153 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.16
Bump sqlalchemy from 1.3.15 to 1.3.16
2020-04-13 13:45:54 +02:00
dependabot-preview[bot]
cfcce0e657 Bump mkdocs-material from 4.6.3 to 5.1.0
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.6.3 to 5.1.0.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/4.6.3...5.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 08:32:29 +00:00
dependabot-preview[bot]
350b4d5e7d Bump coveralls from 1.11.1 to 2.0.0
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 1.11.1 to 2.0.0.
- [Release notes](https://github.com/coveralls-clients/coveralls-python/releases)
- [Changelog](https://github.com/coveralls-clients/coveralls-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/coveralls-clients/coveralls-python/compare/1.11.1...2.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 08:31:00 +00:00
dependabot-preview[bot]
eac4dbcd28 Bump sqlalchemy from 1.3.15 to 1.3.16
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.15 to 1.3.16.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 08:30:31 +00:00
Matthias
4ee0cbb575 Reset index to correctly gather index 2020-04-12 10:40:02 +02:00
Matthias
952d2f7513 have version-detection fall back to freqtrade_commit
this allows freqtrade --version to work in docker too.

sample command:
`docker-compose run --rm freqtrade -version`
2020-04-12 09:55:21 +02:00
Matthias
18a6c98a82 Merge pull request #3054 from Fredrik81/progress-bar
Hyperopt: Progressbar during hyperopt
2020-04-12 09:32:52 +02:00
Fredrik81
2c1c1c7f16 Update freqtrade/optimize/hyperopt.py
nice find

Co-Authored-By: Matthias <xmatthias@outlook.com>
2020-04-11 17:42:32 +02:00
Fredrik81
d9e54ab7a4 Update freqtrade/optimize/hyperopt.py
nice find

Co-Authored-By: Matthias <xmatthias@outlook.com>
2020-04-11 17:42:19 +02:00
Matthias
c03f637f5b Improve safe_value_fallback test 2020-04-09 20:01:21 +02:00
Matthias
f39706cabd Fix #3130 - when corder['remaining'] contains none-type 2020-04-09 19:35:27 +02:00
Matthias
cbf5bf6735 Add safe_value_fallback function 2020-04-09 19:34:48 +02:00
Matthias
346e09fed1 Add test verifying that cancel_order with empty remaining is causing the
bug
2020-04-09 19:32:10 +02:00
Fredrik81
4707484a4c Fix issue with colring enabled + styling 2020-04-09 11:42:13 +02:00
Matthias
5cff72a42e Improve logging to ensure which branch is used for buy order cancels 2020-04-09 09:22:38 +02:00
Matthias
68a5e0c51b Merge pull request #3138 from orkblutt/develop
trades history RPC
2020-04-08 08:23:13 +02:00
Matthias
02192f28cd Small stylistic updates 2020-04-08 07:56:21 +02:00
Fredrik81
cdc774549e Merge branch 'develop' into progress-bar 2020-04-08 01:56:43 +02:00
Matthias
492c2799dc Rename rest-client script history to trades 2020-04-07 19:52:34 +02:00
Matthias
296c616ce7 Add test for api-trades call 2020-04-07 19:50:13 +02:00
Matthias
bdc85ec89b Move create_mock_tests to conftest and add test for test_trade-history 2020-04-07 19:42:16 +02:00
Fredrik81
132f5f73f5 Update hyperopt.py 2020-04-07 10:44:18 +02:00
Fredrik81
c95906cfcf Update hyperopt.py 2020-04-07 10:42:15 +02:00
Matthias
9387585756 Merge pull request #3127 from orehunt/max_drawdown_fix_db_plot
use equality instead of index for row lookups
2020-04-06 20:10:23 +02:00
Ork Blutt
200111fef6 fix method return value 2020-04-06 16:07:43 +02:00
Ork Blutt
2444fb9cd6 fix broken tests: remove duplicated value 2020-04-06 15:56:57 +02:00
orehunt
20abb379aa trim trades to the available ohlcv data before plotting profits 2020-04-06 15:54:17 +02:00
Ork Blutt
c1f9595086 fix broken tests 2020-04-06 15:49:24 +02:00
Fredrik81
d5609d4997 Changed back to progressbar2 for better handling of logger.
Coloring still needs some work (bug + what colors to use)
2020-04-06 13:12:32 +02:00
Matthias
4a85422ce0 Merge pull request #3143 from freqtrade/dependabot/pip/develop/pytest-mock-3.0.0
Bump pytest-mock from 2.0.0 to 3.0.0
2020-04-06 11:56:15 +02:00
Matthias
56d22675bc Merge pull request #3142 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.5.1
Bump python-telegram-bot from 12.5 to 12.5.1
2020-04-06 11:55:52 +02:00
Matthias
f72db44bd7 Merge pull request #3141 from freqtrade/dependabot/pip/develop/flask-1.1.2
Bump flask from 1.1.1 to 1.1.2
2020-04-06 11:55:27 +02:00
Ork Blutt
815660c070 fix tests 2020-04-06 11:32:00 +02:00
dependabot-preview[bot]
be76e3c554 Bump python-telegram-bot from 12.5 to 12.5.1
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.5 to 12.5.1.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.5...v12.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-06 09:23:21 +00:00
Matthias
914303a7c5 Merge pull request #3140 from freqtrade/dependabot/pip/develop/plotly-4.6.0
Bump plotly from 4.5.4 to 4.6.0
2020-04-06 11:22:39 +02:00
Matthias
27a6787a77 Merge pull request #3139 from freqtrade/dependabot/pip/develop/ccxt-1.25.81
Bump ccxt from 1.25.38 to 1.25.81
2020-04-06 11:21:53 +02:00
dependabot-preview[bot]
0b30cb7f8f Bump pytest-mock from 2.0.0 to 3.0.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 2.0.0 to 3.0.0.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v2.0.0...v3.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-06 09:11:33 +00:00
dependabot-preview[bot]
144d252e19 Bump flask from 1.1.1 to 1.1.2
Bumps [flask](https://github.com/pallets/flask) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/master/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/1.1.1...1.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-06 09:10:30 +00:00
dependabot-preview[bot]
5de7ee3bdb Bump plotly from 4.5.4 to 4.6.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.4 to 4.6.0.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.5.4...v4.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-06 09:10:07 +00:00
dependabot-preview[bot]
a1e81a51ef Bump ccxt from 1.25.38 to 1.25.81
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.25.38 to 1.25.81.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.25.38...1.25.81)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-06 09:09:54 +00:00
Ork Blutt
6256025c73 various adjustement from PR discussion 2020-04-06 11:00:31 +02:00
Ork Blutt
8555c5b211 fix return value 2020-04-05 17:03:51 +02:00
Ork Blutt
15c45b984d removing whitespace 2020-04-05 16:47:46 +02:00
Ork Blutt
0a14d5ec46 trades history RPC 2020-04-05 16:14:02 +02:00
Matthias
41d5c40f10 Correctly test drawdown plot 2020-04-05 14:44:44 +02:00
Matthias
4e907e2304 Use timeframe_to_prev_date to move trade-date to candle 2020-04-05 14:35:53 +02:00
Matthias
e204170eb6 Fix max_drawdown bug finding low before high! 2020-04-05 14:29:40 +02:00
Matthias
a99c53f1ec Add test showing that high is before low 2020-04-05 14:29:03 +02:00
Matthias
d4dde01140 Add test 2020-04-02 20:23:20 +02:00
Matthias
c465552df4 Update comment to mention .copy() usage 2020-04-02 20:17:54 +02:00
Matthias
de47186263 Use .loc for assignments 2020-04-02 19:31:48 +02:00
Matthias
3fcd531eac Copy dataframe in interfac.py (reduces memory consumption) 2020-04-02 19:30:59 +02:00
Matthias
cf6e6488c7 Fix filename handling with --strategy-list 2020-04-02 17:29:18 +02:00
Matthias
46f1d1f39f Failing test might be incompatibility 2020-04-02 11:54:30 +02:00
Matthias
9d7ad23d42 Fix test leakage 2020-04-02 08:20:50 +02:00
Matthias
eab6c9c5f2 Fix message 2020-04-01 20:50:00 +02:00
Matthias
0d51383b57 Format logmessages correctly 2020-04-01 20:31:21 +02:00
Matthias
5739ee6e15 Add test for trades data conversation 2020-04-01 20:12:28 +02:00
Matthias
437d4cda5d Add test data for trades 2020-04-01 20:12:13 +02:00
Matthias
ba03d96961 Test 5s offset on since 2020-04-01 20:04:36 +02:00
Matthias
ff9caf790b remove trade duplicates in datahandler 2020-04-01 19:45:46 +02:00
Matthias
0506caf986 Implement trades_remove_dulicates 2020-04-01 19:45:38 +02:00
Matthias
59f1a061f7 adapt exchange tests to use lists instead of dicts 2020-04-01 19:45:38 +02:00
Matthias
b95e9fe351 Fix mocks to return correct things 2020-04-01 19:45:38 +02:00
Matthias
bac0eaab03 fix convert to ohlcv 2020-04-01 19:45:35 +02:00
Matthias
d76bb1ccf4 Use List of Lists instead of list of Dicts for trades data 2020-04-01 19:45:21 +02:00
Matthias
1659ddcc5d Add conversion function from fetch_trades to list 2020-04-01 19:45:21 +02:00
Matthias
8bfbbac748 Add default trades columns 2020-04-01 19:45:00 +02:00
hroff-1902
2915917680 Merge pull request #3107 from orehunt/check_dataframe_after_signals
check that the strategy dataframe matches the one given by the bot
2020-03-31 20:08:03 +03:00
orehunt
45fb4d25ab use equality instead of index for row lookups 2020-03-31 18:47:53 +02:00
hroff-1902
92bd550851 Merge pull request #3126 from freqtrade/max_drawdown_percent
[minor] Plot percent correctly
2020-03-30 21:37:23 +03:00
Matthias
54d20cb81c Plot percent correctly 2020-03-30 20:08:07 +02:00
Matthias
9e1f7cb71c Merge pull request #3122 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.5
Bump prompt-toolkit from 3.0.4 to 3.0.5
2020-03-30 12:00:47 +02:00
Matthias
f93cc52dcc Merge pull request #3124 from freqtrade/dependabot/pip/develop/ccxt-1.25.38
Bump ccxt from 1.24.83 to 1.25.38
2020-03-30 11:55:26 +02:00
Matthias
372f7f3e88 Merge pull request #3125 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.5
Bump python-telegram-bot from 12.4.2 to 12.5
2020-03-30 11:55:03 +02:00
Matthias
e0861b9381 Merge pull request #3123 from freqtrade/dependabot/pip/develop/flake8-tidy-imports-4.1.0
Bump flake8-tidy-imports from 4.0.0 to 4.1.0
2020-03-30 11:54:19 +02:00
dependabot-preview[bot]
d8d6fe3574 Bump python-telegram-bot from 12.4.2 to 12.5
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.4.2 to 12.5.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.4.2...v12.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 08:58:54 +00:00
dependabot-preview[bot]
2de10d4c56 Bump ccxt from 1.24.83 to 1.25.38
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.24.83 to 1.25.38.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.24.83...1.25.38)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 08:58:21 +00:00
dependabot-preview[bot]
7e60e0549a Bump flake8-tidy-imports from 4.0.0 to 4.1.0
Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases)
- [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/master/HISTORY.rst)
- [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/4.0.0...4.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 08:57:16 +00:00
dependabot-preview[bot]
7e1719cfc7 Bump prompt-toolkit from 3.0.4 to 3.0.5
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases)
- [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG)
- [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.4...3.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 08:56:50 +00:00
hroff-1902
3a7199834d Merge pull request #3121 from freqtrade/remove_defaultstrategy
[minor] Remove defaultstrategy occurance from docs
2020-03-30 09:22:02 +03:00
Matthias
f1b92e2569 Improve wording of documentation 2020-03-30 08:11:38 +02:00
Matthias
a5d00ce717 Remove defaultstrategy occurance from docs 2020-03-30 07:56:17 +02:00
Matthias
83cc121b70 Add tsts for assert_df (ensuring it raises when it should) 2020-03-29 11:44:36 +02:00
Matthias
cd2e738e35 Add test for assert error 2020-03-29 11:40:13 +02:00
Matthias
0887a0212c Adjust tests to pass validation 2020-03-29 11:29:31 +02:00
Matthias
78aa658255 Remove unnecessary test (it's a copy of the remaining test) 2020-03-29 11:27:40 +02:00
Matthias
9abfdaaaa2 Merge pull request #3119 from freqtrade/new_release
New release 2020.3
2020-03-28 19:49:39 +01:00
Matthias
da191e4ac8 Version bump 2020.3 2020-03-28 17:45:44 +01:00
Matthias
75de96ae6d Merge branch 'master' into new_release 2020-03-28 17:45:17 +01:00
orehunt
3ef568029f different exception messages 2020-03-26 07:05:30 +01:00
hroff-1902
39ea126698 Merge pull request #3090 from freqtrade/remove_partial_candle_docs
Remove partial candle documentation
2020-03-25 19:55:44 +03:00
Matthias
95011919d3 Remove questionable handling of orders 2020-03-25 11:18:33 +01:00
Matthias
3c1b155e9f Remove filled if amount is modified to suit fee structure 2020-03-25 09:43:04 +01:00
Matthias
1e2fadbc02 Fix failing test 2020-03-25 09:43:04 +01:00
Matthias
f04f606b70 Updateing order amount should use filled - not amount if possible 2020-03-25 09:43:04 +01:00
Matthias
19e5dbddc6 Add filled to all orders 2020-03-25 09:43:04 +01:00
Matthias
f3103be15c Fix test 2020-03-25 09:43:04 +01:00
Matthias
700cedc573 Unify handling of open orders to update_trade_state 2020-03-25 09:43:04 +01:00
Matthias
7c47c6e3bd check for timeouts before exiting positions 2020-03-25 09:43:04 +01:00
Matthias
270ac2e8c1 Add check_order_cancelled_empty method to exchange 2020-03-25 09:43:04 +01:00
Matthias
9c351007f5 Provide reason for cancelled sell order 2020-03-25 09:43:04 +01:00
Matthias
1817e6fbdf Combine real_amount updating into one method 2020-03-25 09:43:04 +01:00
Matthias
91b058cf11 Fix typo in tests 2020-03-25 09:43:04 +01:00
Matthias
53efc56b8a Merge pull request #3096 from freqtrade/max_open_trades
Update max_open_trades documentation
2020-03-25 09:37:40 +01:00
Matthias
6f687c97ce Update docs/configuration.md
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-03-25 09:24:37 +01:00
hroff-1902
be5b68627c Merge pull request #3093 from freqtrade/trades_abs_profit
Add close_profit_abs column
2020-03-25 11:13:56 +03:00
Matthias
dfac7448d1 fix typo
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-03-25 08:33:22 +01:00
Matthias
4ea6f9d7eb Merge pull request #3110 from freqtrade/fix_random_test
[minor] Test warnings with filter always on
2020-03-25 08:32:45 +01:00
Matthias
d9a5e1cd48 Update docs/exchanges.md
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-03-25 08:30:18 +01:00
hroff-1902
65f19fde40 Merge pull request #3097 from freqtrade/parse_config_error
Improve config parse error handling
2020-03-25 09:18:16 +03:00
Matthias
be41981ef0 Test warnings with filter always on 2020-03-24 20:10:15 +01:00
orehunt
0f53e646fd check that the strategy dataframe matches the one given by the bot 2020-03-24 14:08:34 +01:00
Matthias
030c487d6b Merge pull request #3100 from freqtrade/dependabot/pip/develop/pandas-1.0.3
Bump pandas from 1.0.2 to 1.0.3
2020-03-23 10:41:06 +01:00
Matthias
51edddcaf6 Merge pull request #3101 from freqtrade/dependabot/pip/develop/ccxt-1.24.83
Bump ccxt from 1.24.31 to 1.24.83
2020-03-23 10:21:46 +01:00
dependabot-preview[bot]
cb1bc5d5ab Bump pandas from 1.0.2 to 1.0.3
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.0.2 to 1.0.3.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v1.0.2...v1.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-23 09:15:43 +00:00
Matthias
9b43d9d75e Merge pull request #3099 from freqtrade/dependabot/pip/develop/tabulate-0.8.7
Bump tabulate from 0.8.6 to 0.8.7
2020-03-23 10:15:31 +01:00
Matthias
c3787afa2e Merge pull request #3098 from freqtrade/dependabot/pip/develop/numpy-1.18.2
Bump numpy from 1.18.1 to 1.18.2
2020-03-23 10:14:25 +01:00
dependabot-preview[bot]
98dc4b4ca3 Bump ccxt from 1.24.31 to 1.24.83
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.24.31 to 1.24.83.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.24.31...1.24.83)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-23 09:06:41 +00:00
dependabot-preview[bot]
de91e169bc Bump tabulate from 0.8.6 to 0.8.7
Bumps [tabulate](https://github.com/astanin/python-tabulate) from 0.8.6 to 0.8.7.
- [Release notes](https://github.com/astanin/python-tabulate/releases)
- [Changelog](https://github.com/astanin/python-tabulate/blob/master/CHANGELOG)
- [Commits](https://github.com/astanin/python-tabulate/compare/v0.8.6...v0.8.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-23 09:05:12 +00:00
dependabot-preview[bot]
f4a69ba5a7 Bump numpy from 1.18.1 to 1.18.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.18.1 to 1.18.2.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.18.1...v1.18.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-23 09:04:50 +00:00
Matthias
d581b7e2d7 Add fallback if no error could be determined 2020-03-23 07:57:30 +01:00
Matthias
8f7e113d79 Add additional test 2020-03-23 07:54:27 +01:00
Matthias
6c55b40fe0 Add test verifying config printing 2020-03-22 20:15:33 +01:00
Matthias
45aaa8c09d Parse and show relevant configuration section 2020-03-22 20:09:01 +01:00
Matthias
acd402187a Update max_open_trades documentation 2020-03-22 19:39:36 +01:00
hroff-1902
e079d36f84 Merge pull request #3094 from freqtrade/gitignore
[minor] Add example notebook to gitignore again
2020-03-22 18:38:33 +03:00
Matthias
f14c496ce9 Remove calc_close_profit from RPC
This is now possible - but only for closed trades, so certain occurances
need to remain.
2020-03-22 11:28:18 +01:00
Matthias
efd94c84de Add example notebook to gitignore again 2020-03-22 11:22:49 +01:00
Matthias
2c434e9b11 Add close_proit_abs column 2020-03-22 11:16:23 +01:00
Matthias
e30faf8c8c Remove partial candle documentation
It wasn't working 100% correctly - see #2993
2020-03-21 20:04:05 +01:00
hroff-1902
fb4e9b3938 Merge pull request #3025 from yazeed/minor_create_trade_optimization
minor create_trade() optimization
2020-03-21 10:36:39 +03:00
Matthias
f320c0a410 Merge pull request #3087 from hroff-1902/edge-cosmetics-1
minor: Edge cosmetics
2020-03-20 08:12:21 +01:00
Yazeed Al Oyoun
942792f123 updated as suggested 2020-03-20 05:48:53 +01:00
hroff-1902
3e0ffdce75 Adjust tests 2020-03-20 04:21:17 +03:00
hroff-1902
5f9479b39f Edge import cosmetics 2020-03-20 02:10:44 +03:00
hroff-1902
d1bfe12bde Merge pull request #3086 from freqtrade/ftx_cancel_order
Ftx cancel order
2020-03-19 23:43:29 +03:00
Matthias
5e702f6891 Verify cancel_order returnvalue is a dictionary 2020-03-19 19:44:14 +01:00
Matthias
ecf3a3e070 Add test validating different return values 2020-03-19 19:44:10 +01:00
Matthias
ac6eef6922 Merge pull request #3062 from Fredrik81/plot-trades
Plotting: Fix if no file exists and new skip option
2020-03-18 20:00:50 +01:00
Matthias
3e1bef888a Fix flake8 error 2020-03-18 19:40:13 +01:00
Fredrik81
0920d6fce4 Update freqtrade/data/btanalysis.py
Co-Authored-By: Matthias <xmatthias@outlook.com>
2020-03-18 11:01:09 +01:00
Fredrik81
05250ba661 Update docs/plotting.md
Co-Authored-By: Matthias <xmatthias@outlook.com>
2020-03-18 11:00:33 +01:00
hroff-1902
961ad07dba Merge pull request #3079 from freqtrade/fix_pypi_install
Add template and jupyter files to release
2020-03-18 01:07:53 +03:00
Matthias
4f46fb9bf5 Add template and jupyter files to release 2020-03-17 19:33:18 +01:00
Matthias
50e348b81c Merge pull request #3069 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.15
Bump sqlalchemy from 1.3.13 to 1.3.15
2020-03-16 10:19:32 +01:00
Matthias
84b27585e6 Merge pull request #3074 from freqtrade/dependabot/pip/develop/mypy-0.770
Bump mypy from 0.761 to 0.770
2020-03-16 10:19:05 +01:00
dependabot-preview[bot]
62d449251c Bump mypy from 0.761 to 0.770
Bumps [mypy](https://github.com/python/mypy) from 0.761 to 0.770.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.761...v0.770)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-16 08:54:12 +00:00
dependabot-preview[bot]
7a7530d57d Bump sqlalchemy from 1.3.13 to 1.3.15
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.13 to 1.3.15.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-16 08:53:20 +00:00
Matthias
7fb266671d Merge pull request #3073 from freqtrade/dependabot/pip/develop/pytest-5.4.1
Bump pytest from 5.3.5 to 5.4.1
2020-03-16 09:52:58 +01:00
Matthias
addb4b5f8f Merge pull request #3071 from freqtrade/dependabot/pip/develop/ccxt-1.24.31
Bump ccxt from 1.23.81 to 1.24.31
2020-03-16 09:52:10 +01:00
Matthias
d2ab7633ef Merge pull request #3072 from freqtrade/dependabot/pip/develop/plotly-4.5.4
Bump plotly from 4.5.3 to 4.5.4
2020-03-16 09:51:35 +01:00
Matthias
ba1bd2d5a4 Merge pull request #3070 from freqtrade/dependabot/pip/develop/pandas-1.0.2
Bump pandas from 1.0.1 to 1.0.2
2020-03-16 09:51:21 +01:00
dependabot-preview[bot]
3eee0c43a7 Bump pytest from 5.3.5 to 5.4.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.5 to 5.4.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.3.5...5.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-16 08:18:33 +00:00
dependabot-preview[bot]
8cfff40fcf Bump plotly from 4.5.3 to 4.5.4
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.5.3...v4.5.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-16 08:18:07 +00:00
dependabot-preview[bot]
0b34175752 Bump ccxt from 1.23.81 to 1.24.31
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.23.81 to 1.24.31.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/doc/exchanges-by-country.rst)
- [Commits](https://github.com/ccxt/ccxt/compare/1.23.81...1.24.31)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-16 08:17:53 +00:00
dependabot-preview[bot]
e8a92cb313 Bump pandas from 1.0.1 to 1.0.2
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v1.0.1...v1.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-16 08:17:21 +00:00
Fredrik81
06198c0028 Missed configuration.py 2020-03-15 21:27:45 +01:00
Fredrik81
8c33e07dc6 Update based on comments 2020-03-15 21:20:32 +01:00
hroff-1902
0847652df0 Merge pull request #3066 from freqtrade/backtest_small_improvements
Backtest small improvements
2020-03-15 20:20:15 +03:00
Matthias
3d4664c2a6 Remove unnecessary import 2020-03-15 15:40:12 +01:00
Matthias
e1b08ad76c Add docstring to store_backtest_result 2020-03-15 15:38:26 +01:00
Matthias
fe50a0f3a1 Move test for store_bt_results to optimize_reports 2020-03-15 15:36:53 +01:00
Matthias
e95665ceca Make backtestresult storing independent from printing 2020-03-15 15:36:23 +01:00
Matthias
a13d581658 Move backtest-result visualization out of backtesting class 2020-03-15 15:17:53 +01:00
Matthias
6106d59e1a Move store_backtest_results to optimize_reports 2020-03-15 15:17:35 +01:00
Matthias
328dbd3930 Remove unnecessary parameter to generate_text_table_sell_reason 2020-03-15 15:04:48 +01:00
Matthias
a1bbeaa668 Merge branch 'develop' into interface_ordertimeoutcallback 2020-03-15 14:56:14 +01:00
hroff-1902
57ff3ff450 Merge branch 'develop' into plot-trades 2020-03-15 13:31:00 +03:00
hroff-1902
3b89e7d393 Merge pull request #3064 from freqtrade/exportfilename_path
convert exportfilename to Path when config parsing
2020-03-15 13:12:19 +03:00
Matthias
0f1640bed4 convert exportfilename to Path when config parsing 2020-03-15 09:39:45 +01:00
Fredrik81
2c0980aa3a Tests 2020-03-15 00:09:08 +01:00
Fredrik81
cf7e80f45d Docs and logging 2020-03-14 23:55:13 +01:00
Fredrik81
27faf12fde Fix if no file exists 2020-03-14 22:15:03 +01:00
hroff-1902
5d1b1573b7 Merge pull request #3061 from freqtrade/edge_test_warning
Edge test warning
2020-03-14 13:51:05 +03:00
Matthias
308d8fe2a9 Remove deprecation warnings due to date conversion 2020-03-14 10:44:46 +01:00
Matthias
c56cbc21b1 Remove indexing warning in edge 2020-03-14 10:42:01 +01:00
hroff-1902
5bfbf92e69 Merge pull request #3032 from hroff-1902/no-ticker-2
Do not use "ticker" where it's not a ticker
2020-03-13 21:10:29 +03:00
hroff-1902
59fadabb5b Fix merging 2020-03-13 20:26:14 +03:00
hroff-1902
51f52c8609 Merge branch 'develop' into no-ticker-2 2020-03-13 16:43:52 +03:00
hroff-1902
a7ed51c642 return back the name of the hyperopt data file 2020-03-13 04:04:23 +03:00
hroff-1902
ddfe5b5f1c dataframe -> df_analyzed in plotting 2020-03-13 04:00:24 +03:00
hroff-1902
b2952cd42a remove redundant dict 2020-03-13 03:58:16 +03:00
hroff-1902
ebb0187f40 dataframe -> df_analyzed in backtesting and edge 2020-03-13 03:54:56 +03:00
hroff-1902
c6bb32d419 Merge pull request #3045 from orehunt/jsondatahandler-ohlc-respect-timerange
check again for emptiness after trimming dataframe
2020-03-12 22:46:31 +03:00
Matthias
6f67b8d9b9 iCheck after clean_dataframe, too 2020-03-12 19:50:46 +01:00
Fredrik81
5737139979 Small fix 2020-03-12 16:47:09 +01:00
Fredrik81
1a59fc11be doh 2020-03-12 02:36:18 +01:00
Fredrik81
df1ae565dc clean-up 2020-03-12 02:26:41 +01:00
Fredrik81
9387ed923c fix for empty lines 2020-03-12 02:07:50 +01:00
Fredrik81
40a413c524 More remove of progressbar2 2020-03-11 22:50:23 +01:00
Fredrik81
755763ec42 Update requirements 2020-03-11 22:43:27 +01:00
Fredrik81
81cbb92556 Switch to TQDM 2020-03-11 22:30:36 +01:00
Matthias
129a88d5da Extract emptyness check to it's own method 2020-03-11 19:53:28 +01:00
hroff-1902
ed5b0ee36b Merge pull request #3053 from freqtrade/hyperopt_default_volume
Hyperopt - add default volume > 0 filter
2020-03-11 08:17:54 +03:00
Fredrik81
3a8b68c0fd Initial work on progressbar 2020-03-10 20:30:36 +01:00
Matthias
2b1c146940 Add default volume > 0 filter 2020-03-10 16:05:33 +01:00
Matthias
84f0bb9a5d Merge pull request #3051 from hroff-1902/fix-sortino
Adjust handling of zero stdev in loss functions
2020-03-10 13:10:39 +01:00
Matthias
14e7f0bb13 Merge pull request #3049 from hroff-1902/hyperopt-no-unlimited
Do not allow unlimited stake_amount for hyperopt
2020-03-10 11:46:22 +01:00
hroff-1902
73c19da4b9 Adjust handling of zero stdev in loss functions 2020-03-10 13:44:16 +03:00
hroff-1902
1b6e77649a Add test for hyperopt 2020-03-10 12:42:31 +03:00
hroff-1902
81b6a950ac Adjust test for backtesting 2020-03-10 12:42:11 +03:00
hroff-1902
f7ad6c20c7 Do not allow unlimited stake_amount for hyperopt 2020-03-10 12:41:23 +03:00
hroff-1902
c49fefc94d Merge pull request #3044 from freqtrade/default_max_order_book
order_book_max - change example setting
2020-03-10 11:17:27 +03:00
Matthias
a046c4829c Apply suggestions from code review
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-03-10 09:03:44 +01:00
hroff-1902
52d89eadde Merge pull request #3021 from Fredrik81/print-csv
Hyperopt: Add export CSV-file option
2020-03-10 10:46:58 +03:00
hroff-1902
f148b5f734 cosmetics in lambdas 2020-03-10 10:38:37 +03:00
hroff-1902
19a9782a40 Merge pull request #3040 from freqtrade/pairlist_message
reduce Pairlist message warning level
2020-03-10 10:26:19 +03:00
Matthias
42038da7f1 Update docs/configuration.md
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-03-10 07:57:25 +01:00
Fredrik81
bd158eefd2 Fixed loggin 2020-03-10 03:02:52 +01:00
hroff-1902
df2c8b5f32 Merge pull request #3042 from freqtrade/hyperopt_sample_comment
Update hyperopt samples docstring
2020-03-09 23:25:36 +03:00
Fredrik81
2f5fc731bb Removed overwrite option 2020-03-09 18:53:30 +01:00
orehunt
3eaae4661d check again for emptiness after trimming dataframe 2020-03-09 17:51:21 +01:00
Matthias
e0afbcd4af Additional warning about order_book-max 2020-03-09 17:41:44 +01:00
Matthias
74a17c7b7b Clarify warning in the documentation 2020-03-09 17:38:35 +01:00
Matthias
5da63d399b Reduce default order_book_max to 1 2020-03-09 17:38:25 +01:00
Matthias
856ba203d9 Update hyperopt samples docstring 2020-03-09 15:46:46 +01:00
Matthias
c049651784 whitelist_for_active_markets should not remove blacklisted items 2020-03-09 11:30:28 +01:00
Matthias
5cbf325fda Allow different loglevels for message 2020-03-09 11:30:13 +01:00
Matthias
bf2dc90c3c Merge pull request #3039 from freqtrade/dependabot/pip/develop/plotly-4.5.3
Bump plotly from 4.5.2 to 4.5.3
2020-03-09 09:58:46 +01:00
Matthias
964d97da17 Merge pull request #3038 from freqtrade/dependabot/pip/develop/scikit-learn-0.22.2.post1
Bump scikit-learn from 0.22.2 to 0.22.2.post1
2020-03-09 09:57:46 +01:00
Matthias
5c190f82e4 Merge pull request #3035 from freqtrade/dependabot/pip/develop/wrapt-1.12.1
Bump wrapt from 1.12.0 to 1.12.1
2020-03-09 09:54:23 +01:00
Matthias
f125709954 Merge pull request #3037 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.4
Bump prompt-toolkit from 3.0.3 to 3.0.4
2020-03-09 09:53:53 +01:00
Matthias
a3b0b8a7c5 Merge pull request #3036 from freqtrade/dependabot/pip/develop/ccxt-1.23.81
Bump ccxt from 1.23.30 to 1.23.81
2020-03-09 09:45:49 +01:00
dependabot-preview[bot]
4cc0d3dbc4 Bump plotly from 4.5.2 to 4.5.3
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.2 to 4.5.3.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.5.2...v4.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 08:35:16 +00:00
dependabot-preview[bot]
23127b8da0 Bump scikit-learn from 0.22.2 to 0.22.2.post1
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.22.2 to 0.22.2.post1.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.22.2...0.22.2.post1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 08:34:33 +00:00
dependabot-preview[bot]
46763e148b Bump prompt-toolkit from 3.0.3 to 3.0.4
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.3 to 3.0.4.
- [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases)
- [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG)
- [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.3...3.0.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 08:33:59 +00:00
dependabot-preview[bot]
09c25faa51 Bump ccxt from 1.23.30 to 1.23.81
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.23.30 to 1.23.81.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.23.30...1.23.81)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 08:33:37 +00:00
dependabot-preview[bot]
c7b2f173eb Bump wrapt from 1.12.0 to 1.12.1
Bumps [wrapt](https://github.com/GrahamDumpleton/wrapt) from 1.12.0 to 1.12.1.
- [Release notes](https://github.com/GrahamDumpleton/wrapt/releases)
- [Changelog](https://github.com/GrahamDumpleton/wrapt/blob/develop/docs/changes.rst)
- [Commits](https://github.com/GrahamDumpleton/wrapt/compare/1.12.0...1.12.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-09 08:32:42 +00:00
Fredrik81
cb419614cd Spelling miss 2020-03-08 23:00:21 +01:00
Fredrik81
4ad93ed6bb Changed output for null columns 2020-03-08 22:41:05 +01:00
hroff-1902
3208faf7ed Do not use ticker where it's not a ticker 2020-03-08 20:47:02 +03:00
hroff-1902
77944175e2 Merge pull request #3030 from freqtrade/coingekko
Coingekko replacing coinmarketcap
2020-03-07 20:42:08 +03:00
Matthias
281cf577d1 Remove unsupported FIAT 2020-03-07 17:03:31 +01:00
Matthias
d51bb9acfb Update conda environment file 2020-03-07 13:11:36 +01:00
Matthias
1b3038390a Update comment 2020-03-07 13:05:46 +01:00
Matthias
acea49beaf Fix tests / test mocks 2020-03-07 13:01:26 +01:00
Matthias
df5adb6ca5 Exchange coingekko for coinmarketcap 2020-03-07 11:53:08 +01:00
Matthias
93fc14d726 Exchange dependencies to coingekko 2020-03-07 11:52:02 +01:00
Matthias
847df7b70c Merge pull request #3026 from yazeed/add_default_to_ignore_roi_if_buy_signal
default for ignore_roi_if_buy_signal in freqtradebot.py
2020-03-06 19:35:41 +01:00
Matthias
bbdbc59fd1 Merge pull request #3024 from yazeed/unifying_get_buy_sell_rate_msgs
consistency between get_sell_rate with get_buy_rate
2020-03-06 19:32:31 +01:00
hroff-1902
7b0009b38d Merge pull request #3029 from freqtrade/travis_failure
Fix travis build failure
2020-03-06 18:20:19 +03:00
Matthias
78908e2496 Fix travis build failure 2020-03-06 15:57:26 +01:00
Yazeed Al Oyoun
b8d05d8751 found instance of config get without default 2020-03-05 22:14:05 +01:00
Yazeed Al Oyoun
0587256733 minor create_trade() optimization 2020-03-05 21:57:01 +01:00
Yazeed Al Oyoun
4474482307 unifying get_sell_rate with get_buy_rate 2020-03-05 20:44:29 +01:00
Fredrik81
f0d56e23a3 PEP8 fix 2020-03-05 19:58:01 +01:00
Fredrik81
91db75a707 Added tests and updated doc 2020-03-05 19:43:43 +01:00
Matthias
459f1aa130 Merge pull request #2989 from hroff-1902/no-percent-1
No "percent" where "ratio" is to be used
2020-03-05 16:20:13 +01:00
hroff-1902
eee5727426 Adjust webhook docs 2020-03-05 17:44:38 +03:00
hroff-1902
7a3660cd6b Adjust webhook tests 2020-03-05 17:44:21 +03:00
hroff-1902
34093d1208 Merge branch 'develop' into no-percent-1 2020-03-05 14:27:12 +03:00
hroff-1902
bcec46c2aa Merge pull request #3019 from freqtrade/fix_testfailure
Fix random CI failure
2020-03-05 10:56:25 +03:00
Matthias
97b194a454 Throttle may take longer than .10s on slow machines
This made this test fluky on windows CI ...
2020-03-05 06:20:36 +01:00
Fredrik81
7606d814fa Initial work on csv-file export. Missing docs and tests 2020-03-05 01:58:33 +01:00
hroff-1902
57523d58df Merge pull request #2994 from Fredrik81/hyperopt-table
Added dynamic print table function to hyperopt
2020-03-04 23:44:53 +03:00
Fredrik81
090d1e8a70 Alignment and cleanups 2020-03-04 20:51:09 +01:00
hroff-1902
33c1c8f726 Merge pull request #3018 from freqtrade/max_drawdown
Max drawdown in plot-profit
2020-03-04 20:42:57 +03:00
hroff-1902
dea4ef957e Merge pull request #2982 from freqtrade/rate_side_optional
Rate side configurable
2020-03-04 16:07:08 +03:00
Matthias
2f54aff0ce Improve documentation wording for price sides 2020-03-04 06:44:59 +01:00
Matthias
8de35e1c83 Documentation suggestions from Review
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-03-04 06:40:19 +01:00
Fredrik81
7652a2bb95 Updated table layout and aligning better for hyperopt 2020-03-04 00:10:47 +01:00
Matthias
9d8970a76b Add test and formatting to drawdown 2020-03-03 20:23:44 +01:00
Matthias
53dcb5d5ed Fix logging expression 2020-03-03 19:36:03 +01:00
hroff-1902
4513edf450 Merge pull request #3017 from freqtrade/ci_windows_38
CI on windows with python 3.8
2020-03-03 17:21:55 +03:00
Matthias
9bebc9ba76 Fix powershell comparison 2020-03-03 09:40:41 +01:00
Matthias
720ed0eddd Remove flucky test assert 2020-03-03 09:36:04 +01:00
Matthias
d9e83cc4e2 Run CI on windows python 3.8 2020-03-03 09:33:08 +01:00
Matthias
33a63562cb make drawdown function less restrictive 2020-03-03 07:23:38 +01:00
Matthias
88e7cab5b9 Add max_drawdown to profit plot 2020-03-03 07:21:14 +01:00
Matthias
e050511ddc Add test for max_drawdown calculation 2020-03-03 07:20:41 +01:00
Matthias
3479f7d986 Add max_drawdown function 2020-03-03 07:15:03 +01:00
Fredrik81
4aca8d7fcc PEP8 fix 2020-03-03 01:35:18 +01:00
Fredrik81
399c419163 Changed table formating. Adding some code to align hyperopt table generation. WIP 2020-03-03 01:14:56 +01:00
hroff-1902
82bdd01843 Merge pull request #3003 from Fredrik81/cores-and-arguments
Hyperopt: fix number of CPU cores, jobs and total epochs
2020-03-03 02:12:21 +03:00
hroff-1902
52cd5f9127 Better use enumerate: more correct and more pythonic 2020-03-03 01:42:25 +03:00
hroff-1902
45c9496792 Do not run optimizer for 'jobs' epochs for the last iteration 2020-03-03 01:33:11 +03:00
hroff-1902
a7d4755859 optimize calculation of current_jobs 2020-03-03 01:20:14 +03:00
hroff-1902
92425642da Fix config_jobs 2020-03-03 01:00:24 +03:00
Fredrik81
0e4862b0c8 Added logging if argument is miss-configured 2020-03-02 22:58:54 +01:00
Fredrik81
7713cfeb79 Corrected logic for -j + and - argument 2020-03-02 21:02:32 +01:00
Matthias
6e2290c4f0 Allow last to be empty -
closes #3005
2020-03-02 20:05:54 +01:00
Matthias
35ef065d7b Merge pull request #3012 from freqtrade/dependabot/pip/develop/scikit-learn-0.22.2
Bump scikit-learn from 0.22.1 to 0.22.2
2020-03-02 10:54:20 +01:00
Matthias
dae04e2752 Merge pull request #3011 from freqtrade/dependabot/pip/develop/ccxt-1.23.30
Bump ccxt from 1.22.95 to 1.23.30
2020-03-02 10:50:25 +01:00
Matthias
4605bdad29 Merge pull request #3013 from freqtrade/dependabot/pip/develop/plotly-4.5.2
Bump plotly from 4.5.1 to 4.5.2
2020-03-02 10:49:55 +01:00
dependabot-preview[bot]
a17f3fb8be Bump plotly from 4.5.1 to 4.5.2
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.1 to 4.5.2.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.5.1...v4.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-02 08:39:25 +00:00
dependabot-preview[bot]
485075b8f2 Bump scikit-learn from 0.22.1 to 0.22.2
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.22.1 to 0.22.2.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.22.1...0.22.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-02 08:38:36 +00:00
dependabot-preview[bot]
e204e3277b Bump ccxt from 1.22.95 to 1.23.30
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.95 to 1.23.30.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.22.95...1.23.30)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-02 08:37:58 +00:00
hroff-1902
db1227f279 Merge pull request #3007 from yazeed/hyperopt_interface_sort
hyperopt_interface.py code styling
2020-03-02 02:22:44 +03:00
Yazeed Al Oyoun
77b7f95efb simple code styling fixes 2020-03-02 00:14:01 +01:00
hroff-1902
8475baba4e Merge pull request #2995 from freqtrade/stake_curr_empty
Allow Stake currency empty when using download-data
2020-03-02 00:53:09 +03:00
hroff-1902
e20b06408c Merge pull request #3000 from freqtrade/fix/jupyter_example
[minor] Fix jupyter notebook example
2020-03-02 00:49:21 +03:00
Fredrik81
f08c7eedf1 Changed jobs to be dynamic for last loop 2020-03-01 14:35:13 +01:00
Fredrik81
75b4f1a442 Fix alignment of higher values 2020-03-01 14:12:27 +01:00
Matthias
0f2d771634 update docs 2020-03-01 09:46:12 +01:00
Matthias
4d8430c687 Use string typehints to avoid import errors 2020-03-01 09:43:20 +01:00
Matthias
cd54875f03 Add documentation link to advanced functions 2020-03-01 09:40:07 +01:00
Matthias
791148176c Add callback functions to new-strategy --template advanced 2020-03-01 09:35:53 +01:00
Matthias
7736f8d018 Add tests for fallkback 2020-03-01 09:34:42 +01:00
Matthias
eda77aeec8 Add render_template fallback 2020-03-01 09:30:30 +01:00
Fredrik81
379275e2d6 Updated tests 2020-03-01 03:24:04 +01:00
Fredrik81
267416eced Changed test for new table printing 2020-03-01 03:11:00 +01:00
Fredrik81
e89fd33229 Fix for more arguments 2020-02-29 23:57:15 +01:00
Fredrik81
7a4edb1cd8 Fix: When total epochs is less than cpu cores 2020-02-29 23:41:59 +01:00
hroff-1902
0a2f854302 Merge pull request #3001 from freqtrade/doc-nonce
[minor] Add note about InvalidNonce to documentation
2020-03-01 01:28:34 +03:00
Fredrik81
23ae0653bd Changed table output to match hyperopt-list command 2020-02-29 23:24:08 +01:00
Matthias
60f04cff4d Simplify expression 2020-02-29 20:41:03 +01:00
Matthias
54c07e5e62 Merge pull request #2997 from freqtrade/new_release
New release 2020.02
2020-02-29 19:33:12 +01:00
Matthias
8fce82b412 Merge pull request #3002 from freqtrade/kraken_supported
Add official support for Kraken
2020-02-29 19:32:43 +01:00
Matthias
18d724f7a1 Adjust wording of supported exchanges 2020-02-29 19:22:36 +01:00
Matthias
d7373be553 Add official support for Kraken 2020-02-29 16:58:22 +01:00
Matthias
4c39f36084 Add note about InvalidNonce to documentation 2020-02-29 16:36:33 +01:00
hroff-1902
415f1dc25b Merge pull request #2999 from freqtrade/release_docs
[minor] improve and correct release documentation
2020-02-29 18:31:11 +03:00
hroff-1902
293d1fca5c Merge pull request #2998 from freqtrade/try_fix_randomfailure
Try fix random testfailure
2020-02-29 18:29:54 +03:00
Matthias
848054d140 Fix jupyter notebook example -
generate_candlestick_graph() needs a filtered pairlist, not a list
containing all pairs
2020-02-29 15:53:54 +01:00
Matthias
f25adf3b12 improve and correct release documentation 2020-02-29 15:48:36 +01:00
Matthias
9336d8ee02 Try fix random testfailure 2020-02-29 15:44:45 +01:00
Matthias
a6b48f7366 Version bump 2020.02 2020-02-29 15:16:55 +01:00
Matthias
c6fd6a0fbf Merge branch 'master' into new_release 2020-02-29 15:16:45 +01:00
Matthias
60579485e5 fix empty stake currency problem 2020-02-29 14:56:36 +01:00
Matthias
5277d71913 Add test for empty stake-currency 2020-02-29 14:56:04 +01:00
hroff-1902
0528af1700 Merge pull request #2879 from freqtrade/sortino_hyperopt_loss
Sortino hyperopt loss
2020-02-29 11:36:27 +03:00
Fredrik81
349aa2f957 Added dynamic print table function to hyperopt 2020-02-28 21:54:04 +01:00
hroff-1902
bee8e92f02 Final changes, use sqrt i.o. statistics.pstdev 2020-02-28 23:50:25 +03:00
hroff-1902
e411717de9 No percent where ratio is to be used 2020-02-28 12:36:39 +03:00
Matthias
ac7fa8252b Merge pull request #2985 from Fredrik81/pretty-backtesting
Changed table style of backtesting and alignment of headers
2020-02-28 06:20:34 +01:00
hroff-1902
866c51acc5 Merge pull request #2988 from freqtrade/fix/dryrun
run-mode not correctly set when using --dry-run
2020-02-27 22:09:18 +03:00
Matthias
a55964a622 we Must parse --dry-run before setting run-mode 2020-02-27 19:36:54 +01:00
Matthias
5a02026f82 Add test validating behaviour 2020-02-27 19:35:58 +01:00
hroff-1902
c0001fcb8c Merge pull request #2987 from Fredrik81/table-style
Minor change to standardize table style.
2020-02-27 18:30:14 +03:00
hroff-1902
c1c0b59223 Merge pull request #2974 from freqtrade/enhance_roi_doc
Add timeframe_to_minutes to ROI documentation
2020-02-27 18:18:24 +03:00
Fredrik81
15e59654d9 Minor change to standardize table style.
This PR will target commands.
2020-02-27 16:10:45 +01:00
Matthias
e5a9c81412 Add 0 entry to enhanced ROI example 2020-02-27 14:04:12 +01:00
Fredrik81
55d471190a Changed table style of backtesting and alignment of headers 2020-02-27 13:28:28 +01:00
hroff-1902
90065843a5 Merge pull request #2983 from freqtrade/runmode
Logging should be initialized first
2020-02-27 12:22:37 +03:00
Matthias
8623300d15 Merge pull request #2984 from freqtrade/dependabot/docker/python-3.8.2-slim-buster
Bump python from 3.8.1-slim-buster to 3.8.2-slim-buster
2020-02-27 08:26:20 +01:00
dependabot-preview[bot]
bbb438bd40 Bump python from 3.8.1-slim-buster to 3.8.2-slim-buster
Bumps python from 3.8.1-slim-buster to 3.8.2-slim-buster.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-27 06:18:09 +00:00
Matthias
e5ec97495d Logging should be initialized first 2020-02-27 07:01:00 +01:00
hroff-1902
893d9cde8d Merge pull request #2943 from Fredrik81/add-print-table
Added function to print hyperopt-list as table using tabulate
2020-02-27 05:22:41 +03:00
Matthias
b6839289ec Add price_side to sample config files 2020-02-26 20:03:13 +01:00
Matthias
0fea3a7ea7 Some final polish to configurable_side 2020-02-26 19:50:17 +01:00
Matthias
3c5e716d8f Update some documentation regarding price_side 2020-02-26 19:39:12 +01:00
Matthias
8edc3eb5fb Use generator to generate sell price scaffold testing 2020-02-26 19:39:12 +01:00
Matthias
e1cb6f4ae3 fix and improve tests in test_freqtradebot 2020-02-26 19:39:12 +01:00
Matthias
e7b9891335 Adapt rpc tests to corrected price side 2020-02-26 19:39:12 +01:00
Matthias
e4b2949188 Change buy_rate calculation to use price_side 2020-02-26 19:39:12 +01:00
Matthias
5f71232038 Refactor get_buy_rate to use rate variable 2020-02-26 19:39:12 +01:00
Matthias
de48a697b0 Use price_side for get_sell_rate 2020-02-26 19:39:12 +01:00
Matthias
f91d7beaa1 Fix constants wrong parenteses 2020-02-26 19:39:12 +01:00
hroff-1902
30b0911645 Merge pull request #2976 from gaugau3000/doc_update_config_section
[Doc update config section] - [minor]
2020-02-26 12:45:06 +03:00
hroff-1902
e6d003f8f2 Merge pull request #2973 from freqtrade/support_non_pairs
Support non pairs
2020-02-26 12:20:45 +03:00
hroff-1902
297e63de0a Merge pull request #2970 from freqtrade/install_docs
simplify installation documentation
2020-02-26 11:48:51 +03:00
Matthias
8ae0f99a96 Remove duplicate section 2020-02-26 09:05:48 +01:00
Matthias
a29653b510 Wording changes to install docs
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-02-26 08:59:27 +01:00
Matthias
f38accb77b Return empty string if no quote / base currency can be found 2020-02-26 07:09:54 +01:00
Matthias
4e218be51d Don't use markets[pair]['quote'] 2020-02-26 07:08:09 +01:00
Matthias
1021ffa1c3 Apply suggestions from code review
Add suggested changes to comments

Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-02-26 07:00:08 +01:00
Matthias
1e869b86f2 Update checkout aciton to v2
https://github.com/actions/checkout/issues/23 suggests that it's fixed in v2.
2020-02-26 06:54:04 +01:00
Matthias
af4469f073 Convert to str to avoid errors 2020-02-26 06:43:15 +01:00
Matthias
df49b98c25 Implement wording-changes
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-02-26 06:40:13 +01:00
hroff-1902
c9b6bb1229 Merge pull request #2954 from freqtrade/rate_caching
Improve and fix buy / sell Rate caching
2020-02-26 04:27:39 +03:00
hroff-1902
5a900858d8 Merge branch 'develop' into rate_caching 2020-02-26 04:04:20 +03:00
hroff-1902
ce2e039e5f Update docs/configuration.md 2020-02-26 01:58:32 +03:00
gaugau3000
76c449c0c2 volume_pair_list_extra_doc_infos 2020-02-25 19:45:23 +00:00
gaugau3000
7d7318a3ea fix_wrong_order_type 2020-02-25 19:41:20 +00:00
Matthias
a030ce9348 Reformat if condition 2020-02-25 20:22:59 +01:00
Matthias
d44f6651c4 Fix small parenteses bug 2020-02-25 19:55:23 +01:00
Matthias
cfc22577be Add timeframe_to_minutes to ROI documentation 2020-02-25 16:54:48 +01:00
Matthias
47e46bf205 Add second example using dataprovider and current price 2020-02-25 14:48:46 +01:00
Matthias
31ac4598ba Fix last occurances of pair splitting 2020-02-25 07:16:37 +01:00
Matthias
d34515a5de Remove constraint to have pairs in base/quote format 2020-02-25 07:04:20 +01:00
Matthias
e8eaa8920e Use get_base_currency instead of splitting by / 2020-02-25 07:01:31 +01:00
Matthias
e9448dc5e2 Add tsts for quote and base currency 2020-02-25 07:01:23 +01:00
Fredrik81
cd7efde6c0 Fixed coloring so it's only targeting the values not the table borders 2020-02-24 22:06:21 +01:00
Matthias
61037ab7b8 Implement get_pair_base_curr and get_pair_quote_curr 2020-02-24 21:50:27 +01:00
Matthias
3e4f663418 Move pairlist validation to exchange (we need to use .quote) from
markets
2020-02-24 21:33:42 +01:00
Matthias
6581ba56ca Use markets.quote to validate 2020-02-24 20:41:45 +01:00
Matthias
2f349e0504 Improve install documentation by streamlining the process 2020-02-24 20:21:25 +01:00
Matthias
23b47b66ec Update install-script documentation and reorder installation steps 2020-02-24 20:11:25 +01:00
Fredrik81
23bf135b8a Alignment of table content, changed coloring, changed 'Best' column to show if it's initial_point or best 2020-02-24 11:01:14 +01:00
Matthias
6c8b5ea38c Merge pull request #2964 from freqtrade/dependabot/pip/develop/scikit-optimize-0.7.4
Bump scikit-optimize from 0.7.2 to 0.7.4
2020-02-24 10:36:45 +01:00
Matthias
4d040f3123 Merge pull request #2962 from freqtrade/dependabot/pip/develop/requests-2.23.0
Bump requests from 2.22.0 to 2.23.0
2020-02-24 10:36:19 +01:00
Matthias
88121760e4 Merge pull request #2965 from freqtrade/dependabot/pip/develop/ccxt-1.22.95
Bump ccxt from 1.22.61 to 1.22.95
2020-02-24 10:32:12 +01:00
Matthias
ae7a12200c Merge pull request #2963 from freqtrade/dependabot/pip/develop/plotly-4.5.1
Bump plotly from 4.5.0 to 4.5.1
2020-02-24 10:31:40 +01:00
dependabot-preview[bot]
d63aaf3bfd Bump ccxt from 1.22.61 to 1.22.95
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.61 to 1.22.95.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.22.61...1.22.95)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-24 08:05:15 +00:00
dependabot-preview[bot]
ff69b511e3 Bump scikit-optimize from 0.7.2 to 0.7.4
Bumps [scikit-optimize](https://github.com/scikit-optimize/scikit-optimize) from 0.7.2 to 0.7.4.
- [Release notes](https://github.com/scikit-optimize/scikit-optimize/releases)
- [Changelog](https://github.com/scikit-optimize/scikit-optimize/blob/master/CHANGELOG.md)
- [Commits](https://github.com/scikit-optimize/scikit-optimize/compare/v0.7.2...v0.7.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-24 08:04:44 +00:00
dependabot-preview[bot]
4054dec7a0 Bump plotly from 4.5.0 to 4.5.1
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.5.0...v4.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-24 08:04:32 +00:00
dependabot-preview[bot]
353f722dc5 Bump requests from 2.22.0 to 2.23.0
Bumps [requests](https://github.com/psf/requests) from 2.22.0 to 2.23.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/master/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.22.0...v2.23.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-24 08:04:07 +00:00
Matthias
83959f0e56 Merge pull request #2959 from hroff-1902/throttling
Better throttling
2020-02-24 06:54:52 +01:00
Matthias
c657a1df2b Merge pull request #2960 from yazeed/sort_indicators_full
indicators_full.j2 and sample_strategy.py ordering and added indicators
2020-02-24 06:45:20 +01:00
Fredrik81
7eb62ed32e Remove old print option for hyperopt-list and made table as default 2020-02-24 00:33:01 +01:00
hroff-1902
e545ef563c Wording adjusted in helpstring 2020-02-23 22:50:58 +03:00
Yazeed Al Oyoun
0eeafcd157 matched commenting on previous sample_strategy.py 2020-02-23 16:56:55 +01:00
Yazeed Al Oyoun
f25d6224dd modified sample_strategy 2020-02-23 16:22:19 +01:00
Matthias
e37f055dad Improve some tests 2020-02-23 13:12:00 +01:00
Matthias
9301f81fc8 Add test for user-sell_timeout handling 2020-02-23 13:09:46 +01:00
Matthias
634e7cc34a Implement handle_buy_trade_customcallback 2020-02-23 13:08:11 +01:00
Yazeed Al Oyoun
e04c2dda2c fixed typo 2020-02-22 23:58:31 +01:00
hroff-1902
d2181bdd94 Adjust tests 2020-02-23 01:55:07 +03:00
Yazeed Al Oyoun
5ac6244465 added keltner channel and uo 2020-02-22 23:50:26 +01:00
Yazeed Al Oyoun
2957756275 final touches plus 2020-02-22 23:39:01 +01:00
Yazeed Al Oyoun
b49b9b515e final touches 2020-02-22 23:37:15 +01:00
Yazeed Al Oyoun
259dc75a30 some order and added weighted BB indicator to list 2020-02-22 23:10:46 +01:00
hroff-1902
ca8e52dc2c Show heartbeat message earlier after changing the state 2020-02-23 00:21:19 +03:00
Matthias
91ee48f3fb Merge pull request #2957 from hroff-1902/fix/2948-2
Fix #2948
2020-02-22 19:37:00 +01:00
hroff-1902
e2e6b940a3 copy=False does not make the changes inline anyway, so not needed 2020-02-22 19:54:19 +03:00
hroff-1902
c651e0ac82 Fix #2948 2020-02-22 19:46:40 +03:00
hroff-1902
430f53ca11 Merge pull request #2955 from freqtrade/fix/2948
Load ohlcv data as float
2020-02-22 17:16:54 +03:00
Matthias
3186add87b Use explicit column list for float parsing 2020-02-22 14:46:54 +01:00
Matthias
7ecc56fa44 Load ohlcv data as float 2020-02-22 13:10:41 +01:00
Matthias
8cd77b2e27 Add some tests for strategy_wrapper 2020-02-22 11:55:40 +01:00
Matthias
365fdf4c37 Add docstring to strategy wrapper 2020-02-22 11:41:22 +01:00
Matthias
4a188525ec Fix documentation note syntax 2020-02-22 11:28:13 +01:00
Matthias
2fe7b683cb Add tests for cached rates 2020-02-22 11:23:13 +01:00
Matthias
77ef3240cd Implement log messages 2020-02-22 11:20:19 +01:00
Matthias
97e6e5e976 Implement caching in the correct place 2020-02-22 11:12:33 +01:00
Matthias
f5b4a6d3d7 Remove fetch_ticker caching 2020-02-22 11:10:05 +01:00
Matthias
63502ed976 Add new advanced-strategy documentation file 2020-02-22 08:14:08 +01:00
Matthias
bc30162a31 Add some documentation 2020-02-21 20:54:21 +01:00
Matthias
135d9ddf7a Fix test due to changed dry-run cancel order 2020-02-21 20:35:54 +01:00
Matthias
bf556c8678 Merge branch 'develop' into interface_ordertimeoutcallback 2020-02-21 20:35:07 +01:00
Matthias
6c01542fed Ad check_sell_timeout 2020-02-21 20:27:13 +01:00
Matthias
8c1a933221 cancel_order should return a dict 2020-02-21 20:23:43 +01:00
hroff-1902
d9ecf3e4bf Add version and state to heartbeat message 2020-02-21 12:26:32 +03:00
hroff-1902
d2e20d86bb Align heartbeat to throttling logging 2020-02-21 05:31:21 +03:00
hroff-1902
269a669af8 Move heartbeat to worker 2020-02-21 05:07:31 +03:00
hroff-1902
881f602f91 Adjust methods params 2020-02-21 04:17:17 +03:00
hroff-1902
e0800b7c29 Make throttle start time an worker object attribute 2020-02-21 03:52:14 +03:00
hroff-1902
04aa74e5ad Better throttling 2020-02-21 03:37:38 +03:00
Fredrik81
09226fd5d5 PEP8 correction 2020-02-20 19:18:42 +01:00
Fredrik81
e7b12704de Added test for details 2020-02-20 19:12:55 +01:00
hroff-1902
43add0b159 Merge pull request #2947 from freqtrade/fix_failing_dockerbuild
Use correct strategy path for docker testing
2020-02-20 16:53:39 +03:00
Matthias
945ff09e27 Use correct strategy path for docker testing 2020-02-20 14:19:24 +01:00
hroff-1902
78ee36a8c6 Use _throttle() in stopped state instead of sleep() 2020-02-20 15:18:26 +03:00
hroff-1902
bee28a1061 Merge pull request #2944 from freqtrade/move_defaultstrategy
Move defaultstrategy
2020-02-20 08:52:24 +03:00
Matthias
10668bb249 Update tests/strategy/test_strategy.py
Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-02-20 06:22:36 +01:00
hroff-1902
56a06cbd33 Update strings to f-strings 2020-02-20 08:19:22 +03:00
hroff-1902
bca5f804a8 Move divider log message 2020-02-20 08:17:24 +03:00
Yazeed Al Oyoun
09a1c9eed6 fixed docs description of hyperopts 2020-02-19 22:25:34 +01:00
Matthias
5adbe3c2d3 initial search path is optional ... 2020-02-19 19:50:01 +01:00
Matthias
751e2b2359 Merge pull request #2945 from freqtrade/fix/kraken_stoplosshit
Kraken stoploss bugfix
2020-02-19 19:43:29 +01:00
Matthias
a7342bd910 Fix non-existing strategy loading 2020-02-19 19:42:04 +01:00
hroff-1902
f2f2c281c0 Merge pull request #2719 from xmatthias/data_handler
Introduce Data handler
2020-02-19 21:22:08 +03:00
Matthias
d22384c7fb Full support for kraken stoploss 2020-02-19 19:21:48 +01:00
Matthias
29b369c65e Rename cli argument 2020-02-19 14:53:54 +01:00
hroff-1902
2d2fd968c8 Merge pull request #2941 from freqtrade/github_actions_tests
GitHub actions tests
2020-02-19 14:58:12 +03:00
Matthias
882d0a5933 implement documentation feedback after review 2020-02-19 12:55:08 +01:00
Matthias
09d89fbfb3 Fix last test 2020-02-19 07:15:55 +01:00
Yazeed Al Oyoun
41b4fa3b7f fixed two more typos 2020-02-19 02:59:51 +01:00
Yazeed Al Oyoun
3fb6818bd8 Merge branch 'develop' into sortino_hyperopt_loss 2020-02-19 02:37:25 +01:00
Yazeed Al Oyoun
df26c357d2 doc updates 2020-02-19 01:31:25 +01:00
Fredrik Rydin
585545405d Changed tests 2020-02-19 00:51:44 +01:00
Fredrik Rydin
2058b492eb Added function to print hyperopt-list as table using tabulate 2020-02-18 22:46:53 +01:00
Matthias
d91b9d1253 Fix some tests, don't default to freqtrade/strategy for imports 2020-02-18 20:26:20 +01:00
Matthias
1634297685 Move strategies to test subfolder 2020-02-18 20:12:10 +01:00
hroff-1902
16cbd441ce Merge pull request #2931 from freqtrade/status_badge
Add github actions badge
2020-02-18 10:55:34 +03:00
Matthias
e6dd463ca3 Revert versioning 2020-02-17 20:17:36 +01:00
Matthias
1172c95817 Use different versioning scheme 2020-02-17 20:17:08 +01:00
Matthias
0b33b798e4 Add pypi build step 2020-02-17 20:16:24 +01:00
Matthias
4c41da2ea4 Merge pull request #2934 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.4.2
Bump python-telegram-bot from 12.4.1 to 12.4.2
2020-02-17 10:12:28 +01:00
Matthias
9b58b4c54d Merge pull request #2939 from freqtrade/dependabot/pip/develop/scikit-optimize-0.7.2
Bump scikit-optimize from 0.7.1 to 0.7.2
2020-02-17 09:49:45 +01:00
Matthias
a8e0526d87 Merge pull request #2937 from freqtrade/dependabot/pip/develop/wrapt-1.12.0
Bump wrapt from 1.11.2 to 1.12.0
2020-02-17 09:48:58 +01:00
Matthias
90fbf70bcc Merge pull request #2936 from freqtrade/dependabot/pip/develop/coveralls-1.11.1
Bump coveralls from 1.10.0 to 1.11.1
2020-02-17 09:47:47 +01:00
dependabot-preview[bot]
582b59044c Bump python-telegram-bot from 12.4.1 to 12.4.2
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.4.1 to 12.4.2.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.4.1...v12.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 08:47:39 +00:00
Matthias
df955b8104 Merge pull request #2935 from freqtrade/dependabot/pip/develop/ccxt-1.22.61
Bump ccxt from 1.22.39 to 1.22.61
2020-02-17 09:46:24 +01:00
Matthias
e7d687ee11 Merge pull request #2938 from freqtrade/dependabot/pip/develop/mkdocs-material-4.6.3
Bump mkdocs-material from 4.6.2 to 4.6.3
2020-02-17 09:45:51 +01:00
dependabot-preview[bot]
0fd3d74fc4 Bump scikit-optimize from 0.7.1 to 0.7.2
Bumps [scikit-optimize](https://github.com/scikit-optimize/scikit-optimize) from 0.7.1 to 0.7.2.
- [Release notes](https://github.com/scikit-optimize/scikit-optimize/releases)
- [Changelog](https://github.com/scikit-optimize/scikit-optimize/blob/master/CHANGELOG.md)
- [Commits](https://github.com/scikit-optimize/scikit-optimize/compare/v0.7.1...v0.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 08:05:00 +00:00
dependabot-preview[bot]
9435950fc9 Bump mkdocs-material from 4.6.2 to 4.6.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.6.2 to 4.6.3.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/4.6.2...4.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 08:04:40 +00:00
dependabot-preview[bot]
500e1c77de Bump wrapt from 1.11.2 to 1.12.0
Bumps [wrapt](https://github.com/GrahamDumpleton/wrapt) from 1.11.2 to 1.12.0.
- [Release notes](https://github.com/GrahamDumpleton/wrapt/releases)
- [Changelog](https://github.com/GrahamDumpleton/wrapt/blob/develop/docs/changes.rst)
- [Commits](https://github.com/GrahamDumpleton/wrapt/compare/1.11.2...1.12.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 08:04:21 +00:00
dependabot-preview[bot]
c6a3038f52 Bump coveralls from 1.10.0 to 1.11.1
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 1.10.0 to 1.11.1.
- [Release notes](https://github.com/coveralls-clients/coveralls-python/releases)
- [Changelog](https://github.com/coveralls-clients/coveralls-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/coveralls-clients/coveralls-python/compare/1.10.0...1.11.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 08:03:57 +00:00
dependabot-preview[bot]
212d20ed08 Bump ccxt from 1.22.39 to 1.22.61
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.39 to 1.22.61.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.22.39...1.22.61)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-17 08:03:37 +00:00
Matthias
bec86b1325 Add github actions badge 2020-02-16 15:42:41 +01:00
Matthias
6335d81ceb Merge branch 'develop' into data_handler 2020-02-16 15:12:14 +01:00
hroff-1902
7b9bd70d97 Merge pull request #2930 from freqtrade/ftx_fix_ohlcv
increment limit to adjust to FTX defaults (1500 candles)
2020-02-16 15:53:27 +03:00
hroff-1902
674898bd32 Fix usage of vars in the commented out line 2020-02-16 15:26:40 +03:00
Matthias
3787ac7b98 increment limit to adjust to FTX defaults (1500 candles) 2020-02-16 13:20:11 +01:00
hroff-1902
42dfda9231 Adjust docstring 2020-02-16 13:46:07 +03:00
hroff-1902
fbe5cc44da Use statistics.pstdev 2020-02-16 13:43:23 +03:00
hroff-1902
1e84b2770c Fix values of downside_returns 2020-02-16 04:10:53 +03:00
hroff-1902
161dd1a3e6 Rename risk_free_return to minumum_accepted_return 2020-02-16 03:55:16 +03:00
hroff-1902
36670fb5d9 Merge pull request #2929 from yazeed/fix_status_table
/status table quick fix
2020-02-15 23:09:50 +03:00
Yazeed Al Oyoun
180939a962 winner, readability, with brackets as fix 2020-02-15 21:01:45 +01:00
Yazeed Al Oyoun
6e71f2f166 my fix 2020-02-15 20:55:12 +01:00
Matthias
44ac2409ff Merge pull request #2923 from hroff-1902/status-strategies
Add printing statuses for enlisted strategies and hyperopts
2020-02-15 19:43:02 +01:00
hroff-1902
6139239b86 Address points stated in comments 2020-02-15 20:43:11 +03:00
hroff-1902
9d09a67dea Merge pull request #2925 from freqtrade/fix_edgedocs
Fix edge documentation rendering
2020-02-15 19:41:59 +03:00
Matthias
87b506972f Fix edge documentation rendering 2020-02-15 13:12:29 +01:00
hroff-1902
c453969235 Merge pull request #2922 from freqtrade/config_userdir
default to loading config.json from userdir if it exists
2020-02-15 08:00:04 +03:00
hroff-1902
fdd362299f Docs adjusted 2020-02-15 07:34:39 +03:00
hroff-1902
42a5d78e60 Wording (duplicate, not duplicated) 2020-02-15 07:19:24 +03:00
hroff-1902
ddea4b9300 Fix test 2020-02-15 06:54:18 +03:00
hroff-1902
e8c0a0bcd3 Make mypy happy 2020-02-15 06:18:00 +03:00
hroff-1902
1cf19133f4 Added missing failing strategy 2020-02-15 05:41:58 +03:00
hroff-1902
29d9b6a46a Add test for enum failed 2020-02-15 04:32:10 +03:00
hroff-1902
93f9ff1b63 Fix existing test 2020-02-15 04:22:21 +03:00
hroff-1902
06b84b4086 Remove redundant code 2020-02-14 23:13:49 +03:00
hroff-1902
bba7a38144 Merge pull request #2906 from freqtrade/fix/jupyterexample
Update data-analysis documentation to properly initialize configuration
2020-02-14 22:36:35 +03:00
hroff-1902
47a91c9d8e Remove green color 2020-02-14 22:32:46 +03:00
hroff-1902
e598c769d4 Add colorization 2020-02-14 22:28:49 +03:00
Matthias
f024cc40d3 Fix windows test failure 2020-02-14 20:21:09 +01:00
Matthias
ecca7164d9 Fix small issue 2020-02-14 20:13:36 +01:00
Matthias
d5a298bbb7 Add sentence from suggestion 2020-02-14 20:12:26 +01:00
Matthias
5efbdd25a7 Properly default to user_data/config.json if it exists 2020-02-14 20:04:05 +01:00
Matthias
ab27d2c720 Merge pull request #2921 from hroff-1902/adjust-buy-notification
Move rpc send to be after db session add/flash
2020-02-14 20:02:56 +01:00
hroff-1902
c92e1d97d6 Attempt to make mypy happy 2020-02-14 21:52:02 +03:00
hroff-1902
1bc26fd07a Add printing statuses for list-hyperopts 2020-02-14 21:46:22 +03:00
Matthias
be4a9b5f4b Lowercase freqtrade 2020-02-14 19:37:20 +01:00
Matthias
9dafc2f3c8 Load config.json from user_data first 2020-02-14 19:33:10 +01:00
hroff-1902
a2d7f8a70d Split tabular printing into sep. helper function 2020-02-14 21:24:30 +03:00
hroff-1902
9cbf8c5f00 Add status for listed strategies 2020-02-14 21:15:36 +03:00
Matthias
3312fd34f3 Merge pull request #2920 from hroff-1902/remove-delete-trades
Get rid of delete_trade method in Freqtradebot
2020-02-14 07:27:52 +01:00
Matthias
ee92e8dbf4 Merge pull request #2919 from hroff-1902/adjust-main
Minor: Adjust message in main.py
2020-02-14 07:27:19 +01:00
Matthias
ec5d2d78dd Merge pull request #2918 from hroff-1902/bittrex-config
Add order_types into Bittrex config subtemplate
2020-02-14 07:26:49 +01:00
hroff-1902
20c21b42d5 Move rpc send to be after db session add/flash 2020-02-14 06:23:03 +03:00
hroff-1902
36ef5c6bdf Get rid of delete_trades method in Freqtradebot 2020-02-14 04:05:17 +03:00
hroff-1902
2dea362eda Merge pull request #2887 from yazeed/rpc_notification_fixes
Wide RPC notifications fixes
2020-02-14 03:51:23 +03:00
hroff-1902
749463e4b7 Adjust message in main.py 2020-02-14 03:05:07 +03:00
hroff-1902
a0a14a1078 freqtrade/templates/subtemplates/exchange_bittrex.j2 2020-02-14 01:08:17 +03:00
hroff-1902
4cdcf00ddc Merge branch 'develop' into rpc_notification_fixes 2020-02-14 00:10:50 +03:00
hroff-1902
0631fc937a Merge pull request #2915 from freqtrade/documentation_test
fix configuration table
2020-02-13 17:27:54 +03:00
Matthias
02148a1df2 Fix datatype styling issues 2020-02-13 15:09:09 +01:00
Matthias
a93bc74eff Update documentation ... 2020-02-13 07:04:37 +01:00
Matthias
ccc9239751 Reduce indentation of help 2020-02-13 07:02:12 +01:00
Matthias
86592c3ba1 Fix /help from telegram 2020-02-13 06:51:52 +01:00
Matthias
81f849811f Initcap Freqtrade 2020-02-13 06:30:59 +01:00
Matthias
3e6209def2 Merge pull request #2914 from freqtrade/hroff-1902-patch-1
Docs: Fix checking of runmode
2020-02-13 06:28:50 +01:00
hroff-1902
b2328cdf4f Do not subtract risk_free_ratio twice 2020-02-13 07:07:35 +03:00
hroff-1902
634bf2b15c Docs: Fix checking of runmode 2020-02-13 01:44:46 +03:00
Yazeed Al Oyoun
007cc94474 fixed tests to send refresh, since its no longer defaulted 2020-02-12 22:03:56 +01:00
Yazeed Al Oyoun
f09af888b1 modified get_buy/sell_rate refresh to true on notify_sell_cancel and notify_buy_cancel 2020-02-12 21:55:38 +01:00
Yazeed Al Oyoun
2e3b8cdba7 fixed flake8 issues on /help output 2020-02-12 21:51:58 +01:00
Yazeed Al Oyoun
f6db784a85 removed default to refresh argument in get_buy_rate and get_sell_rate 2020-02-12 21:50:33 +01:00
Yazeed Al Oyoun
47874a4527 added logic to differentiate sell orders with double asterisk 2020-02-12 21:45:55 +01:00
Matthias
2efa1c164f Revert data-location section 2020-02-12 21:43:43 +01:00
Matthias
483cba453a Fix last occurence of data_location 2020-02-12 19:58:23 +01:00
Matthias
d6b9397579 Fix typo in datadir key 2020-02-12 06:40:13 +01:00
Matthias
9a22ce69bd Merge pull request #2908 from hroff-1902/tests_load_default_strategy
Do not instantiate directly DefaultStrategy in tests
2020-02-12 06:37:19 +01:00
hroff-1902
4f3376e2a1 Do not instantiate directly DefaultStrategy in tests 2020-02-12 01:39:15 +03:00
hroff-1902
e73dac8d91 Merge pull request #2905 from Fredrik81/hyperopt-more-filters
Adding --min-trades, --max-trades, --max-avg-profit, --max-total-profit for hyperopt-list
2020-02-11 23:46:48 +03:00
Fredrik Rydin
539343b20d Adding 2 more filter options for completeness 2020-02-11 21:29:55 +01:00
Matthias
7be9f0067e Update data-analysis documentation to properly initialize configuration 2020-02-11 20:51:39 +01:00
Matthias
64fb8e28ec Merge pull request #2886 from freqtrade/docker_docs
Docker docs
2020-02-11 19:41:42 +01:00
Matthias
c35fe2c386 Add link to quick-start-guide 2020-02-11 19:29:43 +01:00
Fredrik Rydin
d1c3eabb87 Changed commands to use "check_int_positive" 2020-02-11 18:08:30 +01:00
Yazeed Al Oyoun
899de8b27c modified tests for double partial call 2020-02-11 16:50:18 +01:00
Yazeed Al Oyoun
cde1b2b56c readded rpc status message for partial buys 2020-02-11 16:28:48 +01:00
Yazeed Al Oyoun
5f4c209fca fixed one more occurence of executed buy, and test 2020-02-11 16:14:49 +01:00
Yazeed Al Oyoun
4fedf1e564 default refresh TRUE on get_buy_rate and get_sell_Rate 2020-02-11 16:05:44 +01:00
Fredrik Rydin
5b4d8d69ef Adding --min-trades and --max-trades for hyperopt-list 2020-02-11 16:02:08 +01:00
Yazeed Al Oyoun
fc29564974 Fixed messages and readability 2020-02-11 15:58:40 +01:00
Yazeed Al Oyoun
867b736b84 Fixed to Executing Buys & Sells 2020-02-11 15:50:21 +01:00
Yazeed Al Oyoun
7f4b90c68f fixed actual open_rate in notify_buy_cancel 2020-02-11 15:45:35 +01:00
Yazeed Al Oyoun
f99d1c3829 fixed open_rate instead of open_rate_requested 2020-02-11 15:44:47 +01:00
Matthias
59a576ef3e Merge pull request #2903 from hroff-1902/fix/tests_history-2
Minor: Fix tests_history.py
2020-02-11 07:14:13 +01:00
Matthias
81997cba8a Merge pull request #2902 from hroff-1902/fix/tests_hyperopt_loss
Minor: Fix tests for hyperopt_loss
2020-02-11 07:13:29 +01:00
Matthias
57fcca9696 Merge pull request #2904 from hroff-1902/fix/tests_backtesting_container
Minor: Fix usage of an item from BTContainer in tests
2020-02-11 07:02:28 +01:00
hroff-1902
29f7c5071b Fix usage of an item from BTContainer in tests 2020-02-11 04:17:10 +03:00
hroff-1902
62bcb3d766 Fix tests in test_history.py 2020-02-11 03:43:20 +03:00
hroff-1902
2bcce33f23 Merge pull request #2888 from Fredrik81/hyperopt-filters
Added filter options to "hyperopt-list" in order to easier find epochs.
2020-02-10 23:59:40 +03:00
Fredrik Rydin
f2520c11e7 Used wrong utils.md as base 2020-02-10 21:19:25 +01:00
Fredrik Rydin
c924e4d519 Updated based on feedback:
- Profit commands now use float
- Compatible with --best
- Corrected wrong information in docs
2020-02-10 20:54:31 +01:00
Matthias
d442b31f84 Merge pull request #2894 from freqtrade/hroff-1902-patch-2
Minor: Adjust mypy and flake commands
2020-02-10 19:03:09 +01:00
hroff-1902
df8a27fba6 Merge pull request #2900 from freqtrade/rem_bin
Break the old binary file so users are forced to reinstall
2020-02-10 20:52:13 +03:00
hroff-1902
05128d21a8 Suggest to run flake for scripts 2020-02-10 20:48:49 +03:00
Matthias
faf19eda86 Break the old binary file so users are forced to reinstall
Note:
This should not be relevant anymore - this binary has been deprecated
and is not being used by new installations since July 2019.
2020-02-10 17:31:49 +01:00
hroff-1902
d07c69809d Fix tests for hyperopt_loss 2020-02-10 18:32:41 +03:00
hroff-1902
da03c36875 Merge pull request #2899 from freqtrade/mypy_tests
Fix mypy type errors in tests
2020-02-10 15:43:57 +03:00
hroff-1902
0ac0ca74b5 return back hint for running mypy 2020-02-10 15:41:09 +03:00
Yazeed Al Oyoun
d69ddd2ac3 Apply suggestions from code review
Committed 1 code suggestion in code review.

Co-Authored-By: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-02-10 11:54:12 +01:00
Matthias
1a544be828 Merge pull request #2898 from freqtrade/dependabot/pip/develop/mkdocs-material-4.6.2
Bump mkdocs-material from 4.6.0 to 4.6.2
2020-02-10 11:03:10 +01:00
Matthias
bfccb2e96a Merge pull request #2896 from freqtrade/dependabot/pip/develop/pandas-1.0.1
Bump pandas from 1.0.0 to 1.0.1
2020-02-10 11:02:54 +01:00
Matthias
7bb02d0cc6 Update docker-docs wording 2020-02-10 11:01:33 +01:00
Matthias
f220e0f6ca Merge pull request #2897 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.4.1
Bump python-telegram-bot from 12.3.0 to 12.4.1
2020-02-10 10:40:37 +01:00
Matthias
83644ce5d8 Fix mypy type errors in tests 2020-02-10 10:35:48 +01:00
dependabot-preview[bot]
550f9fc891 Bump python-telegram-bot from 12.3.0 to 12.4.1
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.3.0 to 12.4.1.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.3.0...v12.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 08:45:27 +00:00
Matthias
c7167c83cd Merge pull request #2895 from freqtrade/dependabot/pip/develop/ccxt-1.22.39
Bump ccxt from 1.22.30 to 1.22.39
2020-02-10 09:44:08 +01:00
dependabot-preview[bot]
6b4094fd92 Bump mkdocs-material from 4.6.0 to 4.6.2
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.6.0 to 4.6.2.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/4.6.0...4.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 08:02:45 +00:00
dependabot-preview[bot]
88f2ad1eae Bump pandas from 1.0.0 to 1.0.1
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v1.0.0...v1.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 08:02:07 +00:00
dependabot-preview[bot]
90ee82ac43 Bump ccxt from 1.22.30 to 1.22.39
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.22.30 to 1.22.39.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.22.30...1.22.39)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-10 08:01:42 +00:00
Matthias
db0475f9c3 Merge pull request #2890 from freqtrade/hroff-1902-patch-1
Add tip on running order types for Bittrex
2020-02-10 08:33:24 +01:00
hroff-1902
4af25ec315 Adjust mypy and flake commands 2020-02-10 05:52:07 +03:00
hroff-1902
0ba8d13de9 Merge pull request #2831 from xmatthias/feat/new_config
introduce new-config subcommand
2020-02-09 22:11:37 +03:00
hroff-1902
f7c74e551f Fix wording 2020-02-09 21:56:59 +03:00
Fredrik81
5bf4c5869b Update hyperopt_commands.py
Missed a debug print
2020-02-09 19:32:09 +01:00
hroff-1902
9ec9a7b124 Fix t_index to be normalized 2020-02-09 21:20:15 +03:00
hroff-1902
cc3f65d069 Fix typo 2020-02-09 19:45:04 +03:00
hroff-1902
c83da7cadb Add section about order types into Bittrex Exchange-specific chapter 2020-02-09 19:11:06 +03:00
Matthias
7c91c77fd9 Merge pull request #2891 from freqtrade/hroff-1902-patch-2
Fix SharpeHyperOptLossDaily
2020-02-09 17:06:22 +01:00
hroff-1902
40abdd2608 Suggest changing strategy 2020-02-09 18:54:04 +03:00
hroff-1902
c89a32224c Fix SharpeHyperOptLossDaily 2020-02-09 18:40:19 +03:00
Matthias
d65a06947d Merge branch 'develop' into data_handler 2020-02-09 15:16:43 +01:00
Fredrik Rydin
eb3783dc00 Fixed a blank line issue :-( 2020-02-09 14:30:29 +01:00
Fredrik Rydin
c648ec7c0c Added test cases and fixed a minor bug 2020-02-09 14:18:56 +01:00
hroff-1902
c7ba85c2e6 Add tip on running order types for Bittrex 2020-02-09 14:19:13 +03:00
Matthias
b536d50194 Address PR Review 2020-02-09 11:41:29 +01:00
Matthias
f41de38498 Merge pull request #2884 from freqtrade/fix/stakecurr_validation
fix download-data validation problems
2020-02-09 11:07:39 +01:00
Fredrik Rydin
c96acd6ca0 Fixed to pass PEP8 2020-02-09 00:16:11 +01:00
Yazeed Al Oyoun
2796d3d8a0 added missing tests to increase coverage 2020-02-09 00:11:58 +01:00
Fredrik Rydin
636bd5acb5 Added filter options to "hyperopt-list" in order to easier find epochs.
--profitable
	Select only profitable epochs.
  --min-avg-time INT
	Select epochs on above average time.
  --max-avg-time INT
	Select epochs on under average time.
  --min-avg-profit FLOAT
	Select epochs on above average profit.
  --min-total-profit FLOAT
	Select epochs on above total profit.
2020-02-08 23:21:42 +01:00
Matthias
1a9787ac76 Add validation for data-download relevant settings 2020-02-08 21:53:34 +01:00
Yazeed Al Oyoun
879b513822 enhanced method description 2020-02-08 21:31:36 +01:00
Yazeed Al Oyoun
4fad7a462c fixes in webhook-config docs 2020-02-08 21:19:07 +01:00
Yazeed Al Oyoun
f3b1161640 wide notifications fixes 2020-02-08 21:02:52 +01:00
Matthias
c4031761fe Don't validate exchange for data-download subcommand 2020-02-08 19:29:58 +01:00
Matthias
34f04668c1 Add template for bittrex 2020-02-08 14:02:51 +01:00
Matthias
52f4187129 Allow exchange templates to configure outside-options too 2020-02-08 13:51:55 +01:00
Matthias
f508324fc8 Update docker documentation to be easier to use 2020-02-08 13:38:45 +01:00
Matthias
a1fe3850e2 Improve docker-compose file to be ready to use 2020-02-08 13:34:04 +01:00
Matthias
fff8ced3b0 Merge pull request #2843 from hroff-1902/allow-derived-strategies
Allow derived strategies
2020-02-08 09:15:35 +01:00
Matthias
67e66a6c4a Merge pull request #2882 from hroff-1902/update_advanced_hyperopt_template
Update advanced hyperopt template
2020-02-08 09:07:18 +01:00
Matthias
5bae5a6a35 Merge pull request #2881 from hroff-1902/no_nxt_in_config_example
Minor: Replace NXT with XRP in config.json.example
2020-02-08 09:05:23 +01:00
hroff-1902
61ced5e926 Fix typo 2020-02-08 02:49:06 +03:00
hroff-1902
28184201e4 Align sample_hyperopt_advanced.py to hyperopt_interface.py 2020-02-08 02:47:50 +03:00
hroff-1902
a893f70e49 Replace NXT with XRP in config.json.example 2020-02-08 02:21:39 +03:00
hroff-1902
6990f6af25 Merge pull request #2870 from freqtrade/dry_run_docs
Add considerations for dry-run
2020-02-08 00:09:58 +03:00
hroff-1902
c501fd0a70 Merge pull request #2875 from yazeed/distinguish_draws_from_wins
Add draws column to backtesting tables
2020-02-07 22:55:12 +03:00
Matthias
abf10aec98 Merge branch 'develop' into feat/new_config 2020-02-07 17:02:14 +01:00
Yazeed Al Oyoun
6b279f297c fixed test 2020-02-07 16:45:07 +03:00
Yazeed Al Oyoun
e8b9d88eb6 moved line for total_downside 2020-02-07 16:44:55 +03:00
Yazeed Al Oyoun
a46b7bcd6d more fixes... 2020-02-07 16:44:43 +03:00
Yazeed Al Oyoun
951a19fb00 added tests for both sortino methods 2020-02-07 16:44:30 +03:00
Yazeed Al Oyoun
be34dc463b fixed bad commit 2020-02-07 16:44:01 +03:00
Yazeed Al Oyoun
9bcc5d2eed fixed downside_returns to read from profit_percent_after_slippage 2020-02-07 16:36:12 +03:00
Yazeed Al Oyoun
728ab0ff21 Added both SortinoHyperOptLoss and SortinoHyperOptLossDaily 2020-02-07 16:35:28 +03:00
Yazeed Al Oyoun
b56a1f0603 initial push of sortino, work not done, still need own tests 2020-02-07 16:34:20 +03:00
Yazeed Al Oyoun
deb0b7ad67 Added both SortinoHyperOptLoss and SortinoHyperOptLossDaily 2020-02-07 16:30:37 +03:00
Yazeed Al Oyoun
44d67389d2 initial push of sortino, work not done, still need own tests 2020-02-07 16:29:27 +03:00
Yazeed Al Oyoun
aa2cb937b1 flake8 :) 2020-02-07 03:54:47 +01:00
Yazeed Al Oyoun
ff819386e1 added draws to backtesting tables, reduced len of some labels to help fit this without increasing total width 2020-02-07 03:51:50 +01:00
Matthias
49dcc561b7 POC for check_buy_timeout 2020-02-06 20:30:17 +01:00
Matthias
2816b96650 Create strategy_wrapper to call user-defined code with 2020-02-06 20:26:04 +01:00
hroff-1902
f57bd6b616 Keep the docs clean for unexperienced users 2020-02-06 21:53:03 +03:00
hroff-1902
418e7adac1 Highlight syntax in advanced-hyperopt as well 2020-02-06 17:49:10 +03:00
hroff-1902
2034527faa Update docs/strategy-customization.md
Co-Authored-By: Matthias <xmatthias@outlook.com>
2020-02-06 17:45:15 +03:00
hroff-1902
412f5d68de Add description to hyperopt advanced doc chapter 2020-02-06 17:42:26 +03:00
hroff-1902
2846f9454f Add description in the docs 2020-02-06 17:02:11 +03:00
hroff-1902
739acaa475 Wordings improved 2020-02-06 13:54:51 +03:00
Matthias
97e48080e8 Merge pull request #2839 from hroff-1902/list-hyperopts-2
Add list-hyperopts subcommand
2020-02-06 07:06:36 +01:00
Yazeed Al Oyoun
5b00eaa42d Updated Strategy Summary table to match other backtesting tables (#2864) 2020-02-06 06:58:58 +01:00
Yazeed Al Oyoun
9639ffb140 added daily sharpe ratio hyperopt loss method, ty @djacky (#2826)
* more consistent backtesting tables and labels

* added rounding to Tot Profit % on Sell Reasosn table to be consistent with other percentiles on table.

* added daily sharpe ratio hyperopt loss method, ty @djacky

* removed commented code

* removed unused profit_abs

* added proper slippage to each trade

* replaced use of old value total_profit

* Align quotes in same area

* added daily sharpe ratio test and modified hyperopt_loss_sharpe_daily

* fixed some more line alignments

* updated docs to include SharpeHyperOptLossDaily

* Update dockerfile to 3.8.1

* Run tests against 3.8

* added daily sharpe ratio hyperopt loss method, ty @djacky

* removed commented code

* removed unused profit_abs

* added proper slippage to each trade

* replaced use of old value total_profit

* added daily sharpe ratio test and modified hyperopt_loss_sharpe_daily

* updated docs to include SharpeHyperOptLossDaily

* docs fixes

* missed one fix

* fixed standard deviation line

* fixed to bracket notation

* fixed to bracket notation

* fixed syntax error

* better readability, kept np.sqrt(365) which results in  annualized sharpe ratio

* fixed method arguments indentation

* updated commented out debug print line

* renamed after slippage profit_percent so it wont affect _calculate_results_metrics()

* Reworked to fill leading and trailing days

* No need for np; make flake happy

* Fix risk free rate

Co-authored-by: Matthias <xmatthias@outlook.com>
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-02-06 06:49:08 +01:00
Matthias
586cbc750c Add considerations for dry-run 2020-02-06 06:45:11 +01:00
hroff-1902
b5ee4f17cb Merge pull request #2830 from orehunt/spreadfilter
- added spread filter
2020-02-04 23:37:09 +03:00
Matthias
6866f6389d Fix merge-error 2020-02-04 20:41:13 +01:00
hroff-1902
d2cac1d8fd Merge branch 'develop' into spreadfilter 2020-02-04 16:54:46 +03:00
untoreh
aa54fd2251 - added spread filter
- minimum value to volume pairlist
2020-02-04 14:49:59 +01:00
hroff-1902
f5fb129483 Merge pull request #2858 from freqtrade/fix/rolling_max
Fix implementation of rolling_max
2020-02-04 14:05:05 +03:00
Matthias
a707aeb3d0 Fix implementation of rolling_max 2020-02-04 07:00:53 +01:00
Matthias
f8bb6a3e06 Merge pull request #2855 from yazeed/text_mods_in_check_depth_of_market_buy
More consistency in check_depth_of_market_buy()
2020-02-04 06:24:58 +01:00
Yazeed Al Oyoun
91b4c9668c More consistency changes... 2020-02-04 01:57:24 +01:00
hroff-1902
d457d43999 Merge pull request #2833 from hroff-1902/type-hints
Add some type hints
2020-02-03 23:24:26 +03:00
hroff-1902
ffb53a6df5 get rid of typing.cast() 2020-02-03 23:08:35 +03:00
hroff-1902
82590657fb Merge pull request #2848 from freqtrade/dependabot/pip/develop/scikit-optimize-0.7.1
Bump scikit-optimize from 0.5.2 to 0.7.1
2020-02-03 22:53:01 +03:00
Matthias
54303880d3 Merge pull request #2849 from freqtrade/dependabot/pip/develop/pandas-1.0.0
Bump pandas from 0.25.3 to 1.0.0
2020-02-03 20:34:17 +01:00
Matthias
cbabc295c7 Don't convert to datetime - but convert to datetime64 instead 2020-02-03 20:25:43 +01:00
Matthias
b8aaf744e8 Merge pull request #2851 from hroff-1902/improve-logging-3
Add pair to exception messages in exchange module
2020-02-03 16:04:55 +01:00
hroff-1902
64f04845b6 Merge pull request #2850 from freqtrade/try_fix_randoM-test
make sure asyncio_loop is not initialized within ccxt code
2020-02-03 17:45:49 +03:00
hroff-1902
684cb54992 Add pair to exception msg 2020-02-03 17:17:46 +03:00
Matthias
f6c09160ab make sure asyncio_loop is not initialized within ccxt code 2020-02-03 15:17:36 +01:00
Matthias
221950cdc4 Merge pull request #2845 from freqtrade/dependabot/pip/develop/jinja2-2.11.1
Bump jinja2 from 2.10.3 to 2.11.1
2020-02-03 10:07:56 +01:00
Matthias
6e6c0757d6 Merge pull request #2847 from freqtrade/dependabot/pip/develop/ccxt-1.22.30
Bump ccxt from 1.21.91 to 1.22.30
2020-02-03 10:05:46 +01:00
Matthias
2ee99bde29 Merge pull request #2846 from freqtrade/dependabot/pip/develop/pytest-5.3.5
Bump pytest from 5.3.4 to 5.3.5
2020-02-03 09:58:04 +01:00
dependabot-preview[bot]
d5f704009f Bump pandas from 0.25.3 to 1.0.0
Bumps [pandas](https://github.com/pandas-dev/pandas) from 0.25.3 to 1.0.0.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v0.25.3...v1.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-03 08:03:45 +00:00
dependabot-preview[bot]
3938418ad5 Bump scikit-optimize from 0.5.2 to 0.7.1
Bumps [scikit-optimize](https://github.com/scikit-optimize/scikit-optimize) from 0.5.2 to 0.7.1.
- [Release notes](https://github.com/scikit-optimize/scikit-optimize/releases)
- [Changelog](https://github.com/scikit-optimize/scikit-optimize/blob/master/CHANGELOG.md)
- [Commits](https://github.com/scikit-optimize/scikit-optimize/compare/v0.5.2...v0.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-03 08:03:21 +00:00
dependabot-preview[bot]
401748e9a7 Bump ccxt from 1.21.91 to 1.22.30
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.91 to 1.22.30.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.21.91...1.22.30)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-03 08:02:54 +00:00
dependabot-preview[bot]
bc2ae3e88d Bump pytest from 5.3.4 to 5.3.5
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.4 to 5.3.5.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.3.4...5.3.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-03 08:02:21 +00:00
dependabot-preview[bot]
7b8e665323 Bump jinja2 from 2.10.3 to 2.11.1
Bumps [jinja2](https://github.com/pallets/jinja) from 2.10.3 to 2.11.1.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/2.10.3...2.11.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-03 08:01:28 +00:00
hroff-1902
df249c7c03 Remove unclear comment 2020-02-03 09:37:50 +03:00
hroff-1902
5c20311768 Merge pull request #2844 from freqtrade/coveralls_twice
Only run coveralls once
2020-02-03 09:18:42 +03:00
Matthias
d0506a6435 Use correct matrix variable 2020-02-03 07:01:07 +01:00
Matthias
c8960ab628 Only run coveralls once 2020-02-03 06:50:07 +01:00
hroff-1902
537596001e Allow derived strategies 2020-02-03 06:20:01 +03:00
Matthias
d8c053573a Merge pull request #2840 from freqtrade/fix/testerrror
Fix failing stoploss CI test
2020-02-02 20:49:42 +01:00
Matthias
2b69e7830d Fix failing CI test 2020-02-02 20:08:50 +01:00
Matthias
e3cb5d26c0 Merge pull request #2835 from yazeed/reduce_noise_if_use_order_book_true
reduced noise without verbose mode if use_order_book is true
2020-02-02 19:42:50 +01:00
hroff-1902
84156879f6 Fix NO_CONF_REQUIRED for list-hyperopts 2020-02-02 20:11:42 +03:00
hroff-1902
d12e03e50d Fix test inconsistency in test_freqtradebot.py 2020-02-02 20:01:25 +03:00
hroff-1902
cd0534efcc Add test 2020-02-02 19:41:22 +03:00
hroff-1902
505648fb66 Adjust docs 2020-02-02 19:41:22 +03:00
hroff-1902
857eb5ff69 Add list-hyperopts command 2020-02-02 19:41:22 +03:00
hroff-1902
3fe39a3e1b Rename constant 2020-02-02 19:41:22 +03:00
hroff-1902
a5e670b402 Add USERPATH_NOTEBOOKS 2020-02-02 19:41:22 +03:00
hroff-1902
e8c1abc509 Merge pull request #2799 from freqtrade/fix_stoploss_recreated
Fix stoploss recreated
2020-02-02 16:59:45 +03:00
hroff-1902
6594679e52 Merge pull request #2779 from freqtrade/stoploss_market
Stoploss on exchange for Kraken
2020-02-02 14:48:45 +03:00
Matthias
c1897fbc48 Merge pull request #2834 from yazeed/consistent_main_sharpe_hyperopt_loss
better readability on sharpe ratio loss method
2020-02-02 11:12:56 +01:00
Yazeed Al Oyoun
aeabe1800b modified two lines from logger.info to logger.debug cause they're too spammy 2020-02-02 10:49:00 +01:00
Matthias
d64751687b Fix link and lowercase variable 2020-02-02 10:47:44 +01:00
Yazeed Al Oyoun
3499f1b85c better readability and more consistent with daily sharpe loss method 2020-02-02 08:47:33 +01:00
hroff-1902
f3d500085c Add some type hints 2020-02-02 07:00:40 +03:00
Matthias
aa8731d0fc Merge pull request #2832 from freqtrade/python_3.8
Python 3.8
2020-02-01 19:39:45 +01:00
Matthias
cbd2b265bb Fix small error 2020-02-01 15:16:44 +01:00
Matthias
321bc336ea Run tests against 3.8 2020-02-01 15:14:55 +01:00
Matthias
4459679c64 Update dockerfile to 3.8.1 2020-02-01 15:14:44 +01:00
Matthias
628b06927c Support python3.8 virtualenvs and remove config generation via SED 2020-02-01 14:59:14 +01:00
Matthias
12317b1c53 Add some rudimentary tests for questions 2020-02-01 14:46:43 +01:00
Matthias
d1a3a2d000 Add tests for build_config 2020-02-01 14:22:40 +01:00
Matthias
cfa6a3e3d3 Don't overwrite files 2020-02-01 14:12:21 +01:00
Matthias
c224c66978 Small edits to install.md 2020-02-01 14:06:31 +01:00
Matthias
929bbe3058 Link to docker installation from index.md 2020-02-01 14:01:19 +01:00
Matthias
8796ecb2a9 Ad example for new-config with answered questions 2020-02-01 13:56:57 +01:00
Matthias
54512a66ef Update help-strings for list-utils 2020-02-01 13:52:25 +01:00
Matthias
c40a4d77f8 Use exchange_mapping to determine correct exchange-template 2020-02-01 13:46:58 +01:00
Matthias
d69ef4380b Add basic documentation for new-config option 2020-02-01 13:44:04 +01:00
Matthias
8371003c05 Merge pull request #2827 from freqtrade/release/2020-01
new Release 2020.01
2020-02-01 12:54:32 +01:00
Matthias
19d4e1435c Merge pull request #2828 from yazeed/line_alignment_fixes
fixed some more line alignments
2020-02-01 11:19:28 +01:00
Matthias
4a80c47fd1 Merge pull request #2825 from yazeed/better_backtesting_tables
more consistent backtesting and sell reasons tables
2020-02-01 11:18:50 +01:00
Yazeed Al Oyoun
d038bcedb0 fixed some more line alignments 2020-01-31 22:37:05 +01:00
Matthias
c396ad4daa Align quotes in same area 2020-01-31 20:41:51 +01:00
Matthias
cff8498b42 Version bump 2020.01 2020-01-31 20:17:53 +01:00
Matthias
fdf6121b6e Merge branch 'master' into release/2020-01 2020-01-31 20:17:41 +01:00
Yazeed Al Oyoun
907a61152c added rounding to Tot Profit % on Sell Reasosn table to be consistent with other percentiles on table. 2020-01-31 04:53:37 +01:00
Yazeed Al Oyoun
e2b3907df5 more consistent backtesting tables and labels 2020-01-31 04:39:18 +01:00
Matthias
4be3f053ca Exclude trading against BNB bases on binance 2020-01-30 21:42:48 +01:00
Matthias
83baa6ee2e Add test stub 2020-01-29 22:47:15 +01:00
Matthias
cebf99b5d8 Implement validation 2020-01-29 22:46:47 +01:00
Matthias
acbf13e648 Fail gracefully if user interrupted question session 2020-01-29 21:47:05 +01:00
Matthias
2f0775fa1b Extract build-config tests to new file 2020-01-29 21:31:09 +01:00
Matthias
940bfbee96 Move start_config out of build_commands file 2020-01-29 21:28:01 +01:00
Matthias
e250c56829 Add Questionaire workflow 2020-01-29 21:21:38 +01:00
Matthias
49c9258a08 enhance test 2020-01-29 20:43:10 +01:00
Matthias
dd83cb1b95 Extract selection generation to a seperate method 2020-01-29 20:27:38 +01:00
Matthias
2396f35586 Merge pull request #2819 from hroff-1902/worker-delete-state
Remove state attribute from Worker class
2020-01-29 15:57:35 +01:00
hroff-1902
68771a7861 Remove state attr from Worker 2020-01-29 17:08:36 +03:00
hroff-1902
e1356fb80e Merge pull request #2800 from yazeed/enhanced_check_depth_of_market_logging
better logging on check_depth_of_market_buy()
2020-01-29 10:56:14 +03:00
Matthias
c80d8f432a Add exchange templates 2020-01-29 07:13:38 +01:00
Matthias
122c916356 Add first version of config_deploy 2020-01-29 07:03:22 +01:00
Matthias
9f29128205 Fix small json formatting issue 2020-01-29 07:01:17 +01:00
Matthias
b384ca8fd2 Create new-config command 2020-01-29 06:47:01 +01:00
Yazeed Al Oyoun
a0b92fe0b1 removed typo 2020-01-28 19:29:47 +01:00
Yazeed Al Oyoun
328a9ffafd fixed typo in false statement 2020-01-28 19:27:49 +01:00
Matthias
d40054b9d2 Merge pull request #2815 from hroff-1902/docs-gitclone
Minor: Advise to use https method for git clone instead of ssh
2020-01-28 06:25:08 +01:00
hroff-1902
4c0e586354 Advise to use https method for git clone i.o ssh 2020-01-27 22:39:04 +03:00
Matthias
3541f7bfce Merge pull request #2808 from freqtrade/dependabot/pip/develop/plotly-4.5.0
Bump plotly from 4.4.1 to 4.5.0
2020-01-27 19:45:01 +01:00
Matthias
3a2443b5fa Merge pull request #2811 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.13
Bump sqlalchemy from 1.3.12 to 1.3.13
2020-01-27 09:47:15 +01:00
Matthias
e488ce0d07 Merge pull request #2809 from freqtrade/dependabot/pip/develop/urllib3-1.25.8
Bump urllib3 from 1.25.7 to 1.25.8
2020-01-27 09:46:11 +01:00
Matthias
521e497ba3 Merge pull request #2812 from freqtrade/dependabot/pip/develop/pytest-5.3.4
Bump pytest from 5.3.3 to 5.3.4
2020-01-27 09:38:37 +01:00
dependabot-preview[bot]
c9ee678a52 Bump sqlalchemy from 1.3.12 to 1.3.13
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.12 to 1.3.13.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 08:36:41 +00:00
Matthias
078e25e383 Merge pull request #2810 from freqtrade/dependabot/pip/develop/ccxt-1.21.91
Bump ccxt from 1.21.76 to 1.21.91
2020-01-27 09:35:35 +01:00
dependabot-preview[bot]
a3b0f75289 Bump pytest from 5.3.3 to 5.3.4
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.3 to 5.3.4.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.3.3...5.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 07:44:27 +00:00
dependabot-preview[bot]
66939bdcf6 Bump ccxt from 1.21.76 to 1.21.91
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.76 to 1.21.91.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.21.76...1.21.91)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 07:43:41 +00:00
dependabot-preview[bot]
184a6005a6 Bump urllib3 from 1.25.7 to 1.25.8
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.7 to 1.25.8.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/master/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.25.7...1.25.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 07:43:11 +00:00
dependabot-preview[bot]
161c06fd4e Bump plotly from 4.4.1 to 4.5.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.4.1 to 4.5.0.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.4.1...v4.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 07:42:52 +00:00
Matthias
5d7317ef77 Merge pull request #2807 from hroff-1902/refactor-freqtrade-2
Add notify_status() to FreqtradeBot
2020-01-27 06:44:20 +01:00
Matthias
aae14dd9fe Merge pull request #2806 from hroff-1902/minor-freqtrade-5
Minor cosmetics in start_trading
2020-01-27 06:37:47 +01:00
hroff-1902
30e3e434ab Add notify_status() to FreqtradeBot 2020-01-27 03:34:53 +03:00
hroff-1902
33645e45fd Minor cosmetics in start_trading 2020-01-27 02:49:25 +03:00
Matthias
1ef148317d Merge branch 'develop' into stoploss_market 2020-01-26 20:33:41 +01:00
Matthias
1b9af9d2d8 Merge branch 'develop' into data_handler 2020-01-26 20:31:13 +01:00
hroff-1902
27d46ed06f Merge pull request #2804 from freqtrade/utils_commands
Utils commands
2020-01-26 21:40:04 +03:00
Matthias
02563019fc move setup_utils_config to configuration module 2020-01-26 14:15:53 +01:00
Matthias
8c9119b471 Add docustring to commands module 2020-01-26 13:46:01 +01:00
Matthias
2d02c3f2a4 Split out pairlist_commands 2020-01-26 13:46:01 +01:00
Matthias
a3e9d04383 Adjust imports to new place for arguments 2020-01-26 13:46:01 +01:00
Matthias
7f851ad8d9 Move arguments and cli_options to commands module 2020-01-26 13:46:01 +01:00
Matthias
a1c684f67c Simplify noqa setup for module imports 2020-01-26 13:46:01 +01:00
Matthias
f347e5934a Small adjustments for moved commands 2020-01-26 13:46:01 +01:00
Matthias
e033df6a2f Move optimize_commands to commands module 2020-01-26 13:46:01 +01:00
Matthias
b254bdfea3 Move plot_utils to plot_commands 2020-01-26 13:46:01 +01:00
Matthias
70a0346b0a Move data-stuff to data-commands 2020-01-26 13:46:01 +01:00
Matthias
7e23304187 Adjust tests to new paths 2020-01-26 13:46:01 +01:00
Matthias
926bf07df1 Seperate a few commands into specific files 2020-01-26 13:46:01 +01:00
Matthias
6e85280467 Adjust imports 2020-01-26 13:46:01 +01:00
Matthias
80ed1c3e14 Move utils to commands 2020-01-26 13:46:01 +01:00
hroff-1902
1ae3fb4d2f Merge pull request #2803 from freqtrade/edge_no__init__
Move edge-module out of __init__.py
2020-01-26 15:21:21 +03:00
Matthias
3f2542fcbc Move edge-module out of __init__.py 2020-01-26 10:44:42 +01:00
hroff-1902
f6278da23f Merge pull request #2802 from freqtrade/try_fixrandomfailure
Fix missed mock
2020-01-25 16:05:22 +03:00
Matthias
a3ac05cc16 Fix missed mock 2020-01-25 13:38:13 +01:00
Matthias
a97bb10877 Merge pull request #2801 from freqtrade/backtest_arguments_2
Backtest arguments instead of dictionary
2020-01-25 13:11:23 +01:00
Matthias
bd4dd8403b Fix type-errors with stake_amount 2020-01-25 12:49:37 +01:00
hroff-1902
52f0ed5310 Adjust tests 2020-01-25 12:49:37 +01:00
hroff-1902
f4c7edf551 No args for backtest(), use arguments 2020-01-25 12:49:37 +01:00
Yazeed Al Oyoun
f8db7f1709 added ask price, bid price, immediate ask quantity, and immediate bid quantity to check_depth_of_market_buy. also added a line that mentions if delta condition was satisfied or not. 2020-01-25 04:17:41 +01:00
Matthias
72c273aaed Add test for closed trade case 2020-01-23 21:07:21 +01:00
Matthias
70b9bd9c0e Verify if trade is closed before acting on Stoploss_on_exchange 2020-01-23 20:36:48 +01:00
Matthias
ea5ac1efb5 Don't handle stoploss if there is an open regular order 2020-01-23 20:24:23 +01:00
Matthias
a83de241e4 Check for closed stoploss-orders first 2020-01-23 19:40:31 +01:00
Matthias
f5a44e4fc4 open_order_id should be None when handling stoploss orders 2020-01-23 19:38:35 +01:00
Matthias
1d141cd406 Merge branch 'develop' into stoploss_market 2020-01-23 19:35:05 +01:00
hroff-1902
82797e768f Merge pull request #2796 from freqtrade/update_wallets_after_foresell
update wallets after forcesell
2020-01-23 00:10:47 +03:00
hroff-1902
9176064047 Merge pull request #2795 from freqtrade/tests_buy_rate
Add parametrized tests for get_buy_rate
2020-01-23 00:05:40 +03:00
Matthias
bc4c469797 Merge branch 'develop' into stoploss_market 2020-01-22 20:51:52 +01:00
Matthias
aad10ceee3 Add threading lock object for /forcesell
Protects against stoploss_on_exchange order recreation
in case of /forcesell (it's a timing issue, so may or may not happen).
2020-01-22 20:50:09 +01:00
Matthias
58ceda4b90 update wallets after forcesell 2020-01-22 19:54:55 +01:00
Matthias
f36bc80ad1 Add parametrized tests for get_buy_rate 2020-01-22 19:43:02 +01:00
hroff-1902
2b4d821d30 Merge pull request #2794 from freqtrade/rename_get_target_bid
rename get_target_bid
2020-01-22 17:19:04 +03:00
Matthias
8a940eb0c1 Align price finding function name on buy side with get_sell_rate 2020-01-22 14:46:28 +01:00
Matthias
9c2f21b07e Merge pull request #2788 from drdux/develop
added missing word in hyperopt loss example
2020-01-22 12:47:08 +01:00
hroff-1902
055f3fd1fd Merge pull request #2790 from freqtrade/backtest_optimize
Fix typo in sell-reason table generation
2020-01-22 12:29:20 +03:00
hroff-1902
40843566d0 Merge pull request #2791 from freqtrade/windows_ci_fix
upgrade pip in windows environment
2020-01-22 12:16:04 +03:00
Matthias
e13045b599 upgrade pip in windows environment 2020-01-22 06:17:13 +01:00
Matthias
7d2d0235a0 Fix typo in sell-reason table generation 2020-01-22 06:08:34 +01:00
Daniel Goller
bff0a09537 line was too long 2020-01-21 16:14:19 +00:00
Daniel Goller
c1c2717bc9 added missing word in hyperopt loss example 2020-01-21 15:49:24 +00:00
Matthias
fc2970f41b Merge branch 'develop' into data_handler 2020-01-21 06:58:48 +01:00
hroff-1902
66415d48d4 Merge pull request #2787 from freqtrade/dry_run_optional
remove default value calls for dry_run
2020-01-20 23:08:17 +03:00
hroff-1902
d54b1dade3 Merge pull request #2786 from freqtrade/fix/stoploss_on_exchange_dryrun
Fix/stoploss on exchange dryrun
2020-01-20 22:50:38 +03:00
Matthias
1bf475fa1a Remove .get calls for dry_run - it's a mandatory property 2020-01-20 20:24:40 +01:00
Matthias
099bbc5c7f Fix bug when stoploss_on_exchange in combination with dry-run
does not sell orders
2020-01-20 20:14:40 +01:00
Matthias
6e3336cb30 Adapt test to verify behaviour of stoploss_on_exchange in dry-run 2020-01-20 20:10:06 +01:00
Matthias
eb6c7f8595 Merge pull request #2781 from freqtrade/dependabot/pip/develop/ccxt-1.21.76
Bump ccxt from 1.21.56 to 1.21.76
2020-01-20 14:44:11 +01:00
Matthias
10a706851a Merge pull request #2782 from freqtrade/dependabot/pip/develop/pytest-5.3.3
Bump pytest from 5.3.2 to 5.3.3
2020-01-20 11:40:57 +01:00
dependabot-preview[bot]
8d4515935a Bump pytest from 5.3.2 to 5.3.3
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.2 to 5.3.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.3.2...5.3.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-20 07:49:18 +00:00
dependabot-preview[bot]
9474cb1792 Bump ccxt from 1.21.56 to 1.21.76
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.56 to 1.21.76.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.21.56...1.21.76)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-20 07:48:46 +00:00
Matthias
10d9db72a8 Adjust tests slightly 2020-01-19 20:06:04 +01:00
Matthias
cf9331919f move exchange-specific order-parsing to exchange class
Related to stoploss_on_exchange in combination with trailing stoploss.

Binance contains stopPrice in the info, while kraken returns the same
value as "price".
2020-01-19 19:54:30 +01:00
Matthias
7a22aaa111 UPdate documentation to reflect that stoploss-on-exchange is also
available for kraken
2020-01-19 14:40:09 +01:00
Matthias
f1629c907a Implement stoploss for kraken 2020-01-19 14:40:09 +01:00
Matthias
e6f1912443 Use named arguments for stoploss create_order call 2020-01-19 14:40:09 +01:00
Matthias
16b34e11ca Complete rename of stoploss_limit to stoploss 2020-01-19 14:40:09 +01:00
Matthias
256fc2e78c Rename stoploss_limit to stoploss 2020-01-19 13:30:56 +01:00
Matthias
da0af489a2 Adjust tests to pass in order_types instead of rate 2020-01-19 13:25:41 +01:00
Matthias
8d2e0bfd62 Move rate-calcuation for stoploss-limit order to exchange 2020-01-19 13:13:09 +01:00
hroff-1902
2f82122fc4 Merge pull request #2763 from freqtrade/fix/precision_rounding
Fix/precision rounding
2020-01-17 01:25:30 +03:00
hroff-1902
889929f782 Merge pull request #2772 from freqtrade/safe_sell_amount_update_wallet
Safe sell amount update wallet
2020-01-16 00:15:34 +03:00
Matthias
fa1e9dd70d Adjust tests to allow updating within safe_sell_amount 2020-01-15 21:53:04 +01:00
Matthias
29a5e4fba1 Update wallets before getting amount 2020-01-15 21:52:54 +01:00
hroff-1902
a20f502159 Merge pull request #2771 from freqtrade/fix/2770
Fix bad bug in safe_sell_amount
2020-01-15 23:33:04 +03:00
Matthias
8bcfe4a6aa Up log level of safe_sell_amount message 2020-01-15 21:01:36 +01:00
hroff-1902
854bb0056b Merge pull request #2583 from gaugau3000/doc_feature_section
Doc feature section
2020-01-15 22:55:39 +03:00
Matthias
90ed4c665b Cover equal case via test 2020-01-15 19:59:08 +01:00
Matthias
d1bf388b0e Wallet amount must be compared with >= 2020-01-15 19:56:14 +01:00
Matthias
6feb68b18d Change feature sorting to tell more of a story 2020-01-15 19:51:33 +01:00
Matthias
09621b3ef1 Merge pull request #2769 from tejeshreddy/update-comments
Update comments on backtesting
2020-01-15 15:44:46 +01:00
Tejesh
f73f0b1653 Update comments on backtesting 2020-01-15 19:29:00 +05:30
hroff-1902
f7f56f5eda Merge pull request #2768 from freqtrade/rpc/refresh_balance
refresh wallets on /balance call
2020-01-15 16:34:09 +03:00
Matthias
c8806a16a1 Allow wallet update from /balance 2020-01-15 06:43:41 +01:00
Matthias
4013701bdb allow wallet update to be skipped if the value is fresh enough.
Value is NOT configurable, having this wrong can result in bans on the
exchange.
2020-01-15 06:42:53 +01:00
Matthias
4c823f12e3 Sort imports 2020-01-14 20:25:58 +01:00
Matthias
1e58cd70ad Adapt tests to round price up 2020-01-14 20:16:47 +01:00
Matthias
bea4ad8eff Revert price_to_precision to rounding up 2020-01-14 20:16:20 +01:00
Matthias
d7957bd791 add advanced tests for price_to_precision 2020-01-14 16:04:39 +01:00
Matthias
425ec53b28 Combine amount_to_precision tests into one 2020-01-14 16:01:35 +01:00
Matthias
797dc8a4da Add more detailed tests for amount_to_precision 2020-01-14 15:54:53 +01:00
Matthias
d12a2a5888 Merge pull request #2752 from freqtrade/plotting/indicator_strategy
Allow enhanced plot-dataframe configuration
2020-01-13 19:53:15 +01:00
Matthias
845e27542a Merge pull request #2765 from freqtrade/dependabot/pip/develop/ccxt-1.21.56
Bump ccxt from 1.21.32 to 1.21.56
2020-01-13 11:56:07 +01:00
dependabot-preview[bot]
c67b253099 Bump ccxt from 1.21.32 to 1.21.56
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.32 to 1.21.56.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.21.32...1.21.56)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 10:38:34 +00:00
Matthias
154fff7d02 Merge pull request #2764 from freqtrade/dependabot/pip/develop/numpy-1.18.1
Bump numpy from 1.18.0 to 1.18.1
2020-01-13 11:37:31 +01:00
Matthias
82fd6e6fb3 Merge pull request #2766 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.3.0
Bump python-telegram-bot from 12.2.0 to 12.3.0
2020-01-13 11:37:10 +01:00
dependabot-preview[bot]
b3938a86c3 Bump python-telegram-bot from 12.2.0 to 12.3.0
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.2.0 to 12.3.0.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v12.2.0...v12.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 07:56:20 +00:00
dependabot-preview[bot]
2f8ed7ed19 Bump numpy from 1.18.0 to 1.18.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.18.0 to 1.18.1.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.18.0...v1.18.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-13 07:55:35 +00:00
hroff-1902
af36635769 Minor changes in the docs 2020-01-13 06:41:16 +03:00
hroff-1902
495728f502 Refine docs 2020-01-13 06:41:16 +03:00
Matthias
5dccd01fb7 Merge pull request #2760 from freqtrade/remove_hardcoded_exchange_stuff
Remove hardcoded exchange parameters
2020-01-12 19:47:44 +01:00
Matthias
5fcab1eee8 Align method names to internal ccxt names
These methods are reimplemented from ccxt so we can test their behaviour.
2020-01-12 14:55:05 +01:00
Matthias
b60d7ad42f Use ccxt.decimal_to_precision instead of our own calculation 2020-01-12 14:41:09 +01:00
Matthias
fa1f9bcdbd expose precisionMode from exchange class 2020-01-12 14:37:45 +01:00
Matthias
53abfdbcbf Use sorted on set instead of explicit list conversion 2020-01-12 12:48:29 +01:00
Matthias
3519cebf66 Add test for failing stake_validation 2020-01-11 13:14:19 +01:00
Matthias
a7246ba1ec No need to "fix" stake_currency enum anymore 2020-01-11 12:51:42 +01:00
Matthias
60b47b6eec Add tests for get_quote_currencies 2020-01-11 12:01:34 +01:00
Matthias
ca2880537d Modify tests to skip stake_currency validations 2020-01-11 11:54:11 +01:00
Matthias
13274964a9 Implement validation for valid stake currency 2020-01-11 11:54:00 +01:00
Matthias
235a10ab86 Don't suppport <1m timeframes 2020-01-11 11:36:28 +01:00
Matthias
5faebad863 Don't hardcode TimeFrames - they can differ by exchange. 2020-01-11 11:16:05 +01:00
Matthias
90a9052377 Merge pull request #2734 from freqtrade/relative_stake
Relative stake maximum tradable amount
2020-01-11 08:18:35 +01:00
hroff-1902
d3de398395 Docs adjusted 2020-01-10 23:43:09 +03:00
hroff-1902
83b88e7916 Remove Required marks for new settings 2020-01-10 23:14:17 +03:00
hroff-1902
3faa2d0eb9 Refine description for last_stake_amount_min_ratio 2020-01-10 22:59:02 +03:00
Matthias
fab19ae3a7 Implement last_stake_amount_min_ratio 2020-01-10 06:36:28 +01:00
Matthias
e94dfdeff2 UPdate documentation to remove inexisting setting 2020-01-09 20:13:14 +01:00
Matthias
9713dc8d94 Ensure wallets.update is called before buy
closes #2756
2020-01-09 20:09:21 +01:00
Matthias
b748ed3435 UPdate documentaiton wording 2020-01-09 19:59:13 +01:00
hroff-1902
7c7f7b9ece Merge pull request #2755 from freqtrade/backtest_mean
Add average profit to sell_reason stats
2020-01-09 20:35:35 +03:00
Matthias
785cd2a640 Rename test module 2020-01-09 06:53:51 +01:00
Matthias
c475729c13 Extract edge reporting to optimize_reports 2020-01-09 06:52:34 +01:00
Matthias
989ab646a9 Add profit % to sell_reason table 2020-01-09 06:46:39 +01:00
Matthias
7461b5dc02 Mention custom strategy in features 2020-01-09 06:37:18 +01:00
Matthias
135487b2c9 SPlit control and Analyse feature into 2 seperate points 2020-01-09 06:35:05 +01:00
Matthias
b25f28d1ad Merge pull request #2730 from freqtrade/extract_bt_reporting
Extract backtest reporting
2020-01-09 06:09:05 +01:00
hroff-1902
cee8f3349e rearrange features -- move Run to the top 2020-01-09 04:16:57 +03:00
hroff-1902
9559cb988e reworked 2020-01-09 04:12:43 +03:00
Matthias
db34cb1b75 Do some adjustments to the wording of the index.md section 2020-01-08 19:41:34 +01:00
Matthias
c9b0b4c7a4 Add plot_config to optional plot 2020-01-08 19:35:00 +01:00
Matthias
c3fd894a6c Regenerate plots with new settings 2020-01-07 07:16:31 +01:00
Matthias
9f2d397e1f Merge pull request #2746 from freqtrade/dependabot/pip/develop/arrow-0.15.5
Bump arrow from 0.15.4 to 0.15.5
2020-01-06 13:07:13 +01:00
Matthias
7719d8fbea Merge pull request #2748 from freqtrade/dependabot/pip/develop/coveralls-1.10.0
Bump coveralls from 1.9.2 to 1.10.0
2020-01-06 13:01:20 +01:00
Matthias
3883d18b8a Add bollinger note 2020-01-06 12:59:17 +01:00
Matthias
2b3f2e5fa8 Add first version of documentation 2020-01-06 12:55:12 +01:00
Matthias
5ae554bdff Merge pull request #2747 from freqtrade/dependabot/pip/develop/pytest-mock-2.0.0
Bump pytest-mock from 1.13.0 to 2.0.0
2020-01-06 12:50:04 +01:00
dependabot-preview[bot]
6ac7dcf5e9 Bump arrow from 0.15.4 to 0.15.5
Bumps [arrow](https://github.com/crsmithdev/arrow) from 0.15.4 to 0.15.5.
- [Release notes](https://github.com/crsmithdev/arrow/releases)
- [Changelog](https://github.com/crsmithdev/arrow/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/crsmithdev/arrow/compare/0.15.4...0.15.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 11:45:22 +00:00
dependabot-preview[bot]
6da97fafa8 Bump coveralls from 1.9.2 to 1.10.0
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 1.9.2 to 1.10.0.
- [Release notes](https://github.com/coveralls-clients/coveralls-python/releases)
- [Changelog](https://github.com/coveralls-clients/coveralls-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/coveralls-clients/coveralls-python/compare/1.9.2...1.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 11:45:12 +00:00
Matthias
6d4fe94285 Merge pull request #2751 from freqtrade/dependabot/pip/develop/ccxt-1.21.32
Bump ccxt from 1.21.23 to 1.21.32
2020-01-06 12:44:13 +01:00
Matthias
b27f3b8f2c Merge pull request #2749 from freqtrade/dependabot/pip/develop/flake8-tidy-imports-4.0.0
Bump flake8-tidy-imports from 3.1.0 to 4.0.0
2020-01-06 12:44:02 +01:00
Matthias
ed29232478 Merge pull request #2750 from freqtrade/dependabot/pip/develop/scikit-learn-0.22.1
Bump scikit-learn from 0.22 to 0.22.1
2020-01-06 12:43:43 +01:00
dependabot-preview[bot]
3c0d184097 Bump ccxt from 1.21.23 to 1.21.32
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.23 to 1.21.32.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.21.23...1.21.32)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:43:06 +00:00
dependabot-preview[bot]
d846114d3c Bump scikit-learn from 0.22 to 0.22.1
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.22 to 0.22.1.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.22...0.22.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:42:44 +00:00
dependabot-preview[bot]
aabeece4c0 Bump flake8-tidy-imports from 3.1.0 to 4.0.0
Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 3.1.0 to 4.0.0.
- [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases)
- [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/master/HISTORY.rst)
- [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/3.1.0...4.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:42:19 +00:00
dependabot-preview[bot]
b614964ba9 Bump pytest-mock from 1.13.0 to 2.0.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 1.13.0 to 2.0.0.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v1.13.0...v2.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 07:41:39 +00:00
Matthias
888ea58df2 Add tests for new behaviour 2020-01-05 19:51:12 +01:00
Matthias
d0ccfa1925 Explicitly given indicators should override plot_config 2020-01-05 19:50:21 +01:00
Matthias
41945138ac Converting pairs from filename to pair corrected 2020-01-05 13:35:36 +01:00
Matthias
ca054799d0 Add tests for amend_last_stake_amount 2020-01-05 13:25:21 +01:00
Matthias
b37f34ff5b Implement amend_last_stake_amount 2020-01-05 13:25:11 +01:00
Matthias
a75420f75f Merge branch 'develop' into relative_stake 2020-01-05 12:55:55 +01:00
Matthias
7daa5bc338 Don't return None from unlimited_stake - 0 handles this just as well 2020-01-05 12:50:44 +01:00
Matthias
4eaaec9d1a Implement pair_to_filename to datahandler
includes tests - taken from #2744 and modified to adapt to new structure
2020-01-05 10:36:08 +01:00
hroff-1902
bc6a10353b Introduce pair_to_filename() 2020-01-05 10:22:07 +01:00
Matthias
f82c4346b6 data conversion, not data conversation
* we're not talking to the data yet ...
2020-01-05 09:55:02 +01:00
Matthias
53499e01de Clearly differentiate trade buys sells (positive and negative)
* Swap trade buys to cyan circles
* Show sell-reason description on buy too
* Green positive sells - red negative / 0 sells
2020-01-04 20:27:27 +01:00
Matthias
bdda620397 add plot_config to startegy interface properly 2020-01-04 12:56:46 +01:00
Matthias
2409261cb7 Merge branch 'develop' into data_handler 2020-01-04 11:36:27 +01:00
Matthias
b5a806dec7 Fix typo and add tests for create_plotconfig 2020-01-04 11:30:21 +01:00
Matthias
4628024de6 Adapt tests to new add_indicator methodology 2020-01-04 11:18:51 +01:00
Matthias
f04873b0b0 Add plot_config to interface 2020-01-04 11:14:00 +01:00
Matthias
5853b9904c make Plot_config the default approach 2020-01-04 11:13:45 +01:00
Matthias
5d5074ac9c Implement first working version of plot_config 2020-01-04 10:13:42 +01:00
Matthias
84ef588163 support dicts as indicators 2020-01-04 10:13:42 +01:00
Matthias
d1cda3991c Merge pull request #2742 from freqtrade/hroff-1902-patch-1
Minor: Refine fee example in the docs
2020-01-04 09:46:57 +01:00
hroff-1902
24aa596e3c Minor: Refine fee example in the docs
Taken from https://github.com/freqtrade/freqtrade/issues/2738#issuecomment-570687230. slightly reworded.
2020-01-04 01:08:37 +03:00
hroff-1902
3798f94d4c Merge pull request #2732 from freqtrade/config_validation_split
Config validation split
2020-01-03 23:41:44 +03:00
hroff-1902
75dcc369c0 Merge pull request #2740 from freqtrade/doc/backtest_typo
Update Backtesting fee documentation
2020-01-03 22:40:02 +03:00
Matthias
e1f89e3ad3 Reword Note in backtesting fee docs 2020-01-03 20:11:58 +01:00
Matthias
7e7c82cf4a Small adjustments to relative_stake PR 2020-01-03 11:34:17 +01:00
Matthias
71dd038664 add tradable_balance_ratio to to all config samples 2020-01-03 11:23:06 +01:00
Matthias
55041878ae Update Backtesting fee documentation 2020-01-03 11:20:08 +01:00
Matthias
0dd274917f Update documentation regarding configuration of stake_amount 2020-01-03 11:16:59 +01:00
Matthias
f3beaa3374 Deprecate capital_available_percentage 2020-01-03 10:58:31 +01:00
Matthias
6d01653bfe Adapt test to test more cases with reduced tradable_balance 2020-01-03 10:41:34 +01:00
Matthias
455838648d Apply get_available_balance logic to regular trades, too 2020-01-03 10:41:10 +01:00
Matthias
3c7981160c Extract get_available_stake_amount 2020-01-03 10:14:23 +01:00
Matthias
4ac1ac7ef5 Warn about tradable balance being applied to the current amount of the
balance
2020-01-03 09:56:06 +01:00
hroff-1902
776fc56265 Merge pull request #2735 from freqtrade/doc/macos_install
Add note about MacOS installation
2020-01-03 10:28:14 +03:00
Matthias
a8d56b2850 IMplement check for unlimited settings
verifying that either max_open_trades or stake_amount is set for
operations without edge
2020-01-03 07:07:59 +01:00
Matthias
11059e532b Fix missed default minimum in documentation 2020-01-03 06:39:47 +01:00
Matthias
da1fea6582 Minor correction to wording of MacOS Specific install doc 2020-01-03 06:37:43 +01:00
hroff-1902
3315f994b6 Merge pull request #2733 from hroff-1902/minor-freqtrade-4
Cleanup buy/sell notification in freqtradebot
2020-01-02 22:46:06 +03:00
Matthias
560aea876e Remove fiat_currency temporary variable 2020-01-02 20:20:29 +01:00
hroff-1902
b24d359a27 Merge pull request #2737 from freqtrade/plotting_percent
show percent in sell hover message.
2020-01-02 22:04:34 +03:00
Matthias
90744ff5ab show percent instead of ratio (!) 2020-01-02 19:36:31 +01:00
Matthias
b48bf035f6 Add note about MacOS installation 2020-01-02 14:54:07 +01:00
Matthias
c13c11cfa1 Type does not need to be a list 2020-01-02 14:41:28 +01:00
Matthias
6e615998c0 Fix documentation typo 2020-01-02 13:52:35 +01:00
Matthias
94afb7cb1d Improve integration test with a few additional tests 2020-01-02 13:45:03 +01:00
Matthias
bfef3cf497 Add additional test case for lower balance ratios 2020-01-02 13:38:08 +01:00
Matthias
cba156dfff Add offset calculation for relative stake maximum limit 2020-01-02 13:20:57 +01:00
Matthias
64db1f6736 Prepare tests to valiate reduced full amount. 2020-01-02 13:16:18 +01:00
hroff-1902
a47a25ca88 Refine passing msg params 2020-01-02 14:38:25 +03:00
hroff-1902
88efa4065b Align the name of a variable to be same for buy and sell parts 2020-01-02 13:56:16 +03:00
hroff-1902
f15e5e9d57 Add _notify_buy() 2020-01-02 13:51:25 +03:00
hroff-1902
2ccdb67e4d Merge pull request #2731 from freqtrade/btanalysis_align_columns
Btanalysis align columns
2020-01-02 13:03:51 +03:00
Matthias
1b8943ac54 Add documentation for tradable_balance_ratio 2020-01-02 10:59:41 +01:00
Matthias
9382b38c41 Fix mypy error 2020-01-02 10:56:00 +01:00
Matthias
22fcf7b4dc Allow empty stake currency in certain cases 2020-01-02 10:47:37 +01:00
Matthias
20fc3b7978 validate config for utils too 2020-01-02 10:41:10 +01:00
Matthias
9325880fe5 Split config-validation requires 2020-01-02 10:39:32 +01:00
Matthias
cac0e37b06 Merge pull request #2729 from hroff-1902/minor-freqtrade-3
Cosmetics in freqtradebot
2020-01-02 10:06:42 +01:00
Matthias
2c8e8d8ef6 Align columns for btanalysis loading 2020-01-02 09:51:47 +01:00
Matthias
6fbdd6bee9 Remove unused directory from user_data 2020-01-02 09:51:24 +01:00
hroff-1902
e89fa44680 Arrange common section for update trade state methods 2020-01-02 11:50:54 +03:00
Matthias
a9fbad0741 Improve docstrings 2020-01-02 09:37:54 +01:00
Matthias
8cc48cf4b0 Fix tests where mocks fail now 2020-01-02 09:31:53 +01:00
Matthias
10ee23622a Extract tests for backtest_reports to their own test module 2020-01-02 09:31:53 +01:00
Matthias
904e1647e1 Extract generate_text_table_strategy to seperate module 2020-01-02 09:31:53 +01:00
Matthias
caec345c0b Extract generate_text_table_sell_reason from backtesting class 2020-01-02 09:31:53 +01:00
Matthias
18a53f4467 Extract generate_text_table from backtesting class 2020-01-02 09:31:47 +01:00
Matthias
6dfde99cbe Merge pull request #2728 from hroff-1902/minor-setup-msg
Minor: Fix message in setup.sh
2020-01-02 06:59:44 +01:00
hroff-1902
21418e2988 Minor: fix comment 2020-01-02 03:16:18 +03:00
hroff-1902
4475110df8 Cosmetics in freqtradebot 2020-01-02 03:07:24 +03:00
hroff-1902
0ea44b0143 Fix message in setup.sh 2020-01-02 02:36:59 +03:00
Matthias
3327ebf2b1 Merge pull request #2720 from hroff-1902/refactor-create-trades
Refactor create trades
2019-12-31 15:34:12 +01:00
Matthias
26a2395aeb Include Pair name in exception log message 2019-12-31 07:11:09 +01:00
Matthias
9d518b9d29 Add comment and don't hardcode 4 in test 2019-12-31 07:05:21 +01:00
Matthias
6ebb9017c7 Improve test enter_positions 2019-12-31 07:03:57 +01:00
Matthias
a88464de3a Improve some test code 2019-12-31 07:01:58 +01:00
hroff-1902
fd7af587da Rename process_maybe_execute_buys() --> enter_positions() 2019-12-30 22:50:56 +03:00
hroff-1902
84918ad424 Rename process_maybe_execute_sells() --> exit_positions() 2019-12-30 22:08:36 +03:00
Matthias
699c0d6bc3 Merge branch 'develop' into data_handler 2019-12-30 19:40:43 +01:00
Matthias
2537b8cb0c Merge pull request #2725 from freqtrade/minor_fix
[Minor] Edge-cli should use exchangeresolver
2019-12-30 19:27:40 +01:00
hroff-1902
78883663a0 Merge pull request #2726 from freqtrade/exceptions_seperate_file
Refactor Exceptions to their own file
2019-12-30 21:21:14 +03:00
hroff-1902
b00406a7eb Make process_maybe_execute_*() returning integers 2019-12-30 21:09:35 +03:00
hroff-1902
4d56e3b36e Address some comments made in the review 2019-12-30 20:54:32 +03:00
Matthias
8e9a3e8fc8 Capture FtBaseException at the outermost level 2019-12-30 15:11:07 +01:00
Matthias
1ffda29fd2 Adjust improts to new exception location 2019-12-30 15:02:17 +01:00
Matthias
024aa3ab6b Move exceptions to seperate module 2019-12-30 14:57:26 +01:00
Matthias
20abf67779 Add Debug "code" for randomly failing test 2019-12-30 14:29:36 +01:00
Matthias
fb3a53b8af Use ExchangeResolver for edge_cli too 2019-12-30 14:28:34 +01:00
Matthias
4c9295fe2d Rename Bid-strategy helpervariable to something shorter
avoids unnecessary wrapping...
2019-12-30 14:00:34 +01:00
hroff-1902
6a7163d3a9 Merge pull request #2724 from freqtrade/improve_strattemplate
[minor] Add trailing_only_offset to template and sample
2019-12-30 15:32:24 +03:00
Matthias
de23f3928d Add trailing_only_offset to template and sample 2019-12-30 09:58:20 +01:00
Matthias
8975e38b1d Merge pull request #2723 from freqtrade/dependabot/pip/develop/ccxt-1.21.23
Bump ccxt from 1.21.12 to 1.21.23
2019-12-30 09:32:03 +01:00
dependabot-preview[bot]
20a132651f Bump ccxt from 1.21.12 to 1.21.23
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.21.12 to 1.21.23.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.21.12...1.21.23)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-30 07:34:49 +00:00
hroff-1902
88ba7e467d Merge pull request #2722 from freqtrade/rpc/misinfo
[minor]Fix misinformation in /status table
2019-12-29 22:41:36 +03:00
Matthias
df7ceb4ccb Fix misinformation in /status table 2019-12-29 19:53:02 +01:00
Matthias
47bb8ad0d4 Merge pull request #2721 from freqtrade/jupyter_docs
Document usage of jupyter with venv kernel
2019-12-29 19:49:19 +01:00
Matthias
304d15e236 Small corrections 2019-12-29 19:35:42 +01:00
Matthias
d1c45cf3f8 Update analysis documentation to include kernel installation 2019-12-29 13:07:51 +01:00
hroff-1902
04f28ed9bc Refactor try/except: handle DependencyException for each pair separately 2019-12-29 05:03:10 +03:00
hroff-1902
ce84f74528 Adjust tests 2019-12-29 05:00:22 +03:00
hroff-1902
762604300f Refactor create_trades() 2019-12-29 04:37:44 +03:00
hroff-1902
433fd2a7c3 Merge pull request #2652 from freqtrade/safe_sell_amount
Safe sell amount
2019-12-29 00:09:21 +03:00
Matthias
814cc20c6b Remove potential circular import 2019-12-28 19:58:41 +01:00
Matthias
f4a532ef6d Pass format to load_data 2019-12-28 14:57:39 +01:00
Matthias
6b5983339d Require dataformat entries in configuration 2019-12-28 14:47:30 +01:00
Matthias
ae1b28aab7 Remove get_datahandlerclass from package exposes 2019-12-28 14:32:11 +01:00
hroff-1902
09b77d9f14 Merge pull request #2718 from hroff-1902/minor-freqtrade-2
Minor: code cleanup in freqtradebot
2019-12-28 14:55:42 +03:00
hroff-1902
5c39ebd0a0 Adjust logging 2019-12-28 13:59:40 +03:00
Matthias
e2a00c03d6 Document convert options 2019-12-28 11:24:37 +01:00
Matthias
66d18575a7 Implement abstract interface 2019-12-28 11:10:31 +01:00
Matthias
9e4fc00a0f Add test for convert_ohlcv 2019-12-28 11:03:06 +01:00
Matthias
70f3ff0461 Add test for convert_trades_Format 2019-12-28 11:03:06 +01:00
Matthias
e7054adc49 Add tests for start_convert_data 2019-12-28 11:03:06 +01:00
Matthias
28787a001c Move convert functions to convert module 2019-12-28 11:02:34 +01:00
Matthias
525550e4c7 Fix typo in parameter transition 2019-12-28 11:01:42 +01:00
Matthias
6860491189 Rename datahandler module to history module
Also move previous history.py into this module - so everything is
bundled
2019-12-28 11:01:42 +01:00
Matthias
b37b5c3d90 Remove Explicit datadir conversation 2019-12-28 11:01:42 +01:00
Matthias
9c5b94adf5 Pass data_format to methods 2019-12-28 11:01:42 +01:00
Matthias
65f539e9d8 More tests for datahandler 2019-12-28 11:01:42 +01:00
Matthias
d65c1eea7a Add some tests for datahandler 2019-12-28 11:01:42 +01:00
Matthias
8a030e7fc0 Use exists instead of is_file 2019-12-28 11:01:42 +01:00
Matthias
a3144cb2f0 remove trim_tickerlist 2019-12-28 11:01:42 +01:00
Matthias
baa942ff98 Don't use function to resolve pairname for test 2019-12-28 11:01:42 +01:00
Matthias
32c2ce146e Remove last usage of load_tickerlist 2019-12-28 11:01:42 +01:00
Matthias
4b277afc52 Remove test for load_tickerdata 2019-12-28 11:01:42 +01:00
Matthias
5479c67178 Clean up some codes which use list-based tests 2019-12-28 11:01:41 +01:00
Matthias
80dbba1280 Remove unnecessary mocks 2019-12-28 11:01:41 +01:00
Matthias
aa39f2160b Use load_data instead of a sequence of calls
in tests which don't test this
2019-12-28 11:01:41 +01:00
Matthias
a2567bea64 Remove unnecessary mock 2019-12-28 11:01:41 +01:00
Matthias
d1b52809ac Cleanup history 2019-12-28 11:01:41 +01:00
Matthias
d06777b8ce Remove old "load_cached_data" method 2019-12-28 11:01:41 +01:00
Matthias
7a6476c9ba Update tests 2019-12-28 11:01:41 +01:00
Matthias
e4f185f357 Remove 'line' from load_cached_data tests
Users are unable to use line anyway, it's only there for tests
2019-12-28 11:01:41 +01:00
Matthias
df085a6f15 Fix small bug and test 2019-12-28 11:01:41 +01:00
Matthias
c648d973c1 Implement new "load_data_for_updating" method based on dataframes 2019-12-28 11:01:41 +01:00
Matthias
ec8fb5f308 Make no-data warning optional 2019-12-28 11:01:41 +01:00
Matthias
b83487a70d Extract default dataframe columns to constant 2019-12-28 11:01:41 +01:00
Matthias
dbe8f727cb Fix typehint 2019-12-28 11:01:41 +01:00
Matthias
91c70a0e9c Change to use ohlcv_purge 2019-12-28 11:01:41 +01:00
Matthias
37c5b68987 Move dataframe validation to abstract class 2019-12-28 11:01:41 +01:00
Matthias
e861f05b75 Move dataframe trim to within jsondatahandler 2019-12-28 11:01:41 +01:00
Matthias
552c93abf0 Improve some docstrings 2019-12-28 11:01:41 +01:00
Matthias
b7c1d55491 Modify tests to point to datahandlers 2019-12-28 11:01:41 +01:00
Matthias
9876d126ca Use handler for trades 2019-12-28 11:01:41 +01:00
Matthias
9547d47ae2 Initialize datahandlers 2019-12-28 11:01:41 +01:00
Matthias
5fca17d7e1 Allow initializing handler-class just once 2019-12-28 11:01:41 +01:00
Matthias
416517b0c9 Move trim_dataframe from history to converter 2019-12-28 11:01:41 +01:00
Matthias
9d8ea2f13b Replace calls to load_tickerdata_file with DataHandler calls 2019-12-28 11:01:41 +01:00
Matthias
88fa7fc24c Simplify validate dataframe method 2019-12-28 11:01:41 +01:00
Matthias
53ee636fa0 Check if file exists before loading 2019-12-28 11:01:41 +01:00
Matthias
873f5dbe6b Revrite validate_pairdata to work with pandas 2019-12-28 11:01:41 +01:00
Matthias
db520a09ee Trim dataframe, not tickerlist 2019-12-28 11:01:41 +01:00
Matthias
866908d2ca Load and save using pandas internal function 2019-12-28 11:01:41 +01:00
Matthias
377d59abe7 Be selective how to load ohclv data for conversation 2019-12-28 11:01:41 +01:00
Matthias
d9e7d64f33 Split parse_ticker_dataframe some logic to clean_ohlcv_dataframe. 2019-12-28 11:01:41 +01:00
Matthias
1b90ec58b9 Use changed pair-handling for providers 2019-12-28 11:01:41 +01:00
Matthias
d923bab828 Remove abstract interface for now 2019-12-28 11:01:41 +01:00
Matthias
48728e2d66 Change DataProvider interface to accept pair per method 2019-12-28 11:01:41 +01:00
Matthias
e529a4c261 Fix typehint for get_datahandlerclass 2019-12-28 11:01:41 +01:00
Matthias
eff5cc0568 Add default to internals 2019-12-28 11:01:41 +01:00
Matthias
c6d6dbfdb1 Implement jsondatahandler file store 2019-12-28 11:01:41 +01:00
Matthias
8f214aec89 Fix "dumping" message to work correctly for .gz files 2019-12-28 11:01:41 +01:00
Matthias
abc6b9459a Add ohlcv_store call to convert_ohlcv 2019-12-28 11:01:41 +01:00
Matthias
d804372d74 Enhance ohlcv_convert method 2019-12-28 11:01:41 +01:00
Matthias
018e270336 Allow --pairs for convert arguments 2019-12-28 11:01:41 +01:00
Matthias
2a728ee68f fix bug in find-files 2019-12-28 11:01:41 +01:00
Matthias
3d4f62081e Allow timeframes for convert-data 2019-12-28 11:01:41 +01:00
Matthias
ef0fcb0e0f Make data-finding safe 2019-12-28 11:01:41 +01:00
Matthias
f8b8b9ac63 Convert to Path temporarily 2019-12-28 11:01:41 +01:00
Matthias
2a6b542b09 Add second subcommand to allow conversation of ohlcv and trades data
seprately
2019-12-28 11:01:41 +01:00
Matthias
c3064dfd2b Enhance validation constants 2019-12-28 11:00:45 +01:00
Matthias
cd4466a626 Add convert_* methods 2019-12-28 11:00:45 +01:00
Matthias
e5a61667dd Implement first version of jsondatahandler 2019-12-28 11:00:22 +01:00
Matthias
2496aa8e3f Add convert-data template subcommands 2019-12-28 10:59:30 +01:00
hroff-1902
004993583b Merge pull request #2712 from freqtrade/strategylist
add list-strategies subcommand
2019-12-28 12:32:06 +03:00
Matthias
443fd8f7dd Merge branch 'develop' into safe_sell_amount 2019-12-28 09:42:52 +01:00
Matthias
b2fb28453f Fix tests after changing output 2019-12-28 06:39:25 +01:00
Matthias
fc98cf0037 Address PR feedback - change output to show Filename only 2019-12-28 06:25:45 +01:00
hroff-1902
6db75bc244 Merge pull request #2706 from freqtrade/data_dir
Convert datadir within config to Path
2019-12-28 05:14:48 +03:00
hroff-1902
d6ca562b03 Make mypy happy and handle hypothetical case when stake_amount == 0 2019-12-28 04:05:03 +03:00
hroff-1902
3dbd83e35a Introduce get_free_open_trades() method 2019-12-28 03:46:42 +03:00
hroff-1902
8eeabd2372 Move warning to create_trades() 2019-12-28 03:22:50 +03:00
hroff-1902
ed9cb4219d Make mypy happy 2019-12-28 02:58:23 +03:00
hroff-1902
ef92fd775c Align behavior: check for available in all cases: edge, unlimited and fixed 2019-12-28 02:53:41 +03:00
hroff-1902
abaeab89aa Make _calculate_unlimited_stake_amount() a separate method 2019-12-28 02:36:32 +03:00
hroff-1902
243bcb2368 Make _check_available_stake_amount() a separate method 2019-12-28 02:25:43 +03:00
hroff-1902
86f2693040 cosmetics 2019-12-28 01:54:12 +03:00
hroff-1902
b6d1c5b17a _get_trade_stake_amount() is not private 2019-12-28 01:44:51 +03:00
hroff-1902
039dfc302c No need to convert pair name 2019-12-28 01:34:31 +03:00
hroff-1902
56fd714de2 Merge pull request #2717 from freqtrade/markets_info_nodict
Check if markets.info is a dict before using it
2019-12-27 19:47:56 +03:00
Matthias
e51ac2c973 Remove unavailable pair ... 2019-12-27 16:22:41 +01:00
Matthias
cadde3ab6d Check if markets.info is a dict before using it 2019-12-27 16:15:44 +01:00
hroff-1902
9987e64e8c Merge pull request #2711 from freqtrade/doc/formatting
Align Edge documentation to configuration page
2019-12-26 00:36:40 +03:00
Matthias
98647b490c Remove wrong "once per hour" listings 2019-12-25 19:27:08 +01:00
hroff-1902
32118cc1cb Merge pull request #2714 from freqtrade/sell_reason_counts
backtesting - Sell reason counts
2019-12-25 13:35:11 +03:00
Matthias
63f41cf1c6 Update documentation with new result 2019-12-25 09:44:23 +01:00
Matthias
e5aed098b5 Enhance backtest results with sell reason profit / loss table 2019-12-25 09:39:29 +01:00
hroff-1902
5e6e625694 Merge pull request #2710 from freqtrade/rpc_balance_output
/balance should not convert to BTC
2019-12-24 23:59:05 +03:00
hroff-1902
a95454d338 Merge pull request #2709 from freqtrade/dry_wallet_fix
Fix bug in dry-run wallet
2019-12-24 23:55:22 +03:00
Matthias
ad75048678 Fix testing with path in windows 2019-12-24 15:53:40 +01:00
Matthias
402c761a23 Change loglevel of Path output to debug 2019-12-24 15:44:04 +01:00
Matthias
66f9ece061 Add documentation for strategy-list 2019-12-24 15:35:53 +01:00
Matthias
27b8617077 Add tests 2019-12-24 15:35:38 +01:00
Matthias
2ab989e274 Cleanup some code and add option 2019-12-24 15:28:35 +01:00
Matthias
5a11ca86bb Move instanciation out of search_object 2019-12-24 14:01:28 +01:00
Matthias
25e6d6a7bf Combine load_object methods into one 2019-12-24 13:54:46 +01:00
Matthias
eb1040ddb7 Convert resolvers to classmethods 2019-12-24 13:34:37 +01:00
Matthias
a68445692b Add first steps for list-strategies 2019-12-24 12:44:41 +01:00
Matthias
48935d2932 Align edge documentation to configuration page 2019-12-24 07:25:18 +01:00
Matthias
83ed0b38c1 Wordwrap before keep it secret 2019-12-24 07:13:44 +01:00
Matthias
90670e7401 Merge pull request #2686 from freqtrade/doc/pricing_reasons
Document buy / sell order pricings
2019-12-24 07:05:35 +01:00
Matthias
a105e5664a Align /balance output to show everything in stake currency
the conversation to BTC does not make sense
2019-12-24 06:58:30 +01:00
Matthias
b8442d536a Update integration test to also test dry-run-wallets 2019-12-24 06:47:25 +01:00
Matthias
6688a2c112 Merge branch 'develop' into doc/pricing_reasons 2019-12-24 06:33:51 +01:00
Matthias
33cfeaf9b0 Remove i.e. where it doesn't fit 2019-12-24 06:31:05 +01:00
Matthias
f487dac047 FIx bug in dry-run wallets causing balances to stay there after trades
are sold
2019-12-24 06:27:11 +01:00
hroff-1902
690eb2a52b configuration.md reviewed 2019-12-24 07:19:35 +03:00
hroff-1902
20b52fcef9 Merge pull request #2705 from freqtrade/refactor_resolvers
Refactor resolvers to static resolvers
2019-12-24 00:35:52 +03:00
Matthias
0ac5e5035c Remove unused import 2019-12-23 20:43:31 +01:00
Matthias
c6b9c8eca0 Forgot to save 2019-12-23 19:32:31 +01:00
Matthias
ecbb77c17f Add forgotten option 2019-12-23 15:13:55 +01:00
Matthias
bb8acc61db Convert datadir within config to Path
(it's used as Path all the time!)
2019-12-23 15:11:29 +01:00
Matthias
90cabd7c21 Wrap line 2019-12-23 10:46:35 +01:00
Matthias
c6d2233978 Convert StrategyLoader to static loader 2019-12-23 10:23:48 +01:00
Matthias
6d5aca4f32 Convert hyperoptloss resolver to static loader 2019-12-23 10:09:08 +01:00
Matthias
248ef5a0ea Convert HyperoptResolver to static loader 2019-12-23 10:06:19 +01:00
Matthias
560acb7cea Convert ExchangeResolver to static loader class 2019-12-23 10:03:18 +01:00
Matthias
5fefa9e97c Convert PairlistResolver to static loader 2019-12-23 09:56:12 +01:00
Matthias
1c5f8070e5 Refactor build_paths to staticmethod 2019-12-23 09:53:55 +01:00
Matthias
506907ddc9 Merge pull request #2704 from freqtrade/dependabot/pip/develop/scipy-1.4.1
Bump scipy from 1.3.3 to 1.4.1
2019-12-23 09:48:35 +01:00
Matthias
84f0f451a0 Merge pull request #2703 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.12
Bump sqlalchemy from 1.3.11 to 1.3.12
2019-12-23 09:47:02 +01:00
Matthias
fa466a54cd Merge pull request #2701 from freqtrade/dependabot/pip/develop/numpy-1.18.0
Bump numpy from 1.17.4 to 1.18.0
2019-12-23 09:40:15 +01:00
Matthias
3c668c2f8e Merge pull request #2699 from freqtrade/dependabot/docker/python-3.7.6-slim-stretch
Bump python from 3.7.5-slim-stretch to 3.7.6-slim-stretch
2019-12-23 09:39:22 +01:00
dependabot-preview[bot]
779278ed50 Bump sqlalchemy from 1.3.11 to 1.3.12
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.11 to 1.3.12.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 08:28:05 +00:00
Matthias
96f70118ca Merge pull request #2702 from freqtrade/dependabot/pip/develop/mypy-0.761
Bump mypy from 0.750 to 0.761
2019-12-23 09:26:50 +01:00
Matthias
4e62b62add Merge pull request #2700 from freqtrade/dependabot/pip/develop/ccxt-1.21.12
Bump ccxt from 1.20.84 to 1.21.12
2019-12-23 09:26:35 +01:00
dependabot-preview[bot]
9cfbe98a23 Bump scipy from 1.3.3 to 1.4.1
Bumps [scipy](https://github.com/scipy/scipy) from 1.3.3 to 1.4.1.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.3.3...v1.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 07:39:25 +00:00
dependabot-preview[bot]
31a7e9feed Bump mypy from 0.750 to 0.761
Bumps [mypy](https://github.com/python/mypy) from 0.750 to 0.761.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.750...v0.761)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 07:38:10 +00:00
dependabot-preview[bot]
20ad8a379d Bump numpy from 1.17.4 to 1.18.0
Bumps [numpy](https://github.com/numpy/numpy) from 1.17.4 to 1.18.0.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.17.4...v1.18.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 07:38:05 +00:00
dependabot-preview[bot]
8f17b81329 Bump ccxt from 1.20.84 to 1.21.12
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.20.84 to 1.21.12.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.20.84...1.21.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 07:37:04 +00:00
dependabot-preview[bot]
76a93fabc7 Bump python from 3.7.5-slim-stretch to 3.7.6-slim-stretch
Bumps python from 3.7.5-slim-stretch to 3.7.6-slim-stretch.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 06:26:13 +00:00
hroff-1902
98eed4f2ed Merge pull request #2695 from freqtrade/custom_pairlock
Improve pairlocking mechanism to allow usage from within strategy
2019-12-22 15:03:24 +03:00
Matthias
2195ae59d6 Use different time offsets to avoid confusion 2019-12-22 12:49:01 +01:00
hroff-1902
4f88857442 Merge pull request #2694 from freqtrade/unfilled_strategy
Add unfilledtimeout to strategy overrides
2019-12-22 14:34:25 +03:00
hroff-1902
01d53c0160 Merge pull request #2697 from freqtrade/dry_run_db
persist Dry run db as default
2019-12-22 13:46:32 +03:00
hroff-1902
d98cd6f135 Merge pull request #2693 from freqtrade/doc/pypi
document how to do releases to pypi
2019-12-22 13:42:44 +03:00
Matthias
dc567f99d6 Update documentation to new handling of dry-mode database 2019-12-22 10:16:56 +01:00
Matthias
ffd7034c00 Persist dry-run trade per default 2019-12-22 10:16:16 +01:00
Matthias
43c25c8a32 add documentation for is_pair_locked 2019-12-22 09:59:25 +01:00
Matthias
a71deeda94 Document lock-pair implementation 2019-12-22 09:55:40 +01:00
Matthias
89b4f45fe3 Remove section about strategy template - use new-strategy intead 2019-12-22 09:47:37 +01:00
Matthias
9835312033 Improve pair_lock handling 2019-12-22 09:46:00 +01:00
Matthias
1ff0d0f1fa Add unfilledtimeout to strategy overrides 2019-12-22 09:35:06 +01:00
Matthias
1a73159200 Modify classifiers 2019-12-22 09:25:13 +01:00
Matthias
c417877eb8 sort pytest dependencies 2019-12-22 09:25:13 +01:00
Matthias
9ec4368c6f Add release documentation 2019-12-22 09:25:13 +01:00
Matthias
3f44d51355 Merge pull request #2691 from hroff-1902/cli-no-underscores
Minor: Please no underscores in cli options
2019-12-22 08:43:31 +01:00
hroff-1902
95bd9e8e0b No underscores in cli options 2019-12-22 00:17:51 +03:00
hroff-1902
bc92503c92 Merge pull request #2689 from freqtrade/edge_small_modifications
[minor] Edge small cleanup
2019-12-20 14:50:13 +03:00
hroff-1902
5ba106d96b Merge pull request #2687 from xmatthias/try_covsxxx
Try to get comment from forked repos
2019-12-20 14:26:22 +03:00
Matthias
fc5764f9df Edge small cleanup 2019-12-19 19:55:21 +01:00
Matthias
342f3f450b try with coveralls token in yml ... 2019-12-18 20:38:21 +01:00
Matthias
0c6b5e01fb Try with github-token 2019-12-18 20:30:42 +01:00
Matthias
6507a26cc1 Fix some tests after merge 2019-12-18 20:16:53 +01:00
Matthias
e72c6a0d94 use only first part of the currency to get wallet-amount (!!) 2019-12-18 20:02:15 +01:00
Matthias
834a0ed620 Merge branch 'develop' into safe_sell_amount 2019-12-18 19:45:31 +01:00
Matthias
1af962899d Fix note-box syntax error 2019-12-18 19:43:37 +01:00
Matthias
11e787c884 Finish depth_of_market documentation piece 2019-12-18 19:41:51 +01:00
Matthias
1c19856d26 add section about depth_of_market 2019-12-18 16:49:56 +01:00
Matthias
d73ba71ec6 Improve formatting of orderbook doc 2019-12-18 16:41:54 +01:00
Matthias
dc07037edf Add documentation for price finding 2019-12-18 16:38:57 +01:00
Matthias
21622ac313 Rename get_ticker to fetch_ticker 2019-12-18 16:34:30 +01:00
Matthias
ce190a7485 Merge pull request #2683 from hroff-1902/minor-data-history-4
Minor improvements in data.history
2019-12-18 06:26:06 +01:00
hroff-1902
cf4c3642ce Minor improvements in data.history 2019-12-18 01:06:03 +03:00
hroff-1902
021fa1ca1a Merge pull request #2678 from hroff-1902/dataprovider-history-split-refresh
Dataprovider history: split refresh part
2019-12-18 00:30:47 +03:00
hroff-1902
3a542bce62 Merge pull request #2674 from freqtrade/bt_trade_open_price
Pre-calculate open_trade_price
2019-12-17 21:51:13 +03:00
Matthias
c5e6a34f25 Remove unnecessary parenteses 2019-12-17 19:30:04 +01:00
hroff-1902
1537389617 Remove startup_candles argument in refresh_data 2019-12-17 18:23:31 +03:00
hroff-1902
b07d29b1af Merge pull request #2676 from freqtrade/investigate_random_test_fail
Fix random test failure.
2019-12-17 14:23:30 +03:00
hroff-1902
b2796f99b6 Remove redundant refresh_pair_history 2019-12-17 14:06:21 +03:00
Matthias
bbb05b5286 Remove fixed random order 2019-12-17 11:51:50 +01:00
hroff-1902
60f89c8c01 Split refresh from load_data/load_pair_history 2019-12-17 13:43:42 +03:00
Matthias
8513a5e2d6 Fix failures in test_main 2019-12-17 11:35:39 +01:00
hroff-1902
69f8738d00 Merge pull request #2675 from freqtrade/align_test_history
Align usage of history import in test
2019-12-17 13:13:40 +03:00
hroff-1902
c32507252e Merge pull request #2671 from freqtrade/doc/incompletecandle
Add documentation about ohlcv_partial_candle
2019-12-17 13:10:36 +03:00
Matthias
2e2f084f66 Try to clear caplog ... 2019-12-17 11:07:59 +01:00
Matthias
e1c0c6af7d fix random-seed to failing one 2019-12-17 10:51:49 +01:00
Matthias
86de88ed48 Align usage of history import in test 2019-12-17 09:36:26 +01:00
Matthias
1042f9847a Merge pull request #2672 from hroff-1902/minor-data-history-2
Minor: improvements in data/history.py
2019-12-17 09:22:56 +01:00
Matthias
a2964afd42 Rename profit_percent to profit_ratio to be consistent 2019-12-17 08:53:30 +01:00
Matthias
539b5627fd Fix typo 2019-12-17 08:31:44 +01:00
Matthias
cbd10309f5 Add mid-state test 2019-12-17 07:13:08 +01:00
Matthias
362a40db6f Update docstring 2019-12-17 07:09:56 +01:00
Matthias
861a7834fc Call calc_open_price() whenever necessary 2019-12-17 07:08:36 +01:00
Matthias
307ade6251 Cache open_trade_price 2019-12-17 07:02:02 +01:00
Matthias
0b5354f13d Add required arguments to Trade method 2019-12-17 06:58:10 +01:00
Matthias
707c5668a5 Fix typo 2019-12-17 06:11:44 +01:00
hroff-1902
0277cd82ea Make mypy happy 2019-12-16 23:25:57 +03:00
Matthias
9cea5cd442 Add documentation about ohlcv_partial_candle 2019-12-16 20:38:36 +01:00
hroff-1902
a6fc743d85 Align code in _download_*_history() 2019-12-16 22:12:26 +03:00
hroff-1902
fa968996ed Remove useless check 2019-12-16 22:01:26 +03:00
hroff-1902
4cd45b6535 Rename download_*_history as non-public 2019-12-16 21:57:03 +03:00
hroff-1902
2af9ffa7f2 Align refresh_backtest_ to each other 2019-12-16 21:43:33 +03:00
hroff-1902
39197458f4 Merge pull request #2661 from freqtrade/wallet_dry
Introduce Dry-Run Wallet
2019-12-16 14:00:11 +03:00
Matthias
35bbe12065 Merge pull request #2668 from freqtrade/dependabot/pip/develop/ccxt-1.20.84
Bump ccxt from 1.20.46 to 1.20.84
2019-12-16 11:08:45 +01:00
Matthias
9add86144c Merge pull request #2667 from freqtrade/dependabot/pip/develop/mkdocs-material-4.6.0
Bump mkdocs-material from 4.5.1 to 4.6.0
2019-12-16 10:50:47 +01:00
Matthias
03c8d65d07 Merge pull request #2666 from freqtrade/dependabot/pip/develop/plotly-4.4.1
Bump plotly from 4.3.0 to 4.4.1
2019-12-16 10:47:01 +01:00
dependabot-preview[bot]
75e6acd6ed Bump ccxt from 1.20.46 to 1.20.84
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.20.46 to 1.20.84.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.20.46...1.20.84)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 09:46:17 +00:00
Matthias
95b4189d69 Merge pull request #2669 from freqtrade/dependabot/pip/develop/cachetools-4.0.0
Bump cachetools from 3.1.1 to 4.0.0
2019-12-16 10:45:02 +01:00
Matthias
22dd91fc21 Merge pull request #2665 from freqtrade/dependabot/pip/develop/joblib-0.14.1
Bump joblib from 0.14.0 to 0.14.1
2019-12-16 10:44:00 +01:00
Matthias
700370ac5c Merge pull request #2664 from freqtrade/dependabot/pip/develop/pytest-5.3.2
Bump pytest from 5.3.1 to 5.3.2
2019-12-16 10:43:35 +01:00
dependabot-preview[bot]
05de60a7fe Bump cachetools from 3.1.1 to 4.0.0
Bumps [cachetools](https://github.com/tkem/cachetools) from 3.1.1 to 4.0.0.
- [Release notes](https://github.com/tkem/cachetools/releases)
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v3.1.1...v4.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 07:31:38 +00:00
dependabot-preview[bot]
cc41cdbf22 Bump mkdocs-material from 4.5.1 to 4.6.0
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.5.1 to 4.6.0.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/4.5.1...4.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 07:30:46 +00:00
dependabot-preview[bot]
c05af1b63c Bump plotly from 4.3.0 to 4.4.1
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.3.0 to 4.4.1.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.3.0...v4.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 07:30:27 +00:00
dependabot-preview[bot]
33db37a915 Bump joblib from 0.14.0 to 0.14.1
Bumps [joblib](https://github.com/joblib/joblib) from 0.14.0 to 0.14.1.
- [Release notes](https://github.com/joblib/joblib/releases)
- [Changelog](https://github.com/joblib/joblib/blob/master/CHANGES.rst)
- [Commits](https://github.com/joblib/joblib/compare/0.14.0...0.14.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 07:30:04 +00:00
dependabot-preview[bot]
e398c37526 Bump pytest from 5.3.1 to 5.3.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.1 to 5.3.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.3.1...5.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-16 07:29:42 +00:00
Matthias
655672c957 Enhance documentation Note 2019-12-16 06:22:54 +01:00
hroff-1902
2282f4bd37 Merge pull request #2660 from freqtrade/release_doc-
[minor][doc] Add release section about collapsible section
2019-12-15 20:27:27 +03:00
Matthias
ce845ab092 Improve docstring for dry-run wallet method 2019-12-15 11:03:40 +01:00
Matthias
b5b6458f12 Add note about unlimited stake amount 2019-12-15 10:57:27 +01:00
Matthias
56e13c8919 Enhance documentation for dry-run wallet 2019-12-15 10:55:15 +01:00
Matthias
23d467eb0d Show simulation note also in restserver 2019-12-15 10:41:57 +01:00
Matthias
c741b67c3c Adjust tests for dry_run wallet simulation 2019-12-15 10:39:52 +01:00
Matthias
5a5741878c Improve dry-run calculations 2019-12-15 10:26:56 +01:00
Matthias
4463d58470 Add release section about collapsible section 2019-12-15 09:49:56 +01:00
Matthias
f0bbc75038 Combine dry_run wallet into original Wallets class 2019-12-15 09:48:35 +01:00
Matthias
7c53dcb0af Merge pull request #2656 from freqtrade/new_release
New release - 2019.11
2019-12-15 09:44:10 +01:00
Matthias
fda8f7e305 Introuce WalletDry - supporting dry-run wallets 2019-12-15 09:38:18 +01:00
Matthias
52b212db64 Fix tests after changing dry_run_wallet amount 2019-12-15 09:38:06 +01:00
Matthias
931d24b5a8 Have dry_run_wallet default to 1000 2019-12-15 09:26:17 +01:00
Matthias
18dfa56752 Merge pull request #2659 from hroff-1902/fix_mypy
[critical]: Fix mypy errors in develop
2019-12-15 09:20:36 +01:00
hroff-1902
26ab108890 Fix mypy errors in develop 2019-12-15 01:10:09 +03:00
hroff-1902
1cc174c007 Merge pull request #2624 from freqtrade/backtest_refactor
handle and document ROI=-1
2019-12-14 23:11:36 +03:00
hroff-1902
e26f563f4b Merge pull request #2655 from freqtrade/avoid_keyerror_backtest
Use first pair of pairlist to get fee
2019-12-14 23:10:40 +03:00
hroff-1902
ebd0a1722d Merge pull request #2657 from freqtrade/rpc_fixtypo
[minor] Fix typo causing a trailing "tic" in /show_config output
2019-12-14 22:43:37 +03:00
Matthias
f81c49ce6d Fix typo causing a trailing "tic" in /show_config output 2019-12-14 19:53:20 +01:00
Matthias
ded2d3c293 Version bump to 2019.11 2019-12-14 16:11:34 +01:00
Matthias
2f7181e236 Merge pull request #2648 from hroff-1902/hyperopt-random-state
Seed hyperopt random_state if not passed
2019-12-14 15:54:59 +01:00
Matthias
2275a1539e Remove default symbol from get_fee() 2019-12-14 13:22:42 +01:00
hroff-1902
f2266ea9f4 Use shorter range for seeded random-state 2019-12-14 15:17:45 +03:00
hroff-1902
82ff878e38 Fix typo in the docs 2019-12-14 15:15:20 +03:00
hroff-1902
7200bc3fba Merge pull request #2654 from freqtrade/rpc/show_config
improve show config when using trailing stop
2019-12-14 15:11:12 +03:00
Matthias
a48c0ad868 Use first pair of pairlist to get fee
Use this instead of hardcoded ETH/BTC - so backtesting works with
exchanges without ETH/BTC pair
2019-12-14 12:55:02 +01:00
Matthias
e4cc5c479f Test new show_config branch 2019-12-13 20:27:39 +01:00
Matthias
014c18ead2 Improve output from show_config when trailing_stop is active 2019-12-13 20:27:06 +01:00
hroff-1902
3bd873f3c6 Add notes on random-state to the docs 2019-12-13 13:59:18 +03:00
hroff-1902
6c4f424887 Merge pull request #2651 from freqtrade/dry_amount
Round amount to precision also for dry-runs
2019-12-13 13:13:20 +03:00
Matthias
04257d8ecc Add tests for safe_sell_amount 2019-12-13 07:06:54 +01:00
Matthias
b69f5afaaf Round amount to precision also for dry-runs 2019-12-13 06:59:10 +01:00
Matthias
5db883906a Try to verify available amount on the exchange 2019-12-13 06:52:33 +01:00
Matthias
703924d6c4 Merge pull request #2643 from freqtrade/mins
Remove min (plural) from codebase
2019-12-12 14:27:39 +01:00
Matthias
330b8cf8a1 space before unit ... 2019-12-12 14:08:44 +01:00
hroff-1902
6e778ad710 Seed hyperopt random_state if not passed 2019-12-12 03:12:28 +03:00
Matthias
f44e3dc319 Merge pull request #2642 from hroff-1902/fix-hyperopt-trailing
Fix generation of hyperopt trailing params
2019-12-11 19:53:42 +01:00
Matthias
d8b2d39f2f Merge pull request #2628 from freqtrade/rpc/sell_duration
Telegram / sell duration
2019-12-11 07:15:00 +01:00
Matthias
7c7ca1cb90 Remove min (plural) from codebase 2019-12-11 07:12:37 +01:00
Matthias
1058e5fb72 No plural for min 2019-12-11 06:48:40 +01:00
Matthias
b2a9b87be3 Merge pull request #2632 from freqtrade/dependabot/pip/develop/scikit-learn-0.22
Bump scikit-learn from 0.21.3 to 0.22
2019-12-10 16:20:39 +01:00
Matthias
3f9f29ba4e Fix Flake8 import error 2019-12-10 16:10:51 +01:00
Matthias
390db9503f Show humanized and minutes version of duration 2019-12-10 15:12:36 +01:00
hroff-1902
3448f86263 Suppress scikit-learn FutureWarnings from skopt imports 2019-12-10 15:46:29 +03:00
hroff-1902
3252654ed3 Test adjusted 2019-12-10 14:06:17 +03:00
Matthias
29745bb4ec Merge pull request #2641 from hroff-1902/hyperopt-list
minor: Fix documentation formatting
2019-12-10 06:00:44 +01:00
hroff-1902
641e3fdf7a Fix generation of hyperopt trailing params 2019-12-10 03:32:43 +03:00
hroff-1902
2f76eaf358 minor: Fix documentation formatting 2019-12-10 00:33:57 +03:00
hroff-1902
0e4ef33d6a Merge pull request #2581 from hroff-1902/hyperopt-list
Add hyperopt-list and hyperopt-show commands
2019-12-10 00:30:26 +03:00
hroff-1902
18c73ceb90 Add tests for the last commit 2019-12-10 00:22:11 +03:00
hroff-1902
8431b54b21 Fix index limits handling 2019-12-09 23:50:40 +03:00
hroff-1902
5fc357ee10 Fix typo 2019-12-09 23:43:50 +03:00
Matthias
de33ec4250 use sell_row.open also when the active ROI value just changed 2019-12-09 16:52:12 +01:00
hroff-1902
a9f7e9fb7a Fix NO_CONF; fix tests 2019-12-09 12:49:04 +03:00
Matthias
aa335d8485 Merge pull request #2634 from freqtrade/dependabot/pip/develop/ccxt-1.20.46
Bump ccxt from 1.20.22 to 1.20.46
2019-12-09 09:00:08 +01:00
Matthias
82f7798f48 Merge pull request #2635 from freqtrade/dependabot/pip/develop/colorama-0.4.3
Bump colorama from 0.4.1 to 0.4.3
2019-12-09 08:59:46 +01:00
Matthias
ce80bbe24c Merge pull request #2633 from freqtrade/dependabot/pip/develop/coveralls-1.9.2
Bump coveralls from 1.8.2 to 1.9.2
2019-12-09 08:59:35 +01:00
Matthias
da195d0272 Merge pull request #2631 from freqtrade/dependabot/pip/develop/mkdocs-material-4.5.1
Bump mkdocs-material from 4.5.0 to 4.5.1
2019-12-09 08:42:00 +01:00
Matthias
4eae02b723 Merge pull request #2630 from freqtrade/dependabot/pip/develop/pytest-mock-1.13.0
Bump pytest-mock from 1.12.1 to 1.13.0
2019-12-09 08:34:01 +01:00
dependabot-preview[bot]
081b21fe82 Bump colorama from 0.4.1 to 0.4.3
Bumps [colorama](https://github.com/tartley/colorama) from 0.4.1 to 0.4.3.
- [Release notes](https://github.com/tartley/colorama/releases)
- [Changelog](https://github.com/tartley/colorama/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tartley/colorama/compare/0.4.1...0.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 07:26:53 +00:00
dependabot-preview[bot]
ed053d240e Bump ccxt from 1.20.22 to 1.20.46
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.20.22 to 1.20.46.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.20.22...1.20.46)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 07:26:42 +00:00
dependabot-preview[bot]
0ca3157a8b Bump coveralls from 1.8.2 to 1.9.2
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 1.8.2 to 1.9.2.
- [Release notes](https://github.com/coveralls-clients/coveralls-python/releases)
- [Changelog](https://github.com/coveralls-clients/coveralls-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/coveralls-clients/coveralls-python/compare/1.8.2...1.9.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 07:26:06 +00:00
dependabot-preview[bot]
25447329a0 Bump scikit-learn from 0.21.3 to 0.22
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.21.3 to 0.22.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.21.3...0.22)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 07:25:44 +00:00
dependabot-preview[bot]
4934456751 Bump mkdocs-material from 4.5.0 to 4.5.1
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/4.5.0...4.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 07:25:28 +00:00
dependabot-preview[bot]
0f4dcaa403 Bump pytest-mock from 1.12.1 to 1.13.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 1.12.1 to 1.13.0.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v1.12.1...v1.13.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 07:25:03 +00:00
hroff-1902
4b560880fd Add tests for hyperopt-list, hyperopt-show 2019-12-09 04:37:58 +03:00
Matthias
dc9fed4a5f Adjust documentation 2019-12-08 14:10:26 +01:00
Matthias
88a24da272 Adapt tests to sending open / close date 2019-12-08 14:10:04 +01:00
Matthias
e4655c9b07 include trade-duration with sell-notification 2019-12-08 14:07:46 +01:00
Matthias
1495c93083 Merge pull request #2627 from freqtrade/fix/dockerlatest
Docker: Build latest along with develop image
2019-12-08 11:42:27 +01:00
Matthias
21c6855705 Build latest along with develop image 2019-12-07 20:21:25 +01:00
hroff-1902
a7d6dc9d3a Merge pull request #2625 from freqtrade/validate_stakecurrency
Validate stake-currency against pairlist
2019-12-07 22:08:46 +03:00
Matthias
ed7207d4c8 Show pairs which are wrong ... 2019-12-07 19:31:15 +01:00
Matthias
bb9235c715 Validate stake-currency against pairlist - making sure only correct
pairs are in the whitelist
2019-12-07 15:42:47 +01:00
Matthias
45d12dbc83 Avoid a few calculations during backtesting 2019-12-07 15:28:56 +01:00
Matthias
189835b963 Add documentation for ROI-1 case 2019-12-07 15:26:10 +01:00
Matthias
3163cbdf8a Apply special case for negative ROI 2019-12-07 15:18:12 +01:00
Matthias
1e6f9f9fe2 Add testcase for negative ROI sell using open 2019-12-07 15:18:09 +01:00
Matthias
3091869115 refactor get_close_rate out of get_sell_trade-entry 2019-12-07 14:30:14 +01:00
hroff-1902
9e85376a2d Merge pull request #2619 from freqtrade/hyperopt_quick_mode
Document "quick" hyperopt of roi/stoploss and trailing stoploss
2019-12-06 09:18:40 +03:00
Matthias
a379c19e9a Merge pull request #2618 from freqtrade/fix/hyperopt_no_tickerinterval
Fix hyperopt with ticker_interval from strategy
2019-12-06 06:48:10 +01:00
Matthias
2bd4008cb2 fix space name ... 2019-12-06 06:06:41 +01:00
hroff-1902
d21ae4edd3 Add fixes for comments in the review 2019-12-05 23:29:31 +03:00
Matthias
1da008b3af Document "quick" hyperopt of roi/stoploss and trailing stoploss 2019-12-05 20:44:12 +01:00
Matthias
703458f365 Add test for loading ticker-interval from strategy 2019-12-05 20:35:54 +01:00
Matthias
4b0a4c936a Fix hyperopt with ticker_interval from strategy 2019-12-05 20:31:02 +01:00
hroff-1902
216094a761 Add reference to hyperopt-list and hyperopt-show to the Hyperopt doc 2019-12-05 14:30:55 +03:00
hroff-1902
4efd8b96e5 Add description for hyperopt-list and hyperopt-show to the docs 2019-12-05 14:16:18 +03:00
hroff-1902
b61f43835d Make flake happy 2019-12-05 01:11:06 +03:00
hroff-1902
017a94adc1 Merge develop 2019-12-05 01:08:38 +03:00
hroff-1902
b20bea8492 Adjust tests 2019-12-04 23:15:19 +03:00
hroff-1902
54694dd3a4 Manual merge of some conflicts in hyperopt 2019-12-04 23:14:47 +03:00
hroff-1902
8dd9b5c6fb Merge pull request #2606 from freqtrade/volume_tester
Subcommand: test-pairlist
2019-12-04 18:31:37 +03:00
Matthias
16a50fbe4e Resort documentation 2019-12-04 14:30:53 +01:00
hroff-1902
32897ce769 Merge pull request #2612 from freqtrade/fix/nullerror
Don't return None from load_pair_history
2019-12-04 14:45:44 +03:00
Matthias
51f074ba4b Don't print quote-currency for -1 2019-12-04 12:25:57 +01:00
Matthias
0ba804d051 Address first part of feedback 2019-12-04 12:14:37 +01:00
Matthias
611a594a46 Merge pull request #2607 from hroff-1902/docs/create-advanced-hyperopt
Move docs on loss function creation to a separate doc file
2019-12-04 07:58:30 +01:00
Matthias
8a7fe3f1d6 The file will (for users) be in user_data - just in the repo it's in
templates
2019-12-04 07:01:09 +01:00
Matthias
054484ad73 load_pair_history should not return None, but an empty dataframe if no
data is found
2019-12-04 06:57:44 +01:00
hroff-1902
ac3e061508 Resolve issues stated in the review 2019-12-03 23:20:00 +03:00
hroff-1902
ddf86d6342 Adjust docs index 2019-12-03 21:36:25 +03:00
hroff-1902
ba29a2ffe4 Move docs on loss function creation to a separate doc file 2019-12-03 21:30:50 +03:00
Matthias
b33e47a49e Update documentation with test-pairlist 2019-12-03 16:15:10 +01:00
Matthias
298e8b2332 Add testcase for test_pairlist 2019-12-03 15:10:27 +01:00
Matthias
78f8ba1226 Merge pull request #2605 from freqtrade/hroff-1902-patch-1
minor: fix typo in docs
2019-12-03 12:27:52 +01:00
hroff-1902
17e03559dc minor: fix typo in docs 2019-12-03 12:51:52 +03:00
hroff-1902
2825206d37 Merge pull request #2604 from freqtrade/binance_pairlist
Binance/Kraken default whitelists
2019-12-03 09:11:39 +03:00
Matthias
cd20d5b5c5 Update kraken pairlist 2019-12-03 06:41:59 +01:00
Matthias
ebf6dad3f6 Update binance pairlist default config 2019-12-03 06:37:10 +01:00
Matthias
683406b57d correct fallback to stake_currency 2019-12-03 06:36:43 +01:00
hroff-1902
406dfe21f8 Merge pull request #2492 from hroff-1902/hyperopt-trailing-space
Add trailing stoploss hyperspace
2019-12-03 00:23:14 +03:00
Matthias
346d381ab8 Merge pull request #2597 from freqtrade/dependabot/pip/develop/mypy-0.750
Bump mypy from 0.740 to 0.750
2019-12-02 09:35:59 +01:00
Matthias
d7980fa0b6 Merge pull request #2599 from freqtrade/dependabot/pip/develop/ccxt-1.20.22
Bump ccxt from 1.19.86 to 1.20.22
2019-12-02 08:58:12 +01:00
dependabot-preview[bot]
fc7b9846ae Bump mypy from 0.740 to 0.750
Bumps [mypy](https://github.com/python/mypy) from 0.740 to 0.750.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.740...v0.750)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-02 07:46:57 +00:00
Matthias
15e695a9bd Merge pull request #2598 from freqtrade/dependabot/pip/develop/pytest-5.3.1
Bump pytest from 5.3.0 to 5.3.1
2019-12-02 08:45:47 +01:00
dependabot-preview[bot]
110fbd3f06 Bump ccxt from 1.19.86 to 1.20.22
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.19.86 to 1.20.22.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.19.86...1.20.22)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-02 07:19:49 +00:00
dependabot-preview[bot]
f0428be91e Bump pytest from 5.3.0 to 5.3.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.3.0 to 5.3.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/5.3.1/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.3.0...5.3.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-02 07:19:06 +00:00
Matthias
0b03c6c786 Implement to json 2019-12-02 07:00:38 +01:00
Matthias
150a497cb4 output pairlist after fetching all 2019-12-02 06:56:19 +01:00
Matthias
3d666ea68e Merge pull request #2594 from freqtrade/hroff-1902-patch-1
minor: Fix formatting typo in docs
2019-12-02 06:55:54 +01:00
hroff-1902
ee733210ca minor: Fix formatting typo in docs 2019-12-01 19:10:30 +03:00
hroff-1902
86342efa7a Adjust test 2019-12-01 18:34:25 +03:00
hroff-1902
05967442c3 Adjust test 2019-12-01 18:01:59 +03:00
hroff-1902
d6b587678e Adjust test 2019-12-01 17:44:14 +03:00
hroff-1902
668d42447f Refactor log_trials_result() 2019-12-01 16:15:00 +03:00
hroff-1902
32c9b5f415 Description for generate_roi_table reformulated slightly 2019-12-01 13:13:41 +03:00
hroff-1902
f42ce8fc2a Fix typo in the docs 2019-12-01 13:07:17 +03:00
Matthias
6b142d716f Merge pull request #2418 from hroff-1902/logging-syslog
Add logging to syslog and journald
2019-12-01 09:45:19 +01:00
hroff-1902
26a7af85ea Add trailing_space() into AdvancedSampleHyperOpt 2019-12-01 03:31:03 +03:00
hroff-1902
69b0767165 Merge remote-tracking branch 'upstream/develop' into hyperopt-trailing-space 2019-12-01 03:28:23 +03:00
hroff-1902
f862b4d0f0 Add description for 'default' space 2019-12-01 02:50:44 +03:00
hroff-1902
a88bfa8ded Fix: trailing_stop_positive should be positive 2019-12-01 02:27:17 +03:00
hroff-1902
fffd47e3d8 Add description of trailing space into docs 2019-12-01 01:28:26 +03:00
hroff-1902
7a3c3c4ddf Add directlink to the section 2019-11-30 22:35:13 +03:00
hroff-1902
eafccb445c Add command sample for journalctl with -u 2019-11-30 22:32:12 +03:00
hroff-1902
b040cbffdd syslog and journald cases splitted 2019-11-30 22:28:48 +03:00
Matthias
153434561d Add test_pairlist method 2019-11-30 19:53:22 +01:00
hroff-1902
36b2ed172c Merge branch 'develop' into logging-syslog 2019-11-30 21:38:50 +03:00
gaugau3000
58d70b2079 doc explicit optimization feature 2019-11-29 09:35:13 +01:00
Matthias
e0e0bad7c1 Merge pull request #2577 from xmatthias/configvalidation
"fix" config validation
2019-11-29 06:25:41 +01:00
gaugau3000
0e9e6b3443 refactor feature details doc 2019-11-28 21:22:40 +01:00
gaugau3000
9199fd5964 change doc into 2019-11-28 21:21:43 +01:00
hroff-1902
8f9b5095b5 Fix some tests 2019-11-27 22:52:43 +03:00
Matthias
5b996920f2 Merge branch 'develop' into configvalidation 2019-11-27 19:48:21 +01:00
Matthias
bcec070ad7 Merge pull request #2576 from hroff-1902/fix/get_min_pair_stake_amount
Fix _get_min_pair_stake_amount
2019-11-27 19:28:52 +01:00
hroff-1902
c3d7411668 Fix imports 2019-11-27 19:35:22 +03:00
Matthias
997c426228 fix some datatypes 2019-11-27 16:51:03 +01:00
hroff-1902
7a52334c9f Merge pull request #2533 from xmatthias/rpc/balance
/Balance rework
2019-11-27 18:39:18 +03:00
Matthias
111f018c85 Add datatype to configuration documentation 2019-11-27 14:46:09 +01:00
Matthias
64da877161 Update stake_amount description 2019-11-27 14:24:14 +01:00
Matthias
f0e6a9e0e3 Address feedback 2019-11-27 14:18:40 +01:00
hroff-1902
a373e48939 Comment added 2019-11-27 14:53:01 +03:00
hroff-1902
f2cd4fdafe Fix the rest of tests 2019-11-27 05:12:54 +03:00
hroff-1902
9991c892ac Merge branch 'develop' into hyperopt-list 2019-11-26 15:14:42 +03:00
hroff-1902
8e7512161a Add hyperopt-list and hyperopt-show commands 2019-11-26 15:01:42 +03:00
hroff-1902
5e09913e3d Merge pull request #2578 from freqtrade/actions_coveralls
Try coveralls fixing (again ...)
2019-11-26 14:24:25 +03:00
Matthias
cceb00c406 Try coveralls 2019-11-26 12:12:41 +01:00
Matthias
585b8332ad Improve tests and unify required attribute 2019-11-26 11:48:01 +01:00
hroff-1902
066f324060 Make flake happy 2019-11-26 12:28:04 +03:00
hroff-1902
8e1e20bf0d Fix some tests 2019-11-26 12:07:43 +03:00
hroff-1902
0ac592ad40 Fix markets in conftest 2019-11-26 12:00:20 +03:00
hroff-1902
17269c88be Fix _get_min_pair_stake_amount() 2019-11-26 11:57:58 +03:00
hroff-1902
8204107315 Add test for get_min_pair_stake_amount() with real data 2019-11-26 11:57:02 +03:00
Matthias
9e7d367b5c Realign strategy_override paramters 2019-11-25 15:43:09 +01:00
Matthias
12b9257c6d new-lines before defaults in documentation 2019-11-25 14:25:02 +01:00
Matthias
37f698d9c1 move default values to Description field 2019-11-25 14:20:41 +01:00
Matthias
e7c17df844 validate defaults in documentation 2019-11-25 12:56:05 +01:00
Matthias
28ec8b5bc2 Merge pull request #2568 from freqtrade/dependabot/pip/develop/scipy-1.3.3
Bump scipy from 1.3.2 to 1.3.3
2019-11-25 10:37:09 +01:00
Matthias
200b8e48bf Merge pull request #2570 from freqtrade/dependabot/pip/develop/pytest-mock-1.12.1
Bump pytest-mock from 1.11.2 to 1.12.1
2019-11-25 10:36:43 +01:00
Matthias
2a8ad9e35b Merge pull request #2572 from freqtrade/dependabot/pip/develop/jsonschema-3.2.0
Bump jsonschema from 3.1.1 to 3.2.0
2019-11-25 10:36:22 +01:00
Matthias
be8ad0f022 Merge pull request #2571 from freqtrade/dependabot/pip/develop/pytest-5.3.0
Bump pytest from 5.2.4 to 5.3.0
2019-11-25 10:36:08 +01:00
Matthias
a77efc3949 Merge pull request #2569 from freqtrade/dependabot/pip/develop/ccxt-1.19.86
Bump ccxt from 1.19.54 to 1.19.86
2019-11-25 10:35:50 +01:00
dependabot-preview[bot]
418ca00305 Bump jsonschema from 3.1.1 to 3.2.0
Bumps [jsonschema](https://github.com/Julian/jsonschema) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/Julian/jsonschema/releases)
- [Changelog](https://github.com/Julian/jsonschema/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/Julian/jsonschema/compare/v3.1.1...v3.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 07:22:09 +00:00
dependabot-preview[bot]
03f02294d1 Bump pytest from 5.2.4 to 5.3.0
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.2.4 to 5.3.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.2.4...5.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 07:21:52 +00:00
dependabot-preview[bot]
0a7a1290e3 Bump pytest-mock from 1.11.2 to 1.12.1
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 1.11.2 to 1.12.1.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v1.11.2...v1.12.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 07:21:32 +00:00
dependabot-preview[bot]
28f73ecb3d Bump ccxt from 1.19.54 to 1.19.86
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.19.54 to 1.19.86.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.19.54...1.19.86)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 07:21:16 +00:00
dependabot-preview[bot]
6ab7f93ce7 Bump scipy from 1.3.2 to 1.3.3
Bumps [scipy](https://github.com/scipy/scipy) from 1.3.2 to 1.3.3.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.3.2...v1.3.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-25 07:20:40 +00:00
Matthias
d1511a1085 Update some config documentation 2019-11-25 07:12:39 +01:00
Matthias
0775ac081a Cleanup constants and required 2019-11-25 07:12:30 +01:00
Matthias
646a9d12b2 Align quoting of json schema 2019-11-25 07:06:55 +01:00
Matthias
e7be742c58 Run validation after custom validations 2019-11-25 07:05:30 +01:00
Matthias
8d002a8f28 Fix some more tests 2019-11-25 07:05:30 +01:00
Matthias
af3eea3805 Move config json validation to after strategy loading
Otherwise attributes are mandatory in configuration
while they could be set in the strategy
2019-11-25 07:05:30 +01:00
Matthias
4dc0631a4b Lower minimum tradeable value 2019-11-25 07:05:30 +01:00
Matthias
a3415e52c0 Fix some test-types 2019-11-25 07:05:30 +01:00
Matthias
1b337fe5e1 Remove unnecessary code piece 2019-11-24 19:47:20 +01:00
Matthias
50350a09cd use wallets instead of doing a direct call to /balance 2019-11-24 19:41:51 +01:00
Matthias
1bf8d8cff3 show /balance in stake currency 2019-11-24 19:30:09 +01:00
Matthias
62d50f512d add tests for balance from get-tickers 2019-11-24 19:30:09 +01:00
Matthias
8c64be3cfd get tickers only once to show balance 2019-11-24 19:22:43 +01:00
hroff-1902
cc0a733f1f Merge pull request #2565 from freqtrade/pairlists_transition
Pairlists transition
2019-11-24 15:26:01 +03:00
hroff-1902
1b645d64c8 Merge pull request #2538 from freqtrade/strategy_template
new-strategy / new-hyperopt - from templates
2019-11-24 15:21:23 +03:00
Matthias
a374df7622 some minor fixes from feedback 2019-11-24 09:55:34 +01:00
Matthias
cbf710a4f8 Fix coveralls (?) 2019-11-24 09:50:31 +01:00
Matthias
f05818a86e Allow transition from "no-config"-pairlist to pairlists 2019-11-24 09:49:29 +01:00
hroff-1902
cab748588c Merge pull request #2566 from freqtrade/actions_again
reenable slack
2019-11-23 22:50:46 +03:00
Matthias
63ad95a474 reenable slack 2019-11-23 20:20:34 +01:00
Matthias
e9da4d8505 Merge pull request #2563 from hroff-1902/hyperopt-save
Hyperopt: Save epochs at intermediate points
2019-11-23 19:25:35 +01:00
hroff-1902
26a2292f6d Merge pull request #2564 from freqtrade/plots_plot
[minor] Adjust plotting test to match user_data folder
2019-11-23 21:07:46 +03:00
Matthias
5fb14e769b Adjust folder to match user_data folder - otherwise running tests
creates this folder
2019-11-23 14:52:44 +01:00
Matthias
c7c7a1c2aa skip test due to no journald installed 2019-11-23 14:27:23 +01:00
Matthias
1242263d25 Make test OS dependent 2019-11-23 14:20:41 +01:00
Matthias
31c598f88a Add tests for advanced logging setup 2019-11-23 14:12:27 +01:00
hroff-1902
6cb4830534 Testcase added 2019-11-23 12:30:49 +03:00
hroff-1902
067267f4cf Log messages improved (plural/singular) 2019-11-23 12:20:41 +03:00
hroff-1902
99db53417c Tests adjusted 2019-11-23 12:00:43 +03:00
hroff-1902
737c07c5b6 Make mypy happy 2019-11-23 11:51:52 +03:00
hroff-1902
097cdcb57a Save epochs at intermediate points 2019-11-23 11:32:33 +03:00
hroff-1902
175591e524 Fix test 2019-11-23 04:03:47 +03:00
hroff-1902
e7ddd81251 Merge branch 'develop' into hyperopt-trailing-space 2019-11-23 03:42:58 +03:00
hroff-1902
a183162d8b Add description into Advanced Setup section 2019-11-23 03:37:29 +03:00
Matthias
a6bb7595e8 Update utils doc 2019-11-22 13:44:50 +01:00
Matthias
210d468a9b Reinstate mfi ... 2019-11-21 20:01:08 +01:00
Matthias
5f8fcebb88 Parametrize hyperopt file 2019-11-21 19:49:04 +01:00
Matthias
f23f659ac5 Use strings instead of subtemplates 2019-11-21 19:28:53 +01:00
Matthias
99eeb2e605 Merge pull request #2560 from hroff-1902/fix-informative
minor: Fix second part of freqtrade-strategies #51
2019-11-21 11:06:15 +01:00
hroff-1902
f26171082c Merge pull request #2552 from xmatthias/ci/coveralls
FIx failure for PR's from forked repositories
2019-11-21 12:15:32 +03:00
hroff-1902
2acd2542ac Merge pull request #2559 from freqtrade/fix/cancelordercrash
Fix 'remaining' bug when handling buy timeout
2019-11-21 12:09:43 +03:00
Matthias
f26c40082d Allow selection of templates for strategy 2019-11-21 07:21:19 +01:00
Matthias
b3dbb81838 Add subtemplates 2019-11-21 07:13:56 +01:00
Matthias
5e5ef21f61 Align example imports 2019-11-21 06:49:16 +01:00
Matthias
be4a4180ae Use single line comments for samples 2019-11-21 06:40:30 +01:00
Matthias
f7322358cf Update documentation 2019-11-21 06:32:45 +01:00
Matthias
671b98ecad Fix windows test 2019-11-21 06:32:45 +01:00
Matthias
ed04f7f39d Create userdir and backtest SampleStrategy 2019-11-21 06:32:45 +01:00
Matthias
cbb187e9b9 Use constant for Strategy and hyperopt userdirpaths 2019-11-21 06:32:45 +01:00
Matthias
03cdfe8cae Add tests for new-hyperopt 2019-11-21 06:32:45 +01:00
Matthias
37f8139432 Small stylistic fixes 2019-11-21 06:32:45 +01:00
Matthias
79891671e9 Adapt after rebase 2019-11-21 06:32:45 +01:00
Matthias
65489c894d Add no-arg test 2019-11-21 06:32:45 +01:00
Matthias
b36a1d3260 test new_stratgy 2019-11-21 06:32:45 +01:00
Matthias
8a1d02e185 Update numpy imports in sample strategies 2019-11-21 06:32:45 +01:00
Matthias
8c2ff2f46e Add template for new-hyperopt command 2019-11-21 06:32:45 +01:00
Matthias
e492d47621 Disallow usage of DefaultStrategy 2019-11-21 06:32:45 +01:00
Matthias
98baae9456 Add jinja2 to requirements 2019-11-21 06:32:45 +01:00
Matthias
e3cf6188a1 Add first version of new-strategy generation from template 2019-11-21 06:32:45 +01:00
Matthias
8cf8ab089e Add note about create-datadir to install instruction 2019-11-21 06:32:45 +01:00
Matthias
ed1d450099 Update documentation for create-userdir util 2019-11-21 06:32:45 +01:00
Matthias
41494f28da Allow resetting of the directory 2019-11-21 06:32:45 +01:00
Matthias
19b1a6c638 create-userdir should create the notebooks folder, too 2019-11-21 06:32:45 +01:00
Matthias
471bd4d889 Small stylistic fixes 2019-11-21 06:32:45 +01:00
Matthias
084efc98d7 Address test-failures due to file moves 2019-11-21 06:32:45 +01:00
Matthias
1d2ef5c2ce Extract directory_operation tests to it's own test file 2019-11-21 06:32:45 +01:00
Matthias
fd45ebd0e9 Copy templates when creating userdir 2019-11-21 06:32:45 +01:00
Matthias
258d4bd6ae move sample-files from user_data to templates folder 2019-11-21 06:32:45 +01:00
hroff-1902
b8aa727edf Fix second part of freqtrade-strategies #51 2019-11-21 05:10:48 +03:00
Matthias
eac01960a7 Add testcase for empty-order case 2019-11-20 20:37:46 +01:00
Matthias
a5bd4e329a improve cancel_order handling 2019-11-20 20:36:38 +01:00
hroff-1902
5ce665f279 Merge pull request #2540 from freqtrade/rpc/fixes
Improve rest api client / status response
2019-11-20 22:18:51 +03:00
Matthias
9aac080414 Fix 'remaining' bug when handling buy timeout 2019-11-20 20:10:41 +01:00
Matthias
8b639b5026 Remove only :return: 2019-11-20 19:54:16 +01:00
Matthias
7f119a28e7 Merge pull request #2557 from freqtrade/hroff-1902-patch-1
minor: Add example of usage for Aroon, Aroon Oscillator
2019-11-20 19:39:49 +01:00
hroff-1902
5f88c4aad9 Add example of usage for Aroon, Aroon Oscillator 2019-11-20 19:31:30 +03:00
hroff-1902
dfe3d78767 Merge pull request #2541 from freqtrade/rpc/show_config
[Rpc] - show config
2019-11-20 18:42:41 +03:00
hroff-1902
633996216a Improve commands help list 2019-11-20 15:25:56 +03:00
Matthias
09b302abf7 Merge pull request #2442 from freqtrade/volumeList_enhanced_filter
Pairlists enhanced filter options
2019-11-19 20:19:10 +01:00
Matthias
c92f233c15 Move settings to correct location 2019-11-19 19:33:04 +01:00
Matthias
751157b4ea Don't notify on builds from forks
they don't have secrets available ATM
2019-11-19 12:20:21 +01:00
Matthias
5f62a9e4d8 rename ttl to refresh_period 2019-11-19 06:50:23 +01:00
Matthias
a8855bf795 rename LowPriceFilter to PrieFilter 2019-11-19 06:49:45 +01:00
Matthias
c22b00b303 move pairlist filters out of config[] 2019-11-19 06:37:06 +01:00
Matthias
67c5115b41 Merge pull request #2545 from freqtrade/dependabot/pip/develop/plotly-4.3.0
Bump plotly from 4.2.1 to 4.3.0
2019-11-18 09:45:16 +01:00
Matthias
ab4b1cc8fe Merge pull request #2550 from freqtrade/dependabot/pip/develop/ccxt-1.19.54
Bump ccxt from 1.19.25 to 1.19.54
2019-11-18 09:39:34 +01:00
Matthias
716785c65f Merge pull request #2546 from freqtrade/dependabot/pip/develop/pytest-5.2.4
Bump pytest from 5.2.2 to 5.2.4
2019-11-18 09:39:16 +01:00
Matthias
baa7fd6c79 Merge pull request #2549 from freqtrade/dependabot/pip/develop/mkdocs-material-4.5.0
Bump mkdocs-material from 4.4.3 to 4.5.0
2019-11-18 09:38:33 +01:00
Matthias
9045f796e0 Merge pull request #2548 from freqtrade/dependabot/pip/develop/tabulate-0.8.6
Bump tabulate from 0.8.5 to 0.8.6
2019-11-18 09:38:21 +01:00
Matthias
988c1744af Merge pull request #2547 from freqtrade/dependabot/pip/develop/python-rapidjson-0.9.1
Bump python-rapidjson from 0.8.0 to 0.9.1
2019-11-18 09:38:01 +01:00
dependabot-preview[bot]
cd6d276119 Bump pytest from 5.2.2 to 5.2.4
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.2.2 to 5.2.4.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.2.2...5.2.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:42:57 +00:00
Matthias
d085a2bd3e Merge pull request #2544 from freqtrade/dependabot/pip/develop/flake8-tidy-imports-3.1.0
Bump flake8-tidy-imports from 3.0.0 to 3.1.0
2019-11-18 08:41:42 +01:00
dependabot-preview[bot]
dddccf8f1a Bump ccxt from 1.19.25 to 1.19.54
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.19.25 to 1.19.54.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.19.25...1.19.54)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:39:12 +00:00
Matthias
8b3fb3d6d5 Merge pull request #2543 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.11
Bump sqlalchemy from 1.3.10 to 1.3.11
2019-11-18 08:37:43 +01:00
Matthias
80b450d4e6 Merge pull request #2542 from freqtrade/dependabot/pip/develop/urllib3-1.25.7
Bump urllib3 from 1.25.6 to 1.25.7
2019-11-18 08:30:02 +01:00
dependabot-preview[bot]
0bc71403ff Bump mkdocs-material from 4.4.3 to 4.5.0
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 4.4.3 to 4.5.0.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/4.4.3...4.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:24:39 +00:00
dependabot-preview[bot]
cb6b3e17a9 Bump tabulate from 0.8.5 to 0.8.6
Bumps [tabulate](https://github.com/astanin/python-tabulate) from 0.8.5 to 0.8.6.
- [Release notes](https://github.com/astanin/python-tabulate/releases)
- [Changelog](https://github.com/astanin/python-tabulate/blob/master/CHANGELOG)
- [Commits](https://github.com/astanin/python-tabulate/compare/v0.8.5...v0.8.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:22:41 +00:00
dependabot-preview[bot]
e7157faddd Bump python-rapidjson from 0.8.0 to 0.9.1
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 0.8.0 to 0.9.1.
- [Release notes](https://github.com/python-rapidjson/python-rapidjson/releases)
- [Changelog](https://github.com/python-rapidjson/python-rapidjson/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-rapidjson/python-rapidjson/compare/v0.8.0...v0.9.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:22:18 +00:00
dependabot-preview[bot]
a33d408780 Bump plotly from 4.2.1 to 4.3.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.2.1 to 4.3.0.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.2.1...v4.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:21:25 +00:00
dependabot-preview[bot]
42474b7144 Bump flake8-tidy-imports from 3.0.0 to 3.1.0
Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases)
- [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/master/HISTORY.rst)
- [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/3.0.0...3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:20:50 +00:00
dependabot-preview[bot]
933564591d Bump sqlalchemy from 1.3.10 to 1.3.11
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.10 to 1.3.11.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/master/CHANGES)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:20:30 +00:00
dependabot-preview[bot]
599e18b920 Bump urllib3 from 1.25.6 to 1.25.7
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.6 to 1.25.7.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/master/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.25.6...1.25.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 07:20:02 +00:00
Matthias
547d65b065 Fix broken test 2019-11-17 15:22:44 +01:00
Matthias
e4e8a611be Add tests for telegram 2019-11-17 15:13:24 +01:00
Matthias
2b190e5638 Add documentation 2019-11-17 15:05:56 +01:00
Matthias
acab56793f Add /show_config to telegram 2019-11-17 15:03:45 +01:00
Matthias
2c976bdd24 Add show_config endpoint 2019-11-17 15:03:38 +01:00
Matthias
3aee8d2b2a Improve rest api client / status response 2019-11-17 14:40:59 +01:00
hroff-1902
841c379797 Merge pull request #2539 from freqtrade/seperate_docs_ci
seperate docs job
2019-11-17 13:20:21 +03:00
Matthias
b6a12044ba seperate docs job 2019-11-17 10:38:16 +01:00
hroff-1902
8e087cb639 Merge pull request #2535 from freqtrade/fix/quitting
Fix non-terminating bot
2019-11-17 01:15:59 +03:00
hroff-1902
bcb5913291 Merge pull request #2536 from freqtrade/coveralls_actions
Try moving coveralls to github actions
2019-11-16 23:05:05 +03:00
Matthias
be53c0885d Try moving coveralls to github actions 2019-11-16 15:53:45 +01:00
Matthias
91047830fd Add tst for worker termination 2019-11-16 09:56:16 +01:00
Matthias
6e0655b3b7 add empty worker variable 2019-11-16 09:47:56 +01:00
Matthias
edc0d7f2c7 Fix non-terminating bot 2019-11-15 20:10:17 +01:00
Matthias
1d18e0a11a Merge pull request #2518 from freqtrade/github_actions_tests
Move freqtrade CI to github actions
2019-11-15 06:58:12 +01:00
Matthias
b167fb071a fix windows test 2019-11-14 08:44:10 +01:00
Matthias
3b9899dfd4 hyperopts ... 2019-11-14 07:06:00 +01:00
Matthias
f94d46316e update checkout action to pinned version 2019-11-14 06:51:02 +01:00
Matthias
569a547b3f Update Actions CI to new subcommands 2019-11-14 06:49:21 +01:00
Matthias
6c306c0013 Merge branch 'develop' into github_actions_tests 2019-11-14 06:45:14 +01:00
Matthias
9b050523e9 Merge pull request #2397 from freqtrade/feat/new_args_system
require subcommand for all actions
2019-11-14 06:28:42 +01:00
hroff-1902
f9a92c2879 Adjust test 2019-11-13 23:32:37 +03:00
hroff-1902
ab194c7d75 Add test 2019-11-13 23:09:05 +03:00
hroff-1902
904a9c5dc7 Merge pull request #2527 from freqtrade/fix/openorder_plotprofit
plot-profit script fails in certain conditions
2019-11-13 22:58:44 +03:00
Matthias
38243c52fd Filter open trades - they are not added to the profit calc 2019-11-13 20:46:21 +01:00
Matthias
c8c48156dd Don't load trades twice ... 2019-11-13 20:44:55 +01:00
hroff-1902
f4d18034d9 Merge pull request #2523 from freqtrade/timeout_handling
Improve timedout handling
2019-11-13 22:25:58 +03:00
Matthias
17c11b2afa Merge pull request #2525 from hroff-1902/exchange-bibox
Add fix for bibox exchange
2019-11-13 19:52:50 +01:00
Matthias
68904296e7 Allow timeout of 0 2019-11-13 19:38:38 +01:00
Matthias
d4499338e0 Merge pull request #2519 from freqtrade/actions_test
Update dockerhub description from github readme.md
2019-11-13 19:30:36 +01:00
hroff-1902
6174a5dd55 Reimplement adjustment of ccxt 'has' with more generic ccxt_config class attribute 2019-11-13 20:22:23 +03:00
hroff-1902
e26bbc7de8 Add fix for bibox exchange 2019-11-13 19:50:54 +03:00
Matthias
62c1ff776e update action to 2.1.0 2019-11-13 13:59:38 +01:00
hroff-1902
baea06eac7 Merge pull request #2522 from freqtrade/replace_tickerinterval
Replace tickerinterval
2019-11-13 13:50:07 +03:00
Matthias
6ac73f7cde Update missed strings 2019-11-13 11:28:26 +01:00
Matthias
66619204ba re-add hyperopts multiple ... 2019-11-13 11:13:48 +01:00
hroff-1902
1d7fb2ffac Merge pull request #2521 from freqtrade/rpc/status_table
Add fiat to status table
2019-11-13 13:10:18 +03:00
Matthias
c42c5a1f85 Adjust "requires subcommand" message 2019-11-13 10:03:59 +01:00
Matthias
5b62ad876e Remove hyperopts occurances 2019-11-13 09:39:00 +01:00
hroff-1902
ec460ab9c9 Merge pull request #2520 from freqtrade/fix/randomtestfailure
[minor] Add sleep to allow thread to start
2019-11-13 00:35:04 +03:00
Matthias
2eb6513251 Improve timedout handling 2019-11-12 15:45:14 +01:00
Matthias
c449e39280 Replace more occurances of ticker_interval 2019-11-12 15:13:06 +01:00
Matthias
1c57a4ac35 more replacements of ticker_interval 2019-11-12 15:13:06 +01:00
Matthias
334ac8b10c Adapt documentation for timeframe 2019-11-12 15:13:06 +01:00
Matthias
d801dec6aa Some more places with ticker_interval gone 2019-11-12 15:13:06 +01:00
Matthias
08aedc18e1 Exchange ticker_interval with timeframe in some more places 2019-11-12 15:13:06 +01:00
Matthias
e4bdb92521 Replace some occurances of ticker_interval with timeframe 2019-11-12 15:13:06 +01:00
Matthias
11f7ab61b9 Remove decimal import from rpc 2019-11-12 15:11:31 +01:00
Matthias
df9bfb6c2e Add FIAT currency to status-table 2019-11-12 14:58:41 +01:00
Matthias
ab9506df48 simplify status_table command 2019-11-12 13:55:18 +01:00
Matthias
136ef077b2 Add sleep to allow thread to start 2019-11-12 13:14:43 +01:00
Matthias
e8a8f416f3 Update dockerhub description from github readme.md 2019-11-12 11:04:03 +01:00
Matthias
8c76f45030 Use correct dockerhub image name 2019-11-12 10:54:38 +01:00
Matthias
96f550c6aa Disable tests 2019-11-12 10:35:36 +01:00
Matthias
37ef5c38f0 integrate Slack notification 2019-11-12 10:33:49 +01:00
Matthias
66a273b31b Merge branch 'develop' into volumeList_enhanced_filter 2019-11-12 09:31:46 +01:00
Matthias
52e24c3a25 Split error-messsage between incompatible and wrong stake amount 2019-11-12 09:27:53 +01:00
Matthias
7a2d917c66 Merge pull request #2516 from freqtrade/hroff-1902-patch-1
minor: Fix typo in the rest-api docs
2019-11-12 06:35:26 +01:00
hroff-1902
025350ebff Fix typo in the rest-api docs 2019-11-12 00:07:27 +03:00
hroff-1902
411e035005 Merge pull request #2514 from freqtrade/pong
Add ping endpoing
2019-11-11 22:42:32 +03:00
Matthias
800997437a Update documentation 2019-11-11 20:25:44 +01:00
Matthias
75d5ff69ef Add ping endpoing 2019-11-11 20:10:56 +01:00
Matthias
a241c2af0d Build macos - ... 2019-11-11 19:42:05 +01:00
Matthias
d1729a624d fix windows build 2019-11-11 19:37:22 +01:00
Matthias
e51a720193 Apply cache to pi image 2019-11-11 19:37:18 +01:00
Matthias
ff1d36434d Add github actions action 2019-11-11 19:37:10 +01:00
Matthias
904ae5af91 Merge pull request #2512 from freqtrade/dependabot/pip/develop/numpy-1.17.4
Bump numpy from 1.17.3 to 1.17.4
2019-11-11 14:24:40 +01:00
Matthias
42e8e1c16a Merge pull request #2511 from freqtrade/dependabot/pip/develop/scipy-1.3.2
Bump scipy from 1.3.1 to 1.3.2
2019-11-11 11:41:58 +01:00
Matthias
9fb493d2f4 Merge pull request #2510 from freqtrade/dependabot/pip/develop/ccxt-1.19.25
Bump ccxt from 1.19.14 to 1.19.25
2019-11-11 11:27:43 +01:00
dependabot-preview[bot]
031157f215 Bump numpy from 1.17.3 to 1.17.4
Bumps [numpy](https://github.com/numpy/numpy) from 1.17.3 to 1.17.4.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.17.3...v1.17.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-11 10:20:30 +00:00
dependabot-preview[bot]
c65d217d1e Bump scipy from 1.3.1 to 1.3.2
Bumps [scipy](https://github.com/scipy/scipy) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.3.1...v1.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-11 10:19:36 +00:00
dependabot-preview[bot]
0a13f7e1c7 Bump ccxt from 1.19.14 to 1.19.25
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.19.14 to 1.19.25.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.19.14...1.19.25)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-11 10:18:58 +00:00
Matthias
173375de7c Merge pull request #2508 from freqtrade/hroff-1902-patch-1
minor: More cosmetics on Exchange Notes
2019-11-11 10:39:20 +01:00
hroff-1902
27d81bb68c minor: More cosmetics on Exchange Notes 2019-11-11 12:23:24 +03:00
Matthias
044105e8e0 Merge pull request #2507 from freqtrade/hroff-1902-patch-3
minor: Exchange notes docs
2019-11-11 10:11:46 +01:00
Matthias
48f8a62335 Merge pull request #2506 from freqtrade/hroff-1902-patch-1
minor: Fix link in the Faq docs
2019-11-11 09:59:52 +01:00
Matthias
71f99ba79c Merge pull request #2504 from freqtrade/hroff-1902-patch-2
Minor: Exchange notes typographical cosmetics
2019-11-11 09:59:09 +01:00
hroff-1902
95492958f9 wordings 2019-11-11 11:37:57 +03:00
hroff-1902
661c8251c5 minor: Exchange notes docs
* Formatting (structure of sections)
* Cosmetic changes

This was not noticed in terms of #2505
2019-11-11 11:23:29 +03:00
hroff-1902
83067c1edc minor: Fix link in the Faq docs 2019-11-11 11:18:43 +03:00
hroff-1902
c5ed004c9e Merge pull request #2505 from freqtrade/bittrex_restricted_markets
Add restricted markets snippet to documentation
2019-11-11 11:13:47 +03:00
Matthias
04b51a982e Include warning-message to bittrex explanation 2019-11-11 08:55:37 +01:00
Matthias
e810597eec Add restricted markets snippet to documentation 2019-11-11 07:16:35 +01:00
hroff-1902
692d6afbd9 Minor exchange notes typographical cosmetics 2019-11-11 02:17:41 +03:00
hroff-1902
59fa02e11a Merge pull request #2499 from freqtrade/hroff-1902-patch-1
minor: Wordings on top of #2495
2019-11-11 01:27:43 +03:00
hroff-1902
6ef6a24841 Merge pull request #2501 from freqtrade/readme_small_work
[docs] Add seperate exchange section in docs
2019-11-11 01:14:16 +03:00
Matthias
eba55c2783 Change link 2019-11-10 19:31:13 +01:00
Matthias
085aa3084e Implement ticker caching 2019-11-09 19:45:09 +01:00
Matthias
de2d04f06b Add note about systemd load location
closes #2461
2019-11-09 16:24:24 +01:00
Matthias
12654cb810 Add seperate exchange section in docs 2019-11-09 16:19:58 +01:00
Matthias
4b15873ee1 Simplify examples 2019-11-09 15:41:51 +01:00
Matthias
748fe94603 Merge branch 'develop' into volumeList_enhanced_filter 2019-11-09 15:34:47 +01:00
Matthias
86a5dfa62e Update documentation 2019-11-09 15:28:36 +01:00
Matthias
0b4800835c update documentation 2019-11-09 15:28:03 +01:00
Matthias
5caeca7509 Improve tests for pairlist-sequence behaviour 2019-11-09 15:23:36 +01:00
Matthias
7ff61f12e9 pass pairlist position into the pairlists 2019-11-09 15:04:04 +01:00
Matthias
ae35649366 improve pairlistmanager errorhandling 2019-11-09 14:49:41 +01:00
Matthias
a01b34a004 tests 2019-11-09 14:44:39 +01:00
Matthias
02b9da8aba Update documentation 2019-11-09 14:39:28 +01:00
Matthias
ed0c7a6aaf Update configschema to fit new pairlists approach 2019-11-09 14:16:11 +01:00
Matthias
25cb935eee Some more adjustments for new pairlist 2019-11-09 14:16:03 +01:00
Matthias
c74d766275 move from name to name_list 2019-11-09 14:00:32 +01:00
Matthias
37985310d5 remove cachetools dependency 2019-11-09 13:59:35 +01:00
Matthias
c3b4a4dde1 Update sample configurations 2019-11-09 13:59:19 +01:00
Matthias
d7262c0b4e Fix correct ticker type 2019-11-09 13:40:36 +01:00
Matthias
870966dcd0 Fix more tests 2019-11-09 09:42:34 +01:00
Matthias
85beb3b6a9 Fix test 2019-11-09 09:31:17 +01:00
Matthias
bf69b055eb Add name getting 2019-11-09 09:07:46 +01:00
Matthias
31c7189b8b Verify blacklist correctly 2019-11-09 07:23:34 +01:00
Matthias
eaf3fd80c5 Allow blacklist-verification from all pairlists 2019-11-09 07:19:46 +01:00
Matthias
1059586226 Small adjustments 2019-11-09 07:07:33 +01:00
Matthias
b610e8c7e6 Don't refresh tickers if they are not needed 2019-11-09 07:05:17 +01:00
Matthias
e632720c02 Allow chaining of pairlists 2019-11-09 06:55:16 +01:00
hroff-1902
1f042f5e32 Quick start and easy installation sections reworked 2019-11-08 19:38:32 +03:00
hroff-1902
54b63e89f8 Wordings on top of #2495 2019-11-08 17:32:18 +03:00
Matthias
3f65c31883 Merge pull request #2495 from gaugau3000/prepare_reorg_install_doc
Prepare reorg install doc : explain differences between master and develop
2019-11-08 14:43:27 +01:00
hroff-1902
31ab32f0b9 Always set trailing_stop=True with 'trailing' hyperspace 2019-11-08 12:47:28 +03:00
Gautier Pialat
bc5c91f681 add missing note block 2019-11-08 10:29:00 +01:00
Gautier Pialat
076ef0407b git branch note explanation 2019-11-08 09:39:06 +01:00
Gautier Pialat
b0150d548a remove not use statement 2019-11-08 09:37:54 +01:00
hroff-1902
60acbc97ab Merge pull request #2494 from freqtrade/fix/timezone_timestamp
Fix UTC handling of timestamp() conversation in fetch_my_trades
2019-11-08 11:33:47 +03:00
Matthias
dd47bd04cd Move description to correct place 2019-11-08 01:32:08 -05:00
Matthias
da57396d07 Fix UTC handling of timestamp() conversation in fetch_my_trades 2019-11-08 06:55:07 +01:00
hroff-1902
d3a3765819 Fix test 2019-11-08 03:48:08 +03:00
hroff-1902
f90676cfc5 Add trailing stoploss hyperspace 2019-11-08 03:07:43 +03:00
Matthias
ad2289c34c Merge pull request #2488 from freqtrade/hyperopt_specialchar
[minor] Fix UnicodeError in hyperopt output
2019-11-07 06:18:15 +01:00
Matthias
ca77dbe8da Fix UnicodeError in hyperopt output 2019-11-06 19:33:15 +01:00
Matthias
6c6efd7214 Merge pull request #2481 from freqtrade/dependabot/pip/develop/ccxt-1.19.14
Bump ccxt from 1.18.1346 to 1.19.14
2019-11-06 10:13:46 +01:00
Matthias
7f099d41fa Merge pull request #2484 from freqtrade/dependabot/pip/develop/pandas-0.25.3
Bump pandas from 0.25.2 to 0.25.3
2019-11-06 10:13:31 +01:00
dependabot-preview[bot]
60109aaa1f Bump ccxt from 1.18.1346 to 1.19.14
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.18.1346 to 1.19.14.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.18.1346...1.19.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-06 08:37:38 +00:00
Matthias
ef057c16cb Merge pull request #2483 from freqtrade/dependabot/pip/develop/flake8-3.7.9
Bump flake8 from 3.7.8 to 3.7.9
2019-11-06 09:36:43 +01:00
Matthias
39e728a7c2 Merge pull request #2482 from freqtrade/dependabot/pip/develop/arrow-0.15.4
Bump arrow from 0.15.2 to 0.15.4
2019-11-06 09:36:18 +01:00
dependabot-preview[bot]
28f0c00281 Bump pandas from 0.25.2 to 0.25.3
Bumps [pandas](https://github.com/pandas-dev/pandas) from 0.25.2 to 0.25.3.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/master/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v0.25.2...v0.25.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-06 07:21:55 +00:00
dependabot-preview[bot]
bc78316aa5 Bump flake8 from 3.7.8 to 3.7.9
Bumps [flake8](https://gitlab.com/pycqa/flake8) from 3.7.8 to 3.7.9.
- [Release notes](https://gitlab.com/pycqa/flake8/tags)
- [Commits](https://gitlab.com/pycqa/flake8/compare/3.7.8...3.7.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-06 07:21:39 +00:00
dependabot-preview[bot]
b8a6c55b10 Bump arrow from 0.15.2 to 0.15.4
Bumps [arrow](https://github.com/crsmithdev/arrow) from 0.15.2 to 0.15.4.
- [Release notes](https://github.com/crsmithdev/arrow/releases)
- [Changelog](https://github.com/crsmithdev/arrow/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/crsmithdev/arrow/compare/0.15.2...0.15.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-06 07:21:09 +00:00
Matthias
6df1dd1ef2 Merge pull request #2479 from freqtrade/fix/bids_to_delta
Fix bug where bids_to_ask_delta causes doublebuys
2019-11-05 21:14:26 +01:00
Matthias
c8638ce82f Fix bug where bids_to_ask_delta causes doublebuys
The continue must happen irrespective of the outcome of this - otherwise
the below BUY will happen anyway.
2019-11-05 21:03:06 +01:00
Matthias
1a61d89bcc Merge pull request #2476 from freqtrade/unify_key_removal
Introduce remove_credentials to remove code duplication
2019-11-05 19:34:23 +01:00
Matthias
eb0b0350e0 Introduce remove_credentials to remove code duplication 2019-11-05 12:39:19 +01:00
Matthias
4ec7fcd836 Merge pull request #2475 from gaugau3000/docker_doc_update
Update docker doc (new note about restart policy)
2019-11-05 12:32:23 +01:00
Gautier Pialat
f6a66cd3de Fix typo 2019-11-05 12:14:39 +01:00
Gautier Pialat
871019c8b9 docker doc update about restart policy 2019-11-05 12:08:57 +01:00
hroff-1902
581907305a Merge pull request #2467 from freqtrade/check_exchange_other
Don't check exchange for Utils commands
2019-11-04 19:28:07 +03:00
hroff-1902
54b0fbca59 Merge pull request #2468 from freqtrade/fix_pandas_wraning
Fix pandas access warning
2019-11-04 15:32:05 +03:00
Matthias
1e44f93c31 Fix pandas access warning 2019-11-03 10:58:31 +01:00
Matthias
3eca80217c Don't check exchange for Utils commands 2019-11-03 10:18:46 +01:00
Matthias
6f01d7f8ea Merge branch 'develop' into feat/new_args_system 2019-11-03 10:09:49 +01:00
Matthias
500d16620b Merge pull request #2465 from freqtrade/hyperopt_populate_from_strategy
Hyperopt populate from strategy
2019-11-03 10:03:33 +01:00
Matthias
6550e1fa99 Change docstring in sampleHyperopt 2019-11-03 09:55:38 +01:00
Matthias
80ad37ad93 Updated plot_indicators test 2019-11-02 14:17:15 +01:00
Matthias
3287cdd47a Improve documentation regarding loading methods from hyperopt 2019-11-02 13:01:42 +01:00
Matthias
12e86ee4bd Make travis test-hyperopt the sample strategy 2019-11-02 11:12:08 +01:00
Matthias
97d0f93d3c Align samples (hyperopt and strategy) to work together 2019-11-02 11:11:13 +01:00
Matthias
861f10dca6 Allow populate-indicators to come from strategy 2019-11-02 11:10:33 +01:00
Matthias
2a1385f94b Merge pull request #2462 from freqtrade/hroff-1902-patch-1
Update faq with examples of grepping the log
2019-11-02 06:47:15 +01:00
hroff-1902
e9af6b393f Fix typo 2019-11-02 02:32:57 +03:00
hroff-1902
2124661cee Update faq with examples of grepping the log 2019-11-02 02:22:58 +03:00
hroff-1902
e8a08011be Merge pull request #2460 from freqtrade/new_runmodes
[minor] Add new runmodes
2019-11-01 21:40:23 +03:00
Matthias
691cec7956 Be more selective which startup-messages are shown 2019-11-01 16:42:57 +01:00
Matthias
241d947564 Add new runmodes 2019-11-01 15:39:49 +01:00
Matthias
880834b902 Merge pull request #2446 from hroff-1902/log-stderr
Log to stderr
2019-11-01 06:14:55 +01:00
hroff-1902
f435384bf0 Merge pull request #2451 from freqtrade/bt_analysis_maxopen
Bt analysis maxopen at any time
2019-11-01 00:13:31 +03:00
hroff-1902
3149c12a14 Merge pull request #2444 from freqtrade/sql_cleanup
Fix scoped_session and add Documentation for strategy
2019-10-31 23:19:30 +03:00
hroff-1902
6a9a2e7f88 Merge pull request #2452 from freqtrade/fix/1717
Allow configuration of stoploss on exchange limit
2019-10-31 23:13:37 +03:00
hroff-1902
5b87393a95 Merge pull request #2457 from freqtrade/integration_tests
split up test_freqtradebot.py
2019-10-31 22:05:03 +03:00
Matthias
5a27b10579 Merge pull request #2450 from freqtrade/rpi_docs
[docs] Update Raspberry documentation
2019-10-31 13:30:45 +01:00
Matthias
a80e49bd81 Change level of rpi header 2019-10-31 12:49:41 +01:00
hroff-1902
ffed13b979 Merge pull request #2455 from freqtrade/reduce_startup_indicator_logfrequency
[minor][log]Reduce frequency of "startup-period" message
2019-10-31 13:10:16 +03:00
hroff-1902
9f0f1096e1 Merge pull request #2459 from freqtrade/exchange_helpers
Move exchange-constants and retriers to exchange.common
2019-10-31 13:09:01 +03:00
Matthias
9a42afe0be Move exchange-constants and retriers to exchange.common 2019-10-31 10:59:17 +01:00
Matthias
b6616d7a13 Add test helping debug #1985 2019-10-31 10:04:28 +01:00
Matthias
7be378aaa9 Remove markets mock where it's not needed 2019-10-31 07:26:48 +01:00
Matthias
734a9d5d87 Seperate tests related to worker from test_freqtradebot 2019-10-31 07:16:25 +01:00
Matthias
ce6b869f84 Cleanup test 2019-10-31 07:11:57 +01:00
Matthias
dc5f1b2878 Extract integration tests into sepearte file 2019-10-31 07:08:02 +01:00
hroff-1902
a041b8bf72 Merge remote-tracking branch 'upstream/develop' into log-stderr 2019-10-31 09:07:07 +03:00
hroff-1902
4fa12ffda0 Merge pull request #2454 from freqtrade/release_docs
[minor][docs] Update release-documentation to fit new release style
2019-10-31 09:02:55 +03:00
Matthias
5dcf28cafb Reduce frequency of "startup-period" message 2019-10-31 06:57:37 +01:00
Matthias
365a408df5 Update release-documentation to fit new release style 2019-10-31 06:43:42 +01:00
Matthias
9e988783de Allow configuration of stoploss on exchange limit
fixes #1717
2019-10-30 20:07:26 +01:00
Matthias
bba8e61409 Rename function in samples 2019-10-30 20:05:44 +01:00
Matthias
dee9b84322 Merge branch 'develop' into volumeList_enhanced_filter 2019-10-30 16:41:17 +01:00
Matthias
ad98d61939 Update developer docs 2019-10-30 16:39:45 +01:00
Matthias
14758dbe10 Some small cleanups 2019-10-30 16:32:22 +01:00
Matthias
d89a7d5235 Document new method to configure filters 2019-10-30 16:30:47 +01:00
Matthias
640423c362 Add config samples for chainable pairlist filters 2019-10-30 16:02:24 +01:00
Matthias
fd9c02603c Introduce chainable PairlistFilters 2019-10-30 15:59:52 +01:00
Matthias
44289e4c58 Allow not using files from user_dir 2019-10-30 15:57:08 +01:00
Matthias
6928c685a8 Add documentation sample for parallel_trade_analysis 2019-10-30 14:12:41 +01:00
Matthias
dd408aa5d6 Add analyze_trade_parallelism analysis function 2019-10-30 14:07:23 +01:00
Matthias
dac88c6aed extract Find parallel trades per interval 2019-10-30 13:35:55 +01:00
Matthias
78fe5a46c1 Update travis to verify for correct title usage 2019-10-30 13:27:36 +01:00
Matthias
7a96d3c9ae Update raspbian install documentation
Fix "box" titles ... they need to be in quotes!
2019-10-30 13:27:04 +01:00
Matthias
b7b1e66c6e Convert to % as part of RPC to allow users to use unrounded ratio 2019-10-30 11:12:49 +01:00
Matthias
5ed7771148 Update documentation to include get_trades
fixes #1753
2019-10-30 11:12:49 +01:00
Matthias
c2076d86a4 Use scoped_session as intended 2019-10-30 11:12:49 +01:00
Matthias
b37c5e4878 use get_trades in rpc modules 2019-10-30 11:12:49 +01:00
Matthias
26a5800a7f Extract get_trades function 2019-10-30 11:12:49 +01:00
Matthias
01efebc42f Extract query to it's own function 2019-10-30 11:12:49 +01:00
Matthias
ab117527c9 Refactor get_best_pair to persistence 2019-10-30 11:12:49 +01:00
Matthias
f20f5cebbe Move performance-calculation to persistence 2019-10-30 11:12:49 +01:00
Matthias
0c3a8ddfb9 Merge branch 'develop' into feat/new_args_system 2019-10-30 11:12:27 +01:00
hroff-1902
669a6cf119 Merge pull request #2448 from freqtrade/fix/POWRfailure
Replace coins in whitelist with existing ones
2019-10-30 12:55:45 +03:00
Matthias
6fe7b13e37 Replace coins in whitelist with existing ones 2019-10-30 09:26:08 +01:00
hroff-1902
9c180e587b Log to stderr 2019-10-30 04:04:28 +03:00
Matthias
a368646745 Merge branch 'develop' into feat/new_args_system 2019-10-29 19:33:56 +01:00
Matthias
de2cc58b0c Final cleanups and added tests 2019-10-29 10:44:35 +01:00
Matthias
d803d86f4d Add low_price_percent_filter 2019-10-29 09:32:06 +01:00
hroff-1902
5254059fe4 Merge pull request #2430 from freqtrade/startup_period_bt
Add Startup period for strategies
2019-10-28 23:33:30 +03:00
Matthias
d706571e6f Extract precision_filter to seperate function 2019-10-28 19:41:00 +01:00
hroff-1902
907baea8b2 Merge pull request #2439 from freqtrade/fix/plotprofit
Plot-profit does not work with db file
2019-10-28 21:04:31 +03:00
hroff-1902
062536438e Merge pull request #2433 from freqtrade/docs/stop_positive
[Docs] stoploss documentation improvements
2019-10-28 20:59:56 +03:00
Matthias
4ff035537b Simplify precision_filter code 2019-10-28 16:21:00 +01:00
Matthias
466a3b87fc Enhance tests to cover precision_filter correctly 2019-10-28 16:19:38 +01:00
Matthias
b947f3c2a5 Merge pull request #2417 from freqtrade/whitelist_docs
DynamicPairlist - pair_whitelist
2019-10-28 15:25:17 +01:00
Matthias
069da224bc Add test to verify this is correct 2019-10-28 14:30:01 +01:00
Matthias
e82460bde6 Fix create_cum_profit to work with trades that don't open on candle
opens
2019-10-28 14:24:12 +01:00
Matthias
61c037f2cf Fix some typos and comment mistakes 2019-10-28 13:05:54 +01:00
Matthias
f98290ba6e Merge pull request #2436 from freqtrade/dependabot/pip/develop/pytest-5.2.2
Bump pytest from 5.2.1 to 5.2.2
2019-10-28 13:04:05 +01:00
Matthias
73343b3387 Address feedback 2019-10-28 12:53:12 +01:00
Matthias
3a6020dcd7 small improvements to stoploss doc 2019-10-28 12:43:35 +01:00
dependabot-preview[bot]
596a269dfd Bump pytest from 5.2.1 to 5.2.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.2.1 to 5.2.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/5.2.1...5.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 11:41:44 +00:00
Matthias
7329fce87c Merge pull request #2437 from freqtrade/dependabot/pip/develop/ccxt-1.18.1346
Bump ccxt from 1.18.1306 to 1.18.1346
2019-10-28 12:41:03 +01:00
Matthias
4059116787 Merge pull request #2434 from freqtrade/dependabot/pip/develop/pytest-mock-1.11.2
Bump pytest-mock from 1.11.1 to 1.11.2
2019-10-28 12:40:46 +01:00
Matthias
1561322af2 Merge pull request #2435 from freqtrade/dependabot/pip/develop/nbconvert-5.6.1
Bump nbconvert from 5.6.0 to 5.6.1
2019-10-28 12:40:19 +01:00
dependabot-preview[bot]
44d0a6f2b8 Bump ccxt from 1.18.1306 to 1.18.1346
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.18.1306 to 1.18.1346.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ccxt/ccxt/compare/1.18.1306...1.18.1346)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 07:42:58 +00:00
dependabot-preview[bot]
60b99469b9 Bump nbconvert from 5.6.0 to 5.6.1
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 5.6.0 to 5.6.1.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/5.6.0...5.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 07:40:57 +00:00
dependabot-preview[bot]
46b975a491 Bump pytest-mock from 1.11.1 to 1.11.2
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v1.11.1...v1.11.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-28 07:40:15 +00:00
Matthias
70ad909b16 change samples to python code, and simplify a few things 2019-10-27 19:46:05 +01:00
Matthias
2af3ce3ecc Improve stoploss documentation - split out offset_is_reached 2019-10-27 19:36:00 +01:00
Matthias
132a4da7cf Small style fixes and adjusted tests 2019-10-27 10:56:38 +01:00
Matthias
73f5bff9c5 Add validation to make sure strategies work on that exchange 2019-10-27 10:38:21 +01:00
Matthias
223f0cd4d3 Apply startup_period to edge as well 2019-10-27 10:26:21 +01:00
Matthias
c4cb098d14 Update documentation with indicator_startup_period 2019-10-27 10:26:17 +01:00
Matthias
2bc74882e9 Add test for startup_candles 2019-10-27 10:01:13 +01:00
Matthias
2ba388074e Fix small bugs 2019-10-27 09:44:56 +01:00
Matthias
33164ac78e Refactor loading of bt data to backtesting ... 2019-10-27 09:44:56 +01:00
Matthias
86624411c6 Test trim_dataframe 2019-10-27 09:44:56 +01:00
Matthias
5cdae17d19 Add tests for timerange modifications 2019-10-27 09:44:56 +01:00
Matthias
bd4a23beeb Refactor start-adjust logic to timerange 2019-10-27 09:44:56 +01:00
Matthias
5c2682e2c9 Add startup_candle_count to sample strategy 2019-10-27 09:44:56 +01:00
Matthias
6382a4cd04 Implement startup-period to default-strategy 2019-10-27 09:44:56 +01:00
Matthias
704121c197 Move most logic to history 2019-10-27 09:44:56 +01:00
Matthias
9c7696a8ce Add required_startup to backtesting 2019-10-27 09:44:56 +01:00
Matthias
9e7e051eb4 add trim-dataframe method 2019-10-27 09:44:56 +01:00
Matthias
616fe08bce Add subtract_start to timerange object 2019-10-27 09:44:56 +01:00
Matthias
141c454187 Add startup-candles-argument for strategy 2019-10-27 09:44:56 +01:00
hroff-1902
17fce00a5e Merge pull request #2427 from freqtrade/docs_windows
Improve windows Install documentation with hints
2019-10-27 10:01:25 +03:00
Matthias
0b8d04d75e Merge pull request #2429 from hroff-1902/minor-typos-2
minor: Fix typo in docs
2019-10-27 06:09:38 +01:00
Matthias
e5487441ba Fix typos 2019-10-27 06:08:55 +01:00
hroff-1902
48d83715a5 Fix typo in docs (thanks to Escaliert@Slack) 2019-10-27 03:44:49 +03:00
hroff-1902
8b4fea4b71 Update installation.md 2019-10-27 02:06:10 +03:00
hroff-1902
4c1f0c3c59 Merge remote-tracking branch 'origin/develop' into logging-syslog 2019-10-27 02:03:03 +03:00
Matthias
13ae339a2e Improve windows Install documentation with hints 2019-10-26 16:34:13 +02:00
Matthias
73a03565e5 Merge pull request #2426 from hroff-1902/docs-advanced-setup
docs: Create Advanced Post-installation Tasks section
2019-10-26 16:26:59 +02:00
hroff-1902
bf20f3b7d8 Remove part which is related to #2418 2019-10-26 15:41:31 +03:00
Matthias
20dabd9c41 Merge branch 'develop' into whitelist_docs 2019-10-26 13:36:39 +02:00
Matthias
32df73c056 flake 2019-10-26 13:28:04 +02:00
Matthias
ef1885c38b Fix more tests 2019-10-26 13:24:40 +02:00
Matthias
f5351e60e7 Adjust markets mock 2019-10-26 13:23:37 +02:00
hroff-1902
bfec9d974b docs: Create Advanced Post-installation Tasks section; move systemd stuff there 2019-10-26 13:26:22 +03:00
hroff-1902
3a7553eef6 Adjust option helpstring 2019-10-26 12:45:05 +03:00
Matthias
d0521d33ce Refactor whitelist handling
fixes #2413
2019-10-26 11:36:02 +02:00
hroff-1902
9155598ca4 Merge pull request #2425 from freqtrade/hroff-1902-patch-1
docs: add a tip for The Ocean exchange
2019-10-26 12:08:58 +03:00
hroff-1902
ea6b94fd0c docs: add a tip for The Ocean exchange 2019-10-26 11:54:04 +03:00
Matthias
2e896462c1 Fix wrong volumepairlist message 2019-10-25 19:49:23 +02:00
Matthias
e63377980e Improve pairlist documentation 2019-10-25 19:47:37 +02:00
hroff-1902
41f97a73c9 Add logging to syslog and journald 2019-10-25 17:31:57 +03:00
Matthias
45b83cc544 Don't require pair_whitelist for dynamicPairlist usecases 2019-10-25 07:07:01 +02:00
Matthias
b3e028e853 Improve dynamic pairlist documentation 2019-10-25 07:06:29 +02:00
Matthias
13255b370c Allow non-config to parse config 2019-10-24 06:30:07 +02:00
Matthias
e1edf36307 Fix test failures 2019-10-24 06:22:05 +02:00
hroff-1902
4ce278a06e Merge branch 'develop' into feat/new_args_system 2019-10-23 22:45:06 +03:00
Matthias
1c503f39b2 Handle some merge aftermaths 2019-10-21 06:38:30 +02:00
Matthias
2d34c0f52d Update helpstring exports 2019-10-20 19:35:38 +02:00
Matthias
f3cfe147b5 Merge branch 'develop' into feat/new_args_system 2019-10-20 19:32:34 +02:00
Matthias
df43b1f533 Merge pull request #2264 from freqtrade/args_aftersubcommand2
Allow all arguments after subcommand
2019-10-20 08:50:14 +02:00
hroff-1902
cb4d6efb29 Merge pull request #2377 from freqtrade/aligncustomoptions
Rename --custom-hyperopt to --hyperopt
2019-10-15 14:18:05 +03:00
hroff-1902
f1cddfdc62 Merge pull request #2380 from freqtrade/dry_run_cli
Add --dry-run to trade command
2019-10-15 14:17:17 +03:00
Matthias
6fb96183c0 Reword help string 2019-10-15 12:26:06 +02:00
Matthias
a5c83b66df Add --dry-run to trade command 2019-10-15 06:53:16 +02:00
Matthias
89283ef486 Rename --custom-hyperopt to --hyperopt 2019-10-14 19:42:28 +02:00
Matthias
2c200873c1 Merge pull request #2360 from hroff-1902/no-default-hyperopt
Disable defaulting to DefaultHyperOpts and DefaultHyperOptLoss
2019-10-13 09:42:48 +02:00
hroff-1902
ff1fa17dc3 No default value for the config parameter 2019-10-13 03:41:25 +03:00
hroff-1902
08e6d8a780 Rollback defaulting to DefaultHyperOptLoss 2019-10-11 23:33:22 +03:00
hroff-1902
c4105436eb Disable defaulting to DefaultHyperOpts and DefaultHyperOptLoss 2019-10-10 04:37:32 +03:00
Matthias
95299d94c4 Remove unused test line 2019-10-04 06:39:24 +02:00
hroff-1902
543b19b376 Merge pull request #2286 from freqtrade/no_defaultstrategy
Disable Defaulting to DefaultStrategy
2019-10-01 19:59:08 +03:00
Matthias
b73426b91f Disable Defaulting to DefaultStrategy 2019-10-01 07:02:30 +02:00
Matthias
52ff391c8a Default dockerfile to "freqtrade trade" 2019-09-29 19:48:37 +02:00
Matthias
344a0a094f Update remaining documentations 2019-09-29 19:21:18 +02:00
Matthias
2710226326 Update documentation to use subcommands 2019-09-29 19:18:52 +02:00
Matthias
381b0d3d07 Fix typo with new parser 2019-09-29 19:18:52 +02:00
Matthias
52523bcd8b Use strategy child parser 2019-09-29 19:18:52 +02:00
Matthias
0d13e2cb2e Update travis to run new methods 2019-09-29 19:18:52 +02:00
Matthias
014881e550 Allow query version without subcommand 2019-09-29 16:17:20 +02:00
Matthias
67b82638db Move test without command to test_main 2019-09-29 16:17:20 +02:00
Matthias
09f18d07b0 Adjust some hyperopt tests 2019-09-29 16:17:20 +02:00
Matthias
9ef874e979 Add Custom message during transition period 2019-09-29 16:17:20 +02:00
Matthias
0aa73d5b35 Add test for failing case 2019-09-29 16:17:20 +02:00
Matthias
ad2fa61765 Fix utils test 2019-09-29 16:17:20 +02:00
Matthias
e8106f3792 Fix most tests to have trade as default argument 2019-09-29 16:17:20 +02:00
Matthias
db3b974479 Fix calling sequence 2019-09-29 16:17:20 +02:00
Matthias
d62a4d3566 Fix some minor problems 2019-09-29 16:17:20 +02:00
Matthias
1b25b5f590 Remove duplicate short-form -s 2019-09-29 16:17:20 +02:00
Matthias
03add90c94 Adjust some tests to new call-method 2019-09-29 16:17:20 +02:00
Matthias
0f2e277f80 Rename subparser variable to command 2019-09-29 16:17:20 +02:00
Matthias
8664e7f7d3 Have main.py support only subcommand mode 2019-09-29 16:17:20 +02:00
Matthias
cb37f43277 Add trade subparser (and make subparser a requirement) 2019-09-29 16:17:20 +02:00
Matthias
2a535b72ff Parser should not have default 2019-09-29 16:17:20 +02:00
Matthias
cd2336887c Add first version with shared parent parsers 2019-09-29 16:09:59 +02:00
232 changed files with 21110 additions and 8482 deletions

View File

@@ -1,6 +1,7 @@
[run]
omit =
scripts/*
freqtrade/templates/*
freqtrade/vendor/*
freqtrade/__main__.py
tests/*

View File

@@ -1,33 +0,0 @@
## Step 1: Have you search for this issue before posting it?
If you have discovered a bug in the bot, please [search our issue tracker](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue).
If it hasn't been reported, please create a new issue.
## Step 2: Describe your environment
* Operating system: ____
* Python Version: _____ (`python -V`)
* CCXT version: _____ (`pip freeze | grep ccxt`)
* Branch: Master | Develop
* Last Commit ID: _____ (`git log --format="%H" -n 1`)
## Step 3: Describe the problem:
*Explain the problem you have encountered*
### Steps to reproduce:
1. _____
2. _____
3. _____
### Observed Results:
* What happened?
* What did you expect to happen?
### Relevant code exceptions or logs:
```
// paste your log here
```

48
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,48 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: "Triage Needed"
assignees: ''
---
<!--
Have you searched for similar issues before posting it?
If you have discovered a bug in the bot, please [search our issue tracker](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue).
If it hasn't been reported, please create a new issue.
Please do not use bug reports to request new features.
-->
## Describe your environment
* Operating system: ____
* Python Version: _____ (`python -V`)
* CCXT version: _____ (`pip freeze | grep ccxt`)
* Freqtrade Version: ____ (`freqtrade -V` or `docker-compose run --rm freqtrade -V` for Freqtrade running in docker)
Note: All issues other than enhancement requests will be closed without further comment if the above template is deleted or not filled out.
## Describe the problem:
*Explain the problem you have encountered*
### Steps to reproduce:
1. _____
2. _____
3. _____
### Observed Results:
* What happened?
* What did you expect to happen?
### Relevant code exceptions or logs
Note: Please copy/paste text of the messages, no screenshots of logs please.
```
// paste your log here
```

View File

@@ -0,0 +1,27 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
<!--
Note: this section will not show up in the issue.
Have you search for this feature before requesting it? It's highly likely that a similar request was already filed.
-->
## Describe your environment
(if applicable)
* Operating system: ____
* Python Version: _____ (`python -V`)
* CCXT version: _____ (`pip freeze | grep ccxt`)
* Freqtrade Version: ____ (`freqtrade -V` or `docker-compose run --rm freqtrade -V` for Freqtrade running in docker)
## Describe the enhancement
*Explain the enhancement you would like*

25
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@@ -0,0 +1,25 @@
---
name: BQuestion
about: Ask a question you could not find an answer in the docs
title: ''
labels: "Question"
assignees: ''
---
<!--
Have you searched for similar issues before posting it?
Did you have a VERY good look at the [documentation](https://www.freqtrade.io/en/latest/) and are sure that the question is not explained there
Please do not use the question template to report bugs or to request new features.
-->
## Describe your environment
* Operating system: ____
* Python Version: _____ (`python -V`)
* CCXT version: _____ (`pip freeze | grep ccxt`)
* Freqtrade Version: ____ (`freqtrade -V` or `docker-compose run --rm freqtrade -V` for Freqtrade running in docker)
## Your question
*Ask the question you have not been able to find an answer in our [Documentation](https://www.freqtrade.io/en/latest/)*

302
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,302 @@
name: Freqtrade CI
on:
push:
branches:
- master
- develop
- github_actions_tests
tags:
release:
types: [published]
pull_request:
schedule:
- cron: '0 5 * * 4'
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-18.04, macos-latest ]
python-version: [3.7, 3.8]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Cache_dependencies
uses: actions/cache@v1
id: cache
with:
path: ~/dependencies/
key: ${{ runner.os }}-dependencies
- name: pip cache (linux)
uses: actions/cache@preview
if: startsWith(matrix.os, 'ubuntu')
with:
path: ~/.cache/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
- name: pip cache (macOS)
uses: actions/cache@preview
if: startsWith(matrix.os, 'macOS')
with:
path: ~/Library/Caches/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
- name: TA binary *nix
if: steps.cache.outputs.cache-hit != 'true'
run: |
cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies/; cd ..
- name: Installation - *nix
run: |
python -m pip install --upgrade pip
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
export TA_LIBRARY_PATH=${HOME}/dependencies/lib
export TA_INCLUDE_PATH=${HOME}/dependencies/include
pip install -r requirements-dev.txt
pip install -e .
- name: Tests
run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc
- name: Coveralls
if: (startsWith(matrix.os, 'ubuntu') && matrix.python-version == '3.8')
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
coveralls -v || true
- name: Backtesting
run: |
cp config.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt
run: |
cp config.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt
- name: Flake8
run: |
flake8
- name: Mypy
run: |
mypy freqtrade scripts
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
type: ${{ job.status }}
job_name: '*Freqtrade CI ${{ matrix.os }}*'
mention: 'here'
mention_if: 'failure'
channel: '#notifications'
url: ${{ secrets.SLACK_WEBHOOK }}
build_windows:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ windows-latest ]
python-version: [3.7, 3.8]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Pip cache (Windows)
uses: actions/cache@preview
if: startsWith(runner.os, 'Windows')
with:
path: ~\AppData\Local\pip\Cache
key: ${{ matrix.os }}-${{ matrix.python-version }}-pip
- name: Installation
run: |
./build_helpers/install_windows.ps1
- name: Tests
run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc
- name: Backtesting
run: |
cp config.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt
run: |
cp config.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt
- name: Flake8
run: |
flake8
- name: Mypy
run: |
mypy freqtrade scripts
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
type: ${{ job.status }}
job_name: '*Freqtrade CI windows*'
mention: 'here'
mention_if: 'failure'
channel: '#notifications'
url: ${{ secrets.SLACK_WEBHOOK }}
docs_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Documentation syntax
run: |
./tests/test_docs.sh
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
type: ${{ job.status }}
job_name: '*Freqtrade Docs*'
channel: '#notifications'
url: ${{ secrets.SLACK_WEBHOOK }}
cleanup-prior-runs:
runs-on: ubuntu-latest
steps:
- name: Cleanup previous runs on this branch
uses: rokroskar/workflow-run-cleanup-action@v0.2.2
if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/master' && github.repository == 'freqtrade/freqtrade'"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
# Notify on slack only once - when CI completes (and after deploy) in case it's successfull
notify-complete:
needs: [ build, build_windows, docs_check ]
runs-on: ubuntu-latest
steps:
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
if: always() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
type: ${{ job.status }}
job_name: '*Freqtrade CI*'
channel: '#notifications'
url: ${{ secrets.SLACK_WEBHOOK }}
deploy:
needs: [ build, build_windows, docs_check ]
runs-on: ubuntu-18.04
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade'
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
- name: Build distribution
run: |
pip install -U setuptools wheel
python setup.py sdist bdist_wheel
- name: Publish to PyPI (Test)
uses: pypa/gh-action-pypi-publish@master
if: (steps.extract_branch.outputs.branch == 'master' || github.event_name == 'release')
with:
user: __token__
password: ${{ secrets.pypi_test_password }}
repository_url: https://test.pypi.org/legacy/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@master
if: (steps.extract_branch.outputs.branch == 'master' || github.event_name == 'release')
with:
user: __token__
password: ${{ secrets.pypi_password }}
- name: Dockerhub login
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: |
echo "${DOCKER_PASSWORD}" | docker login --username ${DOCKER_USERNAME} --password-stdin
- name: Build and test and push docker image
env:
IMAGE_NAME: freqtradeorg/freqtrade
BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }}
run: |
build_helpers/publish_docker.sh
# We need docker experimental to pull the ARM image.
- name: Switch docker to experimental
run: |
docker version -f '{{.Server.Experimental}}'
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
docker version -f '{{.Server.Experimental}}'
- name: Set up Docker Buildx
id: buildx
uses: crazy-max/ghaction-docker-buildx@v1
with:
buildx-version: latest
qemu-version: latest
- name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}
- name: Build Raspberry docker image
env:
IMAGE_NAME: freqtradeorg/freqtrade
BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }}_pi
run: |
build_helpers/publish_docker_pi.sh
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
if: always() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
type: ${{ job.status }}
job_name: '*Freqtrade CI Deploy*'
mention: 'here'
mention_if: 'failure'
channel: '#notifications'
url: ${{ secrets.SLACK_WEBHOOK }}

View File

@@ -0,0 +1,18 @@
name: Update Docker Hub Description
on:
push:
branches:
- master
jobs:
dockerHubDescription:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v2.1.0
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKERHUB_REPOSITORY: freqtradeorg/freqtrade

1
.gitignore vendored
View File

@@ -6,7 +6,6 @@ user_data/*
!user_data/strategy/sample_strategy.py
!user_data/notebooks
user_data/notebooks/*
!user_data/notebooks/*example.ipynb
freqtrade-plot.html
freqtrade-profit-plot.html

View File

@@ -1,4 +1,3 @@
sudo: true
os:
- linux
dist: xenial
@@ -11,10 +10,10 @@ env:
global:
- IMAGE_NAME=freqtradeorg/freqtrade
install:
- cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies/; cd ..
- cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies; cd ..
- export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
- export TA_LIBRARY_PATH=${HOME}/dependencies/lib
- export TA_INCLUDE_PATH=${HOME}/dependencies/lib/include
- export TA_INCLUDE_PATH=${HOME}/dependencies/include
- pip install -r requirements-dev.txt
- pip install -e .
jobs:
@@ -24,31 +23,34 @@ jobs:
script:
- pytest --random-order --cov=freqtrade --cov-config=.coveragerc
# Allow failure for coveralls
- coveralls || true
# - coveralls || true
name: pytest
- script:
- cp config.json.example config.json
- freqtrade --datadir tests/testdata backtesting
- freqtrade create-userdir --userdir user_data
- freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
name: backtest
- script:
- cp config.json.example config.json
- freqtrade --datadir tests/testdata hyperopt -e 5
- freqtrade create-userdir --userdir user_data
- freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt
name: hyperopt
- script: flake8
name: flake8
- script:
# Test Documentation boxes -
# !!! <TYPE>: is not allowed!
- grep -Er '^!{3}\s\S+:' docs/*; test $? -ne 0
# !!! <TYPE> "title" - Title needs to be quoted!
- grep -Er '^!{3}\s\S+:|^!{3}\s\S+\s[^"]' docs/*; test $? -ne 0
name: doc syntax
- script: mypy freqtrade scripts
name: mypy
- stage: docker
if: branch in (master, develop, feat/improve_travis) AND (type in (push, cron))
script:
- build_helpers/publish_docker.sh
name: "Build and test and push docker image"
# - stage: docker
# if: branch in (master, develop, feat/improve_travis) AND (type in (push, cron))
# script:
# - build_helpers/publish_docker.sh
# name: "Build and test and push docker image"
notifications:
slack:

View File

@@ -48,7 +48,7 @@ pytest tests/test_<file_name>.py::test_<method_name>
#### Run Flake8
```bash
flake8 freqtrade
flake8 freqtrade tests scripts
```
We receive a lot of code that fails the `flake8` checks.
@@ -109,11 +109,11 @@ Exceptions:
Contributors may be given commit privileges. Preference will be given to those with:
1. Past contributions to FreqTrade and other related open-source projects. Contributions to FreqTrade include both code (both accepted and pending) and friendly participation in the issue tracker and Pull request reviews. Quantity and quality are considered.
1. Past contributions to Freqtrade and other related open-source projects. Contributions to Freqtrade include both code (both accepted and pending) and friendly participation in the issue tracker and Pull request reviews. Quantity and quality are considered.
1. A coding style that the other core committers find simple, minimal, and clean.
1. Access to resources for cross-platform development and testing.
1. Time to devote to the project regularly.
Being a Committer does not grant write permission on `develop` or `master` for security reasons (Users trust FreqTrade with their Exchange API keys).
Being a Committer does not grant write permission on `develop` or `master` for security reasons (Users trust Freqtrade with their Exchange API keys).
After being Committer for some time, a Committer may be named Core Committer and given full repository access.

View File

@@ -1,4 +1,4 @@
FROM python:3.7.5-slim-stretch
FROM python:3.8.3-slim-buster
RUN apt-get update \
&& apt-get -y install curl build-essential libssl-dev \
@@ -24,3 +24,5 @@ RUN pip install numpy --no-cache-dir \
COPY . /freqtrade/
RUN pip install -e . --no-cache-dir
ENTRYPOINT ["freqtrade"]
# Default to trade mode
CMD [ "trade" ]

29
Dockerfile.armhf Normal file
View File

@@ -0,0 +1,29 @@
FROM --platform=linux/arm/v7 python:3.7.7-slim-buster
RUN apt-get update \
&& apt-get -y install curl build-essential libssl-dev libatlas3-base libgfortran5 \
&& apt-get clean \
&& pip install --upgrade pip \
&& echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > /etc/pip.conf
# Prepare environment
RUN mkdir /freqtrade
WORKDIR /freqtrade
# Install TA-lib
COPY build_helpers/* /tmp/
RUN cd /tmp && /tmp/install_ta-lib.sh && rm -r /tmp/*ta-lib*
ENV LD_LIBRARY_PATH /usr/local/lib
# Install dependencies
COPY requirements.txt requirements-common.txt /freqtrade/
RUN pip install numpy --no-cache-dir \
&& pip install -r requirements.txt --no-cache-dir
# Install and execute
COPY . /freqtrade/
RUN pip install -e . --no-cache-dir
ENTRYPOINT ["freqtrade"]
# Default to trade mode
CMD [ "trade" ]

View File

@@ -1,40 +0,0 @@
FROM balenalib/raspberrypi3-debian:stretch
RUN [ "cross-build-start" ]
RUN apt-get update \
&& apt-get -y install wget curl build-essential libssl-dev libffi-dev \
&& apt-get clean
# Prepare environment
RUN mkdir /freqtrade
WORKDIR /freqtrade
# Install TA-lib
COPY build_helpers/ta-lib-0.4.0-src.tar.gz /freqtrade/
RUN tar -xzf /freqtrade/ta-lib-0.4.0-src.tar.gz \
&& cd /freqtrade/ta-lib/ \
&& ./configure \
&& make \
&& make install \
&& rm /freqtrade/ta-lib-0.4.0-src.tar.gz
ENV LD_LIBRARY_PATH /usr/local/lib
# Install berryconda
RUN wget -q https://github.com/jjhelmus/berryconda/releases/download/v2.0.0/Berryconda3-2.0.0-Linux-armv7l.sh \
&& bash ./Berryconda3-2.0.0-Linux-armv7l.sh -b \
&& rm Berryconda3-2.0.0-Linux-armv7l.sh
# Install dependencies
COPY requirements-common.txt /freqtrade/
RUN ~/berryconda3/bin/conda install -y numpy pandas \
&& ~/berryconda3/bin/pip install -r requirements-common.txt --no-cache-dir
# Install and execute
COPY . /freqtrade/
RUN ~/berryconda3/bin/pip install -e . --no-cache-dir
RUN [ "cross-build-end" ]
ENTRYPOINT ["/root/berryconda3/bin/python","./freqtrade/main.py"]

View File

@@ -2,3 +2,4 @@ include LICENSE
include README.md
include config.json.example
recursive-include freqtrade *.py
recursive-include freqtrade/templates/ *.j2 *.ipynb

View File

@@ -1,6 +1,6 @@
# Freqtrade
[![Build Status](https://travis-ci.org/freqtrade/freqtrade.svg?branch=develop)](https://travis-ci.org/freqtrade/freqtrade)
[![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/)
[![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop)
[![Documentation](https://readthedocs.org/projects/freqtrade/badge/)](https://www.freqtrade.io)
[![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability)
@@ -25,7 +25,8 @@ hesitate to read the source code and understand the mechanism of this bot.
## Exchange marketplaces supported
- [X] [Bittrex](https://bittrex.com/)
- [X] [Binance](https://www.binance.com/) ([*Note for binance users](#a-note-on-binance))
- [X] [Binance](https://www.binance.com/) ([*Note for binance users](docs/exchanges.md#blacklists))
- [X] [Kraken](https://kraken.com/)
- [ ] [113 others to tests](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
## Documentation
@@ -62,51 +63,52 @@ git checkout develop
For any other type of installation please refer to [Installation doc](https://www.freqtrade.io/en/latest/installation/).
## Basic Usage
### Bot commands
```
usage: freqtrade [-h] [-v] [--logfile FILE] [--version] [-c PATH] [-d PATH]
[-s NAME] [--strategy-path PATH] [--dynamic-whitelist [INT]]
[--db-url PATH] [--sd-notify]
{backtesting,edge,hyperopt} ...
usage: freqtrade [-h] [-V]
{trade,create-userdir,new-config,new-hyperopt,new-strategy,download-data,convert-data,convert-trade-data,backtesting,edge,hyperopt,hyperopt-list,hyperopt-show,list-exchanges,list-hyperopts,list-markets,list-pairs,list-strategies,list-timeframes,show-trades,test-pairlist,plot-dataframe,plot-profit}
...
Free, open source crypto trading bot
positional arguments:
{backtesting,edge,hyperopt}
{trade,create-userdir,new-config,new-hyperopt,new-strategy,download-data,convert-data,convert-trade-data,backtesting,edge,hyperopt,hyperopt-list,hyperopt-show,list-exchanges,list-hyperopts,list-markets,list-pairs,list-strategies,list-timeframes,show-trades,test-pairlist,plot-dataframe,plot-profit}
trade Trade module.
create-userdir Create user-data directory.
new-config Create new config
new-hyperopt Create new hyperopt
new-strategy Create new strategy
download-data Download backtesting data.
convert-data Convert candle (OHLCV) data from one format to another.
convert-trade-data Convert trade data from one format to another.
backtesting Backtesting module.
edge Edge module.
hyperopt Hyperopt module.
hyperopt-list List Hyperopt results
hyperopt-show Show details of Hyperopt results
list-exchanges Print available exchanges.
list-hyperopts Print available hyperopt classes.
list-markets Print markets on exchange.
list-pairs Print pairs on exchange.
list-strategies Print available strategies.
list-timeframes Print available ticker intervals (timeframes) for the exchange.
show-trades Show trades.
test-pairlist Test your pairlist configuration.
plot-dataframe Plot candles with indicators.
plot-profit Generate plot showing profits.
optional arguments:
-h, --help show this help message and exit
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified
--version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: None). Multiple
--config options may be used.
-d PATH, --datadir PATH
Path to backtest data.
-s NAME, --strategy NAME
Specify strategy class name (default:
DefaultStrategy).
--strategy-path PATH Specify additional strategy lookup path.
--dynamic-whitelist [INT]
Dynamically generate and update whitelist based on 24h
BaseVolume (default: 20). DEPRECATED.
--db-url PATH Override trades database URL, this is useful if
dry_run is enabled or in custom deployments (default:
None).
--sd-notify Notify systemd service manager.
-V, --version show program's version number and exit
```
### Telegram RPC commands
Telegram is not mandatory. However, this is a great way to control your bot. More details on our [documentation](https://www.freqtrade.io/en/latest/telegram-usage/)
Telegram is not mandatory. However, this is a great way to control your bot. More details and the full command list on our [documentation](https://www.freqtrade.io/en/latest/telegram-usage/)
- `/start`: Starts the trader
- `/stop`: Stops the trader
@@ -129,11 +131,6 @@ The project is currently setup in two main branches:
- `master` - This branch contains the latest stable release. The bot 'should' be stable on this branch, and is generally well tested.
- `feat/*` - These are feature branches, which are being worked on heavily. Please don't use these unless you want to test a specific feature.
## A note on Binance
For Binance, please add `"BNB/<STAKE>"` to your blacklist to avoid issues.
Accounts having BNB accounts use this to pay for fees - if your first trade happens to be on `BNB`, further trades will consume this position and make the initial BNB order unsellable as the expected amount is not there anymore.
## Support
### Help / Slack

View File

@@ -1,11 +0,0 @@
#!/usr/bin/env python3
import sys
import warnings
from freqtrade.main import main
warnings.warn(
"Deprecated - To continue to run the bot like this, please run `pip install -e .` again.",
DeprecationWarning)
main(sys.argv[1:])

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,17 @@
# Downloads don't work automatically, since the URL is regenerated via javascript.
# Downloaded from https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib
# Invoke-WebRequest -Uri "https://download.lfd.uci.edu/pythonlibs/xxxxxxx/TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl" -OutFile "TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl"
python -m pip install --upgrade pip
$pyv = python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"
if ($pyv -eq '3.7') {
pip install build_helpers\TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl
}
if ($pyv -eq '3.8') {
pip install build_helpers\TA_Lib-0.4.18-cp38-cp38-win_amd64.whl
}
pip install -r requirements-dev.txt
pip install -e .

View File

@@ -1,17 +1,17 @@
#!/bin/sh
# - export TAG=`if [ "$TRAVIS_BRANCH" == "develop" ]; then echo "latest"; else echo $TRAVIS_BRANCH ; fi`
# Replace / with _ to create a valid tag
TAG=$(echo "${TRAVIS_BRANCH}" | sed -e "s/\//_/")
# Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
echo "Running for ${TAG}"
# Add commit and commit_message to docker container
echo "${TRAVIS_COMMIT} ${TRAVIS_COMMIT_MESSAGE}" > freqtrade_commit
echo "${GITHUB_SHA}" > freqtrade_commit
if [ "${TRAVIS_EVENT_TYPE}" = "cron" ]; then
echo "event ${TRAVIS_EVENT_TYPE}: full rebuild - skipping cache"
if [ "${GITHUB_EVENT_NAME}" = "schedule" ]; then
echo "event ${GITHUB_EVENT_NAME}: full rebuild - skipping cache"
docker build -t freqtrade:${TAG} .
else
echo "event ${TRAVIS_EVENT_TYPE}: building with cache"
echo "event ${GITHUB_EVENT_NAME}: building with cache"
# Pull last build to avoid rebuilding the whole image
docker pull ${IMAGE_NAME}:${TAG}
docker build --cache-from ${IMAGE_NAME}:${TAG} -t freqtrade:${TAG} .
@@ -23,7 +23,7 @@ if [ $? -ne 0 ]; then
fi
# Run backtest
docker run --rm -it -v $(pwd)/config.json.example:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} --datadir /tests/testdata backtesting
docker run --rm -v $(pwd)/config.json.example:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy DefaultStrategy
if [ $? -ne 0 ]; then
echo "failed running backtest"
@@ -38,18 +38,10 @@ if [ $? -ne 0 ]; then
fi
# Tag as latest for develop builds
if [ "${TRAVIS_BRANCH}" = "develop" ]; then
if [ "${TAG}" = "develop" ]; then
docker tag freqtrade:$TAG ${IMAGE_NAME}:latest
fi
# Login
echo "$DOCKER_PASS" | docker login -u $DOCKER_USER --password-stdin
if [ $? -ne 0 ]; then
echo "failed login"
return 1
fi
# Show all available images
docker images

View File

@@ -0,0 +1,36 @@
#!/bin/sh
# The below assumes a correctly setup docker buildx environment
# Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
PI_PLATFORM="linux/arm/v7"
echo "Running for ${TAG}"
CACHE_TAG=freqtradeorg/freqtrade_cache:${TAG}_cache
# Add commit and commit_message to docker container
echo "${GITHUB_SHA}" > freqtrade_commit
if [ "${GITHUB_EVENT_NAME}" = "schedule" ]; then
echo "event ${GITHUB_EVENT_NAME}: full rebuild - skipping cache"
docker buildx build \
--cache-to=type=registry,ref=${CACHE_TAG} \
-f Dockerfile.armhf \
--platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG} --push .
else
echo "event ${GITHUB_EVENT_NAME}: building with cache"
# Pull last build to avoid rebuilding the whole image
# docker pull --platform ${PI_PLATFORM} ${IMAGE_NAME}:${TAG}
docker buildx build \
--cache-from=type=registry,ref=${CACHE_TAG} \
--cache-to=type=registry,ref=${CACHE_TAG} \
-f Dockerfile.armhf \
--platform ${PI_PLATFORM} \
-t ${IMAGE_NAME}:${TAG} --push .
fi
if [ $? -ne 0 ]; then
echo "failed building image"
return 1
fi

View File

@@ -2,9 +2,11 @@
"max_open_trades": 3,
"stake_currency": "BTC",
"stake_amount": 0.05,
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD",
"ticker_interval" : "5m",
"ticker_interval": "5m",
"dry_run": false,
"cancel_open_orders_on_exit": false,
"trailing_stop": false,
"unfilledtimeout": {
"buy": 10,
@@ -22,7 +24,7 @@
"ask_strategy":{
"use_order_book": false,
"order_book_min": 1,
"order_book_max": 9,
"order_book_max": 1,
"use_sell_signal": true,
"sell_profit_only": false,
"ignore_roi_if_buy_signal": false
@@ -43,7 +45,7 @@
"DASH/BTC",
"ZEC/BTC",
"XLM/BTC",
"NXT/BTC",
"XRP/BTC",
"TRX/BTC",
"ADA/BTC",
"XMR/BTC"
@@ -52,11 +54,13 @@
"DOGE/BTC"
]
},
"pairlists": [
{"method": "StaticPairList"}
],
"edge": {
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"capital_available_percentage": 0.5,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,
@@ -68,7 +72,7 @@
"remove_pumps": false
},
"telegram": {
"enabled": true,
"enabled": false,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id"
},

View File

@@ -2,9 +2,11 @@
"max_open_trades": 3,
"stake_currency": "BTC",
"stake_amount": 0.05,
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD",
"ticker_interval" : "5m",
"ticker_interval": "5m",
"dry_run": true,
"cancel_open_orders_on_exit": false,
"trailing_stop": false,
"unfilledtimeout": {
"buy": 10,
@@ -22,7 +24,7 @@
"ask_strategy":{
"use_order_book": false,
"order_book_min": 1,
"order_book_max": 9,
"order_book_max": 1,
"use_sell_signal": true,
"sell_profit_only": false,
"ignore_roi_if_buy_signal": false
@@ -37,28 +39,33 @@
"rateLimit": 200
},
"pair_whitelist": [
"AST/BTC",
"ETC/BTC",
"ETH/BTC",
"ALGO/BTC",
"ATOM/BTC",
"BAT/BTC",
"BCH/BTC",
"BRD/BTC",
"EOS/BTC",
"ETH/BTC",
"IOTA/BTC",
"LINK/BTC",
"LTC/BTC",
"MTH/BTC",
"NCASH/BTC",
"TNT/BTC",
"NEO/BTC",
"NXS/BTC",
"XMR/BTC",
"XLM/BTC",
"XRP/BTC"
"XRP/BTC",
"XTZ/BTC"
],
"pair_blacklist": [
"BNB/BTC"
]
},
"pairlists": [
{"method": "StaticPairList"}
],
"edge": {
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"capital_available_percentage": 0.5,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,

View File

@@ -2,9 +2,13 @@
"max_open_trades": 3,
"stake_currency": "BTC",
"stake_amount": 0.05,
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD",
"amount_reserve_percent" : 0.05,
"amount_reserve_percent": 0.05,
"amend_last_stake_amount": false,
"last_stake_amount_min_ratio": 0.5,
"dry_run": false,
"cancel_open_orders_on_exit": false,
"ticker_interval": "5m",
"trailing_stop": false,
"trailing_stop_positive": 0.005,
@@ -22,6 +26,7 @@
"sell": 30
},
"bid_strategy": {
"price_side": "bid",
"use_order_book": false,
"ask_last_balance": 0.0,
"order_book_top": 1,
@@ -31,9 +36,10 @@
}
},
"ask_strategy":{
"price_side": "ask",
"use_order_book": false,
"order_book_min": 1,
"order_book_max": 9,
"order_book_max": 1,
"use_sell_signal": true,
"sell_profit_only": false,
"ignore_roi_if_buy_signal": false
@@ -50,14 +56,18 @@
"buy": "gtc",
"sell": "gtc"
},
"pairlist": {
"method": "VolumePairList",
"config": {
"pairlists": [
{"method": "StaticPairList"},
{
"method": "VolumePairList",
"number_assets": 20,
"sort_key": "quoteVolume",
"precision_filter": false
}
},
"refresh_period": 1800
},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01},
{"method": "SpreadFilter", "max_spread_ratio": 0.005}
],
"exchange": {
"name": "bittrex",
"sandbox": false,
@@ -92,7 +102,6 @@
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"capital_available_percentage": 0.5,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,
@@ -112,6 +121,7 @@
"enabled": false,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"jwt_secret_key": "somethingrandom",
"username": "freqtrader",
"password": "SuperSecurePassword"
},
@@ -123,5 +133,7 @@
"heartbeat_interval": 60
},
"strategy": "DefaultStrategy",
"strategy_path": "user_data/strategies/"
"strategy_path": "user_data/strategies/",
"dataformat_ohlcv": "json",
"dataformat_trades": "jsongz"
}

View File

@@ -2,9 +2,11 @@
"max_open_trades": 5,
"stake_currency": "EUR",
"stake_amount": 10,
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "EUR",
"ticker_interval" : "5m",
"ticker_interval": "5m",
"dry_run": true,
"cancel_open_orders_on_exit": false,
"trailing_stop": false,
"unfilledtimeout": {
"buy": 10,
@@ -22,7 +24,7 @@
"ask_strategy":{
"use_order_book": false,
"order_book_min": 1,
"order_book_max": 9,
"order_book_max": 1,
"use_sell_signal": true,
"sell_profit_only": false,
"ignore_roi_if_buy_signal": false
@@ -38,19 +40,38 @@
"rateLimit": 1000
},
"pair_whitelist": [
"ETH/EUR",
"ADA/EUR",
"ATOM/EUR",
"BAT/EUR",
"BCH/EUR",
"BTC/EUR",
"BCH/EUR"
"DAI/EUR",
"DASH/EUR",
"EOS/EUR",
"ETC/EUR",
"ETH/EUR",
"LINK/EUR",
"LTC/EUR",
"QTUM/EUR",
"REP/EUR",
"WAVES/EUR",
"XLM/EUR",
"XMR/EUR",
"XRP/EUR",
"XTZ/EUR",
"ZEC/EUR"
],
"pair_blacklist": [
]
},
"pairlists": [
{"method": "StaticPairList"}
],
"edge": {
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"capital_available_percentage": 0.5,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,

View File

@@ -3,6 +3,19 @@ version: '3'
services:
freqtrade:
image: freqtradeorg/freqtrade:master
# image: freqtradeorg/freqtrade:develop
# Build step - only needed when additional dependencies are needed
# build:
# context: .
# dockerfile: "./Dockerfile.technical"
restart: unless-stopped
container_name: freqtrade
volumes:
- "./user_data:/freqtrade/user_data"
- "./config.json:/freqtrade/config.json"
# Default command used when running `docker compose up`
command: >
trade
--logfile /freqtrade/user_data/logs/freqtrade.log
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite
--config /freqtrade/user_data/config.json
--strategy SampleStrategy

91
docs/advanced-hyperopt.md Normal file
View File

@@ -0,0 +1,91 @@
# Advanced Hyperopt
This page explains some advanced Hyperopt topics that may require higher
coding skills and Python knowledge than creation of an ordinal hyperoptimization
class.
## Derived hyperopt classes
Custom hyperop classes can be derived in the same way [it can be done for strategies](strategy-customization.md#derived-strategies).
Applying to hyperoptimization, as an example, you may override how dimensions are defined in your optimization hyperspace:
```python
class MyAwesomeHyperOpt(IHyperOpt):
...
# Uses default stoploss dimension
class MyAwesomeHyperOpt2(MyAwesomeHyperOpt):
@staticmethod
def stoploss_space() -> List[Dimension]:
# Override boundaries for stoploss
return [
Real(-0.33, -0.01, name='stoploss'),
]
```
and then quickly switch between hyperopt classes, running optimization process with hyperopt class you need in each particular case:
```
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt ...
or
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt2 ...
```
## Creating and using a custom loss function
To use a custom loss function class, make sure that the function `hyperopt_loss_function` is defined in your custom hyperopt loss class.
For the sample below, you then need to add the command line parameter `--hyperopt-loss SuperDuperHyperOptLoss` to your hyperopt call so this function is being used.
A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found in [userdata/hyperopts](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_loss.py).
``` python
from freqtrade.optimize.hyperopt import IHyperOptLoss
TARGET_TRADES = 600
EXPECTED_MAX_PROFIT = 3.0
MAX_ACCEPTED_TRADE_DURATION = 300
class SuperDuperHyperOptLoss(IHyperOptLoss):
"""
Defines the default loss function for hyperopt
"""
@staticmethod
def hyperopt_loss_function(results: DataFrame, trade_count: int,
min_date: datetime, max_date: datetime,
*args, **kwargs) -> float:
"""
Objective function, returns smaller number for better results
This is the legacy algorithm (used until now in freqtrade).
Weights are distributed as follows:
* 0.4 to trade duration
* 0.25: Avoiding trade loss
* 1.0 to total profit, compared to the expected value (`EXPECTED_MAX_PROFIT`) defined above
"""
total_profit = results.profit_percent.sum()
trade_duration = results.trade_duration.mean()
trade_loss = 1 - 0.25 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.8)
profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT)
duration_loss = 0.4 * min(trade_duration / MAX_ACCEPTED_TRADE_DURATION, 1)
result = trade_loss + profit_loss + duration_loss
return result
```
Currently, the arguments are:
* `results`: DataFrame containing the result
The following columns are available in results (corresponds to the output-file of backtesting when used with `--export trades`):
`pair, profit_percent, profit_abs, open_time, close_time, open_index, close_index, trade_duration, open_at_end, open_rate, close_rate, sell_reason`
* `trade_count`: Amount of trades (identical to `len(results)`)
* `min_date`: Start date of the hyperopting TimeFrame
* `min_date`: End date of the hyperopting TimeFrame
This function needs to return a floating point number (`float`). Smaller numbers will be interpreted as better results. The parameters and balancing for this is up to you.
!!! Note
This function is called once per iteration - so please make sure to have this as optimized as possible to not slow hyperopt down unnecessarily.
!!! Note
Please keep the arguments `*args` and `**kwargs` in the interface to allow us to extend this interface later.

92
docs/advanced-setup.md Normal file
View File

@@ -0,0 +1,92 @@
# Advanced Post-installation Tasks
This page explains some advanced tasks and configuration options that can be performed after the bot installation and may be uselful in some environments.
If you do not know what things mentioned here mean, you probably do not need it.
## Configure the bot running as a systemd service
Copy the `freqtrade.service` file to your systemd user directory (usually `~/.config/systemd/user`) and update `WorkingDirectory` and `ExecStart` to match your setup.
!!! Note
Certain systems (like Raspbian) don't load service unit files from the user directory. In this case, copy `freqtrade.service` into `/etc/systemd/user/` (requires superuser permissions).
After that you can start the daemon with:
```bash
systemctl --user start freqtrade
```
For this to be persistent (run when user is logged out) you'll need to enable `linger` for your freqtrade user.
```bash
sudo loginctl enable-linger "$USER"
```
If you run the bot as a service, you can use systemd service manager as a software watchdog monitoring freqtrade bot
state and restarting it in the case of failures. If the `internals.sd_notify` parameter is set to true in the
configuration or the `--sd-notify` command line option is used, the bot will send keep-alive ping messages to systemd
using the sd_notify (systemd notifications) protocol and will also tell systemd its current state (Running or Stopped)
when it changes.
The `freqtrade.service.watchdog` file contains an example of the service unit configuration file which uses systemd
as the watchdog.
!!! Note
The sd_notify communication between the bot and the systemd service manager will not work if the bot runs in a Docker container.
## Advanced Logging
On many Linux systems the bot can be configured to send its log messages to `syslog` or `journald` system services. Logging to a remote `syslog` server is also available on Windows. The special values for the `--logfile` command line option can be used for this.
### Logging to syslog
To send Freqtrade log messages to a local or remote `syslog` service use the `--logfile` command line option with the value in the following format:
* `--logfile syslog:<syslog_address>` -- send log messages to `syslog` service using the `<syslog_address>` as the syslog address.
The syslog address can be either a Unix domain socket (socket filename) or a UDP socket specification, consisting of IP address and UDP port, separated by the `:` character.
So, the following are the examples of possible usages:
* `--logfile syslog:/dev/log` -- log to syslog (rsyslog) using the `/dev/log` socket, suitable for most systems.
* `--logfile syslog` -- same as above, the shortcut for `/dev/log`.
* `--logfile syslog:/var/run/syslog` -- log to syslog (rsyslog) using the `/var/run/syslog` socket. Use this on MacOS.
* `--logfile syslog:localhost:514` -- log to local syslog using UDP socket, if it listens on port 514.
* `--logfile syslog:<ip>:514` -- log to remote syslog at IP address and port 514. This may be used on Windows for remote logging to an external syslog server.
Log messages are send to `syslog` with the `user` facility. So you can see them with the following commands:
* `tail -f /var/log/user`, or
* install a comprehensive graphical viewer (for instance, 'Log File Viewer' for Ubuntu).
On many systems `syslog` (`rsyslog`) fetches data from `journald` (and vice versa), so both `--logfile syslog` or `--logfile journald` can be used and the messages be viewed with both `journalctl` and a syslog viewer utility. You can combine this in any way which suites you better.
For `rsyslog` the messages from the bot can be redirected into a separate dedicated log file. To achieve this, add
```
if $programname startswith "freqtrade" then -/var/log/freqtrade.log
```
to one of the rsyslog configuration files, for example at the end of the `/etc/rsyslog.d/50-default.conf`.
For `syslog` (`rsyslog`), the reduction mode can be switched on. This will reduce the number of repeating messages. For instance, multiple bot Heartbeat messages will be reduced to a single message when nothing else happens with the bot. To achieve this, set in `/etc/rsyslog.conf`:
```
# Filter duplicated messages
$RepeatedMsgReduction on
```
### Logging to journald
This needs the `systemd` python package installed as the dependency, which is not available on Windows. Hence, the whole journald logging functionality is not available for a bot running on Windows.
To send Freqtrade log messages to `journald` system service use the `--logfile` command line option with the value in the following format:
* `--logfile journald` -- send log messages to `journald`.
Log messages are send to `journald` with the `user` facility. So you can see them with the following commands:
* `journalctl -f` -- shows Freqtrade log messages sent to `journald` along with other log messages fetched by `journald`.
* `journalctl -f -u freqtrade.service` -- this command can be used when the bot is run as a `systemd` service.
There are many other options in the `journalctl` utility to filter the messages, see manual pages for this utility.
On many systems `syslog` (`rsyslog`) fetches data from `journald` (and vice versa), so both `--logfile syslog` or `--logfile journald` can be used and the messages be viewed with both `journalctl` and a syslog viewer utility. You can combine this in any way which suites you better.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

@@ -11,29 +11,34 @@ Now you have good Buy and Sell strategies and some historic data, you want to te
real data. This is what we call
[backtesting](https://en.wikipedia.org/wiki/Backtesting).
Backtesting will use the crypto-currencies (pairs) from your config file
and load ticker data from `user_data/data/<exchange>` by default.
If no data is available for the exchange / pair / ticker interval combination, backtesting will
ask you to download them first using `freqtrade download-data`.
Backtesting will use the crypto-currencies (pairs) from your config file and load historical candle (OHCLV) data from `user_data/data/<exchange>` by default.
If no data is available for the exchange / pair / timeframe (ticker interval) combination, backtesting will ask you to download them first using `freqtrade download-data`.
For details on downloading, please refer to the [Data Downloading](data-download.md) section in the documentation.
The result of backtesting will confirm if your bot has better odds of making a profit than a loss.
!!! Warning "Using dynamic pairlists for backtesting"
Using dynamic pairlists is possible, however it relies on the current market conditions - which will not reflect the historic status of the pairlist.
Also, when using pairlists other than StaticPairlist, reproducability of backtesting-results cannot be guaranteed.
Please read the [pairlists documentation](configuration.md#pairlists) for more information.
To achieve reproducible results, best generate a pairlist via the [`test-pairlist`](utils.md#test-pairlist) command and use that as static pairlist.
### Run a backtesting against the currencies listed in your config file
#### With 5 min tickers (Per default)
#### With 5 min candle (OHLCV) data (per default)
```bash
freqtrade backtesting
```
#### With 1 min tickers
#### With 1 min candle (OHLCV) data
```bash
freqtrade backtesting --ticker-interval 1m
```
#### Using a different on-disk ticker-data source
#### Using a different on-disk historical candle (OHLCV) data source
Assume you downloaded the history data from the Bittrex exchange and kept it in the `user_data/data/bittrex-20180101` directory.
You can then use this data for backtesting as follows:
@@ -45,7 +50,7 @@ freqtrade --datadir user_data/data/bittrex-20180101 backtesting
#### With a (custom) strategy file
```bash
freqtrade -s SampleStrategy backtesting
freqtrade backtesting -s SampleStrategy
```
Where `-s SampleStrategy` refers to the class name within the strategy file `sample_strategy.py` found in the `freqtrade/user_data/strategies` directory.
@@ -72,16 +77,22 @@ The exported trades can be used for [further analysis](#further-backtest-result-
freqtrade backtesting --export trades --export-filename=backtest_samplestrategy.json
```
Please also read about the [strategy startup period](strategy-customization.md#strategy-startup-period).
#### Supplying custom fee value
Sometimes your account has certain fee rebates (fee reductions starting with a certain account size or monthly volume), which are not visible to ccxt.
To account for this in backtesting, you can use `--fee 0.001` to supply this value to backtesting.
This fee must be a percentage, and will be applied twice (once for trade entry, and once for trade exit).
To account for this in backtesting, you can use the `--fee` command line option to supply this value to backtesting.
This fee must be a ratio, and will be applied twice (once for trade entry, and once for trade exit).
For example, if the buying and selling commission fee is 0.1% (i.e., 0.001 written as ratio), then you would run backtesting as the following:
```bash
freqtrade backtesting --fee 0.001
```
!!! Note
Only supply this option (or the corresponding configuration parameter) if you want to experiment with different fee values. By default, Backtesting fetches the default fee from the exchange pair/market info.
#### Running backtest with smaller testset by using timerange
@@ -112,45 +123,46 @@ A backtesting result will look like that:
```
========================================================= BACKTESTING REPORT ========================================================
| pair | buy count | avg profit % | cum profit % | tot profit BTC | tot profit % | avg duration | profit | loss |
|:---------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:|
| ADA/BTC | 35 | -0.11 | -3.88 | -0.00019428 | -1.94 | 4:35:00 | 14 | 21 |
| ARK/BTC | 11 | -0.41 | -4.52 | -0.00022647 | -2.26 | 2:03:00 | 3 | 8 |
| BTS/BTC | 32 | 0.31 | 9.78 | 0.00048938 | 4.89 | 5:05:00 | 18 | 14 |
| DASH/BTC | 13 | -0.08 | -1.07 | -0.00005343 | -0.53 | 4:39:00 | 6 | 7 |
| ENG/BTC | 18 | 1.36 | 24.54 | 0.00122807 | 12.27 | 2:50:00 | 8 | 10 |
| EOS/BTC | 36 | 0.08 | 3.06 | 0.00015304 | 1.53 | 3:34:00 | 16 | 20 |
| ETC/BTC | 26 | 0.37 | 9.51 | 0.00047576 | 4.75 | 6:14:00 | 11 | 15 |
| ETH/BTC | 33 | 0.30 | 9.96 | 0.00049856 | 4.98 | 7:31:00 | 16 | 17 |
| IOTA/BTC | 32 | 0.03 | 1.09 | 0.00005444 | 0.54 | 3:12:00 | 14 | 18 |
| LSK/BTC | 15 | 1.75 | 26.26 | 0.00131413 | 13.13 | 2:58:00 | 6 | 9 |
| LTC/BTC | 32 | -0.04 | -1.38 | -0.00006886 | -0.69 | 4:49:00 | 11 | 21 |
| NANO/BTC | 17 | 1.26 | 21.39 | 0.00107058 | 10.70 | 1:55:00 | 10 | 7 |
| NEO/BTC | 23 | 0.82 | 18.97 | 0.00094936 | 9.48 | 2:59:00 | 10 | 13 |
| REQ/BTC | 9 | 1.17 | 10.54 | 0.00052734 | 5.27 | 3:47:00 | 4 | 5 |
| XLM/BTC | 16 | 1.22 | 19.54 | 0.00097800 | 9.77 | 3:15:00 | 7 | 9 |
| XMR/BTC | 23 | -0.18 | -4.13 | -0.00020696 | -2.07 | 5:30:00 | 12 | 11 |
| XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 | 23 |
| ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 | 15 |
| TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 243 |
| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |
|:---------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|------:|-------:|--------:|
| ADA/BTC | 35 | -0.11 | -3.88 | -0.00019428 | -1.94 | 4:35:00 | 14 | 0 | 21 |
| ARK/BTC | 11 | -0.41 | -4.52 | -0.00022647 | -2.26 | 2:03:00 | 3 | 0 | 8 |
| BTS/BTC | 32 | 0.31 | 9.78 | 0.00048938 | 4.89 | 5:05:00 | 18 | 0 | 14 |
| DASH/BTC | 13 | -0.08 | -1.07 | -0.00005343 | -0.53 | 4:39:00 | 6 | 0 | 7 |
| ENG/BTC | 18 | 1.36 | 24.54 | 0.00122807 | 12.27 | 2:50:00 | 8 | 0 | 10 |
| EOS/BTC | 36 | 0.08 | 3.06 | 0.00015304 | 1.53 | 3:34:00 | 16 | 0 | 20 |
| ETC/BTC | 26 | 0.37 | 9.51 | 0.00047576 | 4.75 | 6:14:00 | 11 | 0 | 15 |
| ETH/BTC | 33 | 0.30 | 9.96 | 0.00049856 | 4.98 | 7:31:00 | 16 | 0 | 17 |
| IOTA/BTC | 32 | 0.03 | 1.09 | 0.00005444 | 0.54 | 3:12:00 | 14 | 0 | 18 |
| LSK/BTC | 15 | 1.75 | 26.26 | 0.00131413 | 13.13 | 2:58:00 | 6 | 0 | 9 |
| LTC/BTC | 32 | -0.04 | -1.38 | -0.00006886 | -0.69 | 4:49:00 | 11 | 0 | 21 |
| NANO/BTC | 17 | 1.26 | 21.39 | 0.00107058 | 10.70 | 1:55:00 | 10 | 0 | 7 |
| NEO/BTC | 23 | 0.82 | 18.97 | 0.00094936 | 9.48 | 2:59:00 | 10 | 0 | 13 |
| REQ/BTC | 9 | 1.17 | 10.54 | 0.00052734 | 5.27 | 3:47:00 | 4 | 0 | 5 |
| XLM/BTC | 16 | 1.22 | 19.54 | 0.00097800 | 9.77 | 3:15:00 | 7 | 0 | 9 |
| XMR/BTC | 23 | -0.18 | -4.13 | -0.00020696 | -2.07 | 5:30:00 | 12 | 0 | 11 |
| XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 | 0 | 23 |
| ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 | 0 | 15 |
| TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 0 | 243 |
========================================================= SELL REASON STATS =========================================================
| Sell Reason | Count |
|:-------------------|--------:|
| trailing_stop_loss | 205 |
| stop_loss | 166 |
| sell_signal | 56 |
| force_sell | 2 |
| Sell Reason | Sells | Wins | Draws | Losses |
|:-------------------|--------:|------:|-------:|--------:|
| trailing_stop_loss | 205 | 150 | 0 | 55 |
| stop_loss | 166 | 0 | 0 | 166 |
| sell_signal | 56 | 36 | 0 | 20 |
| force_sell | 2 | 0 | 0 | 2 |
====================================================== LEFT OPEN TRADES REPORT ======================================================
| pair | buy count | avg profit % | cum profit % | tot profit BTC | tot profit % | avg duration | profit | loss |
|:---------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:|
| ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 | 0 |
| LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 | 0 |
| TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 | 0 |
| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |
|:---------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|------:|-------:|--------:|
| ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 | 0 | 0 |
| LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 | 0 | 0 |
| TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 | 0 | 0 |
```
The 1st table contains all trades the bot made, including "left open trades".
The 2nd table contains a recap of sell reasons.
This table can tell you which area needs some additional work (i.e. all `sell_signal` trades are losses, so we should disable the sell-signal or work on improving that).
The 3rd table contains all trades the bot had to `forcesell` at the end of the backtest period to present a full picture.
This is necessary to simulate realistic behaviour, since the backtest period has to end at some point, while realistically, you could leave the bot running forever.
@@ -190,13 +202,17 @@ Since backtesting lacks some detailed information about what happens within a ca
- Buys happen at open-price
- Sell signal sells happen at open-price of the following candle
- Low happens before high for stoploss, protecting capital first.
- ROI sells are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the sell will be at 2%)
- Low happens before high for stoploss, protecting capital first
- ROI
- sells are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the sell will be at 2%)
- sells are never "below the candle", so a ROI of 2% may result in a sell at 2.4% if low was at 2.4% profit
- Forcesells caused by `<N>=-1` ROI entries use low as sell value, unless N falls on the candle open (e.g. `120: -1` for 1h candles)
- Stoploss sells happen exactly at stoploss price, even if low was lower
- Trailing stoploss
- High happens first - adjusting stoploss
- Low uses the adjusted stoploss (so sells with large high-low difference are backtested correctly)
- Sell-reason does not explain if a trade was positive or negative, just what triggered the sell (this can look odd if negative ROI values are used)
- Stoploss (and trailing stoploss) is evaluated before ROI within one candle. So you can often see more trades with the `stoploss` and/or `trailing_stop` sell reason comparing to the results obtained with the same strategy in the Dry Run/Live Trade modes.
Taking these assumptions, backtesting tries to mirror real trading as closely as possible. However, backtesting will **never** replace running a strategy in dry-run mode.
Also, keep in mind that past results don't guarantee future success.
@@ -212,7 +228,7 @@ You can then load the trades to perform further analysis as shown in our [data a
To compare multiple strategies, a list of Strategies can be provided to backtesting.
This is limited to 1 ticker-interval per run, however, data is only loaded once from disk so if you have multiple
This is limited to 1 timeframe (ticker interval) value per run. However, data is only loaded once from disk so if you have multiple
strategies you'd like to compare, this will give a nice runtime boost.
All listed Strategies need to be in the same directory.
@@ -226,11 +242,11 @@ There will be an additional table comparing win/losses of the different strategi
Detailed output for all strategies one after the other will be available, so make sure to scroll up to see the details per strategy.
```
=========================================================== Strategy Summary ===========================================================
| Strategy | buy count | avg profit % | cum profit % | tot profit BTC | tot profit % | avg duration | profit | loss |
|:------------|------------:|---------------:|---------------:|-----------------:|---------------:|:---------------|---------:|-------:|
| Strategy1 | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 243 |
| Strategy2 | 1487 | -0.13 | -197.58 | -0.00988917 | -98.79 | 4:43:00 | 662 | 825 |
=========================================================== STRATEGY SUMMARY ===========================================================
| Strategy | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Wins | Draws | Losses |
|:------------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|------:|-------:|-------:|
| Strategy1 | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 | 0 | 243 |
| Strategy2 | 1487 | -0.13 | -197.58 | -0.00988917 | -98.79 | 4:43:00 | 662 | 0 | 825 |
```
## Next step

View File

@@ -5,20 +5,18 @@ This page explains the different parameters of the bot and how to run it.
!!! Note
If you've used `setup.sh`, don't forget to activate your virtual environment (`source .env/bin/activate`) before running freqtrade commands.
## Bot commands
```
usage: freqtrade [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[--db-url PATH] [--sd-notify]
{backtesting,edge,hyperopt,create-userdir,list-exchanges,list-timeframes,download-data,plot-dataframe,plot-profit}
usage: freqtrade [-h] [-V]
{trade,backtesting,edge,hyperopt,create-userdir,list-exchanges,list-timeframes,download-data,plot-dataframe,plot-profit}
...
Free, open source crypto trading bot
positional arguments:
{backtesting,edge,hyperopt,create-userdir,list-exchanges,list-timeframes,download-data,plot-dataframe,plot-profit}
{trade,backtesting,edge,hyperopt,create-userdir,list-exchanges,list-timeframes,download-data,plot-dataframe,plot-profit}
trade Trade module.
backtesting Backtesting module.
edge Edge module.
hyperopt Hyperopt module.
@@ -32,25 +30,49 @@ positional arguments:
optional arguments:
-h, --help show this help message and exit
-V, --version show program's version number and exit
```
### Bot trading commands
```
usage: freqtrade trade [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[--db-url PATH] [--sd-notify] [--dry-run]
optional arguments:
-h, --help show this help message and exit
--db-url PATH Override trades database URL, this is useful in custom
deployments (default: `sqlite:///tradesv3.sqlite` for
Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for
Dry Run).
--sd-notify Notify systemd service manager.
--dry-run Enforce dry-run for trading (removes Exchange secrets
and simulates trades).
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified.
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name (default:
`DefaultStrategy`).
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
--db-url PATH Override trades database URL, this is useful in custom
deployments (default: `sqlite:///tradesv3.sqlite` for
Live Run mode, `sqlite://` for Dry Run).
--sd-notify Notify systemd service manager.
.
```
@@ -60,7 +82,7 @@ The bot allows you to select which configuration file you want to use by means o
the `-c/--config` command line option:
```bash
freqtrade -c path/far/far/away/config.json
freqtrade trade -c path/far/far/away/config.json
```
Per default, the bot loads the `config.json` configuration file from the current
@@ -73,22 +95,22 @@ The bot allows you to use multiple configuration files by specifying multiple
defined in the latter configuration files override parameters with the same name
defined in the previous configuration files specified in the command line earlier.
For example, you can make a separate configuration file with your key and secrete
For example, you can make a separate configuration file with your key and secret
for the Exchange you use for trading, specify default configuration file with
empty key and secrete values while running in the Dry Mode (which does not actually
empty key and secret values while running in the Dry Mode (which does not actually
require them):
```bash
freqtrade -c ./config.json
freqtrade trade -c ./config.json
```
and specify both configuration files when running in the normal Live Trade Mode:
```bash
freqtrade -c ./config.json -c path/to/secrets/keys.config.json
freqtrade trade -c ./config.json -c path/to/secrets/keys.config.json
```
This could help you hide your private Exchange key and Exchange secrete on you local machine
This could help you hide your private Exchange key and Exchange secret on you local machine
by setting appropriate file permissions for the file which contains actual secrets and, additionally,
prevent unintended disclosure of sensitive private data when you publish examples
of your configuration in the project issues or in the Internet.
@@ -122,10 +144,10 @@ It is recommended to use version control to keep track of changes to your strate
### How to use **--strategy**?
This parameter will allow you to load your custom strategy class.
Per default without `--strategy` or `-s` the bot will load the
`DefaultStrategy` included with the bot (`freqtrade/strategy/default_strategy.py`).
To test the bot installation, you can use the `SampleStrategy` installed by the `create-userdir` subcommand (usually `user_data/strategy/sample_strategy.py`).
The bot will search your strategy file within `user_data/strategies` and `freqtrade/strategy`.
The bot will search your strategy file within `user_data/strategies`.
To use other directories, please read the next section about `--strategy-path`.
To load a strategy, simply pass the class name (e.g.: `CustomStrategy`) in this parameter.
@@ -134,7 +156,7 @@ In `user_data/strategies` you have a file `my_awesome_strategy.py` which has
a strategy class called `AwesomeStrategy` to load it:
```bash
freqtrade --strategy AwesomeStrategy
freqtrade trade --strategy AwesomeStrategy
```
If the bot does not find your strategy file, it will display in an error
@@ -149,7 +171,7 @@ This parameter allows you to add an additional strategy lookup path, which gets
checked before the default locations (The passed path must be a directory!):
```bash
freqtrade --strategy AwesomeStrategy --strategy-path /some/directory
freqtrade trade --strategy AwesomeStrategy --strategy-path /some/directory
```
#### How to install a strategy?
@@ -165,7 +187,7 @@ using `--db-url`. This can also be used to specify a custom database
in production mode. Example command:
```bash
freqtrade -c config.json --db-url sqlite:///tradesv3.dry_run.sqlite
freqtrade trade -c config.json --db-url sqlite:///tradesv3.dry_run.sqlite
```
## Backtesting commands
@@ -173,9 +195,11 @@ freqtrade -c config.json --db-url sqlite:///tradesv3.dry_run.sqlite
Backtesting also uses the config specified via `-c/--config`.
```
usage: freqtrade backtesting [-h] [-i TICKER_INTERVAL] [--timerange TIMERANGE]
[--max_open_trades INT]
[--stake_amount STAKE_AMOUNT] [--fee FLOAT]
usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-i TICKER_INTERVAL]
[--timerange TIMERANGE] [--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[--eps] [--dmmp]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
[--export EXPORT] [--export-filename PATH]
@@ -187,10 +211,12 @@ optional arguments:
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--max_open_trades INT
Specify max_open_trades to use.
--stake_amount STAKE_AMOUNT
Specify stake_amount.
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--eps, --enable-position-stacking
@@ -211,11 +237,32 @@ optional arguments:
--export EXPORT Export backtest results, argument are: trades.
Example: `--export=trades`
--export-filename PATH
Save backtest results to the file with this filename
(default: `user_data/backtest_results/backtest-
result.json`). Requires `--export` to be set as well.
Example: `--export-filename=user_data/backtest_results
/backtest_today.json`
Save backtest results to the file with this filename.
Requires `--export` to be set as well. Example:
`--export-filename=user_data/backtest_results/backtest
_today.json`
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
@@ -223,20 +270,22 @@ optional arguments:
The first time your run Backtesting, you will need to download some historic data first.
This can be accomplished by using `freqtrade download-data`.
Check the corresponding [help page section](backtesting.md#Getting-data-for-backtesting-and-hyperopt) for more details
Check the corresponding [Data Downloading](data-download.md) section for more details
## Hyperopt commands
To optimize your strategy, you can use hyperopt parameter hyperoptimization
to find optimal parameter values for your stategy.
to find optimal parameter values for your strategy.
```
usage: freqtrade hyperopt [-h] [-i TICKER_INTERVAL] [--timerange TIMERANGE]
[--max_open_trades INT]
[--stake_amount STAKE_AMOUNT] [--fee FLOAT]
[--customhyperopt NAME] [--hyperopt-path PATH]
[--eps] [-e INT]
[-s {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...]]
usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[-i TICKER_INTERVAL] [--timerange TIMERANGE]
[--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[--hyperopt NAME] [--hyperopt-path PATH] [--eps]
[-e INT]
[--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]]
[--dmmp] [--print-all] [--no-color] [--print-json]
[-j JOBS] [--random-state INT] [--min-trades INT]
[--continue] [--hyperopt-loss NAME]
@@ -248,24 +297,25 @@ optional arguments:
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--max_open_trades INT
Specify max_open_trades to use.
--stake_amount STAKE_AMOUNT
Specify stake_amount.
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--customhyperopt NAME
Specify hyperopt class name (default:
`DefaultHyperOpt`).
--hyperopt-path PATH Specify additional lookup path for Hyperopts and
--hyperopt NAME Specify hyperopt class name which will be used by the
bot.
--hyperopt-path PATH Specify additional lookup path for Hyperopt and
Hyperopt Loss functions.
--eps, --enable-position-stacking
Allow buying the same pair multiple times (position
stacking).
-e INT, --epochs INT Specify number of epochs (default: 100).
-s {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...], --spaces {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...]
--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]
Specify which parameters to hyperopt. Space-separated
list. Default: `all`.
list.
--dmmp, --disable-max-market-positions
Disable applying `max_open_trades` during backtest
(same as setting `max_open_trades` to a very high
@@ -273,7 +323,7 @@ optional arguments:
--print-all Print all results, not only the best ones.
--no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file.
--print-json Print best result detailization in JSON format.
--print-json Print best results in JSON format.
-j JOBS, --job-workers JOBS
The number of concurrently running jobs for
hyperoptimization (hyperopt worker processes). If -1
@@ -291,9 +341,34 @@ optional arguments:
class (IHyperOptLoss). Different functions can
generate completely different results, since the
target for optimization is different. Built-in
Hyperopt-loss-functions are: DefaultHyperOptLoss,
OnlyProfitHyperOptLoss, SharpeHyperOptLoss.(default:
`DefaultHyperOptLoss`).
Hyperopt-loss-functions are:
DefaultHyperOptLoss, OnlyProfitHyperOptLoss,
SharpeHyperOptLoss, SharpeHyperOptLossDaily,
SortinoHyperOptLoss, SortinoHyperOptLossDaily.
(default: `DefaultHyperOptLoss`).
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
## Edge commands
@@ -301,8 +376,10 @@ optional arguments:
To know your trade expectancy and winrate against historical data, you can use Edge.
```
usage: freqtrade edge [-h] [-i TICKER_INTERVAL] [--timerange TIMERANGE]
[--max_open_trades INT] [--stake_amount STAKE_AMOUNT]
usage: freqtrade edge [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[-i TICKER_INTERVAL] [--timerange TIMERANGE]
[--max-open-trades INT] [--stake-amount STAKE_AMOUNT]
[--fee FLOAT] [--stoplosses STOPLOSS_RANGE]
optional arguments:
@@ -312,10 +389,12 @@ optional arguments:
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--max_open_trades INT
Specify max_open_trades to use.
--stake_amount STAKE_AMOUNT
Specify stake_amount.
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--stoplosses STOPLOSS_RANGE
@@ -324,6 +403,28 @@ optional arguments:
(without any space). Example:
`--stoplosses=-0.01,-0.1,-0.001`
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
To understand edge and how to read the results, please read the [edge documentation](edge.md).

View File

@@ -34,109 +34,182 @@ The prevelance for all Options is as follows:
- CLI arguments override any other option
- Configuration files are used in sequence (last file wins), and override Strategy configurations.
- Strategy configurations are only used if they are not set via configuration or via command line arguments. These options are market with [Strategy Override](#parameters-in-the-strategy) in the below table.
- Strategy configurations are only used if they are not set via configuration or via command line arguments. These options are marked with [Strategy Override](#parameters-in-the-strategy) in the below table.
Mandatory parameters are marked as **Required**, which means that they are required to be set in one of the possible ways.
| Command | Default | Description |
|----------|---------|-------------|
| `max_open_trades` | 3 | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades)
| `stake_currency` | BTC | **Required.** Crypto-currency used for trading.
| `stake_amount` | 0.05 | **Required.** Amount of crypto-currency your bot will use for each trade. Per default, the bot will use (0.05 BTC x 3) = 0.15 BTC in total will be always engaged. Set it to `"unlimited"` to allow the bot to use all available balance.
| `amount_reserve_percent` | 0.05 | Reserve some amount in min pair stake amount. Default is 5%. The bot will reserve `amount_reserve_percent` + stop-loss value when calculating min pair stake amount in order to avoid possible trade refusals.
| `ticker_interval` | [1m, 5m, 15m, 30m, 1h, 1d, ...] | The ticker interval to use (1min, 5 min, 15 min, 30 min, 1 hour or 1 day). Default is 5 minutes. [Strategy Override](#parameters-in-the-strategy).
| `fiat_display_currency` | USD | **Required.** Fiat currency used to show your profits. More information below.
| `dry_run` | true | **Required.** Define if the bot must be in Dry-run or production mode.
| `dry_run_wallet` | 999.9 | Overrides the default amount of 999.9 stake currency units in the wallet used by the bot running in the Dry Run mode if you need it for any reason.
| `process_only_new_candles` | false | If set to true indicators are processed only once a new candle arrives. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy).
| `minimal_roi` | See below | Set the threshold in percent the bot will use to sell a trade. More information below. [Strategy Override](#parameters-in-the-strategy).
| `stoploss` | -0.10 | Value of the stoploss in percent used by the bot. More information below. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
| `trailing_stop` | false | Enables trailing stop-loss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
| `trailing_stop_positive` | 0 | Changes stop-loss once profit has been reached. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
| `trailing_stop_positive_offset` | 0 | Offset on when to apply `trailing_stop_positive`. Percentage value which should be positive. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
| `trailing_only_offset_is_reached` | false | Only apply trailing stoploss when the offset is reached. [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy).
| `unfilledtimeout.buy` | 10 | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled.
| `unfilledtimeout.sell` | 10 | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled.
| `bid_strategy.ask_last_balance` | 0.0 | **Required.** Set the bidding price. More information [below](#understand-ask_last_balance).
| `bid_strategy.use_order_book` | false | Allows buying of pair using the rates in Order Book Bids.
| `bid_strategy.order_book_top` | 0 | Bot will use the top N rate in Order Book Bids. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in Order Book Bids.
| `bid_strategy. check_depth_of_market.enabled` | false | Does not buy if the % difference of buy orders and sell orders is met in Order Book.
| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | 0 | The % difference of buy orders and sell orders found in Order Book. A value lesser than 1 means sell orders is greater, while value greater than 1 means buy orders is higher.
| `ask_strategy.use_order_book` | false | Allows selling of open traded pair using the rates in Order Book Asks.
| `ask_strategy.order_book_min` | 0 | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
| `ask_strategy.order_book_max` | 0 | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
| `ask_strategy.use_sell_signal` | true | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy).
| `ask_strategy.sell_profit_only` | false | Wait until the bot makes a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy).
| `ask_strategy.ignore_roi_if_buy_signal` | false | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy).
| `order_types` | None | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).
| `order_time_in_force` | None | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy).
| `exchange.name` | | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
| `exchange.sandbox` | false | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.
| `exchange.key` | '' | API key to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
| `exchange.secret` | '' | API secret to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
| `exchange.password` | '' | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests. ***Keep it in secrete, do not disclose publicly.***
| `exchange.pair_whitelist` | [] | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
| `exchange.pair_blacklist` | [] | List of pairs the bot must absolutely avoid for trading and backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
| `exchange.ccxt_config` | None | Additional CCXT parameters passed to the regular ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
| `exchange.ccxt_async_config` | None | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
| `exchange.markets_refresh_interval` | 60 | The interval in minutes in which markets are reloaded.
| `edge` | false | Please refer to [edge configuration document](edge.md) for detailed explanation.
| `experimental.block_bad_exchanges` | true | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now.
| `pairlist.method` | StaticPairList | Use static or dynamic volume-based pairlist. [More information below](#dynamic-pairlists).
| `pairlist.config` | None | Additional configuration for dynamic pairlists. [More information below](#dynamic-pairlists).
| `telegram.enabled` | true | **Required.** Enable or not the usage of Telegram.
| `telegram.token` | token | Your Telegram bot token. Only required if `telegram.enabled` is `true`. ***Keep it in secrete, do not disclose publicly.***
| `telegram.chat_id` | chat_id | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. ***Keep it in secrete, do not disclose publicly.***
| `webhook.enabled` | false | Enable usage of Webhook notifications
| `webhook.url` | false | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
| `webhook.webhookbuy` | false | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
| `webhook.webhooksell` | false | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
| `webhook.webhookstatus` | false | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
| `db_url` | `sqlite:///tradesv3.sqlite`| Declares database URL to use. NOTE: This defaults to `sqlite://` if `dry_run` is `True`.
| `initial_state` | running | Defines the initial application state. More information below.
| `forcebuy_enable` | false | Enables the RPC Commands to force a buy. More information below.
| `strategy` | DefaultStrategy | Defines Strategy class to use.
| `strategy_path` | null | Adds an additional strategy lookup path (must be a directory).
| `internals.process_throttle_secs` | 5 | **Required.** Set the process throttle. Value in second.
| `internals.heartbeat_interval` | 60 | Print heartbeat message every X seconds. Set to 0 to disable heartbeat messages.
| `internals.sd_notify` | false | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details.
| `logfile` | | Specify Logfile. Uses a rolling strategy of 10 files, with 1Mb per file.
| `user_data_dir` | cwd()/user_data | Directory containing user data. Defaults to `./user_data/`.
| Parameter | Description |
|------------|-------------|
| `max_open_trades` | **Required.** Number of open trades your bot is allowed to have. Only one open trade per pair is possible, so the length of your pairlist is another limitation which can apply. If -1 then it is ignored (i.e. potentially unlimited open trades, limited by the pairlist). [More information below](#configuring-amount-per-trade).<br> **Datatype:** Positive integer or -1.
| `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** String
| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Positive float or `"unlimited"`.
| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade). <br>*Defaults to `0.99` 99%).*<br> **Datatype:** Positive float between `0.1` and `1.0`.
| `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade). <br>*Defaults to `0.5`.* <br> **Datatype:** Float (as ratio)
| `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals. <br>*Defaults to `0.05` (5%).* <br> **Datatype:** Positive Float as ratio.
| `ticker_interval` | The timeframe (ticker interval) to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** String
| `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency). <br> **Datatype:** String
| `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode. <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in the Dry Run mode.<br>*Defaults to `1000`.* <br> **Datatype:** Float
| `cancel_open_orders_on_exit` | Cancel open orders when the `/stop` RPC command is issued, `Ctrl+C` is pressed or the bot dies unexpectedly. When set to `true`, this allows you to use `/stop` to cancel unfilled and partially filled orders in the event of a market crash. It does not impact open positions. <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `minimal_roi` | **Required.** Set the threshold in percent the bot will use to sell a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
| `stoploss` | **Required.** Value of the stoploss in percent used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Float (as ratio)
| `trailing_stop` | Enables trailing stoploss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Boolean
| `trailing_stop_positive` | Changes stoploss once profit has been reached. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Float
| `trailing_stop_positive_offset` | Offset on when to apply `trailing_stop_positive`. Percentage value which should be positive. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0` (no offset).* <br> **Datatype:** Float
| `trailing_only_offset_is_reached` | Only apply trailing stoploss when the offset is reached. [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `unfilledtimeout.buy` | **Required.** How long (in minutes) the bot will wait for an unfilled buy order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Integer
| `unfilledtimeout.sell` | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled. [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Integer
| `bid_strategy.price_side` | Select the side of the spread the bot should look at to get the buy rate. [More information below](#buy-price-side).<br> *Defaults to `bid`.* <br> **Datatype:** String (either `ask` or `bid`).
| `bid_strategy.ask_last_balance` | **Required.** Set the bidding price. More information [below](#buy-price-without-orderbook-enabled).
| `bid_strategy.use_order_book` | Enable buying using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled). <br> **Datatype:** Boolean
| `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book Bids to buy. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in [Order Book Bids](#buy-price-with-orderbook-enabled). <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
| `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market) <br> *Defaults to `0`.* <br> **Datatype:** Float (as ratio)
| `ask_strategy.price_side` | Select the side of the spread the bot should look at to get the sell rate. [More information below](#sell-price-side).<br> *Defaults to `ask`.* <br> **Datatype:** String (either `ask` or `bid`).
| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled). <br> **Datatype:** Boolean
| `ask_strategy.order_book_min` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate. <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
| `ask_strategy.order_book_max` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate. <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
| `ask_strategy.use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `ask_strategy.sell_profit_only` | Wait until the bot makes a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `ask_strategy.ignore_roi_if_buy_signal` | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `order_types` | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Dict
| `order_time_in_force` | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
| `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename). <br> **Datatype:** String
| `exchange.sandbox` | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.<br> **Datatype:** Boolean
| `exchange.key` | API key to use for the exchange. Only required when you are in production mode.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.pair_whitelist` | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Not used by VolumePairList (see [below](#pairlists-and-pairlist-handlers)). <br> **Datatype:** List
| `exchange.pair_blacklist` | List of pairs the bot must absolutely avoid for trading and backtesting (see [below](#pairlists-and-pairlist-handlers)). <br> **Datatype:** List
| `exchange.ccxt_config` | Additional CCXT parameters passed to the regular ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation) <br> **Datatype:** Dict
| `exchange.ccxt_async_config` | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation) <br> **Datatype:** Dict
| `exchange.markets_refresh_interval` | The interval in minutes in which markets are reloaded. <br>*Defaults to `60` minutes.* <br> **Datatype:** Positive Integer
| `edge.*` | Please refer to [edge configuration document](edge.md) for detailed explanation.
| `experimental.block_bad_exchanges` | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now. <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `pairlists` | Define one or more pairlists to be used. [More information below](#pairlists-and-pairlist-handlers). <br>*Defaults to `StaticPairList`.* <br> **Datatype:** List of Dicts
| `telegram.enabled` | Enable the usage of Telegram. <br> **Datatype:** Boolean
| `telegram.token` | Your Telegram bot token. Only required if `telegram.enabled` is `true`. <br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `telegram.chat_id` | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. <br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `webhook.enabled` | Enable usage of Webhook notifications <br> **Datatype:** Boolean
| `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookbuycancel` | Payload to send on buy order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhooksell` | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhooksellcancel` | Payload to send on sell order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details. <br> **Datatype:** Boolean
| `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details. <br> **Datatype:** IPv4
| `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details. <br>**Datatype:** Integer between 1024 and 65535
| `api_server.username` | Username for API server. See the [API Server documentation](rest-api.md) for more details. <br>**Keep it in secret, do not disclose publicly.**<br> **Datatype:** String
| `api_server.password` | Password for API server. See the [API Server documentation](rest-api.md) for more details. <br>**Keep it in secret, do not disclose publicly.**<br> **Datatype:** String
| `db_url` | Declares database URL to use. NOTE: This defaults to `sqlite:///tradesv3.dryrun.sqlite` if `dry_run` is `true`, and to `sqlite:///tradesv3.sqlite` for production instances. <br> **Datatype:** String, SQLAlchemy connect string
| `initial_state` | Defines the initial application state. More information below. <br>*Defaults to `stopped`.* <br> **Datatype:** Enum, either `stopped` or `running`
| `forcebuy_enable` | Enables the RPC Commands to force a buy. More information below. <br> **Datatype:** Boolean
| `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`. <br> **Datatype:** ClassName
| `strategy_path` | Adds an additional strategy lookup path (must be a directory). <br> **Datatype:** String
| `internals.process_throttle_secs` | Set the process throttle. Value in second. <br>*Defaults to `5` seconds.* <br> **Datatype:** Positive Integer
| `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages. <br>*Defaults to `60` seconds.* <br> **Datatype:** Positive Integer or 0
| `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details. <br> **Datatype:** Boolean
| `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file. <br> **Datatype:** String
| `user_data_dir` | Directory containing user data. <br> *Defaults to `./user_data/`*. <br> **Datatype:** String
| `dataformat_ohlcv` | Data format to use to store historical candle (OHLCV) data. <br> *Defaults to `json`*. <br> **Datatype:** String
| `dataformat_trades` | Data format to use to store historical trades data. <br> *Defaults to `jsongz`*. <br> **Datatype:** String
### Parameters in the strategy
The following parameters can be set in either configuration file or strategy.
Values set in the configuration file always overwrite values set in the strategy.
* `ticker_interval`
* `minimal_roi`
* `ticker_interval`
* `stoploss`
* `trailing_stop`
* `trailing_stop_positive`
* `trailing_stop_positive_offset`
* `trailing_only_offset_is_reached`
* `process_only_new_candles`
* `order_types`
* `order_time_in_force`
* `stake_currency`
* `stake_amount`
* `unfilledtimeout`
* `use_sell_signal` (ask_strategy)
* `sell_profit_only` (ask_strategy)
* `ignore_roi_if_buy_signal` (ask_strategy)
### Understand stake_amount
### Configuring amount per trade
The `stake_amount` configuration parameter is an amount of crypto-currency your bot will use for each trade.
The minimal value is 0.0005. If there is not enough crypto-currency in
the account an exception is generated.
To allow the bot to trade all the available `stake_currency` in your account set
There are several methods to configure how much of the stake currency the bot will use to enter a trade. All methods respect the [available balance configuration](#available-balance) as explained below.
#### Available balance
By default, the bot assumes that the `complete amount - 1%` is at it's disposal, and when using [dynamic stake amount](#dynamic-stake-amount), it will split the complete balance into `max_open_trades` buckets per trade.
Freqtrade will reserve 1% for eventual fees when entering a trade and will therefore not touch that by default.
You can configure the "untouched" amount by using the `tradable_balance_ratio` setting.
For example, if you have 10 ETH available in your wallet on the exchange and `tradable_balance_ratio=0.5` (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers this as available balance. The rest of the wallet is untouched by the trades.
!!! Warning
The `tradable_balance_ratio` setting applies to the current balance (free balance + tied up in trades). Therefore, assuming the starting balance of 1000, a configuration with `tradable_balance_ratio=0.99` will not guarantee that 10 currency units will always remain available on the exchange. For example, the free amount may reduce to 5 units if the total balance is reduced to 500 (either by a losing streak, or by withdrawing balance).
#### Amend last stake amount
Assuming we have the tradable balance of 1000 USDT, `stake_amount=400`, and `max_open_trades=3`.
The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades.
To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot.
In the example above this would mean:
- Trade1: 400 USDT
- Trade2: 400 USDT
- Trade3: 200 USDT
!!! Note
This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly.
!!! Note
The minimum last stake amount can be configured using `amend_last_stake_amount` - which defaults to 0.5 (50%). This means that the minimum stake amount that's ever used is `stake_amount * 0.5`. This avoids very low stake amounts, that are close to the minimum tradable amount for the pair and can be refused by the exchange.
#### Static stake amount
The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade.
The minimal configuration value is 0.0001, however, please check your exchange's trading minimums for the stake currency you're using to avoid problems.
This setting works in combination with `max_open_trades`. The maximum capital engaged in trades is `stake_amount * max_open_trades`.
For example, the bot will at most use (0.05 BTC x 3) = 0.15 BTC, assuming a configuration of `max_open_trades=3` and `stake_amount=0.05`.
!!! Note
This setting respects the [available balance configuration](#available-balance).
#### Dynamic stake amount
Alternatively, you can use a dynamic stake amount, which will use the available balance on the exchange, and divide that equally by the amount of allowed trades (`max_open_trades`).
To configure this, set `stake_amount="unlimited"`. We also recommend to set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees.
In this case a trade amount is calculated as:
```python
currency_balance / (max_open_trades - current_open_trades)
```
To allow the bot to trade all the available `stake_currency` in your account (minus `tradable_balance_ratio`) set
```json
"stake_amount" : "unlimited",
"tradable_balance_ratio": 0.99,
```
In this case a trade amount is calclulated as:
!!! Note
This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available).
```python
currency_balanse / (max_open_trades - current_open_trades)
```
!!! Note "When using Dry-Run Mode"
When using `"stake_amount" : "unlimited",` in combination with Dry-Run, the balance will be simulated starting with a stake of `dry_run_wallet` which will evolve over time. It is therefore important to set `dry_run_wallet` to a sensible value (like 0.05 or 0.01 for BTC and 1000 or 100 for USDT, for example), otherwise it may simulate trades with 100 BTC (or more) or 0.05 USDT (or less) at once - which may not correspond to your real available balance or is less than the exchange minimal limit for the order amount for the stake currency.
### Understand minimal_roi
@@ -158,6 +231,9 @@ This parameter can be set in either Strategy or Configuration file. If you use i
`minimal_roi` value from the strategy file.
If it is not set in either Strategy or Configuration, a default of 1000% `{"0": 10}` is used, and minimal roi is disabled unless your trade generates 1000% profit.
!!! Note "Special case to forcesell after a specific time"
A special case presents using `"<N>": -1` as ROI. This forces the bot to sell a trade after N Minutes, no matter if it's positive or negative, so represents a time-limited force-sell.
### Understand stoploss
Go to the [stoploss documentation](stoploss.md) for more details.
@@ -190,13 +266,6 @@ before asking the strategy if we should buy or a sell an asset. After each wait
every opened trade wether or not we should sell, and for all the remaining pairs (either the dynamic list of pairs or
the static list of pairs) if we should buy.
### Understand ask_last_balance
The `ask_last_balance` configuration parameter sets the bidding price. Value `0.0` will use `ask` price, `1.0` will
use the `last` price and values between those interpolate between ask and last
price. Using `ask` price will guarantee quick success in bid, but bot will also
end up paying more then would probably have been necessary.
### Understand order_types
The `order_types` configuration parameter maps actions (`buy`, `sell`, `stoploss`) to order-types (`market`, `limit`, ...) as well as configures stoploss to be on the exchange and defines stoploss on exchange update interval in seconds.
@@ -215,6 +284,11 @@ If this is configured, the following 4 values (`buy`, `sell`, `stoploss` and
`emergencysell` is an optional value, which defaults to `market` and is used when creating stoploss on exchange orders fails.
The below is the default which is used if this is not configured in either strategy or configuration file.
Since `stoploss_on_exchange` uses limit orders, the exchange needs 2 prices, the stoploss_price and the Limit price.
`stoploss` defines the stop-price - and limit should be slightly below this. This defaults to 0.99 / 1% (configurable via `stoploss_on_exchange_limit_ratio`).
Calculation example: we bought the asset at 100$.
Stop-price is 95$, then limit would be `95 * 0.99 = 94.05$` - so the stoploss will happen between 95$ and 94.05$.
Syntax for Strategy:
```python
@@ -224,7 +298,8 @@ order_types = {
"emergencysell": "market",
"stoploss": "market",
"stoploss_on_exchange": False,
"stoploss_on_exchange_interval": 60
"stoploss_on_exchange_interval": 60,
"stoploss_on_exchange_limit_ratio": 0.99,
}
```
@@ -254,7 +329,7 @@ Configuration:
!!! Note
If `stoploss_on_exchange` is enabled and the stoploss is cancelled manually on the exchange, then the bot will create a new order.
!!! Warning stoploss_on_exchange failures
!!! Warning "Warning: stoploss_on_exchange failures"
If stoploss on exchange creation fails for some reason, then an "emergency sell" is initiated. By default, this will sell the asset using a market order. The order-type for the emergency-sell can be changed by setting the `emergencysell` value in the `order_types` dictionary - however this is not advised.
### Understand order_time_in_force
@@ -268,7 +343,7 @@ This is most of the time the default time in force. It means the order will rema
on exchange till it is canceled by user. It can be fully or partially fulfilled.
If partially fulfilled, the remaining will stay on the exchange till cancelled.
**FOK (Full Or Kill):**
**FOK (Fill Or Kill):**
It means if the order is not executed immediately AND fully then it is canceled by the exchange.
@@ -298,16 +373,18 @@ The possible values are: `gtc` (default), `fok` or `ioc`.
Freqtrade is based on [CCXT library](https://github.com/ccxt/ccxt) that supports over 100 cryptocurrency
exchange markets and trading APIs. The complete up-to-date list can be found in the
[CCXT repo homepage](https://github.com/ccxt/ccxt/tree/master/python). However, the bot was tested
with only Bittrex and Binance.
The bot was tested with the following exchanges:
[CCXT repo homepage](https://github.com/ccxt/ccxt/tree/master/python).
However, the bot was tested by the development team with only Bittrex, Binance and Kraken,
so the these are the only officially supported exhanges:
- [Bittrex](https://bittrex.com/): "bittrex"
- [Binance](https://www.binance.com/): "binance"
- [Kraken](https://kraken.com/): "kraken"
Feel free to test other exchanges and submit your PR to improve the bot.
Some exchanges require special configuration, which can be found on the [Exchange-specific Notes](exchanges.md) documentation page.
#### Sample exchange configuration
A exchange configuration for "binance" would look as follows:
@@ -331,13 +408,13 @@ This configuration enables binance, as well as rate limiting to avoid bans from
Optimal settings for rate limiting depend on the exchange and the size of the whitelist, so an ideal parameter will vary on many other settings.
We try to provide sensible defaults per exchange where possible, if you encounter bans please make sure that `"enableRateLimit"` is enabled and increase the `"rateLimit"` parameter step by step.
#### Advanced FreqTrade Exchange configuration
#### Advanced Freqtrade Exchange configuration
Advanced options can be configured using the `_ft_has_params` setting, which will override Defaults and exchange-specific behaviours.
Available options are listed in the exchange-class as `_ft_has_default`.
For example, to test the order type `FOK` with Kraken, and modify candle_limit to 200 (so you only get 200 candles per call):
For example, to test the order type `FOK` with Kraken, and modify candle limit to 200 (so you only get 200 candles per API call):
```json
"exchange": {
@@ -370,6 +447,221 @@ The valid values are:
"BTC", "ETH", "XRP", "LTC", "BCH", "USDT"
```
## Prices used for orders
Prices for regular orders can be controlled via the parameter structures `bid_strategy` for buying and `ask_strategy` for selling.
Prices are always retrieved right before an order is placed, either by querying the exchange tickers or by using the orderbook data.
!!! Note
Orderbook data used by Freqtrade are the data retrieved from exchange by the ccxt's function `fetch_order_book()`, i.e. are usually data from the L2-aggregated orderbook, while the ticker data are the structures returned by the ccxt's `fetch_ticker()`/`fetch_tickers()` functions. Refer to the ccxt library [documentation](https://github.com/ccxt/ccxt/wiki/Manual#market-data) for more details.
### Buy price
#### Check depth of market
When check depth of market is enabled (`bid_strategy.check_depth_of_market.enabled=True`), the buy signals are filtered based on the orderbook depth (sum of all amounts) for each orderbook side.
Orderbook `bid` (buy) side depth is then divided by the orderbook `ask` (sell) side depth and the resulting delta is compared to the value of the `bid_strategy.check_depth_of_market.bids_to_ask_delta` parameter. The buy order is only executed if the orderbook delta is greater than or equal to the configured delta value.
!!! Note
A delta value below 1 means that `ask` (sell) orderbook side depth is greater than the depth of the `bid` (buy) orderbook side, while a value greater than 1 means opposite (depth of the buy side is higher than the depth of the sell side).
#### Buy price side
The configuration setting `bid_strategy.price_side` defines the side of the spread the bot looks for when buying.
The following displays an orderbook.
``` explanation
...
103
102
101 # ask
-------------Current spread
99 # bid
98
97
...
```
If `bid_strategy.price_side` is set to `"bid"`, then the bot will use 99 as buying price.
In line with that, if `bid_strategy.price_side` is set to `"ask"`, then the bot will use 101 as buying price.
Using `ask` price often guarantees quicker filled orders, but the bot can also end up paying more than what would have been necessary.
Taker fees instead of maker fees will most likely apply even when using limit buy orders.
Also, prices at the "ask" side of the spread are higher than prices at the "bid" side in the orderbook, so the order behaves similar to a market order (however with a maximum price).
#### Buy price with Orderbook enabled
When buying with the orderbook enabled (`bid_strategy.use_order_book=True`), Freqtrade fetches the `bid_strategy.order_book_top` entries from the orderbook and then uses the entry specified as `bid_strategy.order_book_top` on the configured side (`bid_strategy.price_side`) of the orderbook. 1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on.
#### Buy price without Orderbook enabled
The following section uses `side` as the configured `bid_strategy.price_side`.
When not using orderbook (`bid_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `side` price is above the `last` price), it calculates a rate between `side` and `last` price.
The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `side` price, while `1.0` will use the `last` price and values between those interpolate between ask and last price.
### Sell price
#### Sell price side
The configuration setting `ask_strategy.price_side` defines the side of the spread the bot looks for when selling.
The following displays an orderbook:
``` explanation
...
103
102
101 # ask
-------------Current spread
99 # bid
98
97
...
```
If `ask_strategy.price_side` is set to `"ask"`, then the bot will use 101 as selling price.
In line with that, if `ask_strategy.price_side` is set to `"bid"`, then the bot will use 99 as selling price.
#### Sell price with Orderbook enabled
When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the configured orderbook side are validated for a profitable sell-possibility based on the strategy configuration (`minimal_roi` conditions) and the sell order is placed at the first profitable spot.
!!! Note
Using `order_book_max` higher than `order_book_min` only makes sense when ask_strategy.price_side is set to `"ask"`.
The idea here is to place the sell order early, to be ahead in the queue.
A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number.
!!! Warning "Order_book_max > 1 - increased risks for stoplosses!"
Using `ask_strategy.order_book_max` higher than 1 will increase the risk the stoploss on exchange is cancelled too early, since an eventual [stoploss on exchange](#understand-order_types) will be cancelled as soon as the order is placed.
Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (with or without using stoploss on exchange).
!!! Warning "Order_book_max > 1 in dry-run"
Using `ask_strategy.order_book_max` higher than 1 will result in improper dry-run results (significantly better than real orders executed on exchange), since dry-run assumes orders to be filled almost instantly.
It is therefore advised to not use this setting for dry-runs.
#### Sell price without Orderbook enabled
When not using orderbook (`ask_strategy.use_order_book=False`), the price at the `ask_strategy.price_side` side (defaults to `"ask"`) from the ticker will be used as the sell price.
## Pairlists and Pairlist Handlers
Pairlist Handlers define the list of pairs (pairlist) that the bot should trade. They are configured in the `pairlists` section of the configuration settings.
In your configuration, you can use Static Pairlist (defined by the [`StaticPairList`](#static-pair-list) Pairlist Handler) and Dynamic Pairlist (defined by the [`VolumePairList`](#volume-pair-list) Pairlist Handler).
Additionaly, [`PrecisionFilter`](#precisionfilter), [`PriceFilter`](#pricefilter), [`ShuffleFilter`](#shufflefilter) and [`SpreadFilter`](#spreadfilter) act as Pairlist Filters, removing certain pairs and/or moving their positions in the pairlist.
If multiple Pairlist Handlers are used, they are chained and a combination of all Pairlist Handlers forms the resulting pairlist the bot uses for trading and backtesting. Pairlist Handlers are executed in the sequence they are configured. You should always configure either `StaticPairList` or `VolumePairList` as the starting Pairlist Handler.
Inactive markets are always removed from the resulting pairlist. Explicitly blacklisted pairs (those in the `pair_blacklist` configuration setting) are also always removed from the resulting pairlist.
### Available Pairlist Handlers
* [`StaticPairList`](#static-pair-list) (default, if not configured differently)
* [`VolumePairList`](#volume-pair-list)
* [`PrecisionFilter`](#precisionfilter)
* [`PriceFilter`](#pricefilter)
* [`ShuffleFilter`](#shufflefilter)
* [`SpreadFilter`](#spreadfilter)
!!! Tip "Testing pairlists"
Pairlist configurations can be quite tricky to get right. Best use the [`test-pairlist`](utils.md#test-pairlist) utility subcommand to test your configuration quickly.
#### Static Pair List
By default, the `StaticPairList` method is used, which uses a statically defined pair whitelist from the configuration.
It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklist`.
```json
"pairlists": [
{"method": "StaticPairList"}
],
```
#### Volume Pair List
`VolumePairList` employs sorting/filtering of pairs by their trading volume. I selects `number_assets` top pairs with sorting based on the `sort_key` (which can only be `quoteVolume`).
When used in the chain of Pairlist Handlers in a non-leading position (after StaticPairList and other Pairlist Filters), `VolumePairList` considers outputs of previous Pairlist Handlers, adding its sorting/selection of the pairs by the trading volume.
When used on the leading position of the chain of Pairlist Handlers, it does not consider `pair_whitelist` configuration setting, but selects the top assets from all available markets (with matching stake-currency) on the exchange.
The `refresh_period` setting allows to define the period (in seconds), at which the pairlist will be refreshed. Defaults to 1800s (30 minutes).
`VolumePairList` is based on the ticker data from exchange, as reported by the ccxt library:
* The `quoteVolume` is the amount of quote (stake) currency traded (bought or sold) in last 24 hours.
```json
"pairlists": [{
"method": "VolumePairList",
"number_assets": 20,
"sort_key": "quoteVolume",
"refresh_period": 1800,
],
```
#### PrecisionFilter
Filters low-value coins which would not allow setting stoplosses.
#### PriceFilter
The `PriceFilter` allows filtering of pairs by price.
Currently, only `low_price_ratio` setting is implemented, where a raise of 1 price unit (pip) is below the `low_price_ratio` ratio.
This option is disabled by default, and will only apply if set to <> 0.
Calculation example:
Min price precision is 8 decimals. If price is 0.00000011 - one step would be 0.00000012 - which is almost 10% higher than the previous value.
These pairs are dangerous since it may be impossible to place the desired stoploss - and often result in high losses. Here is what the PriceFilters takes over.
#### ShuffleFilter
Shuffles (randomizes) pairs in the pairlist. It can be used for preventing the bot from trading some of the pairs more frequently then others when you want all pairs be treated with the same priority.
!!! Tip
You may set the `seed` value for this Pairlist to obtain reproducible results, which can be useful for repeated backtesting sessions. If `seed` is not set, the pairs are shuffled in the non-repeatable random order.
#### SpreadFilter
Removes pairs that have a difference between asks and bids above the specified ratio, `max_spread_ratio` (defaults to `0.005`).
Example:
If `DOGE/BTC` maximum bid is 0.00000026 and minimum ask is 0.00000027, the ratio is calculated as: `1 - bid/ask ~= 0.037` which is `> 0.005` and this pair will be filtered out.
### Full example of Pairlist Handlers
The below example blacklists `BNB/BTC`, uses `VolumePairList` with `20` assets, sorting pairs by `quoteVolume` and applies both [`PrecisionFilter`](#precisionfilter) and [`PriceFilter`](#price-filter), filtering all assets where 1 priceunit is > 1%. Then the `SpreadFilter` is applied and pairs are finally shuffled with the random seed set to some predefined value.
```json
"exchange": {
"pair_whitelist": [],
"pair_blacklist": ["BNB/BTC"]
},
"pairlists": [
{
"method": "VolumePairList",
"number_assets": 20,
"sort_key": "quoteVolume",
},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01},
{"method": "SpreadFilter", "max_spread_ratio": 0.005},
{"method": "ShuffleFilter", "seed": 42}
],
```
## Switch to Dry-run mode
We recommend starting the bot in the Dry-run mode to see how your bot will
@@ -385,7 +677,7 @@ creating trades on the exchange.
"db_url": "sqlite:///tradesv3.dryrun.sqlite",
```
3. Remove your Exchange API key and secrete (change them by empty values or fake credentials):
3. Remove your Exchange API key and secret (change them by empty values or fake credentials):
```json
"exchange": {
@@ -396,41 +688,18 @@ creating trades on the exchange.
}
```
Once you will be happy with your bot performance running in the Dry-run mode,
you can switch it to production mode.
Once you will be happy with your bot performance running in the Dry-run mode, you can switch it to production mode.
### Dynamic Pairlists
!!! Note
A simulated wallet is available during dry-run mode, and will assume a starting capital of `dry_run_wallet` (defaults to 1000).
Dynamic pairlists select pairs for you based on the logic configured.
The bot runs against all pairs (with that stake) on the exchange, and a number of assets
(`number_assets`) is selected based on the selected criteria.
### Considerations for dry-run
By default, the `StaticPairList` method is used.
The Pairlist method is configured as `pair_whitelist` parameter under the `exchange`
section of the configuration.
**Available Pairlist methods:**
* `StaticPairList`
* It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklist`.
* `VolumePairList`
* It selects `number_assets` top pairs based on `sort_key`, which can be one of
`askVolume`, `bidVolume` and `quoteVolume`, defaults to `quoteVolume`.
* There is a possibility to filter low-value coins that would not allow setting a stop loss
(set `precision_filter` parameter to `true` for this).
Example:
```json
"pairlist": {
"method": "VolumePairList",
"config": {
"number_assets": 20,
"sort_key": "quoteVolume",
"precision_filter": false
}
},
```
* API-keys may or may not be provided. Only Read-Only operations (i.e. operations that do not alter account state) on the exchange are performed in the dry-run mode.
* Wallets (`/balance`) are simulated.
* Orders are simulated, and will not be posted to the exchange.
* In combination with `stoploss_on_exchange`, the stop_loss price is assumed to be filled.
* Open orders (not trades, which are stored in the database) are reset on bot restart.
## Switch to production mode
@@ -438,6 +707,11 @@ In production mode, the bot will engage your money. Be careful, since a wrong
strategy can lose all your money. Be aware of what you are doing when
you run it in production mode.
### Setup your exchange account
You will need to create API Keys (usually you get `key` and `secret`, some exchanges require an additional `password`) from the Exchange website and you'll need to insert this into the appropriate fields in the configuration or when asked by the `freqtrade new-config` command.
API Keys are usually only required for live trading (trading for real money, bot running in "production mode", executing real orders on the exchange) and are not required for the bot running in dry-run (trade simulation) mode. When you setup the bot in dry-run mode, you may fill these fields with empty values.
### To switch your bot in production mode
**Edit your `config.json` file.**
@@ -457,12 +731,11 @@ you run it in production mode.
"secret": "08a9dc6db3d7b53e1acebd9275677f4b0a04f1a5",
...
}
```
!!! Note
If you have an exchange API key yet, [see our tutorial](/pre-requisite).
### Using proxy with FreqTrade
You should also make sure to read the [Exchanges](exchanges.md) section of the documentation to be aware of potential configuration details specific to your exchange.
### Using proxy with Freqtrade
To use a proxy with freqtrade, add the kwarg `"aiohttp_trust_env"=true` to the `"ccxt_async_kwargs"` dict in the exchange section of the configuration.
@@ -482,14 +755,13 @@ export HTTPS_PROXY="http://addr:port"
freqtrade
```
## Embedding Strategies
### Embedding Strategies
FreqTrade provides you with with an easy way to embed the strategy into your configuration file.
Freqtrade provides you with with an easy way to embed the strategy into your configuration file.
This is done by utilizing BASE64 encoding and providing this string at the strategy configuration field,
in your chosen config file.
#### Encoding a string as BASE64
### Encoding a string as BASE64
This is a quick example, how to generate the BASE64 string in python

View File

@@ -8,6 +8,27 @@ You can analyze the results of backtests and trading history easily using Jupyte
* Don't forget to start a Jupyter notebook server from within your conda or venv environment or use [nb_conda_kernels](https://github.com/Anaconda-Platform/nb_conda_kernels)*
* Copy the example notebook before use so your changes don't get clobbered with the next freqtrade update.
### Using virtual environment with system-wide Jupyter installation
Sometimes it can be desired to use a system-wide installation of Jupyter notebook, and use a jupyter kernel from the virtual environment.
This prevents you from installing the full jupyter suite multiple times per system, and provides an easy way to switch between tasks (freqtrade / other analytics tasks).
For this to work, first activate your virtual environment and run the following commands:
``` bash
# Activate virtual environment
source .env/bin/activate
pip install ipykernel
ipython kernel install --user --name=freqtrade
# Restart jupyter (lab / notebook)
# select kernel "freqtrade" in the notebook
```
!!! Note
This section is provided for completeness, the Freqtrade Team won't provide full support for problems with this setup and will recommend to install Jupyter in the virtual environment directly, as that is the easiest way to get jupyter notebooks up and running. For help with this setup please refer to the [Project Jupyter](https://jupyter.org/) [documentation](https://jupyter.org/documentation) or [help channels](https://jupyter.org/community).
## Fine print
Some tasks don't work especially well in notebooks. For example, anything using asynchronous execution is a problem for Jupyter. Also, freqtrade's primary entry point is the shell cli, so using pure python in a notebook bypasses arguments that provide required objects and parameters to helper functions. You may need to set those values or create expected objects manually.

View File

@@ -8,10 +8,156 @@ If no additional parameter is specified, freqtrade will download data for `"1m"`
Exchange and pairs will come from `config.json` (if specified using `-c/--config`).
Otherwise `--exchange` becomes mandatory.
!!! Tip Updating existing data
!!! Tip "Tip: Updating existing data"
If you already have backtesting data available in your data-directory and would like to refresh this data up to today, use `--days xx` with a number slightly higher than the missing number of days. Freqtrade will keep the available data and only download the missing data.
Be carefull though: If the number is too small (which would result in a few missing days), the whole dataset will be removed and only xx days will be downloaded.
### Usage
```
usage: freqtrade download-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [-p PAIRS [PAIRS ...]]
[--pairs-file FILE] [--days INT] [--dl-trades] [--exchange EXCHANGE]
[-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...]]
[--erase] [--data-format-ohlcv {json,jsongz}] [--data-format-trades {json,jsongz}]
optional arguments:
-h, --help show this help message and exit
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
Show profits for only these pairs. Pairs are space-separated.
--pairs-file FILE File containing a list of pairs to download.
--days INT Download data for given number of days.
--dl-trades Download trades instead of OHLCV data. The bot will resample trades to the desired timeframe as specified as
--timeframes/-t.
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided.
-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...]
Specify which tickers to download. Space-separated list. Default: `1m 5m`.
--erase Clean all existing data for the selected exchange/pairs/timeframes.
--data-format-ohlcv {json,jsongz}
Storage format for downloaded candle (OHLCV) data. (default: `json`).
--data-format-trades {json,jsongz}
Storage format for downloaded trades data. (default: `jsongz`).
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-`
to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
### Data format
Freqtrade currently supports 2 dataformats, `json` (plain "text" json files) and `jsongz` (a gzipped version of json files).
By default, OHLCV data is stored as `json` data, while trades data is stored as `jsongz` data.
This can be changed via the `--data-format-ohlcv` and `--data-format-trades` parameters respectivly.
If the default dataformat has been changed during download, then the keys `dataformat_ohlcv` and `dataformat_trades` in the configuration file need to be adjusted to the selected dataformat as well.
!!! Note
You can convert between data-formats using the [convert-data](#subcommand-convert-data) and [convert-trade-data](#subcommand-convert-trade-data) methods.
#### Subcommand convert data
```
usage: freqtrade convert-data [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[-p PAIRS [PAIRS ...]] --format-from
{json,jsongz} --format-to {json,jsongz}
[--erase]
[-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...]]
optional arguments:
-h, --help show this help message and exit
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
Show profits for only these pairs. Pairs are space-
separated.
--format-from {json,jsongz}
Source format for data conversion.
--format-to {json,jsongz}
Destination format for data conversion.
--erase Clean all existing data for the selected
exchange/pairs/timeframes.
-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w} ...]
Specify which tickers to download. Space-separated
list. Default: `1m 5m`.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
##### Example converting data
The following command will convert all candle (OHLCV) data available in `~/.freqtrade/data/binance` from json to jsongz, saving diskspace in the process.
It'll also remove original json data files (`--erase` parameter).
``` bash
freqtrade convert-data --format-from json --format-to jsongz --data-dir ~/.freqtrade/data/binance -t 5m 15m --erase
```
#### Subcommand convert-trade data
```
usage: freqtrade convert-trade-data [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[-p PAIRS [PAIRS ...]] --format-from
{json,jsongz} --format-to {json,jsongz}
[--erase]
optional arguments:
-h, --help show this help message and exit
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
Show profits for only these pairs. Pairs are space-
separated.
--format-from {json,jsongz}
Source format for data conversion.
--format-to {json,jsongz}
Destination format for data conversion.
--erase Clean all existing data for the selected
exchange/pairs/timeframes.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
##### Example converting trades
The following command will convert all available trade-data in `~/.freqtrade/data/kraken` from jsongz to json.
It'll also remove original jsongz data files (`--erase` parameter).
``` bash
freqtrade convert-trade-data --format-from jsongz --format-to json --data-dir ~/.freqtrade/data/kraken --erase
```
### Pairs file
In alternative to the whitelist from `config.json`, a `pairs.json` file can be used.
@@ -46,15 +192,15 @@ Then run:
freqtrade download-data --exchange binance
```
This will download ticker data for all the currency pairs you defined in `pairs.json`.
This will download historical candle (OHLCV) data for all the currency pairs you defined in `pairs.json`.
### Other Notes
- To use a different directory than the exchange specific default, use `--datadir user_data/data/some_directory`.
- To change the exchange used to download the tickers, please use a different configuration file (you'll probably need to adjust ratelimits etc.)
- To change the exchange used to download the historical data from, please use a different configuration file (you'll probably need to adjust ratelimits etc.)
- To use `pairs.json` from some other directory, use `--pairs-file some_other_dir/pairs.json`.
- To download ticker data for only 10 days, use `--days 10` (defaults to 30 days).
- Use `--timeframes` to specify which tickers to download. Default is `--timeframes 1m 5m` which will download 1-minute and 5-minute tickers.
- To download historical candle (OHLCV) data for only 10 days, use `--days 10` (defaults to 30 days).
- 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.
### Trades (tick) data
@@ -78,10 +224,8 @@ freqtrade download-data --exchange binance --pairs XRP/ETH ETH/BTC --days 20 --d
!!! Warning
The historic trades are not available during Freqtrade dry-run and live trade modes because all exchanges tested provide this data with a delay of few 100 candles, so it's not suitable for real-time trading.
### Historic Kraken data
The Kraken API does only provide 720 historic candles, which is sufficient for FreqTrade dry-run and live trade modes, but is a problem for backtesting.
To download data for the Kraken exchange, using `--dl-trades` is mandatory, otherwise the bot will download the same 720 candles over and over, and you'll not have enough backtest data.
!!! Note "Kraken user"
Kraken users should read [this](exchanges.md#historic-kraken-data) before starting to download data.
## Next step

View File

@@ -24,3 +24,13 @@ and in freqtrade 2019.7 (master branch).
`--live` in the context of backtesting allowed to download the latest tick data for backtesting.
Did only download the latest 500 candles, so was ineffective in getting good backtest data.
Removed in 2019-7-dev (develop branch) and in freqtrade 2019-8 (master branch)
### Allow running multiple pairlists in sequence
The former `"pairlist"` section in the configuration has been removed, and is replaced by `"pairlists"` - being a list to specify a sequence of pairlists.
The old section of configuration parameters (`"pairlist"`) has been deprecated in 2019.11 and has been removed in 2020.4.
### deprecation of bidVolume and askVolume from volumepairlist
Since only quoteVolume can be compared between assets, the other options (bidVolume, askVolume) have been deprecated in 2020.4.

View File

@@ -1,6 +1,6 @@
# Development Help
This page is intended for developers of FreqTrade, people who want to contribute to the FreqTrade codebase or documentation, or people who want to understand the source code of the application they're running.
This page is intended for developers of Freqtrade, people who want to contribute to the Freqtrade codebase or documentation, or people who want to understand the source code of the application they're running.
All contributions, bug reports, bug fixes, documentation improvements, enhancements and ideas are welcome. We [track issues](https://github.com/freqtrade/freqtrade/issues) on [GitHub](https://github.com) and also have a dev channel in [slack](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) where you can ask questions.
@@ -46,15 +46,18 @@ def test_method_to_test(caplog):
The fastest and easiest way to start up is to use docker-compose.develop which gives developers the ability to start the bot up with all the required dependencies, *without* needing to install any freqtrade specific dependencies on your local machine.
#### Install
* [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [docker](https://docs.docker.com/install/)
* [docker-compose](https://docs.docker.com/compose/install/)
#### Starting the bot
##### Use the develop dockerfile
``` bash
rm docker-compose.yml && mv docker-compose.develop.yml docker-compose.yml
```
#### Docker Compose
##### Starting
@@ -62,9 +65,11 @@ rm docker-compose.yml && mv docker-compose.develop.yml docker-compose.yml
``` bash
docker-compose up
```
![Docker compose up](https://user-images.githubusercontent.com/419355/65456322-47f63a80-de06-11e9-90c6-3c74d1bad0b8.png)
##### Rebuilding
``` bash
docker-compose build
```
@@ -77,8 +82,8 @@ that can be effected by `docker-compose up` or `docker-compose run freqtrade_dev
``` bash
docker-compose exec freqtrade_develop /bin/bash
```
![image](https://user-images.githubusercontent.com/419355/65456522-ba671a80-de06-11e9-9598-df9ca0d8dcac.png)
![image](https://user-images.githubusercontent.com/419355/65456522-ba671a80-de06-11e9-9598-df9ca0d8dcac.png)
## Modules
@@ -95,22 +100,22 @@ This is a simple provider, which however serves as a good example on how to star
Next, modify the classname of the provider (ideally align this with the Filename).
The base-class provides the an instance of the bot (`self._freqtrade`), as well as the configuration (`self._config`), and initiates both `_blacklist` and `_whitelist`.
The base-class provides an instance of the exchange (`self._exchange`) the pairlist manager (`self._pairlistmanager`), as well as the main configuration (`self._config`), the pairlist dedicated configuration (`self._pairlistconfig`) and the absolute position within the list of pairlists.
```python
self._freqtrade = freqtrade
self._exchange = exchange
self._pairlistmanager = pairlistmanager
self._config = config
self._whitelist = self._config['exchange']['pair_whitelist']
self._blacklist = self._config['exchange'].get('pair_blacklist', [])
self._pairlistconfig = pairlistconfig
self._pairlist_pos = pairlist_pos
```
Now, let's step through the methods which require actions:
#### configuration
#### Pairlist configuration
Configuration for PairListProvider is done in the bot configuration file in the element `"pairlist"`.
This Pairlist-object may contain a `"config"` dict with additional configurations for the configured pairlist.
This Pairlist-object may contain configurations with additional configurations for the configured pairlist.
By convention, `"number_assets"` is used to specify the maximum number of pairs to keep in the whitelist. Please follow this to ensure a consistent user experience.
Additional elements can be configured as needed. `VolumePairList` uses `"sort_key"` to specify the sorting value - however feel free to specify whatever is necessary for your great algorithm to be successfull and dynamic.
@@ -120,34 +125,35 @@ Additional elements can be configured as needed. `VolumePairList` uses `"sort_ke
Returns a description used for Telegram messages.
This should contain the name of the Provider, as well as a short description containing the number of assets. Please follow the format `"PairlistName - top/bottom X pairs"`.
#### refresh_pairlist
#### filter_pairlist
Override this method and run all calculations needed in this method.
This is called with each iteration of the bot - so consider implementing caching for compute/network heavy calculations.
Assign the resulting whiteslist to `self._whitelist` and `self._blacklist` respectively. These will then be used to run the bot in this iteration. Pairs with open trades will be added to the whitelist to have the sell-methods run correctly.
It get's passed a pairlist (which can be the result of previous pairlists) as well as `tickers`, a pre-fetched version of `get_tickers()`.
Please also run `self._validate_whitelist(pairs)` and to check and remove pairs with inactive markets. This function is available in the Parent class (`StaticPairList`) and should ideally not be overwritten.
It must return the resulting pairlist (which may then be passed into the next pairlist filter).
Validations are optional, the parent class exposes a `_verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filters. Use this if you limit your result to a certain number of pairs - so the endresult is not shorter than expected.
##### sample
``` python
def refresh_pairlist(self) -> None:
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
# Generate dynamic whitelist
pairs = self._gen_pair_whitelist(self._config['stake_currency'], self._sort_key)
# Validate whitelist to only have active market pairs
self._whitelist = self._validate_whitelist(pairs)[:self._number_pairs]
pairs = self._calculate_pairlist(pairlist, tickers)
return pairs
```
#### _gen_pair_whitelist
This is a simple method used by `VolumePairList` - however serves as a good example.
It implements caching (`@cached(TTLCache(maxsize=1, ttl=1800))`) as well as a configuration option to allow different (but similar) strategies to work with the same PairListProvider.
In VolumePairList, this implements different methods of sorting, does early validation so only the expected number of pairs is returned.
## Implement a new Exchange (WIP)
!!! Note
This section is a Work in Progress and is not a complete guide on how to test a new exchange with FreqTrade.
This section is a Work in Progress and is not a complete guide on how to test a new exchange with Freqtrade.
Most exchanges supported by CCXT should work out of the box.
@@ -159,7 +165,7 @@ Since CCXT does not provide unification for Stoploss On Exchange yet, we'll need
### Incomplete candles
While fetching OHLCV data, we're may end up getting incomplete candles (Depending on the exchange).
While fetching candle (OHLCV) data, we may end up getting incomplete candles (depending on the exchange).
To demonstrate this, we'll use daily candles (`"1d"`) to keep things simple.
We query the api (`ct.fetch_ohlcv()`) for the timeframe and look at the date of the last entry. If this entry changes or shows the date of a "incomplete" candle, then we should drop this since having incomplete candles is problematic because indicators assume that only complete candles are passed to them, and will generate a lot of false buy signals. By default, we're therefore removing the last candle assuming it's incomplete.
@@ -168,74 +174,116 @@ To check how the new exchange behaves, you can use the following snippet:
``` python
import ccxt
from datetime import datetime
from freqtrade.data.converter import parse_ticker_dataframe
from freqtrade.data.converter import ohlcv_to_dataframe
ct = ccxt.binance()
timeframe = "1d"
pair = "XLM/BTC" # Make sure to use a pair that exists on that exchange!
raw = ct.fetch_ohlcv(pair, timeframe=timeframe)
# convert to dataframe
df1 = parse_ticker_dataframe(raw, timeframe, pair=pair, drop_incomplete=False)
df1 = ohlcv_to_dataframe(raw, timeframe, pair=pair, drop_incomplete=False)
print(df1["date"].tail(1))
print(df1.tail(1))
print(datetime.utcnow())
```
``` output
19 2019-06-08 00:00:00+00:00
date open high low close volume
499 2019-06-08 00:00:00+00:00 0.000007 0.000007 0.000007 0.000007 26264344.0
2019-06-09 12:30:27.873327
```
The output will show the last entry from the Exchange as well as the current UTC date.
If the day shows the same day, then the last candle can be assumed as incomplete and should be dropped (leave the setting `"ohlcv_partial_candle"` from the exchange-class untouched / True). Otherwise, set `"ohlcv_partial_candle"` to `False` to not drop Candles (shown in the example above).
Another way is to run this command multiple times in a row and observe if the volume is changing (while the date remains the same).
## Updating example notebooks
To keep the jupyter notebooks aligned with the documentation, the following should be ran after updating a example notebook.
``` bash
jupyter nbconvert --ClearOutputPreprocessor.enabled=True --inplace user_data/notebooks/strategy_analysis_example.ipynb
jupyter nbconvert --ClearOutputPreprocessor.enabled=True --to markdown user_data/notebooks/strategy_analysis_example.ipynb --stdout > docs/strategy_analysis_example.md
jupyter nbconvert --ClearOutputPreprocessor.enabled=True --inplace freqtrade/templates/strategy_analysis_example.ipynb
jupyter nbconvert --ClearOutputPreprocessor.enabled=True --to markdown freqtrade/templates/strategy_analysis_example.ipynb --stdout > docs/strategy_analysis_example.md
```
## Continuous integration
This documents some decisions taken for the CI Pipeline.
* CI runs on all OS variants, Linux (ubuntu), macOS and Windows.
* Docker images are build for the branches `master` and `develop`.
* Raspberry PI Docker images are postfixed with `_pi` - so tags will be `:master_pi` and `develop_pi`.
* Docker images contain a file, `/freqtrade/freqtrade_commit` containing the commit this image is based of.
* Full docker image rebuilds are run once a week via schedule.
* Deployments run on ubuntu.
* ta-lib binaries are contained in the build_helpers directory to avoid fails related to external unavailability.
* All tests must pass for a PR to be merged to `master` or `develop`.
## Creating a release
This part of the documentation is aimed at maintainers, and shows how to create a release.
### Create release branch
``` bash
# make sure you're in develop branch
git checkout develop
First, pick a commit that's about one week old (to not include latest additions to releases).
``` bash
# create new branch
git checkout -b new_release
git checkout -b new_release <commitid>
```
* 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.
Determine if crucial bugfixes have been made between this commit and the current state, and eventually cherry-pick these.
* Edit `freqtrade/__init__.py` and add the version matching the current date (for example `2019.7` for July 2019). Minor versions can be `2019.7.1` should we need to do a second release that month. Version numbers must follow allowed versions from PEP0440 to avoid failures pushing to pypi.
* Commit this part
* push that branch to the remote and create a PR against the master branch
### Create changelog from git commits
!!! Note
Make sure that both master and develop are up-todate!.
Make sure that the master branch is uptodate!
``` bash
# Needs to be done before merging / pulling that branch.
git log --oneline --no-decorate --no-merges master..develop
git log --oneline --no-decorate --no-merges master..new_release
```
To keep the release-log short, best wrap the full git changelog into a collapsible details secction.
```markdown
<details>
<summary>Expand full changelog</summary>
... Full git changelog
</details>
```
### Create github release / tag
Once the PR against master is merged (best right after merging):
* Use the button "Draft a new release" in the Github UI (subsection releases)
* Use the button "Draft a new release" in the Github UI (subsection releases).
* Use the version-number specified as tag.
* Use "master" as reference (this step comes after the above PR is merged).
* Use the above changelog as release comment (as codeblock)
### After-release
## Releases
* Update version in develop by postfixing that with `-dev` (`2019.6 -> 2019.6-dev`).
* Create a PR against develop to update that branch.
### pypi
To create a pypi release, please run the following commands:
Additional requirement: `wheel`, `twine` (for uploading), account on pypi with proper permissions.
``` bash
python setup.py sdist bdist_wheel
# For pypi test (to check if some change to the installation did work)
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
# For production:
twine upload dist/*
```
Please don't push non-releases to the productive / real pypi instance.

View File

@@ -1,4 +1,4 @@
# Using FreqTrade with Docker
# Using Freqtrade with Docker
## Install Docker
@@ -8,13 +8,144 @@ Start by downloading and installing Docker CE for your platform:
* [Windows](https://docs.docker.com/docker-for-windows/install/)
* [Linux](https://docs.docker.com/install/)
Optionally, [docker-compose](https://docs.docker.com/compose/install/) should be installed and available to follow the [docker quick start guide](#docker-quick-start).
Once you have Docker installed, simply prepare the config file (e.g. `config.json`) and run the image for `freqtrade` as explained below.
## Download the official FreqTrade docker image
## Freqtrade with docker-compose
Freqtrade provides an official Docker image on [Dockerhub](https://hub.docker.com/r/freqtradeorg/freqtrade/), as well as a [docker-compose file](https://github.com/freqtrade/freqtrade/blob/develop/docker-compose.yml) ready for usage.
!!! Note
The following section assumes that docker and docker-compose is installed and available to the logged in user.
!!! Note
All below comands use relative directories and will have to be executed from the directory containing the `docker-compose.yml` file.
!!! Note "Docker on Raspberry"
If you're running freqtrade on a Raspberry PI, you must change the image from `freqtradeorg/freqtrade:master` to `freqtradeorg/freqtrade:master_pi` or `freqtradeorg/freqtrade:develop_pi`, otherwise the image will not work.
### Docker quick start
Create a new directory and place the [docker-compose file](https://github.com/freqtrade/freqtrade/blob/develop/docker-compose.yml) in this directory.
``` bash
mkdir ft_userdata
cd ft_userdata/
# Download the docker-compose file from the repository
curl https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docker-compose.yml -o docker-compose.yml
# Pull the freqtrade image
docker-compose pull
# Create user directory structure
docker-compose run --rm freqtrade create-userdir --userdir user_data
# Create configuration - Requires answering interactive questions
docker-compose run --rm freqtrade new-config --config user_data/config.json
```
The above snippet creates a new directory called "ft_userdata", downloads the latest compose file and pulls the freqtrade image.
The last 2 steps in the snippet create the directory with user-data, as well as (interactively) the default configuration based on your selections.
!!! Note
You can edit the configuration at any time, which is available as `user_data/config.json` (within the directory `ft_userdata`) when using the above configuration.
#### Adding your strategy
The configuration is now available as `user_data/config.json`.
You should now copy your strategy to `user_data/strategies/` - and add the Strategy class name to the `docker-compose.yml` file, replacing `SampleStrategy`. If you wish to run the bot with the SampleStrategy, just leave it as it is.
!!! Warning
The `SampleStrategy` is there for your reference and give you ideas for your own strategy.
Please always backtest the strategy and use dry-run for some time before risking real money!
Once this is done, you're ready to launch the bot in trading mode (Dry-run or Live-trading, depending on your answer to the corresponding question you made above).
``` bash
docker-compose up -d
```
#### Docker-compose logs
Logs will be written to `user_data/logs/freqtrade.log`.
Alternatively, you can check the latest logs using `docker-compose logs -f`.
#### Database
The database will be in the user_data directory as well, and will be called `user_data/tradesv3.sqlite`.
#### Updating freqtrade with docker-compose
To update freqtrade when using docker-compose is as simple as running the following 2 commands:
``` bash
# Download the latest image
docker-compose pull
# Restart the image
docker-compose up -d
```
This will first pull the latest image, and will then restart the container with the just pulled version.
!!! Note
You should always check the changelog for breaking changes / manual interventions required and make sure the bot starts correctly after the update.
#### Going from here
Advanced users may edit the docker-compose file further to include all possible options or arguments.
All possible freqtrade arguments will be available by running `docker-compose run --rm freqtrade <command> <optional arguments>`.
!!! Note "`docker-compose run --rm`"
Including `--rm` will clean up the container after completion, and is highly recommended for all modes except trading mode (running with `freqtrade trade` command).
##### Example: Download data with docker-compose
Download backtesting data for 5 days for the pair ETH/BTC and 1h timeframe from Binance. The data will be stored in the directory `user_data/data/` on the host.
``` bash
docker-compose run --rm freqtrade download-data --pairs ETH/BTC --exchange binance --days 5 -t 1h
```
Head over to the [Data Downloading Documentation](data-download.md) for more details on downloading data.
##### Example: Backtest with docker-compose
Run backtesting in docker-containers for SampleStrategy and specified timerange of historical data, on 5m timeframe:
``` bash
docker-compose run --rm freqtrade backtesting --config user_data/config.json --strategy SampleStrategy --timerange 20190801-20191001 -i 5m
```
Head over to the [Backtesting Documentation](backtesting.md) to learn more.
#### Additional dependencies with docker-compose
If your strategy requires dependencies not included in the default image (like [technical](https://github.com/freqtrade/technical)) - it will be necessary to build the image on your host.
For this, please create a Dockerfile containing installation steps for the additional dependencies (have a look at [Dockerfile.technical](https://github.com/freqtrade/freqtrade/blob/develop/Dockerfile.technical) for an example).
You'll then also need to modify the `docker-compose.yml` file and uncomment the build step, as well as rename the image to avoid naming collisions.
``` yaml
image: freqtrade_custom
build:
context: .
dockerfile: "./Dockerfile.<yourextension>"
```
You can then run `docker-compose build` to build the docker image, and run it using the commands described above.
## Freqtrade with docker without docker-compose
!!! Warning
The below documentation is provided for completeness and assumes that you are somewhat familiar with running docker containers. If you're just starting out with docker, we recommend to follow the [Freqtrade with docker-compose](#freqtrade-with-docker-compose) instructions.
### Download the official Freqtrade docker image
Pull the image from docker hub.
Branches / tags available can be checked out on [Dockerhub](https://hub.docker.com/r/freqtradeorg/freqtrade/tags/).
Branches / tags available can be checked out on [Dockerhub tags page](https://hub.docker.com/r/freqtradeorg/freqtrade/tags/).
```bash
docker pull freqtradeorg/freqtrade:develop
@@ -26,7 +157,7 @@ To update the image, simply run the above commands again and restart your runnin
Should you require additional libraries, please [build the image yourself](#build-your-own-docker-image).
!!! Note Docker image update frequency
!!! Note "Docker image update frequency"
The official docker images with tags `master`, `develop` and `latest` are automatically rebuild once a week to keep the base image uptodate.
In addition to that, every merge to `develop` will trigger a rebuild for `develop` and `latest`.
@@ -160,16 +291,18 @@ docker run -d \
-v ~/.freqtrade/config.json:/freqtrade/config.json \
-v ~/.freqtrade/user_data/:/freqtrade/user_data \
-v ~/.freqtrade/tradesv3.sqlite:/freqtrade/tradesv3.sqlite \
freqtrade --db-url sqlite:///tradesv3.sqlite --strategy MyAwesomeStrategy
freqtrade trade --db-url sqlite:///tradesv3.sqlite --strategy MyAwesomeStrategy
```
!!! Note
db-url defaults to `sqlite:///tradesv3.sqlite` but it defaults to `sqlite://` if `dry_run=True` is being used.
To override this behaviour use a custom db-url value: i.e.: `--db-url sqlite:///tradesv3.dryrun.sqlite`
When using docker, it's best to specify `--db-url` explicitly to ensure that the database URL and the mounted database file match.
!!! Note
All available bot command line parameters can be added to the end of the `docker run` command.
!!! Note
You can define a [restart policy](https://docs.docker.com/config/containers/start-containers-automatically/) in docker. It can be useful in some cases to use the `--restart unless-stopped` flag (crash of freqtrade or reboot of your system).
### Monitor your Docker instance
You can use the following commands to monitor and manage your container:
@@ -199,7 +332,7 @@ docker run -d \
-v ~/.freqtrade/config.json:/freqtrade/config.json \
-v ~/.freqtrade/tradesv3.sqlite:/freqtrade/tradesv3.sqlite \
-v ~/.freqtrade/user_data/:/freqtrade/user_data/ \
freqtrade --strategy AwsomelyProfitableStrategy backtesting
freqtrade backtesting --strategy AwsomelyProfitableStrategy
```
Head over to the [Backtesting Documentation](backtesting.md) for more details.

View File

@@ -1,4 +1,4 @@
# Edge positioning
# Edge positioning
This page explains how to use Edge Positioning module in your bot in order to enter into a trade only if the trade has a reasonable win rate and risk reward ratio, and consequently adjust your position size and stoploss.
@@ -9,6 +9,7 @@ This page explains how to use Edge Positioning module in your bot in order to en
Edge does not consider anything else than buy/sell/stoploss signals. So trailing stoploss, ROI, and everything else are ignored in its calculation.
## Introduction
Trading is all about probability. No one can claim that he has a strategy working all the time. You have to assume that sometimes you lose.
But it doesn't mean there is no rule, it only means rules should work "most of the time". Let's play a game: we toss a coin, heads: I give you 10$, tails: you give me 10$. Is it an interesting game? No, it's quite boring, isn't it?
@@ -22,45 +23,63 @@ Let's complicate it more: you win 80% of the time but only 2$, I win 20% of the
The question is: How do you calculate that? How do you know if you wanna play?
The answer comes to two factors:
- Win Rate
- Risk Reward Ratio
### Win Rate
Win Rate (*W*) is is the mean over some amount of trades (*N*) what is the percentage of winning trades to total number of trades (note that we don't consider how much you gained but only if you won or not).
W = (Number of winning trades) / (Total number of trades) = (Number of winning trades) / N
```
W = (Number of winning trades) / (Total number of trades) = (Number of winning trades) / N
```
Complementary Loss Rate (*L*) is defined as
L = (Number of losing trades) / (Total number of trades) = (Number of losing trades) / N
```
L = (Number of losing trades) / (Total number of trades) = (Number of losing trades) / N
```
or, which is the same, as
L = 1 W
```
L = 1 W
```
### Risk Reward Ratio
Risk Reward Ratio (*R*) is a formula used to measure the expected gains of a given investment against the risk of loss. It is basically what you potentially win divided by what you potentially lose:
R = Profit / Loss
```
R = Profit / Loss
```
Over time, on many trades, you can calculate your risk reward by dividing your average profit on winning trades by your average loss on losing trades:
Average profit = (Sum of profits) / (Number of winning trades)
```
Average profit = (Sum of profits) / (Number of winning trades)
Average loss = (Sum of losses) / (Number of losing trades)
Average loss = (Sum of losses) / (Number of losing trades)
R = (Average profit) / (Average loss)
R = (Average profit) / (Average loss)
```
### Expectancy
At this point we can combine *W* and *R* to create an expectancy ratio. This is a simple process of multiplying the risk reward ratio by the percentage of winning trades and subtracting the percentage of losing trades, which is calculated as follows:
Expectancy Ratio = (Risk Reward Ratio X Win Rate) Loss Rate = (R X W) L
```
Expectancy Ratio = (Risk Reward Ratio X Win Rate) Loss Rate = (R X W) L
```
So lets say your Win rate is 28% and your Risk Reward Ratio is 5:
Expectancy = (5 X 0.28) 0.72 = 0.68
```
Expectancy = (5 X 0.28) 0.72 = 0.68
```
Superficially, this means that on average you expect this strategys trades to return .68 times the size of your loses. This is important for two reasons: First, it may seem obvious, but you know right away that you have a positive return. Second, you now have a number you can compare to other candidate systems to make decisions about which ones you employ.
Superficially, this means that on average you expect this strategys trades to return 1.68 times the size of your loses. Said another way, you can expect to win $1.68 for every $1 you lose. This is important for two reasons: First, it may seem obvious, but you know right away that you have a positive return. Second, you now have a number you can compare to other candidate systems to make decisions about which ones you employ.
It is important to remember that any system with an expectancy greater than 0 is profitable using past data. The key is finding one that will be profitable in the future.
@@ -69,6 +88,7 @@ You can also use this value to evaluate the effectiveness of modifications to th
**NOTICE:** It's important to keep in mind that Edge is testing your expectancy using historical data, there's no guarantee that you will have a similar edge in the future. It's still vital to do this testing in order to build confidence in your methodology, but be wary of "curve-fitting" your approach to the historical data as things are unlikely to play out the exact same way for future trades.
## How does it work?
If enabled in config, Edge will go through historical data with a range of stoplosses in order to find buy and sell/stoploss signals. It then calculates win rate and expectancy over *N* trades for each stoploss. Here is an example:
| Pair | Stoploss | Win Rate | Risk Reward Ratio | Expectancy |
@@ -83,6 +103,7 @@ The goal here is to find the best stoploss for the strategy in order to have the
Edge module then forces stoploss value it evaluated to your strategy dynamically.
### Position size
Edge also dictates the stake amount for each trade to the bot according to the following factors:
- Allowed capital at risk
@@ -90,13 +111,17 @@ Edge also dictates the stake amount for each trade to the bot according to the f
Allowed capital at risk is calculated as follows:
Allowed capital at risk = (Capital available_percentage) X (Allowed risk per trade)
```
Allowed capital at risk = (Capital available_percentage) X (Allowed risk per trade)
```
Stoploss is calculated as described above against historical data.
Your position size then will be:
Position size = (Allowed capital at risk) / Stoploss
```
Position size = (Allowed capital at risk) / Stoploss
```
Example:
@@ -115,100 +140,30 @@ Available capital doesnt change before a position is sold. Lets assume tha
So the Bot receives another buy signal for trade 4 with a stoploss at 2% then your position size would be **0.055 / 0.02 = 2.75 ETH**.
## Configurations
Edge module has following configuration options:
#### enabled
If true, then Edge will run periodically.
(defaults to false)
#### process_throttle_secs
How often should Edge run in seconds?
(defaults to 3600 so one hour)
#### calculate_since_number_of_days
Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy
Note that it downloads historical data so increasing this number would lead to slowing down the bot.
(defaults to 7)
#### capital_available_percentage
This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
(defaults to 0.5)
#### allowed_risk
Percentage of allowed risk per trade.
(defaults to 0.01 so 1%)
#### stoploss_range_min
Minimum stoploss.
(defaults to -0.01)
#### stoploss_range_max
Maximum stoploss.
(defaults to -0.10)
#### stoploss_range_step
As an example if this is set to -0.01 then Edge will test the strategy for \[-0.01, -0,02, -0,03 ..., -0.09, -0.10\] ranges.
Note than having a smaller step means having a bigger range which could lead to slow calculation.
If you set this parameter to -0.001, you then slow down the Edge calculation by a factor of 10.
(defaults to -0.01)
#### minimum_winrate
It filters out pairs which don't have at least minimum_winrate.
This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio.
(defaults to 0.60)
#### minimum_expectancy
It filters out pairs which have the expectancy lower than this number.
Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return.
(defaults to 0.20)
#### min_trade_number
When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable.
Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something.
(defaults to 10, it is highly recommended not to decrease this number)
#### max_trade_duration_minute
Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.
**NOTICE:** While configuring this value, you should take into consideration your ticker interval. As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).
(defaults to 1 day, i.e. to 60 * 24 = 1440 minutes)
#### remove_pumps
Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off.
(defaults to false)
| Parameter | Description |
|------------|-------------|
| `enabled` | If true, then Edge will run periodically. <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `process_throttle_secs` | How often should Edge run in seconds. <br>*Defaults to `3600` (once per hour).* <br> **Datatype:** Integer
| `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy. <br> **Note** that it downloads historical data so increasing this number would lead to slowing down the bot. <br>*Defaults to `7`.* <br> **Datatype:** Integer
| `capital_available_percentage` | **DEPRECATED - [replaced with `tradable_balance_ratio`](configuration.md#Available balance)** This is the percentage of the total capital on exchange in stake currency. <br>As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital. <br>*Defaults to `0.5`.* <br> **Datatype:** Float
| `allowed_risk` | Ratio of allowed risk per trade. <br>*Defaults to `0.01` (1%)).* <br> **Datatype:** Float
| `stoploss_range_min` | Minimum stoploss. <br>*Defaults to `-0.01`.* <br> **Datatype:** Float
| `stoploss_range_max` | Maximum stoploss. <br>*Defaults to `-0.10`.* <br> **Datatype:** Float
| `stoploss_range_step` | As an example if this is set to -0.01 then Edge will test the strategy for `[-0.01, -0,02, -0,03 ..., -0.09, -0.10]` ranges. <br> **Note** than having a smaller step means having a bigger range which could lead to slow calculation. <br> If you set this parameter to -0.001, you then slow down the Edge calculation by a factor of 10. <br>*Defaults to `-0.001`.* <br> **Datatype:** Float
| `minimum_winrate` | It filters out pairs which don't have at least minimum_winrate. <br>This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio. <br>*Defaults to `0.60`.* <br> **Datatype:** Float
| `minimum_expectancy` | It filters out pairs which have the expectancy lower than this number. <br>Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return. <br>*Defaults to `0.20`.* <br> **Datatype:** Float
| `min_trade_number` | When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable. <br>Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something. <br>*Defaults to `10` (it is highly recommended not to decrease this number).* <br> **Datatype:** Integer
| `max_trade_duration_minute` | Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.<br>**NOTICE:** While configuring this value, you should take into consideration your timeframe (ticker interval). As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).<br>*Defaults to `1440` (one day).* <br> **Datatype:** Integer
| `remove_pumps` | Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off.<br>*Defaults to `false`.* <br> **Datatype:** Boolean
## Running Edge independently
You can run Edge independently in order to see in details the result. Here is an example:
```bash
``` bash
freqtrade edge
```
@@ -235,7 +190,7 @@ An example of its output:
### Update cached pairs with the latest data
Edge requires historic data the same way as backtesting does.
Please refer to the [download section](backtesting.md#Getting-data-for-backtesting-and-hyperopt) of the documentation for details.
Please refer to the [Data Downloading](data-download.md) section of the documentation for details.
### Precising stoploss range

86
docs/exchanges.md Normal file
View File

@@ -0,0 +1,86 @@
# Exchange-specific Notes
This page combines common gotchas and informations which are exchange-specific and most likely don't apply to other exchanges.
## Binance
!!! Tip "Stoploss on Exchange"
Binance supports `stoploss_on_exchange` and uses stop-loss-limit orders. It provides great advantages, so we recommend to benefit from it.
### Blacklists
For Binance, please add `"BNB/<STAKE>"` to your blacklist to avoid issues.
Accounts having BNB accounts use this to pay for fees - if your first trade happens to be on `BNB`, further trades will consume this position and make the initial BNB order unsellable as the expected amount is not there anymore.
### Binance sites
Binance has been split into 3, and users must use the correct ccxt exchange ID for their exchange, otherwise API keys are not recognized.
* [binance.com](https://www.binance.com/) - International users. Use exchange id: `binance`.
* [binance.us](https://www.binance.us/) - US based users. Use exchange id: `binanceus`.
* [binance.je](https://www.binance.je/) - Binance Jersey, trading fiat currencies. Use exchange id: `binanceje`.
## Kraken
!!! Tip "Stoploss on Exchange"
Kraken supports `stoploss_on_exchange` and uses stop-loss-market orders. It provides great advantages, so we recommend to benefit from it, however since the resulting order is a stoploss-market order, sell-rates are not guaranteed, which makes this feature less secure than on other exchanges. This limitation is based on kraken's policy [source](https://blog.kraken.com/post/1234/announcement-delisting-pairs-and-temporary-suspension-of-advanced-order-types/) and [source2](https://blog.kraken.com/post/1494/kraken-enables-advanced-orders-and-adds-10-currency-pairs/) - which has stoploss-limit orders disabled.
### Historic Kraken data
The Kraken API does only provide 720 historic candles, which is sufficient for Freqtrade dry-run and live trade modes, but is a problem for backtesting.
To download data for the Kraken exchange, using `--dl-trades` is mandatory, otherwise the bot will download the same 720 candles over and over, and you'll not have enough backtest data.
## Bittrex
### Order types
Bittrex does not support market orders. If you have a message at the bot startup about this, you should change order type values set in your configuration and/or in the strategy from `"market"` to `"limit"`. See some more details on this [here in the FAQ](faq.md#im-getting-the-exchange-bittrex-does-not-support-market-orders-message-and-cannot-run-my-strategy).
### Restricted markets
Bittrex split its exchange into US and International versions.
The International version has more pairs available, however the API always returns all pairs, so there is currently no automated way to detect if you're affected by the restriction.
If you have restricted pairs in your whitelist, you'll get a warning message in the log on Freqtrade startup for each restricted pair.
The warning message will look similar to the following:
``` output
[...] Message: bittrex {"success":false,"message":"RESTRICTED_MARKET","result":null,"explanation":null}"
```
If you're an "International" customer on the Bittrex exchange, then this warning will probably not impact you.
If you're a US customer, the bot will fail to create orders for these pairs, and you should remove them from your whitelist.
You can get a list of restricted markets by using the following snippet:
``` python
import ccxt
ct = ccxt.bittrex()
_ = ct.load_markets()
res = [ f"{x['MarketCurrency']}/{x['BaseCurrency']}" for x in ct.publicGetMarkets()['result'] if x['IsRestricted']]
print(res)
```
## All exchanges
Should you experience constant errors with Nonce (like `InvalidNonce`), it is best to regenerate the API keys. Resetting Nonce is difficult and it's usually easier to regenerate the API keys.
## Random notes for other exchanges
* The Ocean (exchange id: `theocean`) exchange uses Web3 functionality and requires `web3` python package to be installed:
```shell
$ pip3 install web3
```
### Getting latest price / Incomplete candles
Most exchanges return current incomplete candle via their OHLCV/klines API interface.
By default, Freqtrade assumes that incomplete candle is fetched from the exchange and removes the last candle assuming it's the incomplete candle.
Whether your exchange returns incomplete candles or not can be checked using [the helper script](developer.md#Incomplete-candles) from the Contributor documentation.
Due to the danger of repainting, Freqtrade does not allow you to use this incomplete candle.
However, if it is based on the need for the latest price for your strategy - then this requirement can be acquired using the [data provider](strategy-customization.md#possible-options-for-dataprovider) from within the strategy.

View File

@@ -4,7 +4,7 @@
### The bot does not start
Running the bot with `freqtrade --config config.json` does show the output `freqtrade: command not found`.
Running the bot with `freqtrade trade --config config.json` does show the output `freqtrade: command not found`.
This could have the following reasons:
@@ -45,15 +45,65 @@ the tutorial [here|Testing-new-strategies-with-Hyperopt](bot-usage.md#hyperopt-c
You can use the `/forcesell all` command from Telegram.
### I get the message "RESTRICTED_MARKET"
### I'm getting the "RESTRICTED_MARKET" message in the log
Currently known to happen for US Bittrex users.
Bittrex split its exchange into US and International versions.
The International version has more pairs available, however the API always returns all pairs, so there is currently no automated way to detect if you're affected by the restriction.
If you have restricted pairs in your whitelist, you'll get a warning message in the log on FreqTrade startup for each restricted pair.
If you're an "International" Customer on the Bittrex exchange, then this warning will probably not impact you.
If you're a US customer, the bot will fail to create orders for these pairs, and you should remove them from your Whitelist.
Read [the Bittrex section about restricted markets](exchanges.md#restricted-markets) for more information.
### I'm getting the "Exchange Bittrex does not support market orders." message and cannot run my strategy
As the message says, Bittrex does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Probably your strategy was written with other exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of the exchanges supporting market orders (but not for Bittrex).
To fix it for Bittrex, redefine order types in the strategy to use "limit" instead of "market":
```
order_types = {
...
'stoploss': 'limit',
...
}
```
Same fix should be done in the configuration file, if order types are defined in your custom config rather than in the strategy.
### How do I search the bot logs for something?
By default, the bot writes its log into stderr stream. This is implemented this way so that you can easily separate the bot's diagnostics messages from Backtesting, Edge and Hyperopt results, output from other various Freqtrade utility subcommands, as well as from the output of your custom `print()`'s you may have inserted into your strategy. So if you need to search the log messages with the grep utility, you need to redirect stderr to stdout and disregard stdout.
* In unix shells, this normally can be done as simple as:
```shell
$ freqtrade --some-options 2>&1 >/dev/null | grep 'something'
```
(note, `2>&1` and `>/dev/null` should be written in this order)
* Bash interpreter also supports so called process substitution syntax, you can grep the log for a string with it as:
```shell
$ freqtrade --some-options 2> >(grep 'something') >/dev/null
```
or
```shell
$ freqtrade --some-options 2> >(grep -v 'something' 1>&2)
```
* You can also write the copy of Freqtrade log messages to a file with the `--logfile` option:
```shell
$ freqtrade --logfile /path/to/mylogfile.log --some-options
```
and then grep it as:
```shell
$ cat /path/to/mylogfile.log | grep 'something'
```
or even on the fly, as the bot works and the logfile grows:
```shell
$ tail -f /path/to/mylogfile.log | grep 'something'
```
from a separate terminal window.
On Windows, the `--logfile` option is also supported by Freqtrade and you can use the `findstr` command to search the log for the string of interest:
```
> type \path\to\mylogfile.log | findstr "something"
```
## Hyperopt module

View File

@@ -6,39 +6,82 @@ algorithms included in the `scikit-optimize` package to accomplish this. The
search will burn all your CPU cores, make your laptop sound like a fighter jet
and still take a long time.
In general, the search for best parameters starts with a few random combinations (see [below](#reproducible-results) for more details) and then uses Bayesian search with a ML regressor algorithm (currently ExtraTreesRegressor) to quickly find a combination of parameters in the search hyperspace that minimizes the value of the [loss function](#loss-functions).
Hyperopt requires historic data to be available, just as backtesting does.
To learn how to get data for the pairs and exchange you're interrested in, head over to the [Data Downloading](data-download.md) section of the documentation.
To learn how to get data for the pairs and exchange you're interested in, head over to the [Data Downloading](data-download.md) section of the documentation.
!!! Bug
Hyperopt can crash when used with only 1 CPU Core as found out in [Issue #1133](https://github.com/freqtrade/freqtrade/issues/1133)
## Install hyperopt dependencies
Since Hyperopt dependencies are not needed to run the bot itself, are heavy, can not be easily built on some platforms (like Raspberry PI), they are not installed by default. Before you run Hyperopt, you need to install the corresponding dependencies, as described in this section below.
!!! Note
Since Hyperopt is a resource intensive process, running it on a Raspberry Pi is not recommended nor supported.
### Docker
The docker-image includes hyperopt dependencies, no further action needed.
### Easy installation script (setup.sh) / Manual installation
```bash
source .env/bin/activate
pip install -r requirements-hyperopt.txt
```
## Prepare Hyperopting
Before we start digging into Hyperopt, we recommend you to take a look at
the sample hyperopt file located in [user_data/hyperopts/](https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt.py).
the sample hyperopt file located in [user_data/hyperopts/](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt.py).
Configuring hyperopt is similar to writing your own strategy, and many tasks will be similar and a lot of code can be copied across from the strategy.
The simplest way to get started is to use `freqtrade new-hyperopt --hyperopt AwesomeHyperopt`.
This will create a new hyperopt file from a template, which will be located under `user_data/hyperopts/AwesomeHyperopt.py`.
### Checklist on all tasks / possibilities in hyperopt
Depending on the space you want to optimize, only some of the below are required:
* fill `populate_indicators` - probably a copy from your strategy
* fill `buy_strategy_generator` - for buy signal optimization
* fill `indicator_space` - for buy signal optimzation
* fill `indicator_space` - for buy signal optimization
* fill `sell_strategy_generator` - for sell signal optimization
* fill `sell_indicator_space` - for sell signal optimzation
* fill `sell_indicator_space` - for sell signal optimization
Optional, but recommended:
!!! Note
`populate_indicators` needs to create all indicators any of thee spaces may use, otherwise hyperopt will not work.
Optional - can also be loaded from a strategy:
* copy `populate_indicators` from your strategy - otherwise default-strategy will be used
* copy `populate_buy_trend` from your strategy - otherwise default-strategy will be used
* copy `populate_sell_trend` from your strategy - otherwise default-strategy will be used
!!! Note
Assuming the optional methods are not in your hyperopt file, please use `--strategy AweSomeStrategy` which contains these methods so hyperopt can use these methods instead.
!!! Note
You always have to provide a strategy to Hyperopt, even if your custom Hyperopt class contains all methods.
Rarely you may also need to override:
* `roi_space` - for custom ROI optimization (if you need the ranges for the ROI parameters in the optimization hyperspace that differ from default)
* `generate_roi_table` - for custom ROI optimization (if you need more than 4 entries in the ROI table)
* `generate_roi_table` - for custom ROI optimization (if you need the ranges for the values in the ROI table that differ from default or the number of entries (steps) in the ROI table which differs from the default 4 steps)
* `stoploss_space` - for custom stoploss optimization (if you need the range for the stoploss parameter in the optimization hyperspace that differs from default)
* `trailing_space` - for custom trailing stop optimization (if you need the ranges for the trailing stop parameters in the optimization hyperspace that differ from default)
!!! Tip "Quickly optimize ROI, stoploss and trailing stoploss"
You can quickly optimize the spaces `roi`, `stoploss` and `trailing` without changing anything (i.e. without creation of a "complete" Hyperopt class with dimensions, parameters, triggers and guards, as described in this document) from the default hyperopt template by relying on your strategy to do most of the calculations.
```python
# Have a working strategy at hand.
freqtrade new-hyperopt --hyperopt EmptyHyperopt
freqtrade hyperopt --hyperopt EmptyHyperopt --spaces roi stoploss trailing --strategy MyWorkingStrategy --config config.json -e 100
```
### 1. Install a Custom Hyperopt File
@@ -51,17 +94,17 @@ Copy the file `user_data/hyperopts/sample_hyperopt.py` into `user_data/hyperopts
There are two places you need to change in your hyperopt file to add a new buy hyperopt for testing:
- Inside `indicator_space()` - the parameters hyperopt shall be optimizing.
- Inside `populate_buy_trend()` - applying the parameters.
* Inside `indicator_space()` - the parameters hyperopt shall be optimizing.
* Inside `populate_buy_trend()` - applying the parameters.
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".
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".
Hyperoptimization will, for each eval round, pick one trigger and possibly
multiple guards. The constructed strategy will be something like
"*buy exactly when close price touches lower bollinger band, BUT only if
"*buy exactly when close price touches lower Bollinger band, BUT only if
ADX > 10*".
If you have updated the buy strategy, i.e. changed the contents of
@@ -79,9 +122,10 @@ Place the corresponding settings into the following methods
The configuration and rules are the same than for buy signals.
To avoid naming collisions in the search-space, please prefix all sell-spaces with `sell-`.
#### Using ticker-interval as part of the Strategy
#### Using timeframe as a part of the Strategy
The Strategy exposes the ticker-interval as `self.ticker_interval`. The same value is available as class-attribute `HyperoptName.ticker_interval`.
The Strategy class exposes the timeframe (ticker interval) value as the `self.ticker_interval` attribute.
The same value is available as class-attribute `HyperoptName.ticker_interval`.
In the case of the linked sample-value this would be `SampleHyperOpt.ticker_interval`.
## Solving a Mystery
@@ -117,7 +161,7 @@ one we call `trigger` and use it to decide which buy trigger we want to use.
So let's write the buy strategy using these values:
``` python
```python
def populate_buy_trend(dataframe: DataFrame) -> DataFrame:
conditions = []
# GUARDS AND TRENDS
@@ -135,6 +179,9 @@ So let's write the buy strategy using these values:
dataframe['macd'], dataframe['macdsignal']
))
# Check that volume is not 0
conditions.append(dataframe['volume'] > 0)
if conditions:
dataframe.loc[
reduce(lambda x, y: x & y, conditions),
@@ -148,21 +195,17 @@ So let's write the buy strategy using these values:
Hyperopting will now call this `populate_buy_trend` as many times you ask it (`epochs`)
with different value combinations. It will then use the given historical data and make
buys based on the buy signals generated with the above function and based on the results
it will end with telling you which paramter combination produced the best profits.
The search for best parameters starts with a few random combinations and then uses a
regressor algorithm (currently ExtraTreesRegressor) to quickly find a parameter combination
that minimizes the value of the [loss function](#loss-functions).
it will end with telling you which parameter combination produced the best profits.
The above setup expects to find ADX, RSI and Bollinger Bands in the populated indicators.
When you want to test an indicator that isn't used by the bot currently, remember to
add it to the `populate_indicators()` method in `hyperopt.py`.
add it to the `populate_indicators()` method in your custom hyperopt file.
## Loss-functions
Each hyperparameter tuning requires a target. This is usually defined as a loss function (sometimes also called objective function), which should decrease for more desirable results, and increase for bad results.
By default, FreqTrade uses a loss function, which has been with freqtrade since the beginning and optimizes mostly for short trade duration and avoiding losses.
By default, Freqtrade uses a loss function, which has been with freqtrade since the beginning and optimizes mostly for short trade duration and avoiding losses.
A different loss function can be specified by using the `--hyperopt-loss <Class-name>` argument.
This class should be in its own file within the `user_data/hyperopts/` directory.
@@ -171,65 +214,12 @@ Currently, the following loss functions are builtin:
* `DefaultHyperOptLoss` (default legacy Freqtrade hyperoptimization loss function)
* `OnlyProfitHyperOptLoss` (which takes only amount of profit into consideration)
* `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on the trade returns)
* `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on trade returns relative to standard deviation)
* `SharpeHyperOptLossDaily` (optimizes Sharpe Ratio calculated on **daily** trade returns relative to standard deviation)
* `SortinoHyperOptLoss` (optimizes Sortino Ratio calculated on trade returns relative to **downside** standard deviation)
* `SortinoHyperOptLossDaily` (optimizes Sortino Ratio calculated on **daily** trade returns relative to **downside** standard deviation)
### Creating and using a custom loss function
To use a custom loss function class, make sure that the function `hyperopt_loss_function` is defined in your custom hyperopt loss class.
For the sample below, you then need to add the command line parameter `--hyperopt-loss SuperDuperHyperOptLoss` to your hyperopt call so this fuction is being used.
A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found [user_data/hyperopts/](https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_loss.py)
``` python
from freqtrade.optimize.hyperopt import IHyperOptLoss
TARGET_TRADES = 600
EXPECTED_MAX_PROFIT = 3.0
MAX_ACCEPTED_TRADE_DURATION = 300
class SuperDuperHyperOptLoss(IHyperOptLoss):
"""
Defines the default loss function for hyperopt
"""
@staticmethod
def hyperopt_loss_function(results: DataFrame, trade_count: int,
min_date: datetime, max_date: datetime,
*args, **kwargs) -> float:
"""
Objective function, returns smaller number for better results
This is the legacy algorithm (used until now in freqtrade).
Weights are distributed as follows:
* 0.4 to trade duration
* 0.25: Avoiding trade loss
* 1.0 to total profit, compared to the expected value (`EXPECTED_MAX_PROFIT`) defined above
"""
total_profit = results.profit_percent.sum()
trade_duration = results.trade_duration.mean()
trade_loss = 1 - 0.25 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.8)
profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT)
duration_loss = 0.4 * min(trade_duration / MAX_ACCEPTED_TRADE_DURATION, 1)
result = trade_loss + profit_loss + duration_loss
return result
```
Currently, the arguments are:
* `results`: DataFrame containing the result
The following columns are available in results (corresponds to the output-file of backtesting when used with `--export trades`):
`pair, profit_percent, profit_abs, open_time, close_time, open_index, close_index, trade_duration, open_at_end, open_rate, close_rate, sell_reason`
* `trade_count`: Amount of trades (identical to `len(results)`)
* `min_date`: Start date of the hyperopting TimeFrame
* `min_date`: End date of the hyperopting TimeFrame
This function needs to return a floating point number (`float`). Smaller numbers will be interpreted as better results. The parameters and balancing for this is up to you.
!!! Note
This function is called once per iteration - so please make sure to have this as optimized as possible to not slow hyperopt down unnecessarily.
!!! Note
Please keep the arguments `*args` and `**kwargs` in the interface to allow us to extend this interface later.
Creation of a custom loss function is covered in the [Advanced Hyperopt](advanced-hyperopt.md) part of the documentation.
## Execute Hyperopt
@@ -239,15 +229,15 @@ Because hyperopt tries a lot of combinations to find the best parameters it will
We strongly recommend to use `screen` or `tmux` to prevent any connection loss.
```bash
freqtrade -c config.json hyperopt --customhyperopt <hyperoptname> -e 5000 --spaces all
freqtrade hyperopt --config config.json --hyperopt <hyperoptname> -e 5000 --spaces all
```
Use `<hyperoptname>` as the name of the custom hyperopt used.
Use `<hyperoptname>` as the name of the custom hyperopt used.
The `-e` flag will set how many evaluations hyperopt will do. We recommend
The `-e` option will set how many evaluations hyperopt will do. We recommend
running at least several thousand evaluations.
The `--spaces all` flag determines that all possible parameters should be optimized. Possibilities are listed below.
The `--spaces all` option determines that all possible parameters should be optimized. Possibilities are listed below.
!!! Note
By default, hyperopt will erase previous results and start from scratch. Continuation can be archived by using `--continue`.
@@ -255,11 +245,11 @@ The `--spaces all` flag determines that all possible parameters should be optimi
!!! Warning
When switching parameters or changing configuration options, make sure to not use the argument `--continue` so temporary results can be removed.
### Execute Hyperopt with Different Ticker-Data Source
### Execute Hyperopt with different historical data source
If you would like to hyperopt parameters using an alternate ticker data that
you have on-disk, use the `--datadir PATH` option. Default hyperopt will
use data from directory `user_data/data`.
If you would like to hyperopt parameters using an alternate historical data set that
you have on-disk, use the `--datadir PATH` option. By default, hyperopt
uses data from directory `user_data/data`.
### Running Hyperopt with Smaller Testset
@@ -270,9 +260,17 @@ For example, to use one month of data, pass the following parameter to the hyper
freqtrade hyperopt --timerange 20180401-20180501
```
### Running Hyperopt using methods from a strategy
Hyperopt can reuse `populate_indicators`, `populate_buy_trend`, `populate_sell_trend` from your strategy, assuming these methods are **not** in your custom hyperopt file, and a strategy is provided.
```bash
freqtrade hyperopt --strategy SampleStrategy --customhyperopt SampleHyperopt
```
### Running Hyperopt with Smaller Search Space
Use the `--spaces` argument to limit the search space used by hyperopt.
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
@@ -285,8 +283,12 @@ Legal values are:
* `sell`: just search for a new sell strategy
* `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
* `default`: `all` except `trailing`
* 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.
### Position stacking and disabling max market positions
In some situations, you may need to run Hyperopt (and Backtesting) with the
@@ -295,7 +297,7 @@ In some situations, you may need to run Hyperopt (and Backtesting) with the
By default, hyperopt emulates the behavior of the Freqtrade Live Run/Dry Run, where only one
open trade is allowed for every traded pair. The total number of trades open for all pairs
is also limited by the `max_open_trades` setting. During Hyperopt/Backtesting this may lead to
some potential trades to be hidden (or masked) by previosly open trades.
some potential trades to be hidden (or masked) by previously open trades.
The `--eps`/`--enable-position-stacking` argument allows emulation of buying the same pair multiple times,
while `--dmmp`/`--disable-max-market-positions` disables applying `max_open_trades`
@@ -308,6 +310,16 @@ number).
You can also enable position stacking in the configuration file by explicitly setting
`"position_stacking"=true`.
### Reproducible results
The search for optimal parameters starts with a few (currently 30) random combinations in the hyperspace of parameters, random Hyperopt epochs. These random epochs are marked with an asterisk character (`*`) in the first column in the Hyperopt output.
The initial state for generation of these random values (random state) is controlled by the value of the `--random-state` command line option. You can set it to some arbitrary value of your choice to obtain reproducible results.
If you have not set this value explicitly in the command line options, Hyperopt seeds the random state with some random value for you. The random state value for each Hyperopt run is shown in the log, so you can copy and paste it into the `--random-state` command line option to repeat the set of the initial random epochs used.
If you have not changed anything in the command line options, configuration, timerange, Strategy and Hyperopt classes, historical data and the Loss Function -- you should obtain same hyperoptimization results with same random state value used.
## Understand the Hyperopt Result
Once Hyperopt is completed you can use the result to create a new strategy.
@@ -337,12 +349,11 @@ method, what those values match to.
So for example you had `rsi-value: 29.0` so we would look at `rsi`-block, that translates to the following code block:
``` python
```python
(dataframe['rsi'] < 29.0)
```
Translating your whole hyperopt result as the new buy-signal
would then look like:
Translating your whole hyperopt result as the new buy-signal would then look like:
```python
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame:
@@ -361,19 +372,13 @@ You can use the `--print-all` command line option if you would like to see all r
### Understand Hyperopt ROI results
If you are optimizing ROI (i.e. if optimization search-space contains 'all' or 'roi'), your result will look as follows and include a ROI table:
If you are optimizing ROI (i.e. if optimization search-space contains 'all', 'default' or 'roi'), your result will look as follows and include a ROI table:
```
Best result:
44/100: 135 trades. Avg profit 0.57%. Total profit 0.03871918 BTC (0.7722Σ%). Avg duration 180.4 mins. Objective: 1.94367
Buy hyperspace params:
{ 'adx-value': 44,
'rsi-value': 29,
'adx-enabled': False,
'rsi-enabled': True,
'trigger': 'bb_lower'}
ROI table:
{ 0: 0.10674,
21: 0.09158,
@@ -393,28 +398,29 @@ In order to use this best ROI table found by Hyperopt in backtesting and for liv
118: 0
}
```
As stated in the comment, you can also use it as the value of the `minimal_roi` setting in the configuration file.
#### Default ROI Search Space
If you are optimizing ROI, Freqtrade creates the 'roi' optimization hyperspace for you -- it's the hyperspace of components for the ROI tables. By default, each ROI table generated by the Freqtrade consists of 4 rows (steps). Hyperopt implements adaptive ranges for ROI tables with ranges for values in the ROI steps that depend on the ticker_interval used. By default the values can vary in the following ranges (for some of the most used ticker intervals, values are rounded to 5 digits after the decimal point):
If you are optimizing ROI, Freqtrade creates the 'roi' optimization hyperspace for you -- it's the hyperspace of components for the ROI tables. By default, each ROI table generated by the Freqtrade consists of 4 rows (steps). Hyperopt implements adaptive ranges for ROI tables with ranges for values in the ROI steps that depend on the ticker_interval used. By default the values vary in the following ranges (for some of the most used timeframes, values are rounded to 5 digits after the decimal point):
| # step | 1m | | 5m | | 1h | | 1d | |
|---|---|---|---|---|---|---|---|---|
| 1 | 0 | 0.01161...0.11992 | 0 | 0.03...0.31 | 0 | 0.06883...0.71124 | 0 | 0.12178...1.25835 |
| 2 | 2...8 | 0.00774...0.04255 | 10...40 | 0.02...0.11 | 120...480 | 0.04589...0.25238 | 2880...11520 | 0.08118...0.44651 |
| 3 | 4...20 | 0.00387...0.01547 | 20...100 | 0.01...0.04 | 240...1200 | 0.02294...0.09177 | 5760...28800 | 0.04059...0.16237 |
| 4 | 6...44 | 0.0 | 30...220 | 0.0 | 360...2640 | 0.0 | 8640...63360 | 0.0 |
| # step | 1m | | 5m | | 1h | | 1d | |
| ------ | ------ | ----------------- | -------- | ----------- | ---------- | ----------------- | ------------ | ----------------- |
| 1 | 0 | 0.01161...0.11992 | 0 | 0.03...0.31 | 0 | 0.06883...0.71124 | 0 | 0.12178...1.25835 |
| 2 | 2...8 | 0.00774...0.04255 | 10...40 | 0.02...0.11 | 120...480 | 0.04589...0.25238 | 2880...11520 | 0.08118...0.44651 |
| 3 | 4...20 | 0.00387...0.01547 | 20...100 | 0.01...0.04 | 240...1200 | 0.02294...0.09177 | 5760...28800 | 0.04059...0.16237 |
| 4 | 6...44 | 0.0 | 30...220 | 0.0 | 360...2640 | 0.0 | 8640...63360 | 0.0 |
These ranges should be sufficient in most cases. The minutes in the steps (ROI dict keys) are scaled linearly depending on the ticker interval used. The ROI values in the steps (ROI dict values) are scaled logarithmically depending on the ticker interval used.
These ranges should be sufficient in most cases. The minutes in the steps (ROI dict keys) are scaled linearly depending on the timeframe (ticker interval) used. The ROI values in the steps (ROI dict values) are scaled logarithmically depending on the timeframe used.
If you have the `generate_roi_table()` and `roi_space()` methods in your custom hyperopt file, remove them in order to utilize these adaptive ROI tables and the ROI hyperoptimization space generated by Freqtrade by default.
Override the `roi_space()` method if you need components of the ROI tables to vary in other ranges. Override the `generate_roi_table()` and `roi_space()` methods and implement your own custom approach for generation of the ROI tables during hyperoptimization if you need a different structure of the ROI tables or other amount of rows (steps). A sample for these methods can be found in [user_data/hyperopts/sample_hyperopt_advanced.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_advanced.py).
Override the `roi_space()` method if you need components of the ROI tables to vary in other ranges. Override the `generate_roi_table()` and `roi_space()` methods and implement your own custom approach for generation of the ROI tables during hyperoptimization if you need a different structure of the ROI tables or other amount of rows (steps). A sample for these methods can be found in [user_data/hyperopts/sample_hyperopt_advanced.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py).
### Understand Hyperopt Stoploss results
If you are optimizing stoploss values (i.e. if optimization search-space contains 'all' or 'stoploss'), your result will look as follows and include stoploss:
If you are optimizing stoploss values (i.e. if optimization search-space contains 'all', 'default' or 'stoploss'), your result will look as follows and include stoploss:
```
Best result:
@@ -437,17 +443,57 @@ In order to use this best stoploss value found by Hyperopt in backtesting and fo
# This attribute will be overridden if the config file contains "stoploss"
stoploss = -0.27996
```
As stated in the comment, you can also use it as the value of the `stoploss` setting in the configuration file.
#### Default Stoploss Search Space
If you are optimizing stoploss values, Freqtrade creates the 'stoploss' optimization hyperspace for you. By default, the stoploss values in that hyperspace can vary in the range -0.35...-0.02, which is sufficient in most cases.
If you are optimizing stoploss values, Freqtrade creates the 'stoploss' optimization hyperspace for you. By default, the stoploss values in that hyperspace vary in the range -0.35...-0.02, which is sufficient in most cases.
If you have the `stoploss_space()` method in your custom hyperopt file, remove it in order to utilize Stoploss hyperoptimization space generated by Freqtrade by default.
Override the `stoploss_space()` method and define the desired range in it if you need stoploss values to vary in other range during hyperoptimization. A sample for this method can be found in [user_data/hyperopts/sample_hyperopt_advanced.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_advanced.py).
Override the `stoploss_space()` method and define the desired range in it if you need stoploss values to vary in other range during hyperoptimization. A sample for this method can be found in [user_data/hyperopts/sample_hyperopt_advanced.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py).
### Validate backtesting results
### Understand Hyperopt Trailing Stop results
If you are optimizing trailing stop values (i.e. if optimization search-space contains 'all' or 'trailing'), your result will look as follows and include trailing stop parameters:
```
Best result:
45/100: 606 trades. Avg profit 1.04%. Total profit 0.31555614 BTC ( 630.48Σ%). Avg duration 150.3 mins. Objective: -1.10161
Trailing stop:
{ 'trailing_only_offset_is_reached': True,
'trailing_stop': True,
'trailing_stop_positive': 0.02001,
'trailing_stop_positive_offset': 0.06038}
```
In order to use these best trailing stop parameters found by Hyperopt in backtesting and for live trades/dry-run, copy-paste them as the values of the corresponding attributes of your custom strategy:
```
# Trailing stop
# These attributes will be overridden if the config file contains corresponding values.
trailing_stop = True
trailing_stop_positive = 0.02001
trailing_stop_positive_offset = 0.06038
trailing_only_offset_is_reached = True
```
As stated in the comment, you can also use it as the values of the corresponding settings in the configuration file.
#### Default Trailing Stop Search Space
If you are optimizing trailing stop values, Freqtrade creates the 'trailing' optimization hyperspace for you. By default, the `trailing_stop` parameter is always set to True in that hyperspace, the value of the `trailing_only_offset_is_reached` vary between True and False, the values of the `trailing_stop_positive` and `trailing_stop_positive_offset` parameters vary in the ranges 0.02...0.35 and 0.01...0.1 correspondingly, which is sufficient in most cases.
Override the `trailing_space()` method and define the desired range in it if you need values of the trailing stop parameters to vary in other ranges during hyperoptimization. A sample for this method can be found in [user_data/hyperopts/sample_hyperopt_advanced.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py).
## Show details of Hyperopt results
After you run Hyperopt for the desired amount of epochs, you can later list all results for analysis, select only best or profitable once, and show the details for any of the epochs previously evaluated. This can be done with the `hyperopt-list` and `hyperopt-show` subcommands. The usage of these subcommands is described in the [Utils](utils.md#list-hyperopt-results) chapter.
## Validate backtesting results
Once the optimized strategy has been implemented into your strategy, you should backtest this strategy to make sure everything is working as expected.

View File

@@ -1,5 +1,5 @@
# Freqtrade
[![Build Status](https://travis-ci.org/freqtrade/freqtrade.svg?branch=develop)](https://travis-ci.org/freqtrade/freqtrade)
[![Freqtrade CI](https://github.com/freqtrade/freqtrade/workflows/Freqtrade%20CI/badge.svg)](https://github.com/freqtrade/freqtrade/actions/)
[![Coverage Status](https://coveralls.io/repos/github/freqtrade/freqtrade/badge.svg?branch=develop&service=github)](https://coveralls.io/github/freqtrade/freqtrade?branch=develop)
[![Maintainability](https://api.codeclimate.com/v1/badges/5737e6d668200b7518ff/maintainability)](https://codeclimate.com/github/freqtrade/freqtrade/maintainability)
@@ -11,8 +11,10 @@
<a class="github-button" href="https://github.com/freqtrade/freqtrade/archive/master.zip" data-icon="octicon-cloud-download" data-size="large" aria-label="Download freqtrade/freqtrade on GitHub">Download</a>
<!-- Place this tag where you want the button to render. -->
<a class="github-button" href="https://github.com/freqtrade" data-size="large" aria-label="Follow @freqtrade on GitHub">Follow @freqtrade</a>
## Introduction
Freqtrade is a cryptocurrency trading bot written in Python.
Freqtrade is a crypto-currency algorithmic trading software developed in python (3.6+) and supported on Windows, macOS and Linux.
!!! Danger "DISCLAIMER"
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.
@@ -23,18 +25,15 @@ Freqtrade is a cryptocurrency trading bot written in Python.
## Features
- Based on Python 3.6+: For botting on any operating system — Windows, macOS and Linux.
- Persistence: Persistence is achieved through sqlite database.
- Dry-run mode: Run the bot without playing money.
- Backtesting: Run a simulation of your buy/sell strategy with historical data.
- Strategy Optimization by machine learning: Use machine learning to optimize your buy/sell strategy parameters with real exchange data.
- Edge position sizing: Calculate your win rate, risk reward ratio, the best stoploss and adjust your position size before taking a position for each specific market.
- Whitelist crypto-currencies: Select which crypto-currency you want to trade or use dynamic whitelists based on market (pair) trade volume.
- Blacklist crypto-currencies: Select which crypto-currency you want to avoid.
- Manageable via Telegram or REST APi: Manage the bot with Telegram or via the builtin REST API.
- Display profit/loss in fiat: Display your profit/loss in any of 33 fiat currencies supported.
- Daily summary of profit/loss: Receive the daily summary of your profit/loss.
- Performance status report: Receive the performance status of your current trades.
- Develop your Strategy: Write your strategy in python, using [pandas](https://pandas.pydata.org/). Example strategies to inspire you are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies).
- Download market data: Download historical data of the exchange and the markets your may want to trade with.
- Backtest: Test your strategy on downloaded historical data.
- Optimize: Find the best parameters for your strategy using hyperoptimization which employs machining learning methods. You can optimize buy, sell, take profit (ROI), stop-loss and trailing stop-loss parameters for your strategy.
- Select markets: Create your static list or use an automatic one based on top traded volumes and/or prices (not available during backtesting). You can also explicitly blacklist markets you don't want to trade.
- Run: Test your strategy with simulated money (Dry-Run mode) or deploy it with real money (Live-Trade mode).
- Run using Edge (optional module): The concept is to find the best historical [trade expectancy](edge.md#expectancy) by markets based on variation of the stop-loss and then allow/reject markets to trade. The sizing of the trade is based on a risk of a percentage of your capital.
- Control/Monitor: Use Telegram or a REST API (start/stop the bot, show profit/loss, daily summary, current open trades results, etc.).
- Analyse: Further analysis can be performed on either Backtesting data or Freqtrade trading history (SQL database), including automated standard plots, and methods to load the data into [interactive environments](data-analysis.md).
## Requirements
@@ -52,20 +51,23 @@ To run this bot we recommend you a cloud instance with a minimum of:
### Software requirements
- Docker (Recommended)
Alternatively
- Python 3.6.x
- pip (pip3)
- git
- TA-Lib
- virtualenv (Recommended)
- Docker (Recommended)
## Support
Help / Slack
For any questions not covered by the documentation or for further information about the bot, we encourage you to join our Slack channel.
### Help / Slack
For any questions not covered by the documentation or for further information about the bot, we encourage you to join our passionate Slack community.
Click [here](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) to join Slack channel.
Click [here](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) to join the Freqtrade Slack channel.
## Ready to try?
Begin by reading our installation guide [here](installation).
Begin by reading our installation guide [for docker](docker.md), or for [installation without docker](installation.md).

View File

@@ -2,6 +2,8 @@
This page explains how to prepare your environment for running the bot.
Please consider using the prebuilt [docker images](docker.md) to get started quickly while trying out freqtrade evaluating how it operates.
## Prerequisite
### Requirements
@@ -14,36 +16,37 @@ Click each one for install guide:
* [virtualenv](https://virtualenv.pypa.io/en/stable/installation/) (Recommended)
* [TA-Lib](https://mrjbq7.github.io/ta-lib/install.html) (install instructions below)
### API keys
Before running your bot in production you will need to setup few
external API. In production mode, the bot will require valid Exchange API
credentials. We also recommend a [Telegram bot](telegram-usage.md#setup-your-telegram-bot) (optional but recommended).
### Setup your exchange account
You will need to create API Keys (Usually you get `key` and `secret`) from the Exchange website and insert this into the appropriate fields in the configuration or when asked by the installation script.
We also recommend a [Telegram bot](telegram-usage.md#setup-your-telegram-bot), which is optional but recommended.
## Quick start
Freqtrade provides a Linux/MacOS script to install all dependencies and help you to configure the bot.
!!! Note
Python3.6 or higher and the corresponding pip are assumed to be available. The install-script will warn and stop if that's not the case.
```bash
git clone git@github.com:freqtrade/freqtrade.git
cd freqtrade
git checkout develop
./setup.sh --install
```
Freqtrade provides the Linux/MacOS Easy Installation script to install all dependencies and help you configure the bot.
!!! Note
Windows installation is explained [here](#windows).
## Easy Installation - Linux Script
The easiest way to install and run Freqtrade is to clone the bot Github repository and then run the Easy Installation script, if it's available for your platform.
If you are on Debian, Ubuntu or MacOS freqtrade provides a script to Install, Update, Configure, and Reset your bot.
!!! 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). The `master` branch contains the code of the last release (done usually once per month on an approximately one week old snapshot of the `develop` branch to prevent packaging bugs, so potentially it's more stable).
!!! Note
Python3.6 or higher and the corresponding `pip` are assumed to be available. The install-script will warn you and stop if that's not the case. `git` is also needed to clone the Freqtrade repository.
This can be achieved with the following commands:
```bash
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
git checkout master # Optional, see (1)
./setup.sh --install
```
(1) This command switches the cloned repository to the use of the `master` branch. It's not needed if you wish to stay on the `develop` branch. You may later switch between branches at any time with the `git checkout master`/`git checkout develop` commands.
## Easy Installation Script (Linux/MacOS)
If you are on Debian, Ubuntu or MacOS Freqtrade provides the script to install, update, configure and reset the codebase of your bot.
```bash
$ ./setup.sh
@@ -56,25 +59,25 @@ usage:
** --install **
This script will install everything you need to run the bot:
With this option, the script will install the bot and most dependencies:
You will need to have git and python3.6+ installed beforehand for this to work.
* Mandatory software as: `ta-lib`
* Setup your virtualenv
* Configure your `config.json` file
* Setup your virtualenv under `.env/`
This script is a combination of `install script` `--reset`, `--config`
This option is a combination of installation tasks, `--reset` and `--config`.
** --update **
Update parameter will pull the last version of your current branch and update your virtualenv.
This option will pull the last version of your current branch and update your virtualenv. Run the script with this option periodically to update your bot.
** --reset **
Reset parameter will hard reset your branch (only if you are on `master` or `develop`) and recreate your virtualenv.
This option will hard reset your branch (only if you are on either `master` or `develop`) and recreate your virtualenv.
** --config **
Config parameter is a `config.json` configurator. This script will ask you questions to setup your bot and create your `config.json`.
DEPRECATED - use `freqtrade new-config -c config.json` instead.
------
@@ -95,35 +98,43 @@ sudo apt-get update
sudo apt-get install build-essential git
```
#### Raspberry Pi / Raspbian
### Raspberry Pi / Raspbian
Before installing FreqTrade on a Raspberry Pi running the official Raspbian Image, make sure you have at least Python 3.6 installed. The default image only provides Python 3.5. Probably the easiest way to get a recent version of python is [miniconda](https://repo.continuum.io/miniconda/).
The following assumes the latest [Raspbian Buster lite image](https://www.raspberrypi.org/downloads/raspbian/) from at least September 2019.
This image comes with python3.7 preinstalled, making it easy to get freqtrade up and running.
The following assumes that miniconda3 is installed and available in your environment. Since the last miniconda3 installation file uses python 3.4, we will update to python 3.6 on this installation.
It's recommended to use (mini)conda for this as installation/compilation of `numpy` and `pandas` takes a long time.
Additional package to install on your Raspbian, `libffi-dev` required by cryptography (from python-telegram-bot).
Tested using a Raspberry Pi 3 with the Raspbian Buster lite image, all updates applied.
``` bash
conda config --add channels rpi
conda install python=3.6
conda create -n freqtrade python=3.6
conda activate freqtrade
conda install pandas numpy
sudo apt-get install python3-venv libatlas-base-dev
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
sudo apt install libffi-dev
python3 -m pip install -r requirements-common.txt
python3 -m pip install -e .
bash setup.sh -i
```
!!! Note "Installation duration"
Depending on your internet speed and the Raspberry Pi version, installation can take multiple hours to complete.
!!! Note
This does not install hyperopt dependencies. To install these, please use `python3 -m pip install -e .[hyperopt]`.
The above does not install hyperopt dependencies. To install these, please use `python3 -m pip install -e .[hyperopt]`.
We do not advise to run hyperopt on a Raspberry Pi, since this is a very resource-heavy operation, which should be done on powerful machine.
### Common
#### 1. Install TA-Lib
Use the provided ta-lib installation script
```bash
sudo ./build_helpers/install_ta-lib.sh
```
!!! Note
This will use the ta-lib tar.gz included in this repository.
##### TA-Lib manual installation
Official webpage: https://mrjbq7.github.io/ta-lib/install.html
```bash
@@ -151,13 +162,13 @@ python3 -m venv .env
source .env/bin/activate
```
#### 3. Install FreqTrade
#### 3. Install Freqtrade
Clone the git repository:
```bash
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
```
Optionally checkout the master branch to get the latest stable release:
@@ -166,59 +177,38 @@ Optionally checkout the master branch to get the latest stable release:
git checkout master
```
#### 4. Initialize the configuration
```bash
cd freqtrade
cp config.json.example config.json
```
> *To edit the config please refer to [Bot Configuration](configuration.md).*
#### 5. Install python dependencies
#### 4. Install python dependencies
``` bash
python3 -m pip install --upgrade pip
python3 -m pip install -e .
```
#### 5. Initialize the configuration
```bash
# Initialize the user_directory
freqtrade create-userdir --userdir user_data/
# Create a new configuration file
freqtrade new-config --config config.json
```
> *To edit the config please refer to [Bot Configuration](configuration.md).*
#### 6. Run the Bot
If this is the first time you run the bot, ensure you are running it in Dry-run `"dry_run": true,` otherwise it will start to buy and sell coins.
```bash
freqtrade -c config.json
freqtrade trade -c config.json
```
*Note*: If you run the bot on a server, you should consider using [Docker](docker.md) or a terminal multiplexer like `screen` or [`tmux`](https://en.wikipedia.org/wiki/Tmux) to avoid that the bot is stopped on logout.
#### 7. [Optional] Configure `freqtrade` as a `systemd` service
#### 7. (Optional) Post-installation Tasks
From the freqtrade repo... copy `freqtrade.service` to your systemd user directory (usually `~/.config/systemd/user`) and update `WorkingDirectory` and `ExecStart` to match your setup.
After that you can start the daemon with:
```bash
systemctl --user start freqtrade
```
For this to be persistent (run when user is logged out) you'll need to enable `linger` for your freqtrade user.
```bash
sudo loginctl enable-linger "$USER"
```
If you run the bot as a service, you can use systemd service manager as a software watchdog monitoring freqtrade bot
state and restarting it in the case of failures. If the `internals.sd_notify` parameter is set to true in the
configuration or the `--sd-notify` command line option is used, the bot will send keep-alive ping messages to systemd
using the sd_notify (systemd notifications) protocol and will also tell systemd its current state (Running or Stopped)
when it changes.
The `freqtrade.service.watchdog` file contains an example of the service unit configuration file which uses systemd
as the watchdog.
!!! Note
The sd_notify communication between the bot and the systemd service manager will not work if the bot runs in a Docker container.
On Linux, as an optional post-installation task, you may wish to setup the bot to run as a `systemd` service or configure it to send the log messages to the `syslog`/`rsyslog` or `journald` daemons. See [Advanced Logging](advanced-setup.md#advanced-logging) for details.
------
@@ -242,6 +232,12 @@ If that is not available on your system, feel free to try the instructions below
### Install freqtrade manually
!!! Note
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.
!!! Hint
Using the [Anaconda Distribution](https://www.anaconda.com/distribution/) under Windows can greatly help with installation problems. Check out the [Conda section](#using-conda) in this document for more information.
#### Clone the git repository
```bash
@@ -252,14 +248,14 @@ git clone https://github.com/freqtrade/freqtrade.git
Install ta-lib according to the [ta-lib documentation](https://github.com/mrjbq7/ta-lib#windows).
As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial precompiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which needs to be downloaded and installed using `pip install TA_Lib0.4.17cp36cp36mwin32.whl` (make sure to use the version matching your python version)
As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial precompiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which needs to be downloaded and installed using `pip install TA_Lib0.4.18cp38cp38win_amd64.whl` (make sure to use the version matching your python version)
```cmd
>cd \path\freqtrade-develop
>python -m venv .env
>.env\Scripts\activate.bat
REM optionally install ta-lib from wheel
REM >pip install TA_Lib0.4.17cp36cp36mwin32.whl
REM >pip install TA_Lib0.4.18cp38cp38win_amd64.whl
>pip install -r requirements.txt
>pip install -e .
>freqtrade
@@ -281,3 +277,18 @@ The easiest way is to download install Microsoft Visual Studio Community [here](
Now you have an environment ready, the next step is
[Bot Configuration](configuration.md).
## Troubleshooting
### MacOS installation error
Newer versions of MacOS may have installation failed with errors like `error: command 'g++' failed with exit status 1`.
This error will require explicit installation of the SDK Headers, which are not installed by default in this version of MacOS.
For MacOS 10.14, this can be accomplished with the below command.
``` bash
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```
If this file is inexistant, then you're probably on a different version of MacOS, so you may need to consult the internet for specific resolution details.

View File

@@ -23,13 +23,16 @@ The `freqtrade plot-dataframe` subcommand shows an interactive graph with three
Possible arguments:
```
usage: freqtrade plot-dataframe [-h] [-p PAIRS [PAIRS ...]]
usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-p PAIRS [PAIRS ...]]
[--indicators1 INDICATORS1 [INDICATORS1 ...]]
[--indicators2 INDICATORS2 [INDICATORS2 ...]]
[--plot-limit INT] [--db-url PATH]
[--trade-source {DB,file}] [--export EXPORT]
[--export-filename PATH]
[--timerange TIMERANGE]
[--timerange TIMERANGE] [-i TICKER_INTERVAL]
[--no-trades]
optional arguments:
-h, --help show this help message and exit
@@ -48,21 +51,46 @@ optional arguments:
values cause huge files. Default: 750.
--db-url PATH Override trades database URL, this is useful in custom
deployments (default: `sqlite:///tradesv3.sqlite` for
Live Run mode, `sqlite://` for Dry Run).
Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for
Dry Run).
--trade-source {DB,file}
Specify the source for trades (Can be DB or file
(backtest file)) Default: file
--export EXPORT Export backtest results, argument are: trades.
Example: `--export=trades`
--export-filename PATH
Save backtest results to the file with this filename
(default: `user_data/backtest_results/backtest-
result.json`). Requires `--export` to be set as well.
Example: `--export-filename=user_data/backtest_results
/backtest_today.json`
Save backtest results to the file with this filename.
Requires `--export` to be set as well. Example:
`--export-filename=user_data/backtest_results/backtest
_today.json`
--timerange TIMERANGE
Specify what timerange of data to use.
-i TICKER_INTERVAL, --ticker-interval TICKER_INTERVAL
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
--no-trades Skip using trades from backtesting file and DB.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
Example:
@@ -79,11 +107,11 @@ The `-p/--pairs` argument can be used to specify pairs you would like to plot.
Specify custom indicators.
Use `--indicators1` for the main plot and `--indicators2` for the subplot below (if values are in a different range than prices).
!!! tip
!!! Tip
You will almost certainly want to specify a custom strategy! This can be done by adding `-s Classname` / `--strategy ClassName` to the command.
``` bash
freqtrade --strategy AwesomeStrategy plot-dataframe -p BTC/ETH --indicators1 sma ema --indicators2 macd
freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --indicators1 sma ema --indicators2 macd
```
### Further usage examples
@@ -91,52 +119,115 @@ freqtrade --strategy AwesomeStrategy plot-dataframe -p BTC/ETH --indicators1 sma
To plot multiple pairs, separate them with a space:
``` bash
freqtrade --strategy AwesomeStrategy plot-dataframe -p BTC/ETH XRP/ETH
freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH XRP/ETH
```
To plot a timerange (to zoom in)
``` bash
freqtrade --strategy AwesomeStrategy plot-dataframe -p BTC/ETH --timerange=20180801-20180805
freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --timerange=20180801-20180805
```
To plot trades stored in a database use `--db-url` in combination with `--trade-source DB`:
``` bash
freqtrade --strategy AwesomeStrategy plot-dataframe --db-url sqlite:///tradesv3.dry_run.sqlite -p BTC/ETH --trade-source DB
freqtrade plot-dataframe --strategy AwesomeStrategy --db-url sqlite:///tradesv3.dry_run.sqlite -p BTC/ETH --trade-source DB
```
To plot trades from a backtesting result, use `--export-filename <filename>`
``` bash
freqtrade --strategy AwesomeStrategy plot-dataframe --export-filename user_data/backtest_results/backtest-result.json -p BTC/ETH
freqtrade plot-dataframe --strategy AwesomeStrategy --export-filename user_data/backtest_results/backtest-result.json -p BTC/ETH
```
### Plot dataframe basics
![plot-dataframe2](assets/plot-dataframe2.png)
The `plot-dataframe` subcommand requires backtesting data, a strategy and either a backtesting-results file or a database, containing trades corresponding to the strategy.
The resulting plot will have the following elements:
* Green triangles: Buy signals from the strategy. (Note: not every buy signal generates a trade, compare to cyan circles.)
* Red triangles: Sell signals from the strategy. (Also, not every sell signal terminates a trade, compare to red and green squares.)
* Cyan circles: Trade entry points.
* Red squares: Trade exit points for trades with loss or 0% profit.
* Green squares: Trade exit points for profitable trades.
* Indicators with values corresponding to the candle scale (e.g. SMA/EMA), as specified with `--indicators1`.
* Volume (bar chart at the bottom of the main chart).
* Indicators with values in different scales (e.g. MACD, RSI) below the volume bars, as specified with `--indicators2`.
!!! Note "Bollinger Bands"
Bollinger bands are automatically added to the plot if the columns `bb_lowerband` and `bb_upperband` exist, and are painted as a light blue area spanning from the lower band to the upper band.
#### Advanced plot configuration
An advanced plot configuration can be specified in the strategy in the `plot_config` parameter.
Additional features when using plot_config include:
* Specify colors per indicator
* Specify additional subplots
The sample plot configuration below specifies fixed colors for the indicators. Otherwise consecutive plots may produce different colorschemes each time, making comparisons difficult.
It also allows multiple subplots to display both MACD and RSI at the same time.
Sample configuration with inline comments explaining the process:
``` python
plot_config = {
'main_plot': {
# Configuration for main plot indicators.
# Specifies `ema10` to be red, and `ema50` to be a shade of gray
'ema10': {'color': 'red'},
'ema50': {'color': '#CCCCCC'},
# By omitting color, a random color is selected.
'sar': {},
},
'subplots': {
# Create subplot MACD
"MACD": {
'macd': {'color': 'blue'},
'macdsignal': {'color': 'orange'},
},
# Additional subplot RSI
"RSI": {
'rsi': {'color': 'red'},
}
}
}
```
!!! Note
The above configuration assumes that `ema10`, `ema50`, `macd`, `macdsignal` and `rsi` are columns in the DataFrame created by the strategy.
## Plot profit
![plot-profit](assets/plot-profit.png)
The `freqtrade plot-profit` subcommand shows an interactive graph with three plots:
The `plot-profit` subcommand shows an interactive graph with three plots:
1) Average closing price for all pairs
2) The summarized profit made by backtesting.
Note that this is not the real-world profit, but more of an estimate.
3) Profit for each individual pair
* Average closing price for all pairs.
* The summarized profit made by backtesting.
Note that this is not the real-world profit, but more of an estimate.
* Profit for each individual pair.
The first graph is good to get a grip of how the overall market progresses.
The second graph will show if your algorithm works or doesn't.
Perhaps you want an algorithm that steadily makes small profits, or one that acts less often, but makes big swings.
This graph will also highlight the start (and end) of the Max drawdown period.
The third graph can be useful to spot outliers, events in pairs that cause profit spikes.
Possible options for the `freqtrade plot-profit` subcommand:
```
usage: freqtrade plot-profit [-h] [-p PAIRS [PAIRS ...]]
usage: freqtrade plot-profit [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-p PAIRS [PAIRS ...]]
[--timerange TIMERANGE] [--export EXPORT]
[--export-filename PATH] [--db-url PATH]
[--trade-source {DB,file}]
[--trade-source {DB,file}] [-i TICKER_INTERVAL]
optional arguments:
-h, --help show this help message and exit
@@ -148,17 +239,35 @@ optional arguments:
--export EXPORT Export backtest results, argument are: trades.
Example: `--export=trades`
--export-filename PATH
Save backtest results to the file with this filename
(default: `user_data/backtest_results/backtest-
result.json`). Requires `--export` to be set as well.
Example: `--export-filename=user_data/backtest_results
/backtest_today.json`
Save backtest results to the file with this filename.
Requires `--export` to be set as well. Example:
`--export-filename=user_data/backtest_results/backtest
_today.json`
--db-url PATH Override trades database URL, this is useful in custom
deployments (default: `sqlite:///tradesv3.sqlite` for
Live Run mode, `sqlite://` for Dry Run).
Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for
Dry Run).
--trade-source {DB,file}
Specify the source for trades (Can be DB or file
(backtest file)) Default: file
-i TICKER_INTERVAL, --ticker-interval TICKER_INTERVAL
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```

View File

@@ -1,2 +1,2 @@
mkdocs-material==4.4.3
mkdocs-material==5.2.1
mdx_truly_sane_lists==1.2

View File

@@ -11,18 +11,26 @@ Sample configuration:
"enabled": true,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"jwt_secret_key": "somethingrandom",
"username": "Freqtrader",
"password": "SuperSecret1!"
},
```
!!! Danger Security warning
By default, the configuration listens on localhost only (so it's not reachable from other systems). We strongly recommend to not expose this API to the internet and choose a strong, unique password, since others will potentially be able to control your bot.
!!! Danger "Security warning"
By default, the configuration listens on localhost only (so it's not reachable from other systems). We strongly recommend to not expose this API to the internet and choose a strong, unique password, since others will potentially be able to control your bot.
!!! Danger Password selection
Please make sure to select a very strong, unique password to protect your bot from unauthorized access.
!!! Danger "Password selection"
Please make sure to select a very strong, unique password to protect your bot from unauthorized access.
You can then access the API by going to `http://127.0.0.1:8080/api/v1/version` to check if the API is running correctly.
You can then access the API by going to `http://127.0.0.1:8080/api/v1/ping` in a browser to check if the API is running correctly.
This should return the response:
``` output
{"status":"pong"}
```
All other endpoints return sensitive info and require authentication and are therefore not available through a web browser.
To generate a secure password, either use a password manager, or use the below code snipped.
@@ -31,6 +39,9 @@ import secrets
secrets.token_hex()
```
!!! Hint
Use the same method to also generate a JWT secret key (`jwt_secret_key`).
### Configuration with docker
If you run your bot using docker, you'll need to have the bot listen to incomming connections. The security is then handled by docker.
@@ -58,7 +69,7 @@ docker run -d \
-v ~/.freqtrade/user_data/:/freqtrade/user_data \
-v ~/.freqtrade/tradesv3.sqlite:/freqtrade/tradesv3.sqlite \
-p 127.0.0.1:8080:8080 \
freqtrade --db-url sqlite:///tradesv3.sqlite --strategy MyAwesomeStrategy
freqtrade trade --db-url sqlite:///tradesv3.sqlite --strategy MyAwesomeStrategy
```
!!! Danger "Security warning"
@@ -67,7 +78,7 @@ docker run -d \
## Consuming the API
You can consume the API by using the script `scripts/rest_client.py`.
The client script only requires the `requests` module, so FreqTrade does not need to be installed on the system.
The client script only requires the `requests` module, so Freqtrade does not need to be installed on the system.
``` bash
python3 scripts/rest_client.py <command> [optional parameters]
@@ -99,6 +110,7 @@ python3 scripts/rest_client.py --config rest_config.json <command> [optional par
| `stop` | | Stops the trader
| `stopbuy` | | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `reload_conf` | | Reloads the configuration file
| `show_config` | | Shows part of the current configuration with relevant settings to operation
| `status` | | Lists all open trades
| `count` | | Displays number of trades used and available
| `profit` | | Display a summary of your profit/loss from close trades and some stats about your performance
@@ -165,6 +177,10 @@ reload_conf
Reload configuration
:returns: json object
show_config
Returns part of the configuration, relevant for trading operations.
:return: json object containing the version
start
Start the bot if it's in stopped state.
:returns: json object
@@ -190,3 +206,28 @@ whitelist
Show the current whitelist
:returns: json object
```
## Advanced API usage using JWT tokens
!!! Note
The below should be done in an application (a Freqtrade REST API client, which fetches info via API), and is not intended to be used on a regular basis.
Freqtrade's REST API also offers JWT (JSON Web Tokens).
You can login using the following command, and subsequently use the resulting access_token.
``` bash
> curl -X POST --user Freqtrader http://localhost:8080/api/v1/token/login
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiMmEwYmY0NWUtMjhmOS00YTUzLTlmNzItMmM5ZWVlYThkNzc2IiwiZXhwIjoxNTg5MTIwNTgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.qt6MAXYIa-l556OM7arBvYJ0SDI9J8bIk3_glDujF5g","refresh_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiZWQ1ZWI3YjAtYjMwMy00YzAyLTg2N2MtNWViMjIxNWQ2YTMxIiwiZXhwIjoxNTkxNzExNjgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJ0eXBlIjoicmVmcmVzaCJ9.d1AT_jYICyTAjD0fiQAr52rkRqtxCjUGEMwlNuuzgNQ"}
> access_token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk2ODEsIm5iZiI6MTU4OTExOTY4MSwianRpIjoiMmEwYmY0NWUtMjhmOS00YTUzLTlmNzItMmM5ZWVlYThkNzc2IiwiZXhwIjoxNTg5MTIwNTgxLCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.qt6MAXYIa-l556OM7arBvYJ0SDI9J8bIk3_glDujF5g"
# Use access_token for authentication
> curl -X GET --header "Authorization: Bearer ${access_token}" http://localhost:8080/api/v1/count
```
Since the access token has a short timeout (15 min) - the `token/refresh` request should be used periodically to get a fresh access token:
``` bash
> curl -X POST --header "Authorization: Bearer ${refresh_token}"http://localhost:8080/api/v1/token/refresh
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk5NzQsIm5iZiI6MTU4OTExOTk3NCwianRpIjoiMDBjNTlhMWUtMjBmYS00ZTk0LTliZjAtNWQwNTg2MTdiZDIyIiwiZXhwIjoxNTg5MTIwODc0LCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.1seHlII3WprjjclY6DpRhen0rqdF4j6jbvxIhUFaSbs"}
```

View File

@@ -1,13 +1,20 @@
# SQL Helper
This page contains some help if you want to edit your sqlite db.
## Install sqlite3
**Ubuntu/Debian installation**
Sqlite3 is a terminal based sqlite application.
Feel free to use a visual Database editor like SqliteBrowser if you feel more comfortable with that.
### Ubuntu/Debian installation
```bash
sudo apt-get install sqlite3
```
## Open the DB
```bash
sqlite3
.open <filepath>
@@ -16,45 +23,61 @@ sqlite3
## Table structure
### List tables
```bash
.tables
```
### Display table structure
```bash
.schema <table_name>
```
### Trade table structure
```sql
CREATE TABLE trades (
id INTEGER NOT NULL,
exchange VARCHAR NOT NULL,
pair VARCHAR NOT NULL,
is_open BOOLEAN NOT NULL,
fee_open FLOAT NOT NULL,
fee_close FLOAT NOT NULL,
open_rate FLOAT,
open_rate_requested FLOAT,
close_rate FLOAT,
close_rate_requested FLOAT,
close_profit FLOAT,
stake_amount FLOAT NOT NULL,
amount FLOAT,
open_date DATETIME NOT NULL,
close_date DATETIME,
open_order_id VARCHAR,
stop_loss FLOAT,
initial_stop_loss FLOAT,
stoploss_order_id VARCHAR,
stoploss_last_update DATETIME,
max_rate FLOAT,
sell_reason VARCHAR,
strategy VARCHAR,
ticker_interval INTEGER,
PRIMARY KEY (id),
CHECK (is_open IN (0, 1))
CREATE TABLE trades
id INTEGER NOT NULL,
exchange VARCHAR NOT NULL,
pair VARCHAR NOT NULL,
is_open BOOLEAN NOT NULL,
fee_open FLOAT NOT NULL,
fee_open_cost FLOAT,
fee_open_currency VARCHAR,
fee_close FLOAT NOT NULL,
fee_close_cost FLOAT,
fee_close_currency VARCHAR,
open_rate FLOAT,
open_rate_requested FLOAT,
open_trade_price FLOAT,
close_rate FLOAT,
close_rate_requested FLOAT,
close_profit FLOAT,
close_profit_abs FLOAT,
stake_amount FLOAT NOT NULL,
amount FLOAT,
open_date DATETIME NOT NULL,
close_date DATETIME,
open_order_id VARCHAR,
stop_loss FLOAT,
stop_loss_pct FLOAT,
initial_stop_loss FLOAT,
initial_stop_loss_pct FLOAT,
stoploss_order_id VARCHAR,
stoploss_last_update DATETIME,
max_rate FLOAT,
min_rate FLOAT,
sell_reason VARCHAR,
strategy VARCHAR,
ticker_interval INTEGER,
PRIMARY KEY (id),
CHECK (is_open IN (0, 1))
);
CREATE INDEX ix_trades_stoploss_order_id ON trades (stoploss_order_id);
CREATE INDEX ix_trades_pair ON trades (pair);
CREATE INDEX ix_trades_is_open ON trades (is_open);
```
## Get all trades in the table
@@ -67,22 +90,32 @@ SELECT * FROM trades;
!!! Warning
Manually selling a pair on the exchange will not be detected by the bot and it will try to sell anyway. Whenever possible, forcesell <tradeid> should be used to accomplish the same thing.
It is strongly advised to backup your database file before making any manual changes.
It is strongly advised to backup your database file before making any manual changes.
!!! Note
This should not be necessary after /forcesell, as forcesell orders are closed automatically by the bot on the next iteration.
```sql
UPDATE trades
SET is_open=0, close_date=<close_date>, close_rate=<close_rate>, close_profit=close_rate/open_rate-1, sell_reason=<sell_reason>
SET is_open=0,
close_date=<close_date>,
close_rate=<close_rate>,
close_profit=close_rate/open_rate-1,
close_profit_abs = (amount * <close_rate> * (1 - fee_close) - (amount * open_rate * 1 - fee_open),
sell_reason=<sell_reason>
WHERE id=<trade_ID_to_update>;
```
##### Example
### Example
```sql
UPDATE trades
SET is_open=0, close_date='2017-12-20 03:08:45.103418', close_rate=0.19638016, close_profit=0.0496, sell_reason='force_sell'
SET is_open=0,
close_date='2017-12-20 03:08:45.103418',
close_rate=0.19638016,
close_profit=0.0496,
close_profit_abs = (amount * 0.19638016 * (1 - fee_close) - (amount * open_rate * 1 - fee_open)
sell_reason='force_sell'
WHERE id=31;
```
@@ -99,10 +132,3 @@ VALUES ('bittrex', 'ETH/BTC', 1, 0.0025, 0.0025, <open_rate>, <stake_amount>, <a
INSERT INTO trades (exchange, pair, is_open, fee_open, fee_close, open_rate, stake_amount, amount, open_date)
VALUES ('bittrex', 'ETH/BTC', 1, 0.0025, 0.0025, 0.00258580, 0.002, 0.7715262081, '2017-11-28 12:44:24.000000')
```
## Fix wrong fees in the table
If your DB was created before [PR#200](https://github.com/freqtrade/freqtrade/pull/200) was merged (before 12/23/17).
```sql
UPDATE trades SET fee=0.0025 WHERE fee=0.005;
```

View File

@@ -3,74 +3,101 @@
The `stoploss` configuration parameter is loss in percentage that should trigger a sale.
For example, value `-0.10` will cause immediate sell if the profit dips below -10% for a given trade. This parameter is optional.
Most of the strategy files already include the optimal `stoploss`
value. This parameter is optional. If you use it in the configuration file, it will take over the
`stoploss` value from the strategy file.
Most of the strategy files already include the optimal `stoploss` value.
## Stop Loss support
!!! Info
All stoploss properties mentioned in this file can be set in the Strategy, or in the configuration. Configuration values will override the strategy values.
## Stop Loss Types
At this stage the bot contains the following stoploss support modes:
1. static stop loss, defined in either the strategy or configuration.
2. trailing stop loss, defined in the configuration.
3. trailing stop loss, custom positive loss, defined in configuration.
1. Static stop loss.
2. Trailing stop loss.
3. Trailing stop loss, custom positive loss.
4. Trailing stop loss only once the trade has reached a certain offset.
Those stoploss modes can be *on exchange* or *off exchange*. If the stoploss is *on exchange* it means a stoploss limit order is placed on the exchange immediately after buy order happens successfully. This will protect you against sudden crashes in market as the order will be in the queue immediately and if market goes down then the order has more chance of being fulfilled.
In case of stoploss on exchange there is another parameter called `stoploss_on_exchange_interval`. This configures the interval in seconds at which the bot will check the stoploss and update it if necessary.
For example, assuming the stoploss is on exchange, and trailing stoploss is enabled, and the market is going up, then the bot automatically cancels the previous stoploss order and puts a new one with a stop value higher than the previous stoploss order.
The bot cannot do this every 5 seconds (at each iteration), otherwise it would get banned by the exchange.
So this parameter will tell the bot how often it should update the stoploss order. The default value is 60 (1 minute).
This same logic will reapply a stoploss order on the exchange should you cancel it accidentally.
!!! Note
All stoploss properties can be configured in either Strategy or configuration. Configuration values override strategy values.
Those stoploss modes can be *on exchange* or *off exchange*. If the stoploss is *on exchange* it means a stoploss limit order is placed on the exchange immediately after buy order happens successfuly. This will protect you against sudden crashes in market as the order will be in the queue immediately and if market goes down then the order has more chance of being fulfilled.
In case of stoploss on exchange there is another parameter called `stoploss_on_exchange_interval`. This configures the interval in seconds at which the bot will check the stoploss and update it if necessary. As an example in case of trailing stoploss if the order is on the exchange and the market is going up then the bot automatically cancels the previous stoploss order and put a new one with a stop value higher than previous one. It is clear that the bot cannot do it every 5 seconds otherwise it gets banned. So this parameter will tell the bot how often it should update the stoploss order. The default value is 60 (1 minute).
!!! Note
Stoploss on exchange is only supported for Binance as of now.
Stoploss on exchange is only supported for Binance (stop-loss-limit) and Kraken (stop-loss-market) as of now.
## Static Stop Loss
This is very simple, basically you define a stop loss of x in your strategy file or alternative in the configuration, which
will overwrite the strategy definition. This will basically try to sell your asset, the second the loss exceeds the defined loss.
This is very simple, you define a stop loss of x (as a ratio of price, i.e. x * 100% of price). This will try to sell the asset once the loss exceeds the defined loss.
## Trailing Stop Loss
The initial value for this stop loss, is defined in your strategy or configuration. Just as you would define your Stop Loss normally.
To enable this Feauture all you have to do is to define the configuration element:
The initial value for this is `stoploss`, just as you would define your static Stop loss.
To enable trailing stoploss:
``` json
"trailing_stop" : True
``` python
trailing_stop = True
```
This will now activate an algorithm, which automatically moves your stop loss up every time the price of your asset increases.
This will now activate an algorithm, which automatically moves the stop loss up every time the price of your asset increases.
For example, simplified math,
For example, simplified math:
* you buy an asset at a price of 100$
* your stop loss is defined at 2%
* which means your stop loss, gets triggered once your asset dropped below 98$
* assuming your asset now increases to 102$
* your stop loss, will now be 2% of 102$ or 99.96$
* now your asset drops in value to 101$, your stop loss, will still be 99.96$
* the bot buys an asset at a price of 100$
* the stop loss is defined at 2%
* the stop loss would get triggered once the asset dropps below 98$
* assuming the asset now increases to 102$
* the stop loss will now be 2% of 102$ or 99.96$
* now the asset drops in value to 101$, the stop loss will still be 99.96$ and would trigger at 99.96$.
basically what this means is that your stop loss will be adjusted to be always be 2% of the highest observed price
In summary: The stoploss will be adjusted to be always be 2% of the highest observed price.
### Custom positive loss
### Custom positive stoploss
Due to demand, it is possible to have a default stop loss, when you are in the red with your buy, but once your profit surpasses a certain percentage,
the system will utilize a new stop loss, which can be a different value. For example your default stop loss is 5%, but once you have 1.1% profit,
it will be changed to be only a 1% stop loss, which trails the green candles until it goes below them.
It is also possible to have a default stop loss, when you are in the red with your buy, but once your profit surpasses a certain percentage, the system will utilize a new stop loss, which can have a different value.
For example your default stop loss is 5%, but once you have 1.1% profit, it will be changed to be only a 1% stop loss, which trails the green candles until it goes below them.
Both values can be configured in the main configuration file and requires `"trailing_stop": true` to be set to true.
Both values require `trailing_stop` to be set to true.
``` json
"trailing_stop_positive": 0.01,
"trailing_stop_positive_offset": 0.011,
"trailing_only_offset_is_reached": false
``` python
trailing_stop_positive = 0.01
trailing_stop_positive_offset = 0.011
```
The 0.01 would translate to a 1% stop loss, once you hit 1.1% profit.
Before this, `stoploss` is used for the trailing stoploss.
You should also make sure to have this value (`trailing_stop_positive_offset`) lower than your minimal ROI, otherwise minimal ROI will apply first and sell your trade.
Read the [next section](#trailing-only-once-offset-is-reached) to keep stoploss at 5% of the entry point.
If `"trailing_only_offset_is_reached": true` then the trailing stoploss is only activated once the offset is reached. Until then, the stoploss remains at the configured`stoploss`.
!!! Tip
Make sure to have this value (`trailing_stop_positive_offset`) lower than minimal ROI, otherwise minimal ROI will apply first and sell the trade.
### Trailing only once offset is reached
It is also possible to use a static stoploss until the offset is reached, and then trail the trade to take profits once the market turns.
If `"trailing_only_offset_is_reached": true` then the trailing stoploss is only activated once the offset is reached. Until then, the stoploss remains at the configured `stoploss`.
This option can be used with or without `trailing_stop_positive`, but uses `trailing_stop_positive_offset` as offset.
``` python
trailing_stop_positive_offset = 0.011
trailing_only_offset_is_reached = true
```
Simplified example:
``` python
stoploss = 0.05
trailing_stop_positive_offset = 0.03
trailing_only_offset_is_reached = True
```
* the bot buys an asset at a price of 100$
* the stop loss is defined at 5%
* the stop loss will remain at 95% until profit reaches +3%
## Changing stoploss on open trades

91
docs/strategy-advanced.md Normal file
View File

@@ -0,0 +1,91 @@
# Advanced Strategies
This page explains some advanced concepts available for strategies.
If you're just getting started, please be familiar with the methods described in the [Strategy Customization](strategy-customization.md) documentation first.
## Custom order timeout rules
Simple, timebased order-timeouts can be configured either via strategy or in the configuration in the `unfilledtimeout` section.
However, freqtrade also offers a custom callback for both ordertypes, which allows you to decide based on custom criteria if a order did time out or not.
!!! Note
Unfilled order timeouts are not relevant during backtesting or hyperopt, and are only relevant during real (live) trading. Therefore these methods are only called in these circumstances.
### Custom order timeout example
A simple example, which applies different unfilled-timeouts depending on the price of the asset can be seen below.
It applies a tight timeout for higher priced assets, while allowing more time to fill on cheap coins.
The function must return either `True` (cancel order) or `False` (keep order alive).
``` python
from datetime import datetime, timedelta
from freqtrade.persistence import Trade
class Awesomestrategy(IStrategy):
# ... populate_* methods
# Set unfilledtimeout to 25 hours, since our maximum timeout from below is 24 hours.
unfilledtimeout = {
'buy': 60 * 25,
'sell': 60 * 25
}
def check_buy_timeout(self, pair: str, trade: 'Trade', order: dict, **kwargs) -> bool:
if trade.open_rate > 100 and trade.open_date < datetime.utcnow() - timedelta(minutes=5):
return True
elif trade.open_rate > 10 and trade.open_date < datetime.utcnow() - timedelta(minutes=3):
return True
elif trade.open_rate < 1 and trade.open_date < datetime.utcnow() - timedelta(hours=24):
return True
return False
def check_sell_timeout(self, pair: str, trade: 'Trade', order: dict, **kwargs) -> bool:
if trade.open_rate > 100 and trade.open_date < datetime.utcnow() - timedelta(minutes=5):
return True
elif trade.open_rate > 10 and trade.open_date < datetime.utcnow() - timedelta(minutes=3):
return True
elif trade.open_rate < 1 and trade.open_date < datetime.utcnow() - timedelta(hours=24):
return True
return False
```
!!! Note
For the above example, `unfilledtimeout` must be set to something bigger than 24h, otherwise that type of timeout will apply first.
### Custom order timeout example (using additional data)
``` python
from datetime import datetime
from freqtrade.persistence import Trade
class Awesomestrategy(IStrategy):
# ... populate_* methods
# Set unfilledtimeout to 25 hours, since our maximum timeout from below is 24 hours.
unfilledtimeout = {
'buy': 60 * 25,
'sell': 60 * 25
}
def check_buy_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool:
ob = self.dp.orderbook(pair, 1)
current_price = ob['bids'][0][0]
# Cancel buy order if price is more than 2% above the order.
if current_price > order['price'] * 1.02:
return True
return False
def check_sell_timeout(self, pair: str, trade: Trade, order: dict, **kwargs) -> bool:
ob = self.dp.orderbook(pair, 1)
current_price = ob['asks'][0][0]
# Cancel sell order if price is more than 2% below the order.
if current_price < order['price'] * 0.98:
return True
return False
```

View File

@@ -1,30 +1,33 @@
# Optimization
# Strategy Customization
This page explains where to customize your strategies, and add new
indicators.
This page explains where to customize your strategies, and add new indicators.
## Install a custom strategy file
This is very simple. Copy paste your strategy file into the directory `user_data/strategies`.
Let assume you have a class called `AwesomeStrategy` in the file `awesome-strategy.py`:
Let assume you have a class called `AwesomeStrategy` in the file `AwesomeStrategy.py`:
1. Move your file into `user_data/strategies` (you should have `user_data/strategies/awesome-strategy.py`
1. Move your file into `user_data/strategies` (you should have `user_data/strategies/AwesomeStrategy.py`
2. Start the bot with the param `--strategy AwesomeStrategy` (the parameter is the class name)
```bash
freqtrade --strategy AwesomeStrategy
freqtrade trade --strategy AwesomeStrategy
```
## Change your strategy
## Develop your own strategy
The bot includes a default strategy file. However, we recommend you to
use your own file to not have to lose your parameters every time the default
strategy file will be updated on Github. Put your custom strategy file
into the directory `user_data/strategies`.
The bot includes a default strategy file.
Also, several other strategies are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies).
Best copy the test-strategy and modify this copy to avoid having bot-updates override your changes.
`cp user_data/strategies/sample_strategy.py user_data/strategies/awesome-strategy.py`
You will however most likely have your own idea for a strategy.
This document intends to help you develop one for yourself.
To get started, use `freqtrade new-strategy --strategy AwesomeStrategy`.
This will create a new strategy file from a template, which will be located under `user_data/strategies/AwesomeStrategy.py`.
!!! Note
This is just a template file, which will most likely not be profitable out of the box.
### Anatomy of a strategy
@@ -45,19 +48,19 @@ The current version is 2 - which is also the default when it's not set explicitl
Future versions will require this to be set.
```bash
freqtrade --strategy AwesomeStrategy
freqtrade trade --strategy AwesomeStrategy
```
**For the following section we will use the [user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/strategies/sample_strategy.py)
**For the following section we will use the [user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_strategy.py)
file as reference.**
!!! Note Strategies and Backtesting
!!! Note "Strategies and Backtesting"
To avoid problems and unexpected differences between Backtesting and dry/live modes, please be aware
that during backtesting the full time-interval is passed to the `populate_*()` methods at once.
It is therefore best to use vectorized operations (across the whole dataframe, not loops) and
avoid index referencing (`df.iloc[-1]`), but instead use `df.shift()` to get to the previous candle.
!!! Warning Using future data
!!! Warning "Warning: Using future data"
Since backtesting passes the full time interval to the `populate_*()` methods, the strategy author
needs to take care to avoid having the strategy utilize data from the future.
Some common patterns for this are listed in the [Common Mistakes](#common-mistakes-when-developing-strategies) section of this document.
@@ -80,7 +83,7 @@ def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame
Performance Note: For the best performance be frugal on the number of indicators
you are using. Let uncomment only the indicator you are using in your strategies
or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
:param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
:param dataframe: Dataframe with data from the exchange
:param metadata: Additional information, like the currently traded pair
:return: a Dataframe with all mandatory indicators for the strategies
"""
@@ -114,9 +117,40 @@ def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame
```
!!! Note "Want more indicator examples?"
Look into the [user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/strategies/sample_strategy.py).
Look into the [user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_strategy.py).
Then uncomment indicators you need.
### Strategy startup period
Most indicators have an instable startup period, in which they are either not available, or the calculation is incorrect. This can lead to inconsistencies, since Freqtrade does not know how long this instable period should be.
To account for this, the strategy can be assigned the `startup_candle_count` attribute.
This should be set to the maximum number of candles that the strategy requires to calculate stable indicators.
In this example strategy, this should be set to 100 (`startup_candle_count = 100`), since the longest needed history is 100 candles.
``` python
dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)
```
By letting the bot know how much history is needed, backtest trades can start at the specified timerange during backtesting and hyperopt.
!!! Warning
`startup_candle_count` should be below `ohlcv_candle_limit` (which is 500 for most exchanges) - since only this amount of candles will be available during Dry-Run/Live Trade operations.
#### Example
Let's try to backtest 1 month (January 2019) of 5m candles using the an example strategy with EMA100, as above.
``` bash
freqtrade backtesting --timerange 20190101-20190201 --ticker-interval 5m
```
Assuming `startup_candle_count` is set to 100, backtesting knows it needs 100 candles to generate valid buy signals. It will load data from `20190101 - (100 * 5m)` - which is ~2019-12-31 15:30:00.
If this data is available, indicators will be calculated with this extended timerange. The instable startup period (up to 2019-01-01 00:00:00) will then be removed before starting backtesting.
!!! Note
If data for the startup period is not available, then the timerange will be adjusted to account for this startup period - so Backtesting would start at 2019-01-01 08:30:00.
### Buy signal rules
Edit the method `populate_buy_trend()` in your strategy file to update your buy strategy.
@@ -214,6 +248,23 @@ minimal_roi = {
While technically not completely disabled, this would sell once the trade reaches 10000% Profit.
To use times based on candle duration (ticker_interval or timeframe), the following snippet can be handy.
This will allow you to change the ticket_interval for the strategy, and ROI times will still be set as candles (e.g. after 3 candles ...)
``` python
from freqtrade.exchange import timeframe_to_minutes
class AwesomeStrategy(IStrategy):
ticker_interval = "1d"
ticker_interval_mins = timeframe_to_minutes(ticker_interval)
minimal_roi = {
"0": 0.05, # 5% for the first 3 candles
str(ticker_interval_mins * 3)): 0.02, # 2% after 3 candles
str(ticker_interval_mins * 6)): 0.01, # 1% After 6 candles
}
```
### Stoploss
Setting a stoploss is highly recommended to protect your capital from strong moves against you.
@@ -232,13 +283,14 @@ If your exchange supports it, it's recommended to also set `"stoploss_on_exchang
For more information on order_types please look [here](configuration.md#understand-order_types).
### Ticker interval
### Timeframe (ticker interval)
This is the set of candles the bot should download and use for the analysis.
Common values are `"1m"`, `"5m"`, `"15m"`, `"1h"`, however all values supported by your exchange should work.
Please note that the same buy/sell signals may work with one interval, but not the other.
This setting is accessible within the strategy by using `self.ticker_interval`.
Please note that the same buy/sell signals may work well with one timeframe, but not with the others.
This setting is accessible within the strategy methods as the `self.ticker_interval` attribute.
### Metadata dict
@@ -267,72 +319,19 @@ class Awesomestrategy(IStrategy):
```
!!! Warning
The data is not persisted after a bot-restart (or config-reload). Also, the amount of data should be kept smallish (no DataFrames and such), otherwise the bot will start to consume a lot of memory and eventually run out of memory and crash.
The data is not persisted after a bot-restart (or config-reload). Also, the amount of data should be kept smallish (no DataFrames and such), otherwise the bot will start to consume a lot of memory and eventually run out of memory and crash.
!!! Note
If the data is pair-specific, make sure to use pair as one of the keys in the dictionary.
If the data is pair-specific, make sure to use pair as one of the keys in the dictionary.
### Additional data (DataProvider)
***
The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy.
All methods return `None` in case of failure (do not raise an exception).
Please always check the mode of operation to select the correct method to get data (samples see below).
#### Possible options for DataProvider
- `available_pairs` - Property with tuples listing cached pairs with their intervals (pair, interval).
- `ohlcv(pair, ticker_interval)` - Currently cached ticker data for the pair, returns DataFrame or empty DataFrame.
- `historic_ohlcv(pair, ticker_interval)` - Returns historical data stored on disk.
- `get_pair_dataframe(pair, ticker_interval)` - This is a universal method, which returns either historical data (for backtesting) or cached live data (for the Dry-Run and Live-Run modes).
- `orderbook(pair, maximum)` - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries.
- `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on Market data structure.
- `runmode` - Property containing the current runmode.
#### Example: fetch live ohlcv / historic data for the first informative pair
``` python
if self.dp:
inf_pair, inf_timeframe = self.informative_pairs()[0]
informative = self.dp.get_pair_dataframe(pair=inf_pair,
ticker_interval=inf_timeframe)
```
!!! Warning Warning about backtesting
Be carefull when using dataprovider in backtesting. `historic_ohlcv()` (and `get_pair_dataframe()`
for the backtesting runmode) provides the full time-range in one go,
so please be aware of it and make sure to not "look into the future" to avoid surprises when running in dry/live mode).
!!! Warning Warning in hyperopt
This option cannot currently be used during hyperopt.
#### Orderbook
``` python
if self.dp:
if self.dp.runmode in ('live', 'dry_run'):
ob = self.dp.orderbook(metadata['pair'], 1)
dataframe['best_bid'] = ob['bids'][0][0]
dataframe['best_ask'] = ob['asks'][0][0]
```
!!! Warning
The order book is not part of the historic data which means backtesting and hyperopt will not work if this
method is used.
#### Available Pairs
``` python
if self.dp:
for pair, ticker in self.dp.available_pairs:
print(f"available {pair}, {ticker}")
```
### Additional data (informative_pairs)
#### Get data for non-tradeable pairs
Data for additional, informative pairs (reference pairs) can be beneficial for some strategies.
Ohlcv data for these pairs will be downloaded as part of the regular whitelist refresh process and is available via `DataProvider` just as other pairs (see above).
Ohlcv data for these pairs will be downloaded as part of the regular whitelist refresh process and is available via `DataProvider` just as other pairs (see below).
These parts will **not** be traded unless they are also specified in the pair whitelist, or have been selected by Dynamic Whitelisting.
The pairs need to be specified as tuples in the format `("pair", "interval")`, with pair as the first and time interval as the second argument.
@@ -352,6 +351,125 @@ def informative_pairs(self):
It is however better to use resampling to longer time-intervals when possible
to avoid hammering the exchange with too many requests and risk being blocked.
***
### Additional data (DataProvider)
The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy.
All methods return `None` in case of failure (do not raise an exception).
Please always check the mode of operation to select the correct method to get data (samples see below).
#### Possible options for DataProvider
- [`available_pairs`](#available_pairs) - Property with tuples listing cached pairs with their intervals (pair, interval).
- [`current_whitelist()`](#current_whitelist) - Returns a current list of whitelisted pairs. Useful for accessing dynamic whitelists (ie. VolumePairlist)
- [`get_pair_dataframe(pair, timeframe)`](#get_pair_dataframepair-timeframe) - This is a universal method, which returns either historical data (for backtesting) or cached live data (for the Dry-Run and Live-Run modes).
- `historic_ohlcv(pair, timeframe)` - Returns historical data stored on disk.
- `market(pair)` - Returns market data for the pair: fees, limits, precisions, activity flag, etc. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#markets) for more details on the Market data structure.
- `ohlcv(pair, timeframe)` - Currently cached candle (OHLCV) data for the pair, returns DataFrame or empty DataFrame.
- [`orderbook(pair, maximum)`](#orderbookpair-maximum) - Returns latest orderbook data for the pair, a dict with bids/asks with a total of `maximum` entries.
- [`ticker(pair)`](#tickerpair) - Returns current ticker data for the pair. See [ccxt documentation](https://github.com/ccxt/ccxt/wiki/Manual#price-tickers) for more details on the Ticker data structure.
- `runmode` - Property containing the current runmode.
#### Example Usages:
#### *available_pairs*
``` python
if self.dp:
for pair, timeframe in self.dp.available_pairs:
print(f"available {pair}, {timeframe}")
```
#### *current_whitelist()*
Imagine you've developed a strategy that trades the `5m` timeframe using signals generated from a `1d` timeframe on the top 10 volume pairs by volume.
The strategy might look something like this:
*Scan through the top 10 pairs by volume using the `VolumePairList` every 5 minutes and use a 14 day ATR to buy and sell.*
Due to the limited available data, it's very difficult to resample our `5m` candles into daily candles for use in a 14 day ATR. Most exchanges limit us to just 500 candles which effectively gives us around 1.74 daily candles. We need 14 days at least!
Since we can't resample our data we will have to use an informative pair; and since our whitelist will be dynamic we don't know which pair(s) to use.
This is where calling `self.dp.current_whitelist()` comes in handy.
```python
class SampleStrategy(IStrategy):
# strategy init stuff...
ticker_interval = '5m'
# more strategy init stuff..
def informative_pairs(self):
# get access to all pairs available in whitelist.
pairs = self.dp.current_whitelist()
# Assign tf to each pair so they can be downloaded and cached for strategy.
informative_pairs = [(pair, '1d') for pair in pairs]
return informative_pairs
def populate_indicators(self, dataframe, metadata):
# Get the informative pair
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d')
# Get the 14 day ATR.
atr = ta.ATR(informative, timeperiod=14)
# Do other stuff
```
#### *get_pair_dataframe(pair, timeframe)*
``` python
# fetch live / historical candle (OHLCV) data for the first informative pair
if self.dp:
inf_pair, inf_timeframe = self.informative_pairs()[0]
informative = self.dp.get_pair_dataframe(pair=inf_pair,
timeframe=inf_timeframe)
```
!!! Warning "Warning about backtesting"
Be carefull when using dataprovider in backtesting. `historic_ohlcv()` (and `get_pair_dataframe()`
for the backtesting runmode) provides the full time-range in one go,
so please be aware of it and make sure to not "look into the future" to avoid surprises when running in dry/live mode).
!!! Warning "Warning in hyperopt"
This option cannot currently be used during hyperopt.
#### *orderbook(pair, maximum)*
``` python
if self.dp:
if self.dp.runmode.value in ('live', 'dry_run'):
ob = self.dp.orderbook(metadata['pair'], 1)
dataframe['best_bid'] = ob['bids'][0][0]
dataframe['best_ask'] = ob['asks'][0][0]
```
!!! Warning
The order book is not part of the historic data which means backtesting and hyperopt will not work if this
method is used.
#### *ticker(pair)*
``` python
if self.dp:
if self.dp.runmode.value in ('live', 'dry_run'):
ticker = self.dp.ticker(metadata['pair'])
dataframe['last_price'] = ticker['last']
dataframe['volume24h'] = ticker['quoteVolume']
dataframe['vwap'] = ticker['vwap']
```
!!! Warning
Although the ticker data structure is a part of the ccxt Unified Interface, the values returned by this method can
vary for different exchanges. For instance, many exchanges do not return `vwap` values, the FTX exchange
does not always fills in the `last` field (so it can be None), etc. So you need to carefully verify the ticker
data returned from the exchange and add appropriate error handling / defaults.
***
### Additional data (Wallets)
The strategy provides access to the `Wallets` object. This contains the current balances on the exchange.
@@ -374,6 +492,98 @@ if self.wallets:
- `get_used(asset)` - currently tied up balance (open orders)
- `get_total(asset)` - total available balance - sum of the 2 above
***
### Additional data (Trades)
A history of Trades can be retrieved in the strategy by querying the database.
At the top of the file, import Trade.
```python
from freqtrade.persistence import Trade
```
The following example queries for the current pair and trades from today, however other filters can easily be added.
``` python
if self.config['runmode'].value in ('live', 'dry_run'):
trades = Trade.get_trades([Trade.pair == metadata['pair'],
Trade.open_date > datetime.utcnow() - timedelta(days=1),
Trade.is_open == False,
]).order_by(Trade.close_date).all()
# Summarize profit for this pair.
curdayprofit = sum(trade.close_profit for trade in trades)
```
Get amount of stake_currency currently invested in Trades:
``` python
if self.config['runmode'].value in ('live', 'dry_run'):
total_stakes = Trade.total_open_trades_stakes()
```
Retrieve performance per pair.
Returns a List of dicts per pair.
``` python
if self.config['runmode'].value in ('live', 'dry_run'):
performance = Trade.get_overall_performance()
```
Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of 0.015).
``` json
{'pair': "ETH/BTC", 'profit': 0.015, 'count': 5}
```
!!! Warning
Trade history is not available during backtesting or hyperopt.
### Prevent trades from happening for a specific pair
Freqtrade locks pairs automatically for the current candle (until that candle is over) when a pair is sold, preventing an immediate re-buy of that pair.
Locked pairs will show the message `Pair <pair> is currently locked.`.
#### Locking pairs from within the strategy
Sometimes it may be desired to lock a pair after certain events happen (e.g. multiple losing trades in a row).
Freqtrade has an easy method to do this from within the strategy, by calling `self.lock_pair(pair, until)`.
`until` must be a datetime object in the future, after which trading will be reenabled for that pair.
Locks can also be lifted manually, by calling `self.unlock_pair(pair)`.
To verify if a pair is currently locked, use `self.is_pair_locked(pair)`.
!!! Note
Locked pairs are not persisted, so a restart of the bot, or calling `/reload_conf` will reset locked pairs.
!!! Warning
Locking pairs is not functioning during backtesting.
##### Pair locking example
``` python
from freqtrade.persistence import Trade
from datetime import timedelta, datetime, timezone
# Put the above lines a the top of the strategy file, next to all the other imports
# --------
# Within populate indicators (or populate_buy):
if self.config['runmode'].value in ('live', 'dry_run'):
# fetch closed trades for the last 2 days
trades = Trade.get_trades([Trade.pair == metadata['pair'],
Trade.open_date > datetime.utcnow() - timedelta(days=2),
Trade.is_open == False,
]).all()
# Analyze the conditions you'd like to lock the pair .... will probably be different for every strategy
sumprofit = sum(trade.close_profit for trade in trades)
if sumprofit < 0:
# Lock pair for 12 hours
self.lock_pair(metadata['pair'], until=datetime.now(timezone.utc) + timedelta(hours=12))
```
### Print created dataframe
To inspect the created dataframe, you can issue a print-statement in either `populate_buy_trend()` or `populate_sell_trend()`.
@@ -398,19 +608,35 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
Printing more than a few rows is also possible (simply use `print(dataframe)` instead of `print(dataframe.tail())`), however not recommended, as that will be very verbose (~500 lines per pair every 5 seconds).
### Where can i find a strategy template?
The strategy template is located in the file
[user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/strategies/sample_strategy.py).
### Specify custom strategy location
If you want to use a strategy from a different directory you can pass `--strategy-path`
```bash
freqtrade --strategy AwesomeStrategy --strategy-path /some/directory
freqtrade trade --strategy AwesomeStrategy --strategy-path /some/directory
```
### Derived strategies
The strategies can be derived from other strategies. This avoids duplication of your custom strategy code. You can use this technique to override small parts of your main strategy, leaving the rest untouched:
``` python
class MyAwesomeStrategy(IStrategy):
...
stoploss = 0.13
trailing_stop = False
# All other attributes and methods are here as they
# should be in any custom strategy...
...
class MyAwesomeStrategy2(MyAwesomeStrategy):
# Override something
stoploss = 0.08
trailing_stop = True
```
Both attributes and methods may be overriden, altering behavior of the original strategy in a way you need.
### Common mistakes when developing strategies
Backtesting analyzes the whole time-range at once for performance reasons. Because of this, strategy authors need to make sure that strategies do not look-ahead into the future.

View File

@@ -1,24 +1,28 @@
# Strategy analysis example
Debugging a strategy can be time-consuming. FreqTrade offers helper functions to visualize raw data.
Debugging a strategy can be time-consuming. Freqtrade offers helper functions to visualize raw data.
The following assumes you work with SampleStrategy, data for 5m timeframe from Binance and have downloaded them into the data directory in the default location.
## Setup
```python
from pathlib import Path
from freqtrade.configuration import Configuration
# Customize these according to your needs.
# Initialize empty configuration object
config = Configuration.from_files([])
# Optionally, use existing configuration file
# config = Configuration.from_files(["config.json"])
# Define some constants
ticker_interval = "5m"
config["ticker_interval"] = "5m"
# Name of the strategy class
strategy_name = 'SampleStrategy'
# Path to user data
user_data_dir = Path('user_data')
# Location of the strategy
strategy_location = user_data_dir / 'strategies'
config["strategy"] = "SampleStrategy"
# Location of the data
data_location = Path(user_data_dir, 'data', 'binance')
data_location = Path(config['user_data_dir'], 'data', 'binance')
# Pair to analyze - Only use one pair here
pair = "BTC_USDT"
```
@@ -29,7 +33,7 @@ pair = "BTC_USDT"
from freqtrade.data.history import load_pair_history
candles = load_pair_history(datadir=data_location,
ticker_interval=ticker_interval,
timeframe=config["ticker_interval"],
pair=pair)
# Confirm success
@@ -44,9 +48,7 @@ candles.head()
```python
# Load strategy using values set above
from freqtrade.resolvers import StrategyResolver
strategy = StrategyResolver({'strategy': strategy_name,
'user_data_dir': user_data_dir,
'strategy_path': strategy_location}).strategy
strategy = StrategyResolver.load_strategy(config)
# Generate buy/sell signals using strategy
df = strategy.analyze_ticker(candles, {'pair': pair})
@@ -86,7 +88,7 @@ Analyze a trades dataframe (also used below for plotting)
from freqtrade.data.btanalysis import load_backtest_data
# Load backtest results
trades = load_backtest_data(user_data_dir / "backtest_results/backtest-result.json")
trades = load_backtest_data(config["user_data_dir"] / "backtest_results/backtest-result.json")
# Show value-counts per pair
trades.groupby("pair")["sell_reason"].value_counts()
@@ -107,6 +109,21 @@ trades = load_trades_from_db("sqlite:///tradesv3.sqlite")
trades.groupby("pair")["sell_reason"].value_counts()
```
## Analyze the loaded trades for trade parallelism
This can be useful to find the best `max_open_trades` parameter, when used with backtesting in conjunction with `--disable-max-market-positions`.
`analyze_trade_parallelism()` returns a timeseries dataframe with an "open_trades" column, specifying the number of open trades for each candle.
```python
from freqtrade.data.btanalysis import analyze_trade_parallelism
# Analyze the above
parallel_trades = analyze_trade_parallelism(trades, '5m')
parallel_trades.plot()
```
## Plot results
Freqtrade offers interactive plotting capabilities based on plotly.
@@ -116,11 +133,14 @@ Freqtrade offers interactive plotting capabilities based on plotly.
from freqtrade.plot.plotting import generate_candlestick_graph
# Limit graph period to keep plotly quick and reactive
# Filter trades to one pair
trades_red = trades.loc[trades['pair'] == pair]
data_red = data['2019-06-01':'2019-06-10']
# Generate candlestick graph
graph = generate_candlestick_graph(pair=pair,
data=data_red,
trades=trades,
trades=trades_red,
indicators1=['sma20', 'ema50', 'ema55'],
indicators2=['rsi', 'macd', 'macdsignal', 'macdhist']
)

View File

@@ -53,8 +53,9 @@ official commands. You can ask at any moment for help with `/help`.
| `/stop` | | Stops the trader
| `/stopbuy` | | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `/reload_conf` | | Reloads the configuration file
| `/show_config` | | Shows part of the current configuration with relevant settings to operation
| `/status` | | Lists all open trades
| `/status table` | | List all open trades in a table format
| `/status table` | | List all open trades in a table format. Pending buy orders are marked with an asterisk (*) Pending sell orders are marked with a double asterisk (**)
| `/count` | | Displays number of trades used and available
| `/profit` | | Display a summary of your profit/loss from close trades and some stats about your performance
| `/forcesell <trade_id>` | | Instantly sells the given trade (Ignoring `minimum_roi`).
@@ -93,7 +94,7 @@ Once all positions are sold, run `/stop` to completely stop the bot.
`/reload_conf` resets "max_open_trades" to the value set in the configuration and resets this command.
!!! warning
!!! Warning
The stop-buy signal is ONLY active while the bot is running, and is not persisted anyway, so restarting the bot will cause this to reset.
### /status

View File

@@ -2,6 +2,241 @@
Besides the Live-Trade and Dry-Run run modes, the `backtesting`, `edge` and `hyperopt` optimization subcommands, and the `download-data` subcommand which prepares historical data, the bot contains a number of utility subcommands. They are described in this section.
## Create userdir
Creates the directory structure to hold your files for freqtrade.
Will also create strategy and hyperopt examples for you to get started.
Can be used multiple times - using `--reset` will reset the sample strategy and hyperopt files to their default state.
```
usage: freqtrade create-userdir [-h] [--userdir PATH] [--reset]
optional arguments:
-h, --help show this help message and exit
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
--reset Reset sample files to their original state.
```
!!! Warning
Using `--reset` may result in loss of data, since this will overwrite all sample files without asking again.
```
├── backtest_results
├── data
├── hyperopt_results
├── hyperopts
│   ├── sample_hyperopt_advanced.py
│   ├── sample_hyperopt_loss.py
│   └── sample_hyperopt.py
├── notebooks
│   └── strategy_analysis_example.ipynb
├── plot
└── strategies
└── sample_strategy.py
```
## Create new config
Creates a new configuration file, asking some questions which are important selections for a configuration.
```
usage: freqtrade new-config [-h] [-c PATH]
optional arguments:
-h, --help show this help message and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-`
to read config from stdin.
```
!!! Warning
Only vital questions are asked. Freqtrade offers a lot more configuration possibilities, which are listed in the [Configuration documentation](configuration.md#configuration-parameters)
### Create config examples
```
$ freqtrade new-config --config config_binance.json
? Do you want to enable Dry-run (simulated trades)? Yes
? Please insert your stake currency: BTC
? Please insert your stake amount: 0.05
? Please insert max_open_trades (Integer or 'unlimited'): 3
? Please insert your timeframe (ticker interval): 5m
? Please insert your display Currency (for reporting): USD
? Select exchange binance
? Do you want to enable Telegram? No
```
## Create new strategy
Creates a new strategy from a template similar to SampleStrategy.
The file will be named inline with your class name, and will not overwrite existing files.
Results will be located in `user_data/strategies/<strategyclassname>.py`.
``` output
usage: freqtrade new-strategy [-h] [--userdir PATH] [-s NAME]
[--template {full,minimal,advanced}]
optional arguments:
-h, --help show this help message and exit
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--template {full,minimal,advanced}
Use a template which is either `minimal`, `full`
(containing multiple sample indicators) or `advanced`.
Default: `full`.
```
### Sample usage of new-strategy
```bash
freqtrade new-strategy --strategy AwesomeStrategy
```
With custom user directory
```bash
freqtrade new-strategy --userdir ~/.freqtrade/ --strategy AwesomeStrategy
```
Using the advanced template (populates all optional functions and methods)
```bash
freqtrade new-strategy --strategy AwesomeStrategy --template advanced
```
## Create new hyperopt
Creates a new hyperopt from a template similar to SampleHyperopt.
The file will be named inline with your class name, and will not overwrite existing files.
Results will be located in `user_data/hyperopts/<classname>.py`.
``` output
usage: freqtrade new-hyperopt [-h] [--userdir PATH] [--hyperopt NAME]
[--template {full,minimal,advanced}]
optional arguments:
-h, --help show this help message and exit
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
--hyperopt NAME Specify hyperopt class name which will be used by the
bot.
--template {full,minimal,advanced}
Use a template which is either `minimal`, `full`
(containing multiple sample indicators) or `advanced`.
Default: `full`.
```
### Sample usage of new-hyperopt
```bash
freqtrade new-hyperopt --hyperopt AwesomeHyperopt
```
With custom user directory
```bash
freqtrade new-hyperopt --userdir ~/.freqtrade/ --hyperopt AwesomeHyperopt
```
## List Strategies and List Hyperopts
Use the `list-strategies` subcommand to see all strategies in one particular directory and the `list-hyperopts` subcommand to list custom Hyperopts.
These subcommands are useful for finding problems in your environment with loading strategies or hyperopt classes: modules with strategies or hyperopt classes that contain errors and failed to load are printed in red (LOAD FAILED), while strategies or hyperopt classes with duplicate names are printed in yellow (DUPLICATE NAME).
```
usage: freqtrade list-strategies [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[--strategy-path PATH] [-1] [--no-color]
optional arguments:
-h, --help show this help message and exit
--strategy-path PATH Specify additional strategy lookup path.
-1, --one-column Print output in one column.
--no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
```
usage: freqtrade list-hyperopts [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[--hyperopt-path PATH] [-1] [--no-color]
optional arguments:
-h, --help show this help message and exit
--hyperopt-path PATH Specify additional lookup path for Hyperopt and
Hyperopt Loss functions.
-1, --one-column Print output in one column.
--no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
!!! Warning
Using these commands will try to load all python files from a directory. This can be a security risk if untrusted files reside in this directory, since all module-level code is executed.
Example: Search default strategies and hyperopts directories (within the default userdir).
``` bash
freqtrade list-strategies
freqtrade list-hyperopts
```
Example: Search strategies and hyperopts directory within the userdir.
``` bash
freqtrade list-strategies --userdir ~/.freqtrade/
freqtrade list-hyperopts --userdir ~/.freqtrade/
```
Example: Search dedicated strategy path.
``` bash
freqtrade list-strategies --strategy-path ~/.freqtrade/strategies/
```
Example: Search dedicated hyperopt path.
``` bash
freqtrade list-hyperopt --hyperopt-path ~/.freqtrade/hyperopts/
```
## List Exchanges
Use the `list-exchanges` subcommand to see the exchanges available for the bot.
@@ -29,23 +264,34 @@ All exchanges supported by the ccxt library: _1btcxe, acx, adara, allcoin, anxpr
## List Timeframes
Use the `list-timeframes` subcommand to see the list of ticker intervals (timeframes) available for the exchange.
Use the `list-timeframes` subcommand to see the list of timeframes (ticker intervals) available for the exchange.
```
usage: freqtrade list-timeframes [-h] [--exchange EXCHANGE] [-1]
usage: freqtrade list-timeframes [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-1]
optional arguments:
-h, --help show this help message and exit
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no
config is provided.
-1, --one-column Print output in one column.
-h, --help show this help message and exit
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no config is provided.
-1, --one-column Print output in one column.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`). Multiple --config options may be used. Can be set to `-`
to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
* Example: see the timeframes for the 'binance' exchange, set in the configuration file:
```
$ freqtrade -c config_binance.json list-timeframes
$ freqtrade list-timeframes -c config_binance.json
...
Timeframes available for the exchange `binance`: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
```
@@ -69,14 +315,16 @@ You can print info about any pair/market with these subcommands - and you can fi
These subcommands have same usage and same set of available options:
```
usage: freqtrade list-markets [-h] [--exchange EXCHANGE] [--print-list]
[--print-json] [-1] [--print-csv]
usage: freqtrade list-markets [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
[-a]
usage: freqtrade list-pairs [-h] [--exchange EXCHANGE] [--print-list]
[--print-json] [-1] [--print-csv]
usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a]
@@ -95,6 +343,22 @@ optional arguments:
Specify quote currency(-ies). Space-separated list.
-a, --all Print all pairs or market symbols. By default only
active ones are shown.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
By default, only active pairs/markets are shown. Active pairs/markets are those that can currently be traded
@@ -116,7 +380,7 @@ $ freqtrade list-pairs --quote USD --print-json
human-readable list with summary:
```
$ freqtrade -c config_binance.json list-pairs --all --base BTC ETH --quote USDT USD --print-list
$ freqtrade list-pairs -c config_binance.json --all --base BTC ETH --quote USDT USD --print-list
```
* Print all markets on exchange "Kraken", in the tabular format:
@@ -124,3 +388,181 @@ $ freqtrade -c config_binance.json list-pairs --all --base BTC ETH --quote USDT
```
$ freqtrade list-markets --exchange kraken --all
```
## Test pairlist
Use the `test-pairlist` subcommand to test the configuration of [dynamic pairlists](configuration.md#pairlists).
Requires a configuration with specified `pairlists` attribute.
Can be used to generate static pairlists to be used during backtesting / hyperopt.
```
usage: freqtrade test-pairlist [-h] [-c PATH]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
[-1] [--print-json]
optional arguments:
-h, --help show this help message and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]
Specify quote currency(-ies). Space-separated list.
-1, --one-column Print output in one column.
--print-json Print list of pairs or market symbols in JSON format.
```
### Examples
Show whitelist when using a [dynamic pairlist](configuration.md#pairlists).
```
freqtrade test-pairlist --config config.json --quote USDT BTC
```
## List Hyperopt results
You can list the hyperoptimization epochs the Hyperopt module evaluated previously with the `hyperopt-list` subcommand.
```
usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--best]
[--profitable] [--min-trades INT]
[--max-trades INT] [--min-avg-time FLOAT]
[--max-avg-time FLOAT] [--min-avg-profit FLOAT]
[--max-avg-profit FLOAT]
[--min-total-profit FLOAT]
[--max-total-profit FLOAT] [--no-color]
[--print-json] [--no-details]
[--export-csv FILE]
optional arguments:
-h, --help show this help message and exit
--best Select only best epochs.
--profitable Select only profitable epochs.
--min-trades INT Select epochs with more than INT trades.
--max-trades INT Select epochs with less than INT trades.
--min-avg-time FLOAT Select epochs on above average time.
--max-avg-time FLOAT Select epochs on under average time.
--min-avg-profit FLOAT
Select epochs on above average profit.
--max-avg-profit FLOAT
Select epochs on below average profit.
--min-total-profit FLOAT
Select epochs on above total profit.
--max-total-profit FLOAT
Select epochs on below total profit.
--no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file.
--print-json Print best result detailization in JSON format.
--no-details Do not print best epoch details.
--export-csv FILE Export to CSV-File. This will disable table print.
Example: --export-csv hyperopt.csv
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
### Examples
List all results, print details of the best result at the end:
```
freqtrade hyperopt-list
```
List only epochs with positive profit. Do not print the details of the best epoch, so that the list can be iterated in a script:
```
freqtrade hyperopt-list --profitable --no-details
```
## Show details of Hyperopt results
You can show the details of any hyperoptimization epoch previously evaluated by the Hyperopt module with the `hyperopt-show` subcommand.
```
usage: freqtrade hyperopt-show [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--best]
[--profitable] [-n INT] [--print-json]
[--no-header]
optional arguments:
-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.
--print-json Print best result detailization in JSON format.
--no-header Do not print epoch details header.
```
### Examples
Print details for the epoch 168 (the number of the epoch is shown by the `hyperopt-list` subcommand or by Hyperopt itself during hyperoptimization run):
```
freqtrade hyperopt-show -n 168
```
Prints JSON data with details for the last best epoch (i.e., the best of all epochs):
```
freqtrade hyperopt-show --best -n -1 --print-json --no-header
```
## Show trades
Print selected (or all) trades from database to screen.
```
usage: freqtrade show-trades [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--db-url PATH]
[--trade-ids TRADE_IDS [TRADE_IDS ...]]
[--print-json]
optional arguments:
-h, --help show this help message and exit
--db-url PATH Override trades database URL, this is useful in custom
deployments (default: `sqlite:///tradesv3.sqlite` for
Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for
Dry Run).
--trade-ids TRADE_IDS [TRADE_IDS ...]
Specify the list of trade ids.
--print-json Print output in JSON format.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
### Examples
Print trades with id 2 and 3 as json
``` bash
freqtrade show-trades --db-url sqlite:///tradesv3.sqlite --trade-ids 2 3 --print-json
```

View File

@@ -15,10 +15,20 @@ Sample configuration (tested using IFTTT).
"value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}"
},
"webhookbuycancel": {
"value1": "Cancelling Open Buy Order for {pair}",
"value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}"
},
"webhooksell": {
"value1": "Selling {pair}",
"value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency}"
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
},
"webhooksellcancel": {
"value1": "Cancelling Open Sell Order for {pair}",
"value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
},
"webhookstatus": {
"value1": "Status: {status}",
@@ -40,10 +50,29 @@ Possible parameters are:
* `exchange`
* `pair`
* `limit`
* `amount`
* `open_date`
* `stake_amount`
* `stake_currency`
* `fiat_currency`
* `order_type`
* `current_rate`
### Webhookbuycancel
The fields in `webhook.webhookbuycancel` are filled when the bot cancels a buy order. Parameters are filled using string.format.
Possible parameters are:
* `exchange`
* `pair`
* `limit`
* `amount`
* `open_date`
* `stake_amount`
* `stake_currency`
* `fiat_currency`
* `order_type`
* `current_rate`
### Webhooksell
@@ -58,11 +87,34 @@ Possible parameters are:
* `open_rate`
* `current_rate`
* `profit_amount`
* `profit_percent`
* `profit_ratio`
* `stake_currency`
* `fiat_currency`
* `sell_reason`
* `order_type`
* `open_date`
* `close_date`
### Webhooksellcancel
The fields in `webhook.webhooksellcancel` are filled when the bot cancels a sell order. Parameters are filled using string.format.
Possible parameters are:
* `exchange`
* `pair`
* `gain`
* `limit`
* `amount`
* `open_rate`
* `current_rate`
* `profit_amount`
* `profit_ratio`
* `stake_currency`
* `fiat_currency`
* `sell_reason`
* `order_type`
* `open_date`
* `close_date`
### Webhookstatus

View File

@@ -45,7 +45,7 @@ dependencies:
- pip:
# Required for app
- cython
- coinmarketcap
- pycoingecko
- ccxt
- TA-Lib
- py_find_1st

View File

@@ -6,7 +6,7 @@ After=network.target
# Set WorkingDirectory and ExecStart to your file paths accordingly
# NOTE: %h will be resolved to /home/<username>
WorkingDirectory=%h/freqtrade
ExecStart=/usr/bin/freqtrade
ExecStart=/usr/bin/freqtrade trade
Restart=on-failure
[Install]

View File

@@ -6,7 +6,7 @@ After=network.target
# Set WorkingDirectory and ExecStart to your file paths accordingly
# NOTE: %h will be resolved to /home/<username>
WorkingDirectory=%h/freqtrade
ExecStart=/usr/bin/freqtrade --sd-notify
ExecStart=/usr/bin/freqtrade trade --sd-notify
Restart=always
#Restart=on-failure

View File

@@ -1,44 +1,34 @@
""" FreqTrade bot """
__version__ = '2019.10'
""" Freqtrade bot """
__version__ = '2020.5'
if __version__ == 'develop':
try:
import subprocess
__version__ = 'develop-' + subprocess.check_output(
['git', 'log', '--format="%h"', '-n 1'],
stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"')
# from datetime import datetime
# last_release = subprocess.check_output(
# ['git', 'tag']
# ).decode('utf-8').split()[-1].split(".")
# # Releases are in the format "2020.1" - we increment the latest version for dev.
# prefix = f"{last_release[0]}.{int(last_release[1]) + 1}"
# dev_version = int(datetime.now().timestamp() // 1000)
# __version__ = f"{prefix}.dev{dev_version}"
# subprocess.check_output(
# ['git', 'log', '--format="%h"', '-n 1'],
# stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"')
except Exception:
# git not available, ignore
pass
class DependencyException(Exception):
"""
Indicates that an assumed dependency is not met.
This could happen when there is currently not enough money on the account.
"""
class OperationalException(Exception):
"""
Requires manual intervention and will usually stop the bot.
This happens when an exchange returns an unexpected error during runtime
or given configuration is invalid.
"""
class InvalidOrderException(Exception):
"""
This is returned when the order is not valid. Example:
If stoploss on exchange order is hit, then trying to cancel the order
should return this exception.
"""
class TemporaryError(Exception):
"""
Temporary network or exchange related error.
This could happen when an exchange is congested, unavailable, or the user
has networking problems. Usually resolves itself after a time.
"""
try:
# Try Fallback to freqtrade_commit file (created by CI while building docker image)
from pathlib import Path
versionfile = Path('./freqtrade_commit')
if versionfile.is_file():
__version__ = f"docker-{versionfile.read_text()[:8]}"
except Exception:
pass

View File

@@ -0,0 +1,29 @@
# flake8: noqa: F401
"""
Commands module.
Contains all start-commands, subcommands and CLI Interface creation.
Note: Be careful with file-scoped imports in these subfiles.
as they are parsed on startup, nothing containing optional modules should be loaded.
"""
from freqtrade.commands.arguments import Arguments
from freqtrade.commands.build_config_commands import start_new_config
from freqtrade.commands.data_commands import (start_convert_data,
start_download_data)
from freqtrade.commands.deploy_commands import (start_create_userdir,
start_new_hyperopt,
start_new_strategy)
from freqtrade.commands.hyperopt_commands import (start_hyperopt_list,
start_hyperopt_show)
from freqtrade.commands.list_commands import (start_list_exchanges,
start_list_hyperopts,
start_list_markets,
start_list_strategies,
start_list_timeframes,
start_show_trades)
from freqtrade.commands.optimize_commands import (start_backtesting,
start_edge, start_hyperopt)
from freqtrade.commands.pairlist_commands import start_test_pairlist
from freqtrade.commands.plot_commands import (start_plot_dataframe,
start_plot_profit)
from freqtrade.commands.trade_commands import start_trading

View File

@@ -0,0 +1,360 @@
"""
This module contains the argument manager class
"""
import argparse
from functools import partial
from pathlib import Path
from typing import Any, Dict, List, Optional
from freqtrade.commands.cli_options import AVAILABLE_CLI_OPTIONS
from freqtrade.constants import DEFAULT_CONFIG
ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"]
ARGS_STRATEGY = ["strategy", "strategy_path"]
ARGS_TRADE = ["db_url", "sd_notify", "dry_run"]
ARGS_COMMON_OPTIMIZE = ["ticker_interval", "timerange",
"max_open_trades", "stake_amount", "fee"]
ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_positions",
"strategy_list", "export", "exportfilename"]
ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
"position_stacking", "epochs", "spaces",
"use_max_market_positions", "print_all",
"print_colorized", "print_json", "hyperopt_jobs",
"hyperopt_random_state", "hyperopt_min_trades",
"hyperopt_continue", "hyperopt_loss"]
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column", "print_colorized"]
ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column", "print_colorized"]
ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"]
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
ARGS_LIST_PAIRS = ["exchange", "print_list", "list_pairs_print_json", "print_one_column",
"print_csv", "base_currencies", "quote_currencies", "list_pairs_all"]
ARGS_TEST_PAIRLIST = ["config", "quote_currencies", "print_one_column", "list_pairs_print_json"]
ARGS_CREATE_USERDIR = ["user_data_dir", "reset"]
ARGS_BUILD_CONFIG = ["config"]
ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"]
ARGS_BUILD_HYPEROPT = ["user_data_dir", "hyperopt", "template"]
ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to", "erase"]
ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes"]
ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange",
"timeframes", "erase", "dataformat_ohlcv", "dataformat_trades"]
ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit",
"db_url", "trade_source", "export", "exportfilename",
"timerange", "ticker_interval", "no_trades"]
ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url",
"trade_source", "ticker_interval"]
ARGS_SHOW_TRADES = ["db_url", "trade_ids", "print_json"]
ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable",
"hyperopt_list_min_trades", "hyperopt_list_max_trades",
"hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time",
"hyperopt_list_min_avg_profit", "hyperopt_list_max_avg_profit",
"hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit",
"print_colorized", "print_json", "hyperopt_list_no_details",
"export_csv"]
ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index",
"print_json", "hyperopt_show_no_header"]
NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes",
"list-markets", "list-pairs", "list-strategies",
"list-hyperopts", "hyperopt-list", "hyperopt-show",
"plot-dataframe", "plot-profit", "show-trades"]
NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"]
class Arguments:
"""
Arguments Class. Manage the arguments received by the cli
"""
def __init__(self, args: Optional[List[str]]) -> None:
self.args = args
self._parsed_arg: Optional[argparse.Namespace] = None
def get_parsed_arg(self) -> Dict[str, Any]:
"""
Return the list of arguments
:return: List[str] List of arguments
"""
if self._parsed_arg is None:
self._build_subcommands()
self._parsed_arg = self._parse_args()
return vars(self._parsed_arg)
def _parse_args(self) -> argparse.Namespace:
"""
Parses given arguments and returns an argparse Namespace instance.
"""
parsed_arg = self.parser.parse_args(self.args)
# Workaround issue in argparse with action='append' and default value
# (see https://bugs.python.org/issue16399)
# Allow no-config for certain commands (like downloading / plotting)
if ('config' in parsed_arg and parsed_arg.config is None):
conf_required = ('command' in parsed_arg and parsed_arg.command in NO_CONF_REQURIED)
if 'user_data_dir' in parsed_arg and parsed_arg.user_data_dir is not None:
user_dir = parsed_arg.user_data_dir
else:
# Default case
user_dir = 'user_data'
# Try loading from "user_data/config.json"
cfgfile = Path(user_dir) / DEFAULT_CONFIG
if cfgfile.is_file():
parsed_arg.config = [str(cfgfile)]
else:
# Else use "config.json".
cfgfile = Path.cwd() / DEFAULT_CONFIG
if cfgfile.is_file() or not conf_required:
parsed_arg.config = [DEFAULT_CONFIG]
return parsed_arg
def _build_args(self, optionlist, parser):
for val in optionlist:
opt = AVAILABLE_CLI_OPTIONS[val]
parser.add_argument(*opt.cli, dest=val, **opt.kwargs)
def _build_subcommands(self) -> None:
"""
Builds and attaches all subcommands.
:return: None
"""
# Build shared arguments (as group Common Options)
_common_parser = argparse.ArgumentParser(add_help=False)
group = _common_parser.add_argument_group("Common arguments")
self._build_args(optionlist=ARGS_COMMON, parser=group)
_strategy_parser = argparse.ArgumentParser(add_help=False)
strategy_group = _strategy_parser.add_argument_group("Strategy arguments")
self._build_args(optionlist=ARGS_STRATEGY, parser=strategy_group)
# Build main command
self.parser = argparse.ArgumentParser(description='Free, open source crypto trading bot')
self._build_args(optionlist=['version'], parser=self.parser)
from freqtrade.commands import (start_create_userdir, start_convert_data,
start_download_data,
start_hyperopt_list, start_hyperopt_show,
start_list_exchanges, start_list_hyperopts,
start_list_markets, start_list_strategies,
start_list_timeframes, start_new_config,
start_new_hyperopt, start_new_strategy,
start_plot_dataframe, start_plot_profit, start_show_trades,
start_backtesting, start_hyperopt, start_edge,
start_test_pairlist, start_trading)
subparsers = self.parser.add_subparsers(dest='command',
# Use custom message when no subhandler is added
# shown from `main.py`
# required=True
)
# Add trade subcommand
trade_cmd = subparsers.add_parser('trade', help='Trade module.',
parents=[_common_parser, _strategy_parser])
trade_cmd.set_defaults(func=start_trading)
self._build_args(optionlist=ARGS_TRADE, parser=trade_cmd)
# add create-userdir subcommand
create_userdir_cmd = subparsers.add_parser('create-userdir',
help="Create user-data directory.",
)
create_userdir_cmd.set_defaults(func=start_create_userdir)
self._build_args(optionlist=ARGS_CREATE_USERDIR, parser=create_userdir_cmd)
# add new-config subcommand
build_config_cmd = subparsers.add_parser('new-config',
help="Create new config")
build_config_cmd.set_defaults(func=start_new_config)
self._build_args(optionlist=ARGS_BUILD_CONFIG, parser=build_config_cmd)
# add new-hyperopt subcommand
build_hyperopt_cmd = subparsers.add_parser('new-hyperopt',
help="Create new hyperopt")
build_hyperopt_cmd.set_defaults(func=start_new_hyperopt)
self._build_args(optionlist=ARGS_BUILD_HYPEROPT, parser=build_hyperopt_cmd)
# add new-strategy subcommand
build_strategy_cmd = subparsers.add_parser('new-strategy',
help="Create new strategy")
build_strategy_cmd.set_defaults(func=start_new_strategy)
self._build_args(optionlist=ARGS_BUILD_STRATEGY, parser=build_strategy_cmd)
# Add download-data subcommand
download_data_cmd = subparsers.add_parser(
'download-data',
help='Download backtesting data.',
parents=[_common_parser],
)
download_data_cmd.set_defaults(func=start_download_data)
self._build_args(optionlist=ARGS_DOWNLOAD_DATA, parser=download_data_cmd)
# Add convert-data subcommand
convert_data_cmd = subparsers.add_parser(
'convert-data',
help='Convert candle (OHLCV) data from one format to another.',
parents=[_common_parser],
)
convert_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=True))
self._build_args(optionlist=ARGS_CONVERT_DATA_OHLCV, parser=convert_data_cmd)
# Add convert-trade-data subcommand
convert_trade_data_cmd = subparsers.add_parser(
'convert-trade-data',
help='Convert trade data from one format to another.',
parents=[_common_parser],
)
convert_trade_data_cmd.set_defaults(func=partial(start_convert_data, ohlcv=False))
self._build_args(optionlist=ARGS_CONVERT_DATA, parser=convert_trade_data_cmd)
# Add backtesting subcommand
backtesting_cmd = subparsers.add_parser('backtesting', help='Backtesting module.',
parents=[_common_parser, _strategy_parser])
backtesting_cmd.set_defaults(func=start_backtesting)
self._build_args(optionlist=ARGS_BACKTEST, parser=backtesting_cmd)
# Add edge subcommand
edge_cmd = subparsers.add_parser('edge', help='Edge module.',
parents=[_common_parser, _strategy_parser])
edge_cmd.set_defaults(func=start_edge)
self._build_args(optionlist=ARGS_EDGE, parser=edge_cmd)
# Add hyperopt subcommand
hyperopt_cmd = subparsers.add_parser('hyperopt', help='Hyperopt module.',
parents=[_common_parser, _strategy_parser],
)
hyperopt_cmd.set_defaults(func=start_hyperopt)
self._build_args(optionlist=ARGS_HYPEROPT, parser=hyperopt_cmd)
# Add hyperopt-list subcommand
hyperopt_list_cmd = subparsers.add_parser(
'hyperopt-list',
help='List Hyperopt results',
parents=[_common_parser],
)
hyperopt_list_cmd.set_defaults(func=start_hyperopt_list)
self._build_args(optionlist=ARGS_HYPEROPT_LIST, parser=hyperopt_list_cmd)
# Add hyperopt-show subcommand
hyperopt_show_cmd = subparsers.add_parser(
'hyperopt-show',
help='Show details of Hyperopt results',
parents=[_common_parser],
)
hyperopt_show_cmd.set_defaults(func=start_hyperopt_show)
self._build_args(optionlist=ARGS_HYPEROPT_SHOW, parser=hyperopt_show_cmd)
# Add list-exchanges subcommand
list_exchanges_cmd = subparsers.add_parser(
'list-exchanges',
help='Print available exchanges.',
parents=[_common_parser],
)
list_exchanges_cmd.set_defaults(func=start_list_exchanges)
self._build_args(optionlist=ARGS_LIST_EXCHANGES, parser=list_exchanges_cmd)
# Add list-hyperopts subcommand
list_hyperopts_cmd = subparsers.add_parser(
'list-hyperopts',
help='Print available hyperopt classes.',
parents=[_common_parser],
)
list_hyperopts_cmd.set_defaults(func=start_list_hyperopts)
self._build_args(optionlist=ARGS_LIST_HYPEROPTS, parser=list_hyperopts_cmd)
# Add list-markets subcommand
list_markets_cmd = subparsers.add_parser(
'list-markets',
help='Print markets on exchange.',
parents=[_common_parser],
)
list_markets_cmd.set_defaults(func=partial(start_list_markets, pairs_only=False))
self._build_args(optionlist=ARGS_LIST_PAIRS, parser=list_markets_cmd)
# Add list-pairs subcommand
list_pairs_cmd = subparsers.add_parser(
'list-pairs',
help='Print pairs on exchange.',
parents=[_common_parser],
)
list_pairs_cmd.set_defaults(func=partial(start_list_markets, pairs_only=True))
self._build_args(optionlist=ARGS_LIST_PAIRS, parser=list_pairs_cmd)
# Add list-strategies subcommand
list_strategies_cmd = subparsers.add_parser(
'list-strategies',
help='Print available strategies.',
parents=[_common_parser],
)
list_strategies_cmd.set_defaults(func=start_list_strategies)
self._build_args(optionlist=ARGS_LIST_STRATEGIES, parser=list_strategies_cmd)
# Add list-timeframes subcommand
list_timeframes_cmd = subparsers.add_parser(
'list-timeframes',
help='Print available ticker intervals (timeframes) for the exchange.',
parents=[_common_parser],
)
list_timeframes_cmd.set_defaults(func=start_list_timeframes)
self._build_args(optionlist=ARGS_LIST_TIMEFRAMES, parser=list_timeframes_cmd)
# Add show-trades subcommand
show_trades = subparsers.add_parser(
'show-trades',
help='Show trades.',
parents=[_common_parser],
)
show_trades.set_defaults(func=start_show_trades)
self._build_args(optionlist=ARGS_SHOW_TRADES, parser=show_trades)
# Add test-pairlist subcommand
test_pairlist_cmd = subparsers.add_parser(
'test-pairlist',
help='Test your pairlist configuration.',
)
test_pairlist_cmd.set_defaults(func=start_test_pairlist)
self._build_args(optionlist=ARGS_TEST_PAIRLIST, parser=test_pairlist_cmd)
# Add Plotting subcommand
plot_dataframe_cmd = subparsers.add_parser(
'plot-dataframe',
help='Plot candles with indicators.',
parents=[_common_parser, _strategy_parser],
)
plot_dataframe_cmd.set_defaults(func=start_plot_dataframe)
self._build_args(optionlist=ARGS_PLOT_DATAFRAME, parser=plot_dataframe_cmd)
# Plot profit
plot_profit_cmd = subparsers.add_parser(
'plot-profit',
help='Generate plot showing profits.',
parents=[_common_parser],
)
plot_profit_cmd.set_defaults(func=start_plot_profit)
self._build_args(optionlist=ARGS_PLOT_PROFIT, parser=plot_profit_cmd)

View File

@@ -0,0 +1,193 @@
import logging
from pathlib import Path
from typing import Any, Dict
from questionary import Separator, prompt
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT
from freqtrade.exchange import available_exchanges, MAP_EXCHANGE_CHILDCLASS
from freqtrade.misc import render_template
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
def validate_is_int(val):
try:
_ = int(val)
return True
except Exception:
return False
def validate_is_float(val):
try:
_ = float(val)
return True
except Exception:
return False
def ask_user_overwrite(config_path: Path) -> bool:
questions = [
{
"type": "confirm",
"name": "overwrite",
"message": f"File {config_path} already exists. Overwrite?",
"default": False,
},
]
answers = prompt(questions)
return answers['overwrite']
def ask_user_config() -> Dict[str, Any]:
"""
Ask user a few questions to build the configuration.
Interactive questions built using https://github.com/tmbo/questionary
:returns: Dict with keys to put into template
"""
questions = [
{
"type": "confirm",
"name": "dry_run",
"message": "Do you want to enable Dry-run (simulated trades)?",
"default": True,
},
{
"type": "text",
"name": "stake_currency",
"message": "Please insert your stake currency:",
"default": 'BTC',
},
{
"type": "text",
"name": "stake_amount",
"message": "Please insert your stake amount:",
"default": "0.01",
"validate": lambda val: val == UNLIMITED_STAKE_AMOUNT or validate_is_float(val),
},
{
"type": "text",
"name": "max_open_trades",
"message": f"Please insert max_open_trades (Integer or '{UNLIMITED_STAKE_AMOUNT}'):",
"default": "3",
"validate": lambda val: val == UNLIMITED_STAKE_AMOUNT or validate_is_int(val)
},
{
"type": "text",
"name": "ticker_interval",
"message": "Please insert your timeframe (ticker interval):",
"default": "5m",
},
{
"type": "text",
"name": "fiat_display_currency",
"message": "Please insert your display Currency (for reporting):",
"default": 'USD',
},
{
"type": "select",
"name": "exchange_name",
"message": "Select exchange",
"choices": [
"binance",
"binanceje",
"binanceus",
"bittrex",
"kraken",
Separator(),
"other",
],
},
{
"type": "autocomplete",
"name": "exchange_name",
"message": "Type your exchange name (Must be supported by ccxt)",
"choices": available_exchanges(),
"when": lambda x: x["exchange_name"] == 'other'
},
{
"type": "password",
"name": "exchange_key",
"message": "Insert Exchange Key",
"when": lambda x: not x['dry_run']
},
{
"type": "password",
"name": "exchange_secret",
"message": "Insert Exchange Secret",
"when": lambda x: not x['dry_run']
},
{
"type": "confirm",
"name": "telegram",
"message": "Do you want to enable Telegram?",
"default": False,
},
{
"type": "password",
"name": "telegram_token",
"message": "Insert Telegram token",
"when": lambda x: x['telegram']
},
{
"type": "text",
"name": "telegram_chat_id",
"message": "Insert Telegram chat id",
"when": lambda x: x['telegram']
},
]
answers = prompt(questions)
if not answers:
# Interrupted questionary sessions return an empty dict.
raise OperationalException("User interrupted interactive questions.")
return answers
def deploy_new_config(config_path: Path, selections: Dict[str, Any]) -> None:
"""
Applies selections to the template and writes the result to config_path
:param config_path: Path object for new config file. Should not exist yet
:param selecions: Dict containing selections taken by the user.
"""
from jinja2.exceptions import TemplateNotFound
try:
exchange_template = MAP_EXCHANGE_CHILDCLASS.get(
selections['exchange_name'], selections['exchange_name'])
selections['exchange'] = render_template(
templatefile=f"subtemplates/exchange_{exchange_template}.j2",
arguments=selections
)
except TemplateNotFound:
selections['exchange'] = render_template(
templatefile="subtemplates/exchange_generic.j2",
arguments=selections
)
config_text = render_template(templatefile='base_config.json.j2',
arguments=selections)
logger.info(f"Writing config to `{config_path}`.")
config_path.write_text(config_text)
def start_new_config(args: Dict[str, Any]) -> None:
"""
Create a new strategy from a template
Asking the user questions to fill out the templateaccordingly.
"""
config_path = Path(args['config'][0])
if config_path.exists():
overwrite = ask_user_overwrite(config_path)
if overwrite:
config_path.unlink()
else:
raise OperationalException(
f"Configuration file `{config_path}` already exists. "
"Please delete it or use a different configuration file name.")
selections = ask_user_config()
deploy_new_config(config_path, selections)

View File

@@ -1,7 +1,7 @@
"""
Definition of cli arguments used in arguments.py
"""
import argparse
from argparse import ArgumentTypeError
from freqtrade import __version__, constants
@@ -12,12 +12,24 @@ def check_int_positive(value: str) -> int:
if uint <= 0:
raise ValueError
except ValueError:
raise argparse.ArgumentTypeError(
raise ArgumentTypeError(
f"{value} is invalid for this parameter, should be a positive integer value"
)
return uint
def check_int_nonzero(value: str) -> int:
try:
uint = int(value)
if uint == 0:
raise ValueError
except ValueError:
raise ArgumentTypeError(
f"{value} is invalid for this parameter, should be a non-zero integer value"
)
return uint
class Arg:
# Optional CLI arguments
def __init__(self, *args, **kwargs):
@@ -36,7 +48,8 @@ AVAILABLE_CLI_OPTIONS = {
),
"logfile": Arg(
'--logfile',
help='Log to the file specified.',
help="Log to the file specified. Special values are: 'syslog', 'journald'. "
"See the documentation for more details.",
metavar='FILE',
),
"version": Arg(
@@ -46,7 +59,8 @@ AVAILABLE_CLI_OPTIONS = {
),
"config": Arg(
'-c', '--config',
help=f'Specify configuration file (default: `{constants.DEFAULT_CONFIG}`). '
help=f'Specify configuration file (default: `userdir/{constants.DEFAULT_CONFIG}` '
f'or `config.json` whichever exists). '
f'Multiple --config options may be used. '
f'Can be set to `-` to read config from stdin.',
action='append',
@@ -62,12 +76,16 @@ AVAILABLE_CLI_OPTIONS = {
help='Path to userdata directory.',
metavar='PATH',
),
"reset": Arg(
'--reset',
help='Reset sample files to their original state.',
action='store_true',
),
# Main options
"strategy": Arg(
'-s', '--strategy',
help='Specify strategy class name (default: `%(default)s`).',
help='Specify strategy class name which will be used by the bot.',
metavar='NAME',
default='DefaultStrategy',
),
"strategy_path": Arg(
'--strategy-path',
@@ -86,6 +104,11 @@ AVAILABLE_CLI_OPTIONS = {
help='Notify systemd service manager.',
action='store_true',
),
"dry_run": Arg(
'--dry-run',
help='Enforce dry-run for trading (removes Exchange secrets and simulates trades).',
action='store_true',
),
# Optimize common
"ticker_interval": Arg(
'-i', '--ticker-interval',
@@ -96,14 +119,14 @@ AVAILABLE_CLI_OPTIONS = {
help='Specify what timerange of data to use.',
),
"max_open_trades": Arg(
'--max_open_trades',
help='Specify max_open_trades to use.',
'--max-open-trades',
help='Override the value of the `max_open_trades` configuration setting.',
type=int,
metavar='INT',
),
"stake_amount": Arg(
'--stake_amount',
help='Specify stake_amount.',
'--stake-amount',
help='Override the value of the `stake_amount` configuration setting.',
type=float,
),
# Backtesting
@@ -136,7 +159,7 @@ AVAILABLE_CLI_OPTIONS = {
),
"exportfilename": Arg(
'--export-filename',
help='Save backtest results to the file with this filename (default: `%(default)s`). '
help='Save backtest results to the file with this filename. '
'Requires `--export` to be set as well. '
'Example: `--export-filename=user_data/backtest_results/backtest_today.json`',
metavar='PATH',
@@ -156,14 +179,13 @@ AVAILABLE_CLI_OPTIONS = {
),
# Hyperopt
"hyperopt": Arg(
'--customhyperopt',
help='Specify hyperopt class name (default: `%(default)s`).',
'--hyperopt',
help='Specify hyperopt class name which will be used by the bot.',
metavar='NAME',
default=constants.DEFAULT_HYPEROPT,
),
"hyperopt_path": Arg(
'--hyperopt-path',
help='Specify additional lookup path for Hyperopts and Hyperopt Loss functions.',
help='Specify additional lookup path for Hyperopt and Hyperopt Loss functions.',
metavar='PATH',
),
"epochs": Arg(
@@ -174,12 +196,11 @@ AVAILABLE_CLI_OPTIONS = {
default=constants.HYPEROPT_EPOCH,
),
"spaces": Arg(
'-s', '--spaces',
help='Specify which parameters to hyperopt. Space-separated list. '
'Default: `%(default)s`.',
choices=['all', 'buy', 'sell', 'roi', 'stoploss'],
'--spaces',
help='Specify which parameters to hyperopt. Space-separated list.',
choices=['all', 'buy', 'sell', 'roi', 'stoploss', 'trailing', 'default'],
nargs='+',
default='all',
default='default',
),
"print_all": Arg(
'--print-all',
@@ -196,10 +217,17 @@ AVAILABLE_CLI_OPTIONS = {
),
"print_json": Arg(
'--print-json',
help='Print best result detailization in JSON format.',
help='Print output in JSON format.',
action='store_true',
default=False,
),
"export_csv": Arg(
'--export-csv',
help='Export to CSV-File.'
' This will disable table print.'
' Example: --export-csv hyperopt.csv',
metavar='FILE',
),
"hyperopt_jobs": Arg(
'-j', '--job-workers',
help='The number of concurrently running jobs for hyperoptimization '
@@ -236,7 +264,8 @@ AVAILABLE_CLI_OPTIONS = {
help='Specify 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: '
'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss.'
'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss, SharpeHyperOptLossDaily, '
'SortinoHyperOptLoss, SortinoHyperOptLossDaily.'
'(default: `%(default)s`).',
metavar='NAME',
default=constants.DEFAULT_HYPEROPT_LOSS,
@@ -312,6 +341,30 @@ AVAILABLE_CLI_OPTIONS = {
'desired timeframe as specified as --timeframes/-t.',
action='store_true',
),
"format_from": Arg(
'--format-from',
help='Source format for data conversion.',
choices=constants.AVAILABLE_DATAHANDLERS,
required=True,
),
"format_to": Arg(
'--format-to',
help='Destination format for data conversion.',
choices=constants.AVAILABLE_DATAHANDLERS,
required=True,
),
"dataformat_ohlcv": Arg(
'--data-format-ohlcv',
help='Storage format for downloaded candle (OHLCV) data. (default: `%(default)s`).',
choices=constants.AVAILABLE_DATAHANDLERS,
default='json'
),
"dataformat_trades": Arg(
'--data-format-trades',
help='Storage format for downloaded trades data. (default: `%(default)s`).',
choices=constants.AVAILABLE_DATAHANDLERS,
default='jsongz'
),
"exchange": Arg(
'--exchange',
help=f'Exchange name (default: `{constants.DEFAULT_EXCHANGE}`). '
@@ -319,8 +372,8 @@ AVAILABLE_CLI_OPTIONS = {
),
"timeframes": Arg(
'-t', '--timeframes',
help=f'Specify which tickers to download. Space-separated list. '
f'Default: `1m 5m`.',
help='Specify which tickers to download. Space-separated list. '
'Default: `1m 5m`.',
choices=['1m', '3m', '5m', '15m', '30m', '1h', '2h', '4h',
'6h', '8h', '12h', '1d', '3d', '1w'],
default=['1m', '5m'],
@@ -331,19 +384,25 @@ AVAILABLE_CLI_OPTIONS = {
help='Clean all existing data for the selected exchange/pairs/timeframes.',
action='store_true',
),
# Templating options
"template": Arg(
'--template',
help='Use a template which is either `minimal`, '
'`full` (containing multiple sample indicators) or `advanced`. Default: `%(default)s`.',
choices=['full', 'minimal', 'advanced'],
default='full',
),
# Plot dataframe
"indicators1": Arg(
'--indicators1',
help='Set indicators from your strategy you want in the first row of the graph. '
'Space-separated list. Example: `ema3 ema5`. Default: `%(default)s`.',
default=['sma', 'ema3', 'ema5'],
"Space-separated list. Example: `ema3 ema5`. Default: `['sma', 'ema3', 'ema5']`.",
nargs='+',
),
"indicators2": Arg(
'--indicators2',
help='Set indicators from your strategy you want in the third row of the graph. '
'Space-separated list. Example: `fastd fastk`. Default: `%(default)s`.',
default=['macd', 'macdsignal'],
"Space-separated list. Example: `fastd fastk`. Default: `['macd', 'macdsignal']`.",
nargs='+',
),
"plot_limit": Arg(
@@ -354,6 +413,11 @@ AVAILABLE_CLI_OPTIONS = {
metavar='INT',
default=750,
),
"no_trades": Arg(
'--no-trades',
help='Skip using trades from backtesting file and DB.',
action='store_true',
),
"trade_source": Arg(
'--trade-source',
help='Specify the source for trades (Can be DB or file (backtest file)) '
@@ -361,4 +425,84 @@ AVAILABLE_CLI_OPTIONS = {
choices=["DB", "file"],
default="file",
),
"trade_ids": Arg(
'--trade-ids',
help='Specify the list of trade ids.',
nargs='+',
),
# hyperopt-list, hyperopt-show
"hyperopt_list_profitable": Arg(
'--profitable',
help='Select only profitable epochs.',
action='store_true',
),
"hyperopt_list_best": Arg(
'--best',
help='Select only best epochs.',
action='store_true',
),
"hyperopt_list_min_trades": Arg(
'--min-trades',
help='Select epochs with more than INT trades.',
type=check_int_positive,
metavar='INT',
),
"hyperopt_list_max_trades": Arg(
'--max-trades',
help='Select epochs with less than INT trades.',
type=check_int_positive,
metavar='INT',
),
"hyperopt_list_min_avg_time": Arg(
'--min-avg-time',
help='Select epochs on above average time.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_max_avg_time": Arg(
'--max-avg-time',
help='Select epochs on under average time.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_min_avg_profit": Arg(
'--min-avg-profit',
help='Select epochs on above average profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_max_avg_profit": Arg(
'--max-avg-profit',
help='Select epochs on below average profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_min_total_profit": Arg(
'--min-total-profit',
help='Select epochs on above total profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_max_total_profit": Arg(
'--max-total-profit',
help='Select epochs on below total profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_no_details": Arg(
'--no-details',
help='Do not print best epoch details.',
action='store_true',
),
"hyperopt_show_index": Arg(
'-n', '--index',
help='Specify the index of the epoch to print details for.',
type=check_int_nonzero,
metavar='INT',
),
"hyperopt_show_no_header": Arg(
'--no-header',
help='Do not print epoch details header.',
action='store_true',
),
}

View File

@@ -0,0 +1,90 @@
import logging
import sys
from typing import Any, Dict, List
import arrow
from freqtrade.configuration import TimeRange, setup_utils_configuration
from freqtrade.data.converter import (convert_ohlcv_format,
convert_trades_format)
from freqtrade.data.history import (convert_trades_to_ohlcv,
refresh_backtest_ohlcv_data,
refresh_backtest_trades_data)
from freqtrade.exceptions import OperationalException
from freqtrade.resolvers import ExchangeResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def start_download_data(args: Dict[str, Any]) -> None:
"""
Download data (former download_backtest_data.py script)
"""
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
timerange = TimeRange()
if 'days' in config:
time_since = arrow.utcnow().shift(days=-config['days']).strftime("%Y%m%d")
timerange = TimeRange.parse_timerange(f'{time_since}-')
if 'pairs' not in config:
raise OperationalException(
"Downloading data requires a list of pairs. "
"Please check the documentation on how to configure this.")
logger.info(f'About to download pairs: {config["pairs"]}, '
f'intervals: {config["timeframes"]} to {config["datadir"]}')
pairs_not_available: List[str] = []
# Init exchange
exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False)
# Manual validations of relevant settings
exchange.validate_pairs(config['pairs'])
for timeframe in config['timeframes']:
exchange.validate_timeframes(timeframe)
try:
if config.get('download_trades'):
pairs_not_available = refresh_backtest_trades_data(
exchange, pairs=config["pairs"], datadir=config['datadir'],
timerange=timerange, erase=bool(config.get("erase")),
data_format=config['dataformat_trades'])
# Convert downloaded trade data to different timeframes
convert_trades_to_ohlcv(
pairs=config["pairs"], timeframes=config["timeframes"],
datadir=config['datadir'], timerange=timerange, erase=bool(config.get("erase")),
data_format_ohlcv=config['dataformat_ohlcv'],
data_format_trades=config['dataformat_trades'],
)
else:
pairs_not_available = refresh_backtest_ohlcv_data(
exchange, pairs=config["pairs"], timeframes=config["timeframes"],
datadir=config['datadir'], timerange=timerange, erase=bool(config.get("erase")),
data_format=config['dataformat_ohlcv'])
except KeyboardInterrupt:
sys.exit("SIGINT received, aborting ...")
finally:
if pairs_not_available:
logger.info(f"Pairs [{','.join(pairs_not_available)}] not available "
f"on exchange {exchange.name}.")
def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None:
"""
Convert data from one format to another
"""
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if ohlcv:
convert_ohlcv_format(config,
convert_from=args['format_from'], convert_to=args['format_to'],
erase=args['erase'])
else:
convert_trades_format(config,
convert_from=args['format_from'], convert_to=args['format_to'],
erase=args['erase'])

View File

@@ -0,0 +1,139 @@
import logging
import sys
from pathlib import Path
from typing import Any, Dict
from freqtrade.configuration import setup_utils_configuration
from freqtrade.configuration.directory_operations import (copy_sample_files,
create_userdata_dir)
from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGIES
from freqtrade.exceptions import OperationalException
from freqtrade.misc import render_template, render_template_with_fallback
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def start_create_userdir(args: Dict[str, Any]) -> None:
"""
Create "user_data" directory to contain user data strategies, hyperopt, ...)
:param args: Cli args from Arguments()
:return: None
"""
if "user_data_dir" in args and args["user_data_dir"]:
userdir = create_userdata_dir(args["user_data_dir"], create_dir=True)
copy_sample_files(userdir, overwrite=args["reset"])
else:
logger.warning("`create-userdir` requires --userdir to be set.")
sys.exit(1)
def deploy_new_strategy(strategy_name: str, strategy_path: Path, subtemplate: str) -> None:
"""
Deploy new strategy from template to strategy_path
"""
fallback = 'full'
indicators = render_template_with_fallback(
templatefile=f"subtemplates/indicators_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/indicators_{fallback}.j2",
)
buy_trend = render_template_with_fallback(
templatefile=f"subtemplates/buy_trend_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/buy_trend_{fallback}.j2",
)
sell_trend = render_template_with_fallback(
templatefile=f"subtemplates/sell_trend_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/sell_trend_{fallback}.j2",
)
plot_config = render_template_with_fallback(
templatefile=f"subtemplates/plot_config_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/plot_config_{fallback}.j2",
)
additional_methods = render_template_with_fallback(
templatefile=f"subtemplates/strategy_methods_{subtemplate}.j2",
templatefallbackfile="subtemplates/strategy_methods_empty.j2",
)
strategy_text = render_template(templatefile='base_strategy.py.j2',
arguments={"strategy": strategy_name,
"indicators": indicators,
"buy_trend": buy_trend,
"sell_trend": sell_trend,
"plot_config": plot_config,
"additional_methods": additional_methods,
})
logger.info(f"Writing strategy to `{strategy_path}`.")
strategy_path.write_text(strategy_text)
def start_new_strategy(args: Dict[str, Any]) -> None:
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if "strategy" in args and args["strategy"]:
if args["strategy"] == "DefaultStrategy":
raise OperationalException("DefaultStrategy is not allowed as name.")
new_path = config['user_data_dir'] / USERPATH_STRATEGIES / (args["strategy"] + ".py")
if new_path.exists():
raise OperationalException(f"`{new_path}` already exists. "
"Please choose another Strategy Name.")
deploy_new_strategy(args['strategy'], new_path, args['template'])
else:
raise OperationalException("`new-strategy` requires --strategy to be set.")
def deploy_new_hyperopt(hyperopt_name: str, hyperopt_path: Path, subtemplate: str) -> None:
"""
Deploys a new hyperopt template to hyperopt_path
"""
fallback = 'full'
buy_guards = render_template_with_fallback(
templatefile=f"subtemplates/hyperopt_buy_guards_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/hyperopt_buy_guards_{fallback}.j2",
)
sell_guards = render_template_with_fallback(
templatefile=f"subtemplates/hyperopt_sell_guards_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/hyperopt_sell_guards_{fallback}.j2",
)
buy_space = render_template_with_fallback(
templatefile=f"subtemplates/hyperopt_buy_space_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/hyperopt_buy_space_{fallback}.j2",
)
sell_space = render_template_with_fallback(
templatefile=f"subtemplates/hyperopt_sell_space_{subtemplate}.j2",
templatefallbackfile=f"subtemplates/hyperopt_sell_space_{fallback}.j2",
)
strategy_text = render_template(templatefile='base_hyperopt.py.j2',
arguments={"hyperopt": hyperopt_name,
"buy_guards": buy_guards,
"sell_guards": sell_guards,
"buy_space": buy_space,
"sell_space": sell_space,
})
logger.info(f"Writing hyperopt to `{hyperopt_path}`.")
hyperopt_path.write_text(strategy_text)
def start_new_hyperopt(args: Dict[str, Any]) -> None:
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if "hyperopt" in args and args["hyperopt"]:
if args["hyperopt"] == "DefaultHyperopt":
raise OperationalException("DefaultHyperopt is not allowed as name.")
new_path = config['user_data_dir'] / USERPATH_HYPEROPTS / (args["hyperopt"] + ".py")
if new_path.exists():
raise OperationalException(f"`{new_path}` already exists. "
"Please choose another Strategy Name.")
deploy_new_hyperopt(args['hyperopt'], new_path, args['template'])
else:
raise OperationalException("`new-hyperopt` requires --hyperopt to be set.")

View File

@@ -0,0 +1,182 @@
import logging
from operator import itemgetter
from typing import Any, Dict, List
from colorama import init as colorama_init
from freqtrade.configuration import setup_utils_configuration
from freqtrade.exceptions import OperationalException
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def start_hyperopt_list(args: Dict[str, Any]) -> None:
"""
List hyperopt epochs previously evaluated
"""
from freqtrade.optimize.hyperopt import Hyperopt
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
print_colorized = config.get('print_colorized', False)
print_json = config.get('print_json', False)
export_csv = config.get('export_csv', None)
no_details = config.get('hyperopt_list_no_details', False)
no_header = False
filteroptions = {
'only_best': config.get('hyperopt_list_best', False),
'only_profitable': config.get('hyperopt_list_profitable', False),
'filter_min_trades': config.get('hyperopt_list_min_trades', 0),
'filter_max_trades': config.get('hyperopt_list_max_trades', 0),
'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None),
'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None),
'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None),
'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', None),
'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None),
'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None)
}
results_file = (config['user_data_dir'] /
'hyperopt_results' / 'hyperopt_results.pickle')
# Previous evaluations
epochs = Hyperopt.load_previous_results(results_file)
total_epochs = len(epochs)
epochs = _hyperopt_filter_epochs(epochs, filteroptions)
if print_colorized:
colorama_init(autoreset=True)
if not export_csv:
try:
print(Hyperopt.get_result_table(config, epochs, total_epochs,
not filteroptions['only_best'], print_colorized, 0))
except KeyboardInterrupt:
print('User interrupted..')
if epochs and not no_details:
sorted_epochs = sorted(epochs, key=itemgetter('loss'))
results = sorted_epochs[0]
Hyperopt.print_epoch_details(results, total_epochs, print_json, no_header)
if epochs and export_csv:
Hyperopt.export_csv_file(
config, epochs, total_epochs, not filteroptions['only_best'], export_csv
)
def start_hyperopt_show(args: Dict[str, Any]) -> None:
"""
Show details of a hyperopt epoch previously evaluated
"""
from freqtrade.optimize.hyperopt import Hyperopt
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
print_json = config.get('print_json', False)
no_header = config.get('hyperopt_show_no_header', False)
results_file = (config['user_data_dir'] /
'hyperopt_results' / 'hyperopt_results.pickle')
n = config.get('hyperopt_show_index', -1)
filteroptions = {
'only_best': config.get('hyperopt_list_best', False),
'only_profitable': config.get('hyperopt_list_profitable', False),
'filter_min_trades': config.get('hyperopt_list_min_trades', 0),
'filter_max_trades': config.get('hyperopt_list_max_trades', 0),
'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None),
'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None),
'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None),
'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', None),
'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None),
'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None)
}
# Previous evaluations
epochs = Hyperopt.load_previous_results(results_file)
total_epochs = len(epochs)
epochs = _hyperopt_filter_epochs(epochs, filteroptions)
filtered_epochs = len(epochs)
if n > filtered_epochs:
raise OperationalException(
f"The index of the epoch to show should be less than {filtered_epochs + 1}.")
if n < -filtered_epochs:
raise OperationalException(
f"The index of the epoch to show should be greater than {-filtered_epochs - 1}.")
# Translate epoch index from human-readable format to pythonic
if n > 0:
n -= 1
if epochs:
val = epochs[n]
Hyperopt.print_epoch_details(val, total_epochs, print_json, no_header,
header_str="Epoch details")
def _hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List:
"""
Filter our items from the list of hyperopt results
"""
if filteroptions['only_best']:
epochs = [x for x in epochs if x['is_best']]
if filteroptions['only_profitable']:
epochs = [x for x in epochs if x['results_metrics']['profit'] > 0]
if filteroptions['filter_min_trades'] > 0:
epochs = [
x for x in epochs
if x['results_metrics']['trade_count'] > filteroptions['filter_min_trades']
]
if filteroptions['filter_max_trades'] > 0:
epochs = [
x for x in epochs
if x['results_metrics']['trade_count'] < filteroptions['filter_max_trades']
]
if filteroptions['filter_min_avg_time'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
x for x in epochs
if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time']
]
if filteroptions['filter_max_avg_time'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
x for x in epochs
if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time']
]
if filteroptions['filter_min_avg_profit'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
x for x in epochs
if x['results_metrics']['avg_profit'] > filteroptions['filter_min_avg_profit']
]
if filteroptions['filter_max_avg_profit'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
x for x in epochs
if x['results_metrics']['avg_profit'] < filteroptions['filter_max_avg_profit']
]
if filteroptions['filter_min_total_profit'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
x for x in epochs
if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit']
]
if filteroptions['filter_max_total_profit'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
x for x in epochs
if x['results_metrics']['profit'] < filteroptions['filter_max_total_profit']
]
logger.info(f"{len(epochs)} " +
("best " if filteroptions['only_best'] else "") +
("profitable " if filteroptions['only_profitable'] else "") +
"epochs found.")
return epochs

View File

@@ -1,46 +1,27 @@
import csv
import logging
import sys
from collections import OrderedDict
from pathlib import Path
from typing import Any, Dict, List
import arrow
import csv
from colorama import init as colorama_init
from colorama import Fore, Style
import rapidjson
from tabulate import tabulate
from freqtrade import OperationalException
from freqtrade.configuration import Configuration, TimeRange
from freqtrade.configuration.directory_operations import create_userdata_dir
from freqtrade.data.history import (convert_trades_to_ohlcv,
refresh_backtest_ohlcv_data,
refresh_backtest_trades_data)
from freqtrade.exchange import (available_exchanges, ccxt_exchanges, market_is_active,
symbol_is_pair)
from freqtrade.configuration import setup_utils_configuration
from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGIES
from freqtrade.exceptions import OperationalException
from freqtrade.exchange import (available_exchanges, ccxt_exchanges,
market_is_active, symbol_is_pair)
from freqtrade.misc import plural
from freqtrade.resolvers import ExchangeResolver
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for utils subcommands
:param args: Cli args from Arguments()
:return: Configuration
"""
configuration = Configuration(args, method)
config = configuration.get_config()
config['exchange']['dry_run'] = True
# Ensure we do not use Exchange credentials
config['exchange']['key'] = ''
config['exchange']['secret'] = ''
return config
def start_list_exchanges(args: Dict[str, Any]) -> None:
"""
Print available exchanges
@@ -57,78 +38,75 @@ def start_list_exchanges(args: Dict[str, Any]) -> None:
print(f"Exchanges available for Freqtrade: {', '.join(exchanges)}")
def start_create_userdir(args: Dict[str, Any]) -> None:
"""
Create "user_data" directory to contain user data strategies, hyperopts, ...)
:param args: Cli args from Arguments()
:return: None
"""
if "user_data_dir" in args and args["user_data_dir"]:
create_userdata_dir(args["user_data_dir"], create_dir=True)
def _print_objs_tabular(objs: List, print_colorized: bool) -> None:
if print_colorized:
colorama_init(autoreset=True)
red = Fore.RED
yellow = Fore.YELLOW
reset = Style.RESET_ALL
else:
logger.warning("`create-userdir` requires --userdir to be set.")
sys.exit(1)
red = ''
yellow = ''
reset = ''
names = [s['name'] for s in objs]
objss_to_print = [{
'name': s['name'] if s['name'] else "--",
'location': s['location'].name,
'status': (red + "LOAD FAILED" + reset if s['class'] is None
else "OK" if names.count(s['name']) == 1
else yellow + "DUPLICATE NAME" + reset)
} for s in objs]
print(tabulate(objss_to_print, headers='keys', tablefmt='psql', stralign='right'))
def start_download_data(args: Dict[str, Any]) -> None:
def start_list_strategies(args: Dict[str, Any]) -> None:
"""
Download data (former download_backtest_data.py script)
Print files with Strategy custom classes available in the directory
"""
config = setup_utils_configuration(args, RunMode.OTHER)
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
timerange = TimeRange()
if 'days' in config:
time_since = arrow.utcnow().shift(days=-config['days']).strftime("%Y%m%d")
timerange = TimeRange.parse_timerange(f'{time_since}-')
directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES))
strategy_objs = StrategyResolver.search_all_objects(directory, not args['print_one_column'])
# Sort alphabetically
strategy_objs = sorted(strategy_objs, key=lambda x: x['name'])
if 'pairs' not in config:
raise OperationalException(
"Downloading data requires a list of pairs. "
"Please check the documentation on how to configure this.")
if args['print_one_column']:
print('\n'.join([s['name'] for s in strategy_objs]))
else:
_print_objs_tabular(strategy_objs, config.get('print_colorized', False))
dl_path = Path(config['datadir'])
logger.info(f'About to download pairs: {config["pairs"]}, '
f'intervals: {config["timeframes"]} to {dl_path}')
pairs_not_available: List[str] = []
def start_list_hyperopts(args: Dict[str, Any]) -> None:
"""
Print files with HyperOpt custom classes available in the directory
"""
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
# Init exchange
exchange = ExchangeResolver(config['exchange']['name'], config).exchange
try:
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if config.get('download_trades'):
pairs_not_available = refresh_backtest_trades_data(
exchange, pairs=config["pairs"], datadir=Path(config['datadir']),
timerange=timerange, erase=config.get("erase"))
directory = Path(config.get('hyperopt_path', config['user_data_dir'] / USERPATH_HYPEROPTS))
hyperopt_objs = HyperOptResolver.search_all_objects(directory, not args['print_one_column'])
# Sort alphabetically
hyperopt_objs = sorted(hyperopt_objs, key=lambda x: x['name'])
# Convert downloaded trade data to different timeframes
convert_trades_to_ohlcv(
pairs=config["pairs"], timeframes=config["timeframes"],
datadir=Path(config['datadir']), timerange=timerange, erase=config.get("erase"))
else:
pairs_not_available = refresh_backtest_ohlcv_data(
exchange, pairs=config["pairs"], timeframes=config["timeframes"],
dl_path=Path(config['datadir']), timerange=timerange, erase=config.get("erase"))
except KeyboardInterrupt:
sys.exit("SIGINT received, aborting ...")
finally:
if pairs_not_available:
logger.info(f"Pairs [{','.join(pairs_not_available)}] not available "
f"on exchange {exchange.name}.")
if args['print_one_column']:
print('\n'.join([s['name'] for s in hyperopt_objs]))
else:
_print_objs_tabular(hyperopt_objs, config.get('print_colorized', False))
def start_list_timeframes(args: Dict[str, Any]) -> None:
"""
Print ticker intervals (timeframes) available on Exchange
"""
config = setup_utils_configuration(args, RunMode.OTHER)
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
# Do not use ticker_interval set in the config
config['ticker_interval'] = None
# Init exchange
exchange = ExchangeResolver(config['exchange']['name'], config, validate=False).exchange
exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False)
if args['print_one_column']:
print('\n'.join(exchange.timeframes))
@@ -144,10 +122,10 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None:
:param pairs_only: if True print only pairs, otherwise print all instruments (markets)
:return: None
"""
config = setup_utils_configuration(args, RunMode.OTHER)
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
# Init exchange
exchange = ExchangeResolver(config['exchange']['name'], config, validate=False).exchange
exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False)
# By default only active pairs/markets are to be shown
active_only = not args.get('list_pairs_all', False)
@@ -214,8 +192,35 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None:
else:
# print data as a table, with the human-readable summary
print(f"{summary_str}:")
print(tabulate(tabular_data, headers='keys', tablefmt='pipe'))
print(tabulate(tabular_data, headers='keys', tablefmt='psql', stralign='right'))
elif not (args.get('print_one_column', False) or
args.get('list_pairs_print_json', False) or
args.get('print_csv', False)):
print(f"{summary_str}.")
def start_show_trades(args: Dict[str, Any]) -> None:
"""
Show trades
"""
from freqtrade.persistence import init, Trade
import json
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if 'db_url' not in config:
raise OperationalException("--db-url is required for this command.")
logger.info(f'Using DB: "{config["db_url"]}"')
init(config['db_url'], clean_open_orders=False)
tfilter = []
if config.get('trade_ids'):
tfilter.append(Trade.id.in_(config['trade_ids']))
trades = Trade.get_trades(tfilter).all()
logger.info(f"Printing {len(trades)} Trades: ")
if config.get('print_json', False):
print(json.dumps([trade.to_json() for trade in trades], indent=4))
else:
for trade in trades:
print(trade)

View File

@@ -0,0 +1,107 @@
import logging
from typing import Any, Dict
from freqtrade import constants
from freqtrade.configuration import setup_utils_configuration
from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def setup_optimize_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for the Hyperopt module
:param args: Cli args from Arguments()
:return: Configuration
"""
config = setup_utils_configuration(args, method)
no_unlimited_runmodes = {
RunMode.BACKTEST: 'backtesting',
RunMode.HYPEROPT: 'hyperoptimization',
}
if (method in no_unlimited_runmodes.keys() and
config['stake_amount'] == constants.UNLIMITED_STAKE_AMOUNT):
raise DependencyException(
f'The value of `stake_amount` cannot be set as "{constants.UNLIMITED_STAKE_AMOUNT}" '
f'for {no_unlimited_runmodes[method]}')
return config
def start_backtesting(args: Dict[str, Any]) -> None:
"""
Start Backtesting script
:param args: Cli args from Arguments()
:return: None
"""
# Import here to avoid loading backtesting module when it's not used
from freqtrade.optimize.backtesting import Backtesting
# Initialize configuration
config = setup_optimize_configuration(args, RunMode.BACKTEST)
logger.info('Starting freqtrade in Backtesting mode')
# Initialize backtesting object
backtesting = Backtesting(config)
backtesting.start()
def start_hyperopt(args: Dict[str, Any]) -> None:
"""
Start hyperopt script
:param args: Cli args from Arguments()
:return: None
"""
# Import here to avoid loading hyperopt module when it's not used
try:
from filelock import FileLock, Timeout
from freqtrade.optimize.hyperopt import Hyperopt
except ImportError as e:
raise OperationalException(
f"{e}. Please ensure that the hyperopt dependencies are installed.") from e
# Initialize configuration
config = setup_optimize_configuration(args, RunMode.HYPEROPT)
logger.info('Starting freqtrade in Hyperopt mode')
lock = FileLock(Hyperopt.get_lock_filename(config))
try:
with lock.acquire(timeout=1):
# Remove noisy log messages
logging.getLogger('hyperopt.tpe').setLevel(logging.WARNING)
logging.getLogger('filelock').setLevel(logging.WARNING)
# Initialize backtesting object
hyperopt = Hyperopt(config)
hyperopt.start()
except Timeout:
logger.info("Another running instance of freqtrade Hyperopt detected.")
logger.info("Simultaneous execution of multiple Hyperopt commands is not supported. "
"Hyperopt module is resource hungry. Please run your Hyperopt sequentially "
"or on separate machines.")
logger.info("Quitting now.")
# TODO: return False here in order to help freqtrade to exit
# with non-zero exit code...
# Same in Edge and Backtesting start() functions.
def start_edge(args: Dict[str, Any]) -> None:
"""
Start Edge script
:param args: Cli args from Arguments()
:return: None
"""
from freqtrade.optimize.edge_cli import EdgeCli
# Initialize configuration
config = setup_optimize_configuration(args, RunMode.EDGE)
logger.info('Starting freqtrade in Edge mode')
# Initialize Edge object
edge_cli = EdgeCli(config)
edge_cli.start()

View File

@@ -0,0 +1,42 @@
import logging
from typing import Any, Dict
import rapidjson
from freqtrade.configuration import setup_utils_configuration
from freqtrade.resolvers import ExchangeResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def start_test_pairlist(args: Dict[str, Any]) -> None:
"""
Test Pairlist configuration
"""
from freqtrade.pairlist.pairlistmanager import PairListManager
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False)
quote_currencies = args.get('quote_currencies')
if not quote_currencies:
quote_currencies = [config.get('stake_currency')]
results = {}
for curr in quote_currencies:
config['stake_currency'] = curr
# Do not use ticker_interval set in the config
pairlists = PairListManager(exchange, config)
pairlists.refresh_pairlist()
results[curr] = pairlists.whitelist
for curr, pairlist in results.items():
if not args.get('print_one_column', False):
print(f"Pairs for {curr}: ")
if args.get('print_one_column', False):
print('\n'.join(pairlist))
elif args.get('list_pairs_print_json', False):
print(rapidjson.dumps(list(pairlist), default=str))
else:
print(pairlist)

View File

@@ -1,11 +1,11 @@
from typing import Any, Dict
from freqtrade import OperationalException
from freqtrade.configuration import setup_utils_configuration
from freqtrade.exceptions import OperationalException
from freqtrade.state import RunMode
from freqtrade.utils import setup_utils_configuration
def validate_plot_args(args: Dict[str, Any]):
def validate_plot_args(args: Dict[str, Any]) -> None:
if not args.get('datadir') and not args.get('config'):
raise OperationalException(
"You need to specify either `--datadir` or `--config` "

View File

@@ -0,0 +1,30 @@
import logging
from typing import Any, Dict
logger = logging.getLogger(__name__)
def start_trading(args: Dict[str, Any]) -> int:
"""
Main entry point for trading mode
"""
# Import here to avoid loading worker module when it's not used
from freqtrade.worker import Worker
# Create and run worker
worker = None
try:
worker = Worker(args)
worker.run()
except Exception as e:
logger.error(str(e))
logger.exception("Fatal exception!")
except KeyboardInterrupt:
logger.info('SIGINT received, aborting ...')
finally:
if worker:
logger.info("worker found ... calling exit")
worker.exit()
return 0

View File

@@ -1,4 +1,7 @@
from freqtrade.configuration.arguments import Arguments # noqa: F401
from freqtrade.configuration.timerange import TimeRange # noqa: F401
from freqtrade.configuration.configuration import Configuration # noqa: F401
from freqtrade.configuration.config_validation import validate_config_consistency # noqa: F401
# flake8: noqa: F401
from freqtrade.configuration.config_setup import setup_utils_configuration
from freqtrade.configuration.check_exchange import check_exchange, remove_credentials
from freqtrade.configuration.timerange import TimeRange
from freqtrade.configuration.configuration import Configuration
from freqtrade.configuration.config_validation import validate_config_consistency

View File

@@ -1,196 +0,0 @@
"""
This module contains the argument manager class
"""
import argparse
from functools import partial
from pathlib import Path
from typing import Any, Dict, List, Optional
from freqtrade import constants
from freqtrade.configuration.cli_options import AVAILABLE_CLI_OPTIONS
ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"]
ARGS_STRATEGY = ["strategy", "strategy_path"]
ARGS_MAIN = ARGS_COMMON + ARGS_STRATEGY + ["db_url", "sd_notify"]
ARGS_COMMON_OPTIMIZE = ["ticker_interval", "timerange",
"max_open_trades", "stake_amount", "fee"]
ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_positions",
"strategy_list", "export", "exportfilename"]
ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
"position_stacking", "epochs", "spaces",
"use_max_market_positions", "print_all",
"print_colorized", "print_json", "hyperopt_jobs",
"hyperopt_random_state", "hyperopt_min_trades",
"hyperopt_continue", "hyperopt_loss"]
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"]
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
ARGS_LIST_PAIRS = ["exchange", "print_list", "list_pairs_print_json", "print_one_column",
"print_csv", "base_currencies", "quote_currencies", "list_pairs_all"]
ARGS_CREATE_USERDIR = ["user_data_dir"]
ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "download_trades", "exchange",
"timeframes", "erase"]
ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", "db_url",
"trade_source", "export", "exportfilename", "timerange", "ticker_interval"]
ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url",
"trade_source", "ticker_interval"]
NO_CONF_REQURIED = ["download-data", "list-timeframes", "list-markets", "list-pairs",
"plot-dataframe", "plot-profit"]
NO_CONF_ALLOWED = ["create-userdir", "list-exchanges"]
class Arguments:
"""
Arguments Class. Manage the arguments received by the cli
"""
def __init__(self, args: Optional[List[str]]) -> None:
self.args = args
self._parsed_arg: Optional[argparse.Namespace] = None
self.parser = argparse.ArgumentParser(description='Free, open source crypto trading bot')
def _load_args(self) -> None:
self._build_args(optionlist=ARGS_MAIN)
self._build_subcommands()
def get_parsed_arg(self) -> Dict[str, Any]:
"""
Return the list of arguments
:return: List[str] List of arguments
"""
if self._parsed_arg is None:
self._load_args()
self._parsed_arg = self._parse_args()
return vars(self._parsed_arg)
def _parse_args(self) -> argparse.Namespace:
"""
Parses given arguments and returns an argparse Namespace instance.
"""
parsed_arg = self.parser.parse_args(self.args)
# When no config is provided, but a config exists, use that configuration!
subparser = parsed_arg.subparser if 'subparser' in parsed_arg else None
# Workaround issue in argparse with action='append' and default value
# (see https://bugs.python.org/issue16399)
# Allow no-config for certain commands (like downloading / plotting)
if (parsed_arg.config is None
and subparser not in NO_CONF_ALLOWED
and ((Path.cwd() / constants.DEFAULT_CONFIG).is_file()
or (subparser not in NO_CONF_REQURIED))):
parsed_arg.config = [constants.DEFAULT_CONFIG]
return parsed_arg
def _build_args(self, optionlist, parser=None):
parser = parser or self.parser
for val in optionlist:
opt = AVAILABLE_CLI_OPTIONS[val]
parser.add_argument(*opt.cli, dest=val, **opt.kwargs)
def _build_subcommands(self) -> None:
"""
Builds and attaches all subcommands.
:return: None
"""
from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge
from freqtrade.utils import (start_create_userdir, start_download_data,
start_list_exchanges, start_list_timeframes,
start_list_markets)
subparsers = self.parser.add_subparsers(dest='subparser')
# Add backtesting subcommand
backtesting_cmd = subparsers.add_parser('backtesting', help='Backtesting module.')
backtesting_cmd.set_defaults(func=start_backtesting)
self._build_args(optionlist=ARGS_BACKTEST, parser=backtesting_cmd)
# Add edge subcommand
edge_cmd = subparsers.add_parser('edge', help='Edge module.')
edge_cmd.set_defaults(func=start_edge)
self._build_args(optionlist=ARGS_EDGE, parser=edge_cmd)
# Add hyperopt subcommand
hyperopt_cmd = subparsers.add_parser('hyperopt', help='Hyperopt module.')
hyperopt_cmd.set_defaults(func=start_hyperopt)
self._build_args(optionlist=ARGS_HYPEROPT, parser=hyperopt_cmd)
# add create-userdir subcommand
create_userdir_cmd = subparsers.add_parser('create-userdir',
help="Create user-data directory.")
create_userdir_cmd.set_defaults(func=start_create_userdir)
self._build_args(optionlist=ARGS_CREATE_USERDIR, parser=create_userdir_cmd)
# Add list-exchanges subcommand
list_exchanges_cmd = subparsers.add_parser(
'list-exchanges',
help='Print available exchanges.'
)
list_exchanges_cmd.set_defaults(func=start_list_exchanges)
self._build_args(optionlist=ARGS_LIST_EXCHANGES, parser=list_exchanges_cmd)
# Add list-timeframes subcommand
list_timeframes_cmd = subparsers.add_parser(
'list-timeframes',
help='Print available ticker intervals (timeframes) for the exchange.'
)
list_timeframes_cmd.set_defaults(func=start_list_timeframes)
self._build_args(optionlist=ARGS_LIST_TIMEFRAMES, parser=list_timeframes_cmd)
# Add list-markets subcommand
list_markets_cmd = subparsers.add_parser(
'list-markets',
help='Print markets on exchange.'
)
list_markets_cmd.set_defaults(func=partial(start_list_markets, pairs_only=False))
self._build_args(optionlist=ARGS_LIST_PAIRS, parser=list_markets_cmd)
# Add list-pairs subcommand
list_pairs_cmd = subparsers.add_parser(
'list-pairs',
help='Print pairs on exchange.'
)
list_pairs_cmd.set_defaults(func=partial(start_list_markets, pairs_only=True))
self._build_args(optionlist=ARGS_LIST_PAIRS, parser=list_pairs_cmd)
# Add download-data subcommand
download_data_cmd = subparsers.add_parser(
'download-data',
help='Download backtesting data.'
)
download_data_cmd.set_defaults(func=start_download_data)
self._build_args(optionlist=ARGS_DOWNLOAD_DATA, parser=download_data_cmd)
# Add Plotting subcommand
from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit
plot_dataframe_cmd = subparsers.add_parser(
'plot-dataframe',
help='Plot candles with indicators.'
)
plot_dataframe_cmd.set_defaults(func=start_plot_dataframe)
self._build_args(optionlist=ARGS_PLOT_DATAFRAME, parser=plot_dataframe_cmd)
# Plot profit
plot_profit_cmd = subparsers.add_parser(
'plot-profit',
help='Generate plot showing profits.'
)
plot_profit_cmd.set_defaults(func=start_plot_profit)
self._build_args(optionlist=ARGS_PLOT_PROFIT, parser=plot_profit_cmd)

View File

@@ -1,15 +1,28 @@
import logging
from typing import Any, Dict
from freqtrade import OperationalException
from freqtrade.exceptions import OperationalException
from freqtrade.exchange import (available_exchanges, get_exchange_bad_reason,
is_exchange_known_ccxt, is_exchange_bad,
is_exchange_bad, is_exchange_known_ccxt,
is_exchange_officially_supported)
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def remove_credentials(config: Dict[str, Any]) -> None:
"""
Removes exchange keys from the configuration and specifies dry-run
Used for backtesting / hyperopt / edge and utils.
Modifies the input dict!
"""
config['exchange']['key'] = ''
config['exchange']['secret'] = ''
config['exchange']['password'] = ''
config['exchange']['uid'] = ''
config['dry_run'] = True
def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool:
"""
Check if the exchange name in the config file is supported by Freqtrade
@@ -21,7 +34,8 @@ def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool:
and thus is not known for the Freqtrade at all.
"""
if config['runmode'] in [RunMode.PLOT] and not config.get('exchange', {}).get('name'):
if (config['runmode'] in [RunMode.PLOT, RunMode.UTIL_NO_EXCHANGE, RunMode.OTHER]
and not config.get('exchange', {}).get('name')):
# Skip checking exchange in plot mode, since it requires no exchange
return True
logger.info("Checking exchange...")

View File

@@ -0,0 +1,25 @@
import logging
from typing import Any, Dict
from .config_validation import validate_config_consistency
from .configuration import Configuration
from .check_exchange import remove_credentials
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for utils subcommands
:param args: Cli args from Arguments()
:return: Configuration
"""
configuration = Configuration(args, method)
config = configuration.get_config()
# Ensure we do not use Exchange credentials
remove_credentials(config)
validate_config_consistency(config)
return config

View File

@@ -1,11 +1,13 @@
import logging
from copy import deepcopy
from typing import Any, Dict
from jsonschema import Draft4Validator, validators
from jsonschema.exceptions import ValidationError, best_match
from freqtrade import constants, OperationalException
from freqtrade import constants
from freqtrade.exceptions import OperationalException
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -41,15 +43,20 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]:
:param conf: Config in JSON format
:return: Returns the config if valid, otherwise throw an exception
"""
conf_schema = deepcopy(constants.CONF_SCHEMA)
if conf.get('runmode', RunMode.OTHER) in (RunMode.DRY_RUN, RunMode.LIVE):
conf_schema['required'] = constants.SCHEMA_TRADE_REQUIRED
else:
conf_schema['required'] = constants.SCHEMA_MINIMAL_REQUIRED
try:
FreqtradeValidator(constants.CONF_SCHEMA).validate(conf)
FreqtradeValidator(conf_schema).validate(conf)
return conf
except ValidationError as e:
logger.critical(
f"Invalid configuration. See config.json.example. Reason: {e}"
)
raise ValidationError(
best_match(Draft4Validator(constants.CONF_SCHEMA).iter_errors(conf)).message
best_match(Draft4Validator(conf_schema).iter_errors(conf)).message
)
@@ -61,9 +68,27 @@ def validate_config_consistency(conf: Dict[str, Any]) -> None:
:param conf: Config in JSON format
:return: Returns None if everything is ok, otherwise throw an OperationalException
"""
# validating trailing stoploss
_validate_trailing_stoploss(conf)
_validate_edge(conf)
_validate_whitelist(conf)
_validate_unlimited_amount(conf)
# validate configuration before returning
logger.info('Validating configuration ...')
validate_config_schema(conf)
def _validate_unlimited_amount(conf: Dict[str, Any]) -> None:
"""
If edge is disabled, either max_open_trades or stake_amount need to be set.
:raise: OperationalException if config validation failed
"""
if (not conf.get('edge', {}).get('enabled')
and conf.get('max_open_trades') == float('inf')
and conf.get('stake_amount') == constants.UNLIMITED_STAKE_AMOUNT):
raise OperationalException("`max_open_trades` and `stake_amount` cannot both be unlimited.")
def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None:
@@ -111,3 +136,17 @@ def _validate_edge(conf: Dict[str, Any]) -> None:
"Edge and VolumePairList are incompatible, "
"Edge will override whatever pairs VolumePairlist selects."
)
def _validate_whitelist(conf: Dict[str, Any]) -> None:
"""
Dynamic whitelist does not require pair_whitelist to be set - however StaticWhitelist does.
"""
if conf.get('runmode', RunMode.OTHER) in [RunMode.OTHER, RunMode.PLOT,
RunMode.UTIL_NO_EXCHANGE, RunMode.UTIL_EXCHANGE]:
return
for pl in conf.get('pairlists', [{'method': 'StaticPairList'}]):
if (pl.get('method') == 'StaticPairList'
and not conf.get('exchange', {}).get('pair_whitelist')):
raise OperationalException("StaticPairList requires pair_whitelist to be set.")

View File

@@ -7,17 +7,16 @@ from copy import deepcopy
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional
from freqtrade import OperationalException, constants
from freqtrade import constants
from freqtrade.configuration.check_exchange import check_exchange
from freqtrade.configuration.config_validation import (validate_config_consistency,
validate_config_schema)
from freqtrade.configuration.deprecated_settings import process_temporary_deprecated_settings
from freqtrade.configuration.directory_operations import (create_datadir,
create_userdata_dir)
from freqtrade.configuration.load_config import load_config_file
from freqtrade.exceptions import OperationalException
from freqtrade.loggers import setup_logging
from freqtrade.misc import deep_merge_dicts, json_load
from freqtrade.state import RunMode
from freqtrade.state import NON_UTIL_MODES, TRADING_MODES, RunMode
logger = logging.getLogger(__name__)
@@ -81,9 +80,8 @@ class Configuration:
if 'ask_strategy' not in config:
config['ask_strategy'] = {}
# validate configuration before returning
logger.info('Validating configuration ...')
validate_config_schema(config)
if 'pairlists' not in config:
config['pairlists'] = []
return config
@@ -93,19 +91,23 @@ class Configuration:
:return: Configuration dictionary
"""
# Load all configs
config: Dict[str, Any] = self.load_from_files(self.args["config"])
config: Dict[str, Any] = self.load_from_files(self.args.get("config", []))
# Keep a copy of the original configuration file
config['original_config'] = deepcopy(config)
self._process_logging_options(config)
self._process_runmode(config)
self._process_common_options(config)
self._process_trading_options(config)
self._process_optimize_options(config)
self._process_plot_options(config)
self._process_runmode(config)
# Check if the exchange set by the user is supported
check_exchange(config, config.get('experimental', {}).get('block_bad_exchanges', True))
@@ -113,8 +115,6 @@ class Configuration:
process_temporary_deprecated_settings(config)
validate_config_consistency(config)
return config
def _process_logging_options(self, config: Dict[str, Any]) -> None:
@@ -130,21 +130,9 @@ class Configuration:
setup_logging(config)
def _process_common_options(self, config: Dict[str, Any]) -> None:
self._process_logging_options(config)
# Set strategy if not specified in config and or if it's non default
if self.args.get("strategy") != constants.DEFAULT_STRATEGY or not config.get('strategy'):
config.update({'strategy': self.args.get("strategy")})
self._args_to_config(config, argname='strategy_path',
logstring='Using additional Strategy lookup path: {}')
if ('db_url' in self.args and self.args["db_url"] and
self.args["db_url"] != constants.DEFAULT_DB_PROD_URL):
config.update({'db_url': self.args["db_url"]})
logger.info('Parameter --db-url detected ...')
def _process_trading_options(self, config: Dict[str, Any]) -> None:
if config['runmode'] not in TRADING_MODES:
return
if config.get('dry_run', False):
logger.info('Dry run is enabled')
@@ -158,13 +146,23 @@ class Configuration:
logger.info(f'Using DB: "{config["db_url"]}"')
def _process_common_options(self, config: Dict[str, Any]) -> None:
# Set strategy if not specified in config and or if it's non default
if self.args.get("strategy") or not config.get('strategy'):
config.update({'strategy': self.args.get("strategy")})
self._args_to_config(config, argname='strategy_path',
logstring='Using additional Strategy lookup path: {}')
if ('db_url' in self.args and self.args["db_url"] and
self.args["db_url"] != constants.DEFAULT_DB_PROD_URL):
config.update({'db_url': self.args["db_url"]})
logger.info('Parameter --db-url detected ...')
if config.get('forcebuy_enable', False):
logger.warning('`forcebuy` RPC message enabled.')
# Setting max_open_trades to infinite if -1
if config.get('max_open_trades') == -1:
config['max_open_trades'] = float('inf')
# Support for sd_notify
if 'sd_notify' in self.args and self.args["sd_notify"]:
config['internals'].update({'sd_notify': True})
@@ -179,6 +177,9 @@ class Configuration:
config['exchange']['name'] = self.args["exchange"]
logger.info(f"Using exchange {config['exchange']['name']}")
if 'pair_whitelist' not in config['exchange']:
config['exchange']['pair_whitelist'] = []
if 'user_data_dir' in self.args and self.args["user_data_dir"]:
config.update({'user_data_dir': self.args["user_data_dir"]})
elif 'user_data_dir' not in config:
@@ -195,6 +196,7 @@ class Configuration:
if self.args.get('exportfilename'):
self._args_to_config(config, argname='exportfilename',
logstring='Storing backtest results to {} ...')
config['exportfilename'] = Path(config['exportfilename'])
else:
config['exportfilename'] = (config['user_data_dir']
/ 'backtest_results/backtest-result.json')
@@ -209,19 +211,23 @@ class Configuration:
self._args_to_config(config, argname='position_stacking',
logstring='Parameter --enable-position-stacking detected ...')
# Setting max_open_trades to infinite if -1
if config.get('max_open_trades') == -1:
config['max_open_trades'] = float('inf')
if 'use_max_market_positions' in self.args and not self.args["use_max_market_positions"]:
config.update({'use_max_market_positions': False})
logger.info('Parameter --disable-max-market-positions detected ...')
logger.info('max_open_trades set to unlimited ...')
elif 'max_open_trades' in self.args and self.args["max_open_trades"]:
config.update({'max_open_trades': self.args["max_open_trades"]})
logger.info('Parameter --max_open_trades detected, '
logger.info('Parameter --max-open-trades detected, '
'overriding max_open_trades to: %s ...', config.get('max_open_trades'))
else:
elif config['runmode'] in NON_UTIL_MODES:
logger.info('Using max_open_trades: %s ...', config.get('max_open_trades'))
self._args_to_config(config, argname='stake_amount',
logstring='Parameter --stake_amount detected, '
logstring='Parameter --stake-amount detected, '
'overriding stake_amount to: {} ...')
self._args_to_config(config, argname='fee',
@@ -277,6 +283,9 @@ class Configuration:
self._args_to_config(config, argname='print_json',
logstring='Parameter --print-json detected ...')
self._args_to_config(config, argname='export_csv',
logstring='Parameter --export-csv detected: {}')
self._args_to_config(config, argname='hyperopt_jobs',
logstring='Parameter -j/--job-workers detected: {}')
@@ -292,6 +301,45 @@ class Configuration:
self._args_to_config(config, argname='hyperopt_loss',
logstring='Using Hyperopt loss class name: {}')
self._args_to_config(config, argname='hyperopt_show_index',
logstring='Parameter -n/--index detected: {}')
self._args_to_config(config, argname='hyperopt_list_best',
logstring='Parameter --best detected: {}')
self._args_to_config(config, argname='hyperopt_list_profitable',
logstring='Parameter --profitable detected: {}')
self._args_to_config(config, argname='hyperopt_list_min_trades',
logstring='Parameter --min-trades detected: {}')
self._args_to_config(config, argname='hyperopt_list_max_trades',
logstring='Parameter --max-trades detected: {}')
self._args_to_config(config, argname='hyperopt_list_min_avg_time',
logstring='Parameter --min-avg-time detected: {}')
self._args_to_config(config, argname='hyperopt_list_max_avg_time',
logstring='Parameter --max-avg-time detected: {}')
self._args_to_config(config, argname='hyperopt_list_min_avg_profit',
logstring='Parameter --min-avg-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_max_avg_profit',
logstring='Parameter --max-avg-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_min_total_profit',
logstring='Parameter --min-total-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_max_total_profit',
logstring='Parameter --max-total-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_no_details',
logstring='Parameter --no-details detected: {}')
self._args_to_config(config, argname='hyperopt_show_no_header',
logstring='Parameter --no-header detected: {}')
def _process_plot_options(self, config: Dict[str, Any]) -> None:
self._args_to_config(config, argname='pairs',
@@ -303,28 +351,46 @@ class Configuration:
self._args_to_config(config, argname='indicators2',
logstring='Using indicators2: {}')
self._args_to_config(config, argname='trade_ids',
logstring='Filtering on trade_ids: {}')
self._args_to_config(config, argname='plot_limit',
logstring='Limiting plot to: {}')
self._args_to_config(config, argname='trade_source',
logstring='Using trades from: {}')
self._args_to_config(config, argname='erase',
logstring='Erase detected. Deleting existing data.')
self._args_to_config(config, argname='no_trades',
logstring='Parameter --no-trades detected.')
self._args_to_config(config, argname='timeframes',
logstring='timeframes --timeframes: {}')
self._args_to_config(config, argname='days',
logstring='Detected --days: {}')
self._args_to_config(config, argname='download_trades',
logstring='Detected --dl-trades: {}')
self._args_to_config(config, argname='dataformat_ohlcv',
logstring='Using "{}" to store OHLCV data.')
self._args_to_config(config, argname='dataformat_trades',
logstring='Using "{}" to store trades data.')
def _process_runmode(self, config: Dict[str, Any]) -> None:
self._args_to_config(config, argname='dry_run',
logstring='Parameter --dry-run detected, '
'overriding dry_run to: {} ...')
if not self.runmode:
# Handle real mode, infer dry/live from config
self.runmode = RunMode.DRY_RUN if config.get('dry_run', True) else RunMode.LIVE
logger.info(f"Runmode set to {self.runmode}.")
logger.info(f"Runmode set to {self.runmode.value}.")
config.update({'runmode': self.runmode})
@@ -380,7 +446,7 @@ class Configuration:
config['pairs'] = config.get('exchange', {}).get('pair_whitelist')
else:
# Fall back to /dl_path/pairs.json
pairs_file = Path(config['datadir']) / "pairs.json"
pairs_file = config['datadir'] / "pairs.json"
if pairs_file.exists():
with pairs_file.open('r') as f:
config['pairs'] = json_load(f)

View File

@@ -5,7 +5,7 @@ Functions to handle deprecated settings
import logging
from typing import Any, Dict
from freqtrade import OperationalException
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
@@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
def check_conflicting_settings(config: Dict[str, Any],
section1: str, name1: str,
section2: str, name2: str):
section2: str, name2: str) -> None:
section1_config = config.get(section1, {})
section2_config = config.get(section2, {})
if name1 in section1_config and name2 in section2_config:
@@ -28,7 +28,7 @@ def check_conflicting_settings(config: Dict[str, Any],
def process_deprecated_setting(config: Dict[str, Any],
section1: str, name1: str,
section2: str, name2: str):
section2: str, name2: str) -> None:
section2_config = config.get(section2, {})
if name2 in section2_config:
@@ -57,3 +57,13 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
'experimental', 'sell_profit_only')
process_deprecated_setting(config, 'ask_strategy', 'ignore_roi_if_buy_signal',
'experimental', 'ignore_roi_if_buy_signal')
if (config.get('edge', {}).get('enabled', False)
and 'capital_available_percentage' in config.get('edge', {})):
logger.warning(
"DEPRECATED: "
"Using 'edge.capital_available_percentage' has been deprecated in favor of "
"'tradable_balance_ratio'. Please migrate your configuration to "
"'tradable_balance_ratio' and remove 'capital_available_percentage' "
"from the edge configuration."
)

View File

@@ -1,13 +1,15 @@
import logging
from typing import Any, Dict, Optional
import shutil
from pathlib import Path
from typing import Any, Dict, Optional
from freqtrade import OperationalException
from freqtrade.exceptions import OperationalException
from freqtrade.constants import USER_DATA_FILES
logger = logging.getLogger(__name__)
def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> str:
def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> Path:
folder = Path(datadir) if datadir else Path(f"{config['user_data_dir']}/data")
if not datadir:
@@ -18,10 +20,10 @@ def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> str
if not folder.is_dir():
folder.mkdir(parents=True)
logger.info(f'Created data directory: {datadir}')
return str(folder)
return folder
def create_userdata_dir(directory: str, create_dir=False) -> Path:
def create_userdata_dir(directory: str, create_dir: bool = False) -> Path:
"""
Create userdata directory structure.
if create_dir is True, then the parent-directory will be created if it does not exist.
@@ -31,7 +33,8 @@ def create_userdata_dir(directory: str, create_dir=False) -> Path:
:param create_dir: Create directory if it does not exist.
:return: Path object containing the directory
"""
sub_dirs = ["backtest_results", "data", "hyperopts", "hyperopt_results", "plot", "strategies", ]
sub_dirs = ["backtest_results", "data", "hyperopts", "hyperopt_results", "logs",
"notebooks", "plot", "strategies", ]
folder = Path(directory)
if not folder.is_dir():
if create_dir:
@@ -48,3 +51,26 @@ def create_userdata_dir(directory: str, create_dir=False) -> Path:
if not subfolder.is_dir():
subfolder.mkdir(parents=False)
return folder
def copy_sample_files(directory: Path, overwrite: bool = False) -> None:
"""
Copy files from templates to User data directory.
:param directory: Directory to copy data to
:param overwrite: Overwrite existing sample files
"""
if not directory.is_dir():
raise OperationalException(f"Directory `{directory}` does not exist.")
sourcedir = Path(__file__).parents[1] / "templates"
for source, target in USER_DATA_FILES.items():
targetdir = directory / target
if not targetdir.is_dir():
raise OperationalException(f"Directory `{targetdir}` does not exist.")
targetfile = targetdir / source
if targetfile.exists():
if not overwrite:
logger.warning(f"File `{targetfile}` exists already, not deploying sample file.")
continue
else:
logger.warning(f"File `{targetfile}` exists already, overwriting.")
shutil.copy(str(sourcedir / source), str(targetfile))

View File

@@ -1,13 +1,15 @@
"""
This module contain functions to load the configuration file
"""
import rapidjson
import logging
import re
import sys
from pathlib import Path
from typing import Any, Dict
from freqtrade import OperationalException
import rapidjson
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
@@ -15,6 +17,26 @@ logger = logging.getLogger(__name__)
CONFIG_PARSE_MODE = rapidjson.PM_COMMENTS | rapidjson.PM_TRAILING_COMMAS
def log_config_error_range(path: str, errmsg: str) -> str:
"""
Parses configuration file and prints range around error
"""
if path != '-':
offsetlist = re.findall(r'(?<=Parse\serror\sat\soffset\s)\d+', errmsg)
if offsetlist:
offset = int(offsetlist[0])
text = Path(path).read_text()
# Fetch an offset of 80 characters around the error line
subtext = text[offset-min(80, offset):offset+80]
segments = subtext.split('\n')
if len(segments) > 3:
# Remove first and last lines, to avoid odd truncations
return '\n'.join(segments[1:-1])
else:
return subtext
return ''
def load_config_file(path: str) -> Dict[str, Any]:
"""
Loads a config file from the given path
@@ -29,5 +51,12 @@ def load_config_file(path: str) -> Dict[str, Any]:
raise OperationalException(
f'Config file "{path}" not found!'
' Please create a config file or check whether it exists.')
except rapidjson.JSONDecodeError as e:
err_range = log_config_error_range(path, str(e))
raise OperationalException(
f'{e}\n'
f'Please verify the following segment of your configuration:\n{err_range}'
if err_range else 'Please verify your configuration file for syntax errors.'
)
return config

View File

@@ -1,12 +1,16 @@
"""
This module contains the argument manager class
"""
import logging
import re
from typing import Optional
import arrow
logger = logging.getLogger(__name__)
class TimeRange:
"""
object defining timerange inputs.
@@ -27,8 +31,36 @@ class TimeRange:
return (self.starttype == other.starttype and self.stoptype == other.stoptype
and self.startts == other.startts and self.stopts == other.stopts)
def subtract_start(self, seconds: int) -> None:
"""
Subtracts <seconds> from startts if startts is set.
:param seconds: Seconds to subtract from starttime
:return: None (Modifies the object in place)
"""
if self.startts:
self.startts = self.startts - seconds
def adjust_start_if_necessary(self, timeframe_secs: int, startup_candles: int,
min_date: arrow.Arrow) -> None:
"""
Adjust startts by <startup_candles> candles.
Applies only if no startup-candles have been available.
:param timeframe_secs: Timeframe in seconds e.g. `timeframe_to_seconds('5m')`
:param startup_candles: Number of candles to move start-date forward
:param min_date: Minimum data date loaded. Key kriterium to decide if start-time
has to be moved
:return: None (Modifies the object in place)
"""
if (not self.starttype or (startup_candles
and min_date.timestamp >= self.startts)):
# If no startts was defined, or backtest-data starts at the defined backtest-date
logger.warning("Moving start-date by %s candles to account for startup time.",
startup_candles)
self.startts = (min_date.timestamp + timeframe_secs * startup_candles)
self.starttype = 'date'
@staticmethod
def parse_timerange(text: Optional[str]):
def parse_timerange(text: Optional[str]) -> 'TimeRange':
"""
Parse the value of the argument --timerange to determine what is the range desired
:param text: value from --timerange

View File

@@ -3,39 +3,53 @@
"""
bot constants
"""
from typing import List, Tuple
DEFAULT_CONFIG = 'config.json'
DEFAULT_EXCHANGE = 'bittrex'
PROCESS_THROTTLE_SECS = 5 # sec
DEFAULT_TICKER_INTERVAL = 5 # min
HYPEROPT_EPOCH = 100 # epochs
RETRY_TIMEOUT = 30 # sec
DEFAULT_STRATEGY = 'DefaultStrategy'
DEFAULT_HYPEROPT = 'DefaultHyperOpt'
DEFAULT_HYPEROPT_LOSS = 'DefaultHyperOptLoss'
DEFAULT_DB_PROD_URL = 'sqlite:///tradesv3.sqlite'
DEFAULT_DB_DRYRUN_URL = 'sqlite://'
DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite'
UNLIMITED_STAKE_AMOUNT = 'unlimited'
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
REQUIRED_ORDERTIF = ['buy', 'sell']
REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']
ORDERBOOK_SIDES = ['ask', 'bid']
ORDERTYPE_POSSIBILITIES = ['limit', 'market']
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList']
DRY_RUN_WALLET = 999.9
AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList',
'PrecisionFilter', 'PriceFilter', 'ShuffleFilter', 'SpreadFilter']
AVAILABLE_DATAHANDLERS = ['json', 'jsongz']
DRY_RUN_WALLET = 1000
MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons
DEFAULT_DATAFRAME_COLUMNS = ['date', 'open', 'high', 'low', 'close', 'volume']
# Don't modify sequence of DEFAULT_TRADES_COLUMNS
# it has wide consequences for stored trades files
DEFAULT_TRADES_COLUMNS = ['timestamp', 'id', 'type', 'side', 'price', 'amount', 'cost']
TICKER_INTERVALS = [
'1m', '3m', '5m', '15m', '30m',
'1h', '2h', '4h', '6h', '8h', '12h',
'1d', '3d', '1w',
]
USERPATH_HYPEROPTS = 'hyperopts'
USERPATH_STRATEGIES = 'strategies'
USERPATH_NOTEBOOKS = 'notebooks'
# Soure files with destination directories within user-directory
USER_DATA_FILES = {
'sample_strategy.py': USERPATH_STRATEGIES,
'sample_hyperopt_advanced.py': USERPATH_HYPEROPTS,
'sample_hyperopt_loss.py': USERPATH_HYPEROPTS,
'sample_hyperopt.py': USERPATH_HYPEROPTS,
'strategy_analysis_example.ipynb': USERPATH_NOTEBOOKS,
}
SUPPORTED_FIAT = [
"AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK",
"EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY",
"KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN",
"RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR", "USD",
"BTC", "XBT", "ETH", "XRP", "LTC", "BCH", "USDT"
"BTC", "ETH", "XRP", "LTC", "BCH"
]
MINIMAL_CONFIG = {
@@ -56,17 +70,28 @@ MINIMAL_CONFIG = {
CONF_SCHEMA = {
'type': 'object',
'properties': {
'max_open_trades': {'type': 'integer', 'minimum': -1},
'ticker_interval': {'type': 'string', 'enum': TICKER_INTERVALS},
'stake_currency': {'type': 'string', 'enum': ['BTC', 'XBT', 'ETH', 'USDT', 'EUR', 'USD']},
'max_open_trades': {'type': ['integer', 'number'], 'minimum': -1},
'ticker_interval': {'type': 'string'},
'stake_currency': {'type': 'string'},
'stake_amount': {
"type": ["number", "string"],
"minimum": 0.0005,
"pattern": UNLIMITED_STAKE_AMOUNT
'type': ['number', 'string'],
'minimum': 0.0001,
'pattern': UNLIMITED_STAKE_AMOUNT
},
'tradable_balance_ratio': {
'type': 'number',
'minimum': 0.1,
'maximum': 1,
'default': 0.99
},
'amend_last_stake_amount': {'type': 'boolean', 'default': False},
'last_stake_amount_min_ratio': {
'type': 'number', 'minimum': 0.0, 'maximum': 1.0, 'default': 0.5
},
'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT},
'dry_run': {'type': 'boolean'},
'dry_run_wallet': {'type': 'number'},
'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET},
'cancel_open_orders_on_exit': {'type': 'boolean', 'default': False},
'process_only_new_candles': {'type': 'boolean'},
'minimal_roi': {
'type': 'object',
@@ -84,8 +109,8 @@ CONF_SCHEMA = {
'unfilledtimeout': {
'type': 'object',
'properties': {
'buy': {'type': 'number', 'minimum': 3},
'sell': {'type': 'number', 'minimum': 10}
'buy': {'type': 'number', 'minimum': 1},
'sell': {'type': 'number', 'minimum': 1}
}
},
'bid_strategy': {
@@ -96,15 +121,16 @@ CONF_SCHEMA = {
'minimum': 0,
'maximum': 1,
'exclusiveMaximum': False,
'use_order_book': {'type': 'boolean'},
'order_book_top': {'type': 'number', 'maximum': 20, 'minimum': 1},
'check_depth_of_market': {
'type': 'object',
'properties': {
'enabled': {'type': 'boolean'},
'bids_to_ask_delta': {'type': 'number', 'minimum': 0},
}
},
},
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'bid'},
'use_order_book': {'type': 'boolean'},
'order_book_top': {'type': 'integer', 'maximum': 20, 'minimum': 1},
'check_depth_of_market': {
'type': 'object',
'properties': {
'enabled': {'type': 'boolean'},
'bids_to_ask_delta': {'type': 'number', 'minimum': 0},
}
},
},
'required': ['ask_last_balance']
@@ -112,9 +138,10 @@ CONF_SCHEMA = {
'ask_strategy': {
'type': 'object',
'properties': {
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'ask'},
'use_order_book': {'type': 'boolean'},
'order_book_min': {'type': 'number', 'minimum': 1},
'order_book_max': {'type': 'number', 'minimum': 1, 'maximum': 50},
'order_book_min': {'type': 'integer', 'minimum': 1},
'order_book_max': {'type': 'integer', 'minimum': 1, 'maximum': 50},
'use_sell_signal': {'type': 'boolean'},
'sell_profit_only': {'type': 'boolean'},
'ignore_roi_if_buy_signal': {'type': 'boolean'}
@@ -151,13 +178,16 @@ CONF_SCHEMA = {
'block_bad_exchanges': {'type': 'boolean'}
}
},
'pairlist': {
'type': 'object',
'properties': {
'method': {'type': 'string', 'enum': AVAILABLE_PAIRLISTS},
'config': {'type': 'object'}
},
'required': ['method']
'pairlists': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'method': {'type': 'string', 'enum': AVAILABLE_PAIRLISTS},
'config': {'type': 'object'}
},
'required': ['method'],
}
},
'telegram': {
'type': 'object',
@@ -173,7 +203,9 @@ CONF_SCHEMA = {
'properties': {
'enabled': {'type': 'boolean'},
'webhookbuy': {'type': 'object'},
'webhookbuycancel': {'type': 'object'},
'webhooksell': {'type': 'object'},
'webhooksellcancel': {'type': 'object'},
'webhookstatus': {'type': 'object'},
},
},
@@ -184,8 +216,8 @@ CONF_SCHEMA = {
'listen_ip_address': {'format': 'ipv4'},
'listen_port': {
'type': 'integer',
"minimum": 1024,
"maximum": 65535
'minimum': 1024,
'maximum': 65535
},
'username': {'type': 'string'},
'password': {'type': 'string'},
@@ -197,11 +229,22 @@ CONF_SCHEMA = {
'forcebuy_enable': {'type': 'boolean'},
'internals': {
'type': 'object',
'default': {},
'properties': {
'process_throttle_secs': {'type': 'number'},
'process_throttle_secs': {'type': 'integer'},
'interval': {'type': 'integer'},
'sd_notify': {'type': 'boolean'},
}
},
'dataformat_ohlcv': {
'type': 'string',
'enum': AVAILABLE_DATAHANDLERS,
'default': 'json'
},
'dataformat_trades': {
'type': 'string',
'enum': AVAILABLE_DATAHANDLERS,
'default': 'jsongz'
}
},
'definitions': {
@@ -218,7 +261,6 @@ CONF_SCHEMA = {
'type': 'array',
'items': {
'type': 'string',
'pattern': '^[0-9A-Z]+/[0-9A-Z]+$'
},
'uniqueItems': True
},
@@ -226,7 +268,6 @@ CONF_SCHEMA = {
'type': 'array',
'items': {
'type': 'string',
'pattern': '^[0-9A-Z]+/[0-9A-Z]+$'
},
'uniqueItems': True
},
@@ -235,37 +276,62 @@ CONF_SCHEMA = {
'ccxt_config': {'type': 'object'},
'ccxt_async_config': {'type': 'object'}
},
'required': ['name', 'pair_whitelist']
'required': ['name']
},
'edge': {
'type': 'object',
'properties': {
"enabled": {'type': 'boolean'},
"process_throttle_secs": {'type': 'integer', 'minimum': 600},
"calculate_since_number_of_days": {'type': 'integer'},
"allowed_risk": {'type': 'number'},
"capital_available_percentage": {'type': 'number'},
"stoploss_range_min": {'type': 'number'},
"stoploss_range_max": {'type': 'number'},
"stoploss_range_step": {'type': 'number'},
"minimum_winrate": {'type': 'number'},
"minimum_expectancy": {'type': 'number'},
"min_trade_number": {'type': 'number'},
"max_trade_duration_minute": {'type': 'integer'},
"remove_pumps": {'type': 'boolean'}
'enabled': {'type': 'boolean'},
'process_throttle_secs': {'type': 'integer', 'minimum': 600},
'calculate_since_number_of_days': {'type': 'integer'},
'allowed_risk': {'type': 'number'},
'capital_available_percentage': {'type': 'number'},
'stoploss_range_min': {'type': 'number'},
'stoploss_range_max': {'type': 'number'},
'stoploss_range_step': {'type': 'number'},
'minimum_winrate': {'type': 'number'},
'minimum_expectancy': {'type': 'number'},
'min_trade_number': {'type': 'number'},
'max_trade_duration_minute': {'type': 'integer'},
'remove_pumps': {'type': 'boolean'}
},
'required': ['process_throttle_secs', 'allowed_risk', 'capital_available_percentage']
'required': ['process_throttle_secs', 'allowed_risk']
}
},
'anyOf': [
{'required': ['exchange']}
],
'required': [
'max_open_trades',
'stake_currency',
'stake_amount',
'dry_run',
'bid_strategy',
'unfilledtimeout',
]
}
SCHEMA_TRADE_REQUIRED = [
'exchange',
'max_open_trades',
'stake_currency',
'stake_amount',
'tradable_balance_ratio',
'last_stake_amount_min_ratio',
'dry_run',
'dry_run_wallet',
'ask_strategy',
'bid_strategy',
'unfilledtimeout',
'stoploss',
'minimal_roi',
'internals',
'dataformat_ohlcv',
'dataformat_trades',
]
SCHEMA_MINIMAL_REQUIRED = [
'exchange',
'dry_run',
'dataformat_ohlcv',
'dataformat_trades',
]
CANCEL_REASON = {
"TIMEOUT": "cancelled due to timeout",
"PARTIALLY_FILLED": "partially filled - keeping order open",
"ALL_CANCELLED": "cancelled (all unfilled and partially filled open orders cancelled)",
"CANCELLED_ON_EXCHANGE": "cancelled on exchange",
}
# List of pairs with their timeframes
ListPairsWithTimeframes = List[Tuple[str, str]]

View File

@@ -3,11 +3,11 @@ Helpers when analyzing backtest data
"""
import logging
from pathlib import Path
from typing import Dict
from typing import Dict, Union, Tuple
import numpy as np
import pandas as pd
import pytz
from datetime import timezone
from freqtrade import persistence
from freqtrade.misc import json_load
@@ -20,7 +20,7 @@ BT_DATA_COLUMNS = ["pair", "profitperc", "open_time", "close_time", "index", "du
"open_rate", "close_rate", "open_at_end", "sell_reason"]
def load_backtest_data(filename) -> pd.DataFrame:
def load_backtest_data(filename: Union[Path, str]) -> pd.DataFrame:
"""
Load backtest data file.
:param filename: pathlib.Path object, or string pointing to the file.
@@ -47,21 +47,23 @@ def load_backtest_data(filename) -> pd.DataFrame:
utc=True,
infer_datetime_format=True
)
df['profitabs'] = df['close_rate'] - df['open_rate']
df['profit'] = df['close_rate'] - df['open_rate']
df = df.sort_values("open_time").reset_index(drop=True)
return df
def evaluate_result_multi(results: pd.DataFrame, freq: str, max_open_trades: int) -> pd.DataFrame:
def analyze_trade_parallelism(results: pd.DataFrame, timeframe: str) -> pd.DataFrame:
"""
Find overlapping trades by expanding each trade once per period it was open
and then counting overlaps
and then counting overlaps.
:param results: Results Dataframe - can be loaded
:param freq: Frequency used for the backtest
:param max_open_trades: parameter max_open_trades used during backtest run
:return: dataframe with open-counts per time-period in freq
:param timeframe: Timeframe used for backtest
:return: dataframe with open-counts per time-period in timeframe
"""
dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time, freq=freq))
from freqtrade.exchange import timeframe_to_minutes
timeframe_min = timeframe_to_minutes(timeframe)
dates = [pd.Series(pd.date_range(row[1].open_time, row[1].close_time,
freq=f"{timeframe_min}min"))
for row in results[['open_time', 'close_time']].iterrows()]
deltas = [len(x) for x in dates]
dates = pd.Series(pd.concat(dates).values, name='date')
@@ -69,8 +71,23 @@ def evaluate_result_multi(results: pd.DataFrame, freq: str, max_open_trades: int
df2 = pd.concat([dates, df2], axis=1)
df2 = df2.set_index('date')
df_final = df2.resample(freq)[['pair']].count()
return df_final[df_final['pair'] > max_open_trades]
df_final = df2.resample(f"{timeframe_min}min")[['pair']].count()
df_final = df_final.rename({'pair': 'open_trades'}, axis=1)
return df_final
def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
max_open_trades: int) -> pd.DataFrame:
"""
Find overlapping trades by expanding each trade once per period it was open
and then counting overlaps
:param results: Results Dataframe - can be loaded
:param timeframe: Frequency used for the backtest
:param max_open_trades: parameter max_open_trades used during backtest run
:return: dataframe with open-counts per time-period in freq
"""
df_final = analyze_trade_parallelism(results, timeframe)
return df_final[df_final['open_trades'] > max_open_trades]
def load_trades_from_db(db_url: str) -> pd.DataFrame:
@@ -89,12 +106,12 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame:
"stop_loss", "initial_stop_loss", "strategy", "ticker_interval"]
trades = pd.DataFrame([(t.pair,
t.open_date.replace(tzinfo=pytz.UTC),
t.close_date.replace(tzinfo=pytz.UTC) if t.close_date else None,
t.calc_profit(), t.calc_profit_percent(),
t.open_date.replace(tzinfo=timezone.utc),
t.close_date.replace(tzinfo=timezone.utc) if t.close_date else None,
t.calc_profit(), t.calc_profit_ratio(),
t.open_rate, t.close_rate, t.amount,
(round((t.close_date.timestamp() - t.open_date.timestamp()) / 60, 2)
if t.close_date else None),
if t.close_date else None),
t.sell_reason,
t.fee_open, t.fee_close,
t.open_rate_requested,
@@ -106,44 +123,62 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame:
t.stop_loss, t.initial_stop_loss,
t.strategy, t.ticker_interval
)
for t in Trade.query.all()],
for t in Trade.get_trades().all()],
columns=columns)
return trades
def load_trades(source: str, db_url: str, exportfilename: str) -> pd.DataFrame:
def load_trades(source: str, db_url: str, exportfilename: Path,
no_trades: bool = False) -> pd.DataFrame:
"""
Based on configuration option "trade_source":
* loads data from DB (using `db_url`)
* loads data from backtestfile (using `exportfilename`)
:param source: "DB" or "file" - specify source to load from
:param db_url: sqlalchemy formatted url to a database
:param exportfilename: Json file generated by backtesting
:param no_trades: Skip using trades, only return backtesting data columns
:return: DataFrame containing trades
"""
if no_trades:
df = pd.DataFrame(columns=BT_DATA_COLUMNS)
return df
if source == "DB":
return load_trades_from_db(db_url)
elif source == "file":
return load_backtest_data(Path(exportfilename))
return load_backtest_data(exportfilename)
def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame) -> pd.DataFrame:
def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame,
date_index=False) -> pd.DataFrame:
"""
Compare trades and backtested pair DataFrames to get trades performed on backtested period
:return: the DataFrame of a trades of period
"""
trades = trades.loc[(trades['open_time'] >= dataframe.iloc[0]['date']) &
(trades['close_time'] <= dataframe.iloc[-1]['date'])]
if date_index:
trades_start = dataframe.index[0]
trades_stop = dataframe.index[-1]
else:
trades_start = dataframe.iloc[0]['date']
trades_stop = dataframe.iloc[-1]['date']
trades = trades.loc[(trades['open_time'] >= trades_start) &
(trades['close_time'] <= trades_stop)]
return trades
def combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], column: str = "close"):
def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame],
column: str = "close") -> pd.DataFrame:
"""
Combine multiple dataframes "column"
:param tickers: Dict of Dataframes, dict key should be pair.
:param data: Dict of Dataframes, dict key should be pair.
:param column: Column in the original dataframes to use
:return: DataFrame with the column renamed to the dict key, and a column
named mean, containing the mean of all pairs.
"""
df_comb = pd.concat([tickers[pair].set_index('date').rename(
{column: pair}, axis=1)[pair] for pair in tickers], axis=1)
df_comb = pd.concat([data[pair].set_index('date').rename(
{column: pair}, axis=1)[pair] for pair in data], axis=1)
df_comb['mean'] = df_comb.mean(axis=1)
@@ -159,14 +194,44 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
:param col_name: Column name that will be assigned the results
:param timeframe: Timeframe used during the operations
:return: Returns df with one additional column, col_name, containing the cumulative profit.
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
from freqtrade.exchange import timeframe_to_minutes
ticker_minutes = timeframe_to_minutes(timeframe)
# Resample to ticker_interval to make sure trades match candles
_trades_sum = trades.resample(f'{ticker_minutes}min', on='close_time')[['profitperc']].sum()
timeframe_minutes = timeframe_to_minutes(timeframe)
# Resample to timeframe to make sure trades match candles
_trades_sum = trades.resample(f'{timeframe_minutes}min', on='close_time')[['profitperc']].sum()
df.loc[:, col_name] = _trades_sum.cumsum()
# Set first value to 0
df.loc[df.iloc[0].name, col_name] = 0
# FFill to get continuous
df[col_name] = df[col_name].ffill()
return df
def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_time',
value_col: str = 'profitperc'
) -> Tuple[float, pd.Timestamp, pd.Timestamp]:
"""
Calculate max drawdown and the corresponding close dates
:param trades: DataFrame containing trades (requires columns close_time and profitperc)
:param date_col: Column in DataFrame to use for dates (defaults to 'close_time')
:param value_col: Column in DataFrame to use for values (defaults to 'profitperc')
:return: Tuple (float, highdate, lowdate) with absolute max drawdown, high and low time
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
profit_results = trades.sort_values(date_col).reset_index(drop=True)
max_drawdown_df = pd.DataFrame()
max_drawdown_df['cumulative'] = profit_results[value_col].cumsum()
max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax()
max_drawdown_df['drawdown'] = max_drawdown_df['cumulative'] - max_drawdown_df['high_value']
idxmin = max_drawdown_df['drawdown'].idxmin()
if idxmin == 0:
raise ValueError("No losing trade, therefore no drawdown.")
high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col]
low_date = profit_results.loc[idxmin, date_col]
return abs(min(max_drawdown_df['drawdown'])), high_date, low_date

View File

@@ -1,45 +1,68 @@
"""
Functions to convert data from one format to another
"""
import itertools
import logging
from datetime import datetime, timezone
from operator import itemgetter
from typing import Any, Dict, List
import pandas as pd
from pandas import DataFrame, to_datetime
from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS,
DEFAULT_TRADES_COLUMNS)
logger = logging.getLogger(__name__)
def parse_ticker_dataframe(ticker: list, ticker_interval: str, pair: str, *,
fill_missing: bool = True,
drop_incomplete: bool = True) -> DataFrame:
def ohlcv_to_dataframe(ohlcv: list, timeframe: str, pair: str, *,
fill_missing: bool = True, drop_incomplete: bool = True) -> DataFrame:
"""
Converts a ticker-list (format ccxt.fetch_ohlcv) to a Dataframe
:param ticker: ticker list, as returned by exchange.async_get_candle_history
:param ticker_interval: ticker_interval (e.g. 5m). Used to fill up eventual missing data
Converts a list with candle (OHLCV) data (in format returned by ccxt.fetch_ohlcv)
to a Dataframe
:param ohlcv: list with candle (OHLCV) data, as returned by exchange.async_get_candle_history
:param timeframe: timeframe (e.g. 5m). Used to fill up eventual missing data
:param pair: Pair this data is for (used to warn if fillup was necessary)
:param fill_missing: fill up missing candles with 0 candles
(see ohlcv_fill_up_missing_data for details)
:param drop_incomplete: Drop the last candle of the dataframe, assuming it's incomplete
:return: DataFrame
"""
logger.debug("Parsing tickerlist to dataframe")
cols = ['date', 'open', 'high', 'low', 'close', 'volume']
frame = DataFrame(ticker, columns=cols)
logger.debug(f"Converting candle (OHLCV) data to dataframe for pair {pair}.")
cols = DEFAULT_DATAFRAME_COLUMNS
df = DataFrame(ohlcv, columns=cols)
frame['date'] = to_datetime(frame['date'],
unit='ms',
utc=True,
infer_datetime_format=True)
df['date'] = to_datetime(df['date'], unit='ms', utc=True, infer_datetime_format=True)
# Some exchanges return int values for volume and even for ohlc.
# Some exchanges return int values for Volume and even for OHLC.
# Convert them since TA-LIB indicators used in the strategy assume floats
# and fail with exception...
frame = frame.astype(dtype={'open': 'float', 'high': 'float', 'low': 'float', 'close': 'float',
'volume': 'float'})
df = df.astype(dtype={'open': 'float', 'high': 'float', 'low': 'float', 'close': 'float',
'volume': 'float'})
return clean_ohlcv_dataframe(df, timeframe, pair,
fill_missing=fill_missing,
drop_incomplete=drop_incomplete)
def clean_ohlcv_dataframe(data: DataFrame, timeframe: str, pair: str, *,
fill_missing: bool = True,
drop_incomplete: bool = True) -> DataFrame:
"""
Clense a OHLCV dataframe by
* Grouping it by date (removes duplicate tics)
* dropping last candles if requested
* Filling up missing data (if requested)
:param data: DataFrame containing candle (OHLCV) data.
:param timeframe: timeframe (e.g. 5m). Used to fill up eventual missing data
:param pair: Pair this data is for (used to warn if fillup was necessary)
:param fill_missing: fill up missing candles with 0 candles
(see ohlcv_fill_up_missing_data for details)
:param drop_incomplete: Drop the last candle of the dataframe, assuming it's incomplete
:return: DataFrame
"""
# group by index and aggregate results to eliminate duplicate ticks
frame = frame.groupby(by='date', as_index=False, sort=True).agg({
data = data.groupby(by='date', as_index=False, sort=True).agg({
'open': 'first',
'high': 'max',
'low': 'min',
@@ -48,16 +71,16 @@ def parse_ticker_dataframe(ticker: list, ticker_interval: str, pair: str, *,
})
# eliminate partial candle
if drop_incomplete:
frame.drop(frame.tail(1).index, inplace=True)
data.drop(data.tail(1).index, inplace=True)
logger.debug('Dropping last candle')
if fill_missing:
return ohlcv_fill_up_missing_data(frame, ticker_interval, pair)
return ohlcv_fill_up_missing_data(data, timeframe, pair)
else:
return frame
return data
def ohlcv_fill_up_missing_data(dataframe: DataFrame, ticker_interval: str, pair: str) -> DataFrame:
def ohlcv_fill_up_missing_data(dataframe: DataFrame, timeframe: str, pair: str) -> DataFrame:
"""
Fills up missing data with 0 volume rows,
using the previous close as price for "open", "high" "low" and "close", volume is set to 0
@@ -65,16 +88,16 @@ def ohlcv_fill_up_missing_data(dataframe: DataFrame, ticker_interval: str, pair:
"""
from freqtrade.exchange import timeframe_to_minutes
ohlc_dict = {
ohlcv_dict = {
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum'
}
ticker_minutes = timeframe_to_minutes(ticker_interval)
timeframe_minutes = timeframe_to_minutes(timeframe)
# Resample to create "NAN" values
df = dataframe.resample(f'{ticker_minutes}min', on='date').agg(ohlc_dict)
df = dataframe.resample(f'{timeframe_minutes}min', on='date').agg(ohlcv_dict)
# Forwardfill close for missing columns
df['close'] = df['close'].fillna(method='ffill')
@@ -92,8 +115,26 @@ def ohlcv_fill_up_missing_data(dataframe: DataFrame, ticker_interval: str, pair:
return df
def trim_dataframe(df: DataFrame, timerange, df_date_col: str = 'date') -> DataFrame:
"""
Trim dataframe based on given timerange
:param df: Dataframe to trim
:param timerange: timerange (use start and end date if available)
:param: df_date_col: Column in the dataframe to use as Date column
:return: trimmed dataframe
"""
if timerange.starttype == 'date':
start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc)
df = df.loc[df[df_date_col] >= start, :]
if timerange.stoptype == 'date':
stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc)
df = df.loc[df[df_date_col] <= stop, :]
return df
def order_book_to_dataframe(bids: list, asks: list) -> DataFrame:
"""
TODO: This should get a dedicated test
Gets order book list, returns dataframe with below format per suggested by creslin
-------------------------------------------------------------------
b_sum b_size bids asks a_size a_sum
@@ -116,23 +157,105 @@ def order_book_to_dataframe(bids: list, asks: list) -> DataFrame:
return frame
def trades_to_ohlcv(trades: list, timeframe: str) -> list:
def trades_remove_duplicates(trades: List[List]) -> List[List]:
"""
Converts trades list to ohlcv list
Removes duplicates from the trades list.
Uses itertools.groupby to avoid converting to pandas.
Tests show it as being pretty efficient on lists of 4M Lists.
:param trades: List of Lists with constants.DEFAULT_TRADES_COLUMNS as columns
:return: same format as above, but with duplicates removed
"""
return [i for i, _ in itertools.groupby(sorted(trades, key=itemgetter(0)))]
def trades_dict_to_list(trades: List[Dict]) -> List[List]:
"""
Convert fetch_trades result into a List (to be more memory efficient).
:param trades: List of trades, as returned by ccxt.fetch_trades.
:param timeframe: Ticker timeframe to resample data to
:return: ohlcv timeframe as list (as returned by ccxt.fetch_ohlcv)
:return: List of Lists, with constants.DEFAULT_TRADES_COLUMNS as columns
"""
return [[t[col] for col in DEFAULT_TRADES_COLUMNS] for t in trades]
def trades_to_ohlcv(trades: List, timeframe: str) -> DataFrame:
"""
Converts trades list to OHLCV list
TODO: This should get a dedicated test
:param trades: List of trades, as returned by ccxt.fetch_trades.
:param timeframe: Timeframe to resample data to
:return: OHLCV Dataframe.
"""
from freqtrade.exchange import timeframe_to_minutes
ticker_minutes = timeframe_to_minutes(timeframe)
df = pd.DataFrame(trades)
df['datetime'] = pd.to_datetime(df['datetime'])
df = df.set_index('datetime')
timeframe_minutes = timeframe_to_minutes(timeframe)
df = pd.DataFrame(trades, columns=DEFAULT_TRADES_COLUMNS)
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms',
utc=True,)
df = df.set_index('timestamp')
df_new = df['price'].resample(f'{ticker_minutes}min').ohlc()
df_new['volume'] = df['amount'].resample(f'{ticker_minutes}min').sum()
df_new['date'] = df_new.index.astype("int64") // 10 ** 6
df_new = df['price'].resample(f'{timeframe_minutes}min').ohlc()
df_new['volume'] = df['amount'].resample(f'{timeframe_minutes}min').sum()
df_new['date'] = df_new.index
# Drop 0 volume rows
df_new = df_new.dropna()
columns = ["date", "open", "high", "low", "close", "volume"]
return list(zip(*[df_new[x].values.tolist() for x in columns]))
return df_new[DEFAULT_DATAFRAME_COLUMNS]
def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to: str, erase: bool):
"""
Convert trades from one format to another format.
:param config: Config dictionary
:param convert_from: Source format
:param convert_to: Target format
:param erase: Erase souce data (does not apply if source and target format are identical)
"""
from freqtrade.data.history.idatahandler import get_datahandler
src = get_datahandler(config['datadir'], convert_from)
trg = get_datahandler(config['datadir'], convert_to)
if 'pairs' not in config:
config['pairs'] = src.trades_get_pairs(config['datadir'])
logger.info(f"Converting trades for {config['pairs']}")
for pair in config['pairs']:
data = src.trades_load(pair=pair)
logger.info(f"Converting {len(data)} trades for {pair}")
trg.trades_store(pair, data)
if erase and convert_from != convert_to:
logger.info(f"Deleting source Trade data for {pair}.")
src.trades_purge(pair=pair)
def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str, erase: bool):
"""
Convert OHLCV from one format to another
:param config: Config dictionary
:param convert_from: Source format
:param convert_to: Target format
:param erase: Erase souce data (does not apply if source and target format are identical)
"""
from freqtrade.data.history.idatahandler import get_datahandler
src = get_datahandler(config['datadir'], convert_from)
trg = get_datahandler(config['datadir'], convert_to)
timeframes = config.get('timeframes', [config.get('ticker_interval')])
logger.info(f"Converting candle (OHLCV) for timeframe {timeframes}")
if 'pairs' not in config:
config['pairs'] = []
# Check timeframes or fall back to ticker_interval.
for timeframe in timeframes:
config['pairs'].extend(src.ohlcv_get_pairs(config['datadir'],
timeframe))
logger.info(f"Converting candle (OHLCV) data for {config['pairs']}")
for timeframe in timeframes:
for pair in config['pairs']:
data = src.ohlcv_load(pair=pair, timeframe=timeframe,
timerange=None,
fill_missing=False,
drop_incomplete=False,
startup_candles=0)
logger.info(f"Converting {len(data)} candles for {pair}")
trg.ohlcv_store(pair=pair, timeframe=timeframe, data=data)
if erase and convert_from != convert_to:
logger.info(f"Deleting source data for {pair} / {timeframe}")
src.ohlcv_purge(pair=pair, timeframe=timeframe)

View File

@@ -1,31 +1,34 @@
"""
Dataprovider
Responsible to provide data to the bot
including Klines, tickers, historic data
including ticker and orderbook data, live and historical candle (OHLCV) data
Common Interface for bot and strategy to access data.
"""
import logging
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
from typing import Any, Dict, List, Optional
from pandas import DataFrame
from freqtrade.data.history import load_pair_history
from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.exchange import Exchange
from freqtrade.state import RunMode
from freqtrade.constants import ListPairsWithTimeframes
logger = logging.getLogger(__name__)
class DataProvider:
def __init__(self, config: dict, exchange: Exchange) -> None:
def __init__(self, config: dict, exchange: Exchange, pairlists=None) -> None:
self._config = config
self._exchange = exchange
self._pairlists = pairlists
def refresh(self,
pairlist: List[Tuple[str, str]],
helping_pairs: List[Tuple[str, str]] = None) -> None:
pairlist: ListPairsWithTimeframes,
helping_pairs: ListPairsWithTimeframes = None) -> None:
"""
Refresh data, called with each cycle
"""
@@ -35,54 +38,55 @@ class DataProvider:
self._exchange.refresh_latest_ohlcv(pairlist)
@property
def available_pairs(self) -> List[Tuple[str, str]]:
def available_pairs(self) -> ListPairsWithTimeframes:
"""
Return a list of tuples containing pair, ticker_interval for which data is currently cached.
Return a list of tuples containing (pair, timeframe) for which data is currently cached.
Should be whitelist + open trades.
"""
return list(self._exchange._klines.keys())
def ohlcv(self, pair: str, ticker_interval: str = None, copy: bool = True) -> DataFrame:
def ohlcv(self, pair: str, timeframe: str = None, copy: bool = True) -> DataFrame:
"""
Get ohlcv data for the given pair as DataFrame
Get candle (OHLCV) data for the given pair as DataFrame
Please use the `available_pairs` method to verify which pairs are currently cached.
:param pair: pair to get the data for
:param ticker_interval: ticker interval to get data for
:param timeframe: Timeframe to get data for
:param copy: copy dataframe before returning if True.
Use False only for read-only operations (where the dataframe is not modified)
"""
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
return self._exchange.klines((pair, ticker_interval or self._config['ticker_interval']),
return self._exchange.klines((pair, timeframe or self._config['ticker_interval']),
copy=copy)
else:
return DataFrame()
def historic_ohlcv(self, pair: str, ticker_interval: str = None) -> DataFrame:
def historic_ohlcv(self, pair: str, timeframe: str = None) -> DataFrame:
"""
Get stored historic ohlcv data
Get stored historical candle (OHLCV) data
:param pair: pair to get the data for
:param ticker_interval: ticker interval to get data for
:param timeframe: timeframe to get data for
"""
return load_pair_history(pair=pair,
ticker_interval=ticker_interval or self._config['ticker_interval'],
datadir=Path(self._config['datadir'])
timeframe=timeframe or self._config['ticker_interval'],
datadir=self._config['datadir']
)
def get_pair_dataframe(self, pair: str, ticker_interval: str = None) -> DataFrame:
def get_pair_dataframe(self, pair: str, timeframe: str = None) -> DataFrame:
"""
Return pair ohlcv data, either live or cached historical -- depending
Return pair candle (OHLCV) data, either live or cached historical -- depending
on the runmode.
:param pair: pair to get the data for
:param ticker_interval: ticker interval to get data for
:param timeframe: timeframe to get data for
:return: Dataframe for this pair
"""
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
# Get live ohlcv data.
data = self.ohlcv(pair=pair, ticker_interval=ticker_interval)
# Get live OHLCV data.
data = self.ohlcv(pair=pair, timeframe=timeframe)
else:
# Get historic ohlcv data (cached on disk).
data = self.historic_ohlcv(pair=pair, ticker_interval=ticker_interval)
# Get historical OHLCV data (cached on disk).
data = self.historic_ohlcv(pair=pair, timeframe=timeframe)
if len(data) == 0:
logger.warning(f"No data found for ({pair}, {ticker_interval}).")
logger.warning(f"No data found for ({pair}, {timeframe}).")
return data
def market(self, pair: str) -> Optional[Dict[str, Any]]:
@@ -95,19 +99,24 @@ class DataProvider:
def ticker(self, pair: str):
"""
Return last ticker data
Return last ticker data from exchange
:param pair: Pair to get the data for
:return: Ticker dict from exchange or empty dict if ticker is not available for the pair
"""
# TODO: Implement me
pass
try:
return self._exchange.fetch_ticker(pair)
except DependencyException:
return {}
def orderbook(self, pair: str, maximum: int) -> Dict[str, List]:
"""
fetch latest orderbook data
Fetch latest l2 orderbook data
Warning: Does a network request - so use with common sense.
:param pair: pair to get the data for
:param maximum: Maximum number of orderbook entries to query
:return: dict including bids/asks with a total of `maximum` entries.
"""
return self._exchange.get_order_book(pair, maximum)
return self._exchange.fetch_l2_order_book(pair, maximum)
@property
def runmode(self) -> RunMode:
@@ -116,3 +125,17 @@ class DataProvider:
can be "live", "dry-run", "backtest", "edgecli", "hyperopt" or "other".
"""
return RunMode(self._config.get('runmode', RunMode.OTHER))
def current_whitelist(self) -> List[str]:
"""
fetch latest available whitelist.
Useful when you have a large whitelist and need to call each pair as an informative pair.
As available pairs does not show whitelist until after informative pairs have been cached.
:return: list of pairs in whitelist
"""
if self._pairlists:
return self._pairlists.whitelist
else:
raise OperationalException("Dataprovider was not initialized with a pairlist provider.")

View File

@@ -1,442 +0,0 @@
"""
Handle historic data (ohlcv).
Includes:
* load data for a pair (or a list of pairs) from disk
* download data from exchange and store to disk
"""
import logging
import operator
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
import arrow
from pandas import DataFrame
from freqtrade import OperationalException, misc
from freqtrade.configuration import TimeRange
from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv
from freqtrade.exchange import Exchange, timeframe_to_minutes
logger = logging.getLogger(__name__)
def trim_tickerlist(tickerlist: List[Dict], timerange: TimeRange) -> List[Dict]:
"""
Trim tickerlist based on given timerange
"""
if not tickerlist:
return tickerlist
start_index = 0
stop_index = len(tickerlist)
if timerange.starttype == 'date':
while (start_index < len(tickerlist) and
tickerlist[start_index][0] < timerange.startts * 1000):
start_index += 1
if timerange.stoptype == 'date':
while (stop_index > 0 and
tickerlist[stop_index-1][0] > timerange.stopts * 1000):
stop_index -= 1
if start_index > stop_index:
raise ValueError(f'The timerange [{timerange.startts},{timerange.stopts}] is incorrect')
return tickerlist[start_index:stop_index]
def load_tickerdata_file(datadir: Path, pair: str, ticker_interval: str,
timerange: Optional[TimeRange] = None) -> Optional[list]:
"""
Load a pair from file, either .json.gz or .json
:return: tickerlist or None if unsuccessful
"""
filename = pair_data_filename(datadir, pair, ticker_interval)
pairdata = misc.file_load_json(filename)
if not pairdata:
return []
if timerange:
pairdata = trim_tickerlist(pairdata, timerange)
return pairdata
def store_tickerdata_file(datadir: Path, pair: str,
ticker_interval: str, data: list, is_zip: bool = False):
"""
Stores tickerdata to file
"""
filename = pair_data_filename(datadir, pair, ticker_interval)
misc.file_dump_json(filename, data, is_zip=is_zip)
def load_trades_file(datadir: Path, pair: str,
timerange: Optional[TimeRange] = None) -> List[Dict]:
"""
Load a pair from file, either .json.gz or .json
:return: tradelist or empty list if unsuccesful
"""
filename = pair_trades_filename(datadir, pair)
tradesdata = misc.file_load_json(filename)
if not tradesdata:
return []
return tradesdata
def store_trades_file(datadir: Path, pair: str,
data: list, is_zip: bool = True):
"""
Stores tickerdata to file
"""
filename = pair_trades_filename(datadir, pair)
misc.file_dump_json(filename, data, is_zip=is_zip)
def _validate_pairdata(pair, pairdata, timerange: TimeRange):
if timerange.starttype == 'date' and pairdata[0][0] > timerange.startts * 1000:
logger.warning('Missing data at start for pair %s, data starts at %s',
pair, arrow.get(pairdata[0][0] // 1000).strftime('%Y-%m-%d %H:%M:%S'))
if timerange.stoptype == 'date' and pairdata[-1][0] < timerange.stopts * 1000:
logger.warning('Missing data at end for pair %s, data ends at %s',
pair, arrow.get(pairdata[-1][0] // 1000).strftime('%Y-%m-%d %H:%M:%S'))
def load_pair_history(pair: str,
ticker_interval: str,
datadir: Path,
timerange: Optional[TimeRange] = None,
refresh_pairs: bool = False,
exchange: Optional[Exchange] = None,
fill_up_missing: bool = True,
drop_incomplete: bool = True
) -> DataFrame:
"""
Loads cached ticker history for the given pair.
:param pair: Pair to load data for
:param ticker_interval: Ticker-interval (e.g. "5m")
:param datadir: Path to the data storage location.
:param timerange: Limit data to be loaded to this timerange
:param refresh_pairs: Refresh pairs from exchange.
(Note: Requires exchange to be passed as well.)
:param exchange: Exchange object (needed when using "refresh_pairs")
:param fill_up_missing: Fill missing values with "No action"-candles
:param drop_incomplete: Drop last candle assuming it may be incomplete.
:return: DataFrame with ohlcv data
"""
# The user forced the refresh of pairs
if refresh_pairs:
download_pair_history(datadir=datadir,
exchange=exchange,
pair=pair,
ticker_interval=ticker_interval,
timerange=timerange)
pairdata = load_tickerdata_file(datadir, pair, ticker_interval, timerange=timerange)
if pairdata:
if timerange:
_validate_pairdata(pair, pairdata, timerange)
return parse_ticker_dataframe(pairdata, ticker_interval, pair=pair,
fill_missing=fill_up_missing,
drop_incomplete=drop_incomplete)
else:
logger.warning(
f'No history data for pair: "{pair}", interval: {ticker_interval}. '
'Use `freqtrade download-data` to download the data'
)
return None
def load_data(datadir: Path,
ticker_interval: str,
pairs: List[str],
refresh_pairs: bool = False,
exchange: Optional[Exchange] = None,
timerange: Optional[TimeRange] = None,
fill_up_missing: bool = True,
) -> Dict[str, DataFrame]:
"""
Loads ticker history data for a list of pairs
:return: dict(<pair>:<tickerlist>)
TODO: refresh_pairs is still used by edge to keep the data uptodate.
This should be replaced in the future. Instead, writing the current candles to disk
from dataprovider should be implemented, as this would avoid loading ohlcv data twice.
exchange and refresh_pairs are then not needed here nor in load_pair_history.
"""
result: Dict[str, DataFrame] = {}
for pair in pairs:
hist = load_pair_history(pair=pair, ticker_interval=ticker_interval,
datadir=datadir, timerange=timerange,
refresh_pairs=refresh_pairs,
exchange=exchange,
fill_up_missing=fill_up_missing)
if hist is not None:
result[pair] = hist
return result
def pair_data_filename(datadir: Path, pair: str, ticker_interval: str) -> Path:
pair_s = pair.replace("/", "_")
filename = datadir.joinpath(f'{pair_s}-{ticker_interval}.json')
return filename
def pair_trades_filename(datadir: Path, pair: str) -> Path:
pair_s = pair.replace("/", "_")
filename = datadir.joinpath(f'{pair_s}-trades.json.gz')
return filename
def _load_cached_data_for_updating(datadir: Path, pair: str, ticker_interval: str,
timerange: Optional[TimeRange]) -> Tuple[List[Any],
Optional[int]]:
"""
Load cached data to download more data.
If timerange is passed in, checks whether data from an before the stored data will be
downloaded.
If that's the case then what's available should be completely overwritten.
Only used by download_pair_history().
"""
since_ms = None
# user sets timerange, so find the start time
if timerange:
if timerange.starttype == 'date':
since_ms = timerange.startts * 1000
elif timerange.stoptype == 'line':
num_minutes = timerange.stopts * timeframe_to_minutes(ticker_interval)
since_ms = arrow.utcnow().shift(minutes=num_minutes).timestamp * 1000
# read the cached file
# Intentionally don't pass timerange in - since we need to load the full dataset.
data = load_tickerdata_file(datadir, pair, ticker_interval)
# remove the last item, could be incomplete candle
if data:
data.pop()
else:
data = []
if data:
if since_ms and since_ms < data[0][0]:
# Earlier data than existing data requested, redownload all
data = []
else:
# a part of the data was already downloaded, so download unexist data only
since_ms = data[-1][0] + 1
return (data, since_ms)
def download_pair_history(datadir: Path,
exchange: Optional[Exchange],
pair: str,
ticker_interval: str = '5m',
timerange: Optional[TimeRange] = None) -> bool:
"""
Download the latest ticker intervals from the exchange for the pair passed in parameters
The data is downloaded starting from the last correct ticker interval data that
exists in a cache. If timerange starts earlier than the data in the cache,
the full data will be redownloaded
Based on @Rybolov work: https://github.com/rybolov/freqtrade-data
:param pair: pair to download
:param ticker_interval: ticker interval
:param timerange: range of time to download
:return: bool with success state
"""
if not exchange:
raise OperationalException(
"Exchange needs to be initialized when downloading pair history data"
)
try:
logger.info(
f'Download history data for pair: "{pair}", interval: {ticker_interval} '
f'and store in {datadir}.'
)
data, since_ms = _load_cached_data_for_updating(datadir, pair, ticker_interval, timerange)
logger.debug("Current Start: %s", misc.format_ms_time(data[1][0]) if data else 'None')
logger.debug("Current End: %s", misc.format_ms_time(data[-1][0]) if data else 'None')
# Default since_ms to 30 days if nothing is given
new_data = exchange.get_historic_ohlcv(pair=pair, ticker_interval=ticker_interval,
since_ms=since_ms if since_ms
else
int(arrow.utcnow().shift(
days=-30).float_timestamp) * 1000)
data.extend(new_data)
logger.debug("New Start: %s", misc.format_ms_time(data[0][0]))
logger.debug("New End: %s", misc.format_ms_time(data[-1][0]))
store_tickerdata_file(datadir, pair, ticker_interval, data=data)
return True
except Exception as e:
logger.error(
f'Failed to download history data for pair: "{pair}", interval: {ticker_interval}. '
f'Error: {e}'
)
return False
def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes: List[str],
dl_path: Path, timerange: Optional[TimeRange] = None,
erase=False) -> List[str]:
"""
Refresh stored ohlcv data for backtesting and hyperopt operations.
Used by freqtrade download-data
:return: Pairs not available
"""
pairs_not_available = []
for pair in pairs:
if pair not in exchange.markets:
pairs_not_available.append(pair)
logger.info(f"Skipping pair {pair}...")
continue
for ticker_interval in timeframes:
dl_file = pair_data_filename(dl_path, pair, ticker_interval)
if erase and dl_file.exists():
logger.info(
f'Deleting existing data for pair {pair}, interval {ticker_interval}.')
dl_file.unlink()
logger.info(f'Downloading pair {pair}, interval {ticker_interval}.')
download_pair_history(datadir=dl_path, exchange=exchange,
pair=pair, ticker_interval=str(ticker_interval),
timerange=timerange)
return pairs_not_available
def download_trades_history(datadir: Path,
exchange: Exchange,
pair: str,
timerange: Optional[TimeRange] = None) -> bool:
"""
Download trade history from the exchange.
Appends to previously downloaded trades data.
"""
try:
since = timerange.startts * 1000 if timerange and timerange.starttype == 'date' else None
trades = load_trades_file(datadir, pair)
from_id = trades[-1]['id'] if trades else None
logger.debug("Current Start: %s", trades[0]['datetime'] if trades else 'None')
logger.debug("Current End: %s", trades[-1]['datetime'] if trades else 'None')
new_trades = exchange.get_historic_trades(pair=pair,
since=since if since else
int(arrow.utcnow().shift(
days=-30).float_timestamp) * 1000,
# until=xxx,
from_id=from_id,
)
trades.extend(new_trades[1])
store_trades_file(datadir, pair, trades)
logger.debug("New Start: %s", trades[0]['datetime'])
logger.debug("New End: %s", trades[-1]['datetime'])
logger.info(f"New Amount of trades: {len(trades)}")
return True
except Exception as e:
logger.error(
f'Failed to download historic trades for pair: "{pair}". '
f'Error: {e}'
)
return False
def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: Path,
timerange: TimeRange, erase=False) -> List[str]:
"""
Refresh stored trades data.
Used by freqtrade download-data
:return: Pairs not available
"""
pairs_not_available = []
for pair in pairs:
if pair not in exchange.markets:
pairs_not_available.append(pair)
logger.info(f"Skipping pair {pair}...")
continue
dl_file = pair_trades_filename(datadir, pair)
if erase and dl_file.exists():
logger.info(
f'Deleting existing data for pair {pair}.')
dl_file.unlink()
logger.info(f'Downloading trades for pair {pair}.')
download_trades_history(datadir=datadir, exchange=exchange,
pair=pair,
timerange=timerange)
return pairs_not_available
def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str],
datadir: Path, timerange: TimeRange, erase=False) -> None:
"""
Convert stored trades data to ohlcv data
"""
for pair in pairs:
trades = load_trades_file(datadir, pair)
for timeframe in timeframes:
ohlcv_file = pair_data_filename(datadir, pair, timeframe)
if erase and ohlcv_file.exists():
logger.info(f'Deleting existing data for pair {pair}, interval {timeframe}.')
ohlcv_file.unlink()
ohlcv = trades_to_ohlcv(trades, timeframe)
# Store ohlcv
store_tickerdata_file(datadir, pair, timeframe, data=ohlcv)
def get_timeframe(data: Dict[str, DataFrame]) -> Tuple[arrow.Arrow, arrow.Arrow]:
"""
Get the maximum timeframe for the given backtest data
:param data: dictionary with preprocessed backtesting data
:return: tuple containing min_date, max_date
"""
timeframe = [
(arrow.get(frame['date'].min()), arrow.get(frame['date'].max()))
for frame in data.values()
]
return min(timeframe, key=operator.itemgetter(0))[0], \
max(timeframe, key=operator.itemgetter(1))[1]
def validate_backtest_data(data: DataFrame, pair: str, min_date: datetime,
max_date: datetime, ticker_interval_mins: int) -> bool:
"""
Validates preprocessed backtesting data for missing values and shows warnings about it that.
:param data: preprocessed backtesting data (as DataFrame)
:param pair: pair used for log output.
:param min_date: start-date of the data
:param max_date: end-date of the data
:param ticker_interval_mins: ticker interval in minutes
"""
# total difference in minutes / interval-minutes
expected_frames = int((max_date - min_date).total_seconds() // 60 // ticker_interval_mins)
found_missing = False
dflen = len(data)
if dflen < expected_frames:
found_missing = True
logger.warning("%s has missing frames: expected %s, got %s, that's %s missing values",
pair, expected_frames, dflen, expected_frames - dflen)
return found_missing

View File

@@ -0,0 +1,14 @@
"""
Handle historic data (ohlcv).
Includes:
* load data for a pair (or a list of pairs) from disk
* download data from exchange and store to disk
"""
from .history_utils import (convert_trades_to_ohlcv, # noqa: F401
get_timerange, load_data, load_pair_history,
refresh_backtest_ohlcv_data,
refresh_backtest_trades_data, refresh_data,
validate_backtest_data)
from .idatahandler import get_datahandler # noqa: F401

View File

@@ -0,0 +1,391 @@
import logging
import operator
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, List, Optional, Tuple
import arrow
from pandas import DataFrame
from freqtrade.configuration import TimeRange
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
from freqtrade.data.converter import (ohlcv_to_dataframe,
trades_remove_duplicates,
trades_to_ohlcv)
from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler
from freqtrade.exceptions import OperationalException
from freqtrade.exchange import Exchange
from freqtrade.misc import format_ms_time
logger = logging.getLogger(__name__)
def load_pair_history(pair: str,
timeframe: str,
datadir: Path, *,
timerange: Optional[TimeRange] = None,
fill_up_missing: bool = True,
drop_incomplete: bool = True,
startup_candles: int = 0,
data_format: str = None,
data_handler: IDataHandler = None,
) -> DataFrame:
"""
Load cached ohlcv history for the given pair.
:param pair: Pair to load data for
:param timeframe: Timeframe (e.g. "5m")
:param datadir: Path to the data storage location.
:param data_format: Format of the data. Ignored if data_handler is set.
:param timerange: Limit data to be loaded to this timerange
:param fill_up_missing: Fill missing values with "No action"-candles
:param drop_incomplete: Drop last candle assuming it may be incomplete.
:param startup_candles: Additional candles to load at the start of the period
:param data_handler: Initialized data-handler to use.
Will be initialized from data_format if not set
:return: DataFrame with ohlcv data, or empty DataFrame
"""
data_handler = get_datahandler(datadir, data_format, data_handler)
return data_handler.ohlcv_load(pair=pair,
timeframe=timeframe,
timerange=timerange,
fill_missing=fill_up_missing,
drop_incomplete=drop_incomplete,
startup_candles=startup_candles,
)
def load_data(datadir: Path,
timeframe: str,
pairs: List[str], *,
timerange: Optional[TimeRange] = None,
fill_up_missing: bool = True,
startup_candles: int = 0,
fail_without_data: bool = False,
data_format: str = 'json',
) -> Dict[str, DataFrame]:
"""
Load ohlcv history data for a list of pairs.
:param datadir: Path to the data storage location.
:param timeframe: Timeframe (e.g. "5m")
:param pairs: List of pairs to load
:param timerange: Limit data to be loaded to this timerange
:param fill_up_missing: Fill missing values with "No action"-candles
:param startup_candles: Additional candles to load at the start of the period
:param fail_without_data: Raise OperationalException if no data is found.
:param data_format: Data format which should be used. Defaults to json
:return: dict(<pair>:<Dataframe>)
"""
result: Dict[str, DataFrame] = {}
if startup_candles > 0 and timerange:
logger.info(f'Using indicator startup period: {startup_candles} ...')
data_handler = get_datahandler(datadir, data_format)
for pair in pairs:
hist = load_pair_history(pair=pair, timeframe=timeframe,
datadir=datadir, timerange=timerange,
fill_up_missing=fill_up_missing,
startup_candles=startup_candles,
data_handler=data_handler
)
if not hist.empty:
result[pair] = hist
if fail_without_data and not result:
raise OperationalException("No data found. Terminating.")
return result
def refresh_data(datadir: Path,
timeframe: str,
pairs: List[str],
exchange: Exchange,
data_format: str = None,
timerange: Optional[TimeRange] = None,
) -> None:
"""
Refresh ohlcv history data for a list of pairs.
:param datadir: Path to the data storage location.
:param timeframe: Timeframe (e.g. "5m")
:param pairs: List of pairs to load
:param exchange: Exchange object
:param timerange: Limit data to be loaded to this timerange
"""
data_handler = get_datahandler(datadir, data_format)
for pair in pairs:
_download_pair_history(pair=pair, timeframe=timeframe,
datadir=datadir, timerange=timerange,
exchange=exchange, data_handler=data_handler)
def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optional[TimeRange],
data_handler: IDataHandler) -> Tuple[DataFrame, Optional[int]]:
"""
Load cached data to download more data.
If timerange is passed in, checks whether data from an before the stored data will be
downloaded.
If that's the case then what's available should be completely overwritten.
Otherwise downloads always start at the end of the available data to avoid data gaps.
Note: Only used by download_pair_history().
"""
start = None
if timerange:
if timerange.starttype == 'date':
# TODO: convert to date for conversion
start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc)
# Intentionally don't pass timerange in - since we need to load the full dataset.
data = data_handler.ohlcv_load(pair, timeframe=timeframe,
timerange=None, fill_missing=False,
drop_incomplete=True, warn_no_data=False)
if not data.empty:
if start and start < data.iloc[0]['date']:
# Earlier data than existing data requested, redownload all
data = DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS)
else:
start = data.iloc[-1]['date']
start_ms = int(start.timestamp() * 1000) if start else None
return data, start_ms
def _download_pair_history(datadir: Path,
exchange: Exchange,
pair: str, *,
timeframe: str = '5m',
timerange: Optional[TimeRange] = None,
data_handler: IDataHandler = None) -> bool:
"""
Download latest candles from the exchange for the pair and timeframe passed in parameters
The data is downloaded starting from the last correct data that
exists in a cache. If timerange starts earlier than the data in the cache,
the full data will be redownloaded
Based on @Rybolov work: https://github.com/rybolov/freqtrade-data
:param pair: pair to download
:param timeframe: Timeframe (e.g "5m")
:param timerange: range of time to download
:return: bool with success state
"""
data_handler = get_datahandler(datadir, data_handler=data_handler)
try:
logger.info(
f'Download history data for pair: "{pair}", timeframe: {timeframe} '
f'and store in {datadir}.'
)
# data, since_ms = _load_cached_data_for_updating_old(datadir, pair, timeframe, timerange)
data, since_ms = _load_cached_data_for_updating(pair, timeframe, timerange,
data_handler=data_handler)
logger.debug("Current Start: %s",
f"{data.iloc[0]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None')
logger.debug("Current End: %s",
f"{data.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None')
# Default since_ms to 30 days if nothing is given
new_data = exchange.get_historic_ohlcv(pair=pair,
timeframe=timeframe,
since_ms=since_ms if since_ms else
int(arrow.utcnow().shift(
days=-30).float_timestamp) * 1000
)
# TODO: Maybe move parsing to exchange class (?)
new_dataframe = ohlcv_to_dataframe(new_data, timeframe, pair,
fill_missing=False, drop_incomplete=True)
if data.empty:
data = new_dataframe
else:
data = data.append(new_dataframe)
logger.debug("New Start: %s",
f"{data.iloc[0]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None')
logger.debug("New End: %s",
f"{data.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None')
data_handler.ohlcv_store(pair, timeframe, data=data)
return True
except Exception as e:
logger.error(
f'Failed to download history data for pair: "{pair}", timeframe: {timeframe}. '
f'Error: {e}'
)
return False
def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes: List[str],
datadir: Path, timerange: Optional[TimeRange] = None,
erase: bool = False, data_format: str = None) -> List[str]:
"""
Refresh stored ohlcv data for backtesting and hyperopt operations.
Used by freqtrade download-data subcommand.
:return: List of pairs that are not available.
"""
pairs_not_available = []
data_handler = get_datahandler(datadir, data_format)
for pair in pairs:
if pair not in exchange.markets:
pairs_not_available.append(pair)
logger.info(f"Skipping pair {pair}...")
continue
for timeframe in timeframes:
if erase:
if data_handler.ohlcv_purge(pair, timeframe):
logger.info(
f'Deleting existing data for pair {pair}, interval {timeframe}.')
logger.info(f'Downloading pair {pair}, interval {timeframe}.')
_download_pair_history(datadir=datadir, exchange=exchange,
pair=pair, timeframe=str(timeframe),
timerange=timerange, data_handler=data_handler)
return pairs_not_available
def _download_trades_history(exchange: Exchange,
pair: str, *,
timerange: Optional[TimeRange] = None,
data_handler: IDataHandler
) -> bool:
"""
Download trade history from the exchange.
Appends to previously downloaded trades data.
"""
try:
since = timerange.startts * 1000 if \
(timerange and timerange.starttype == 'date') else int(arrow.utcnow().shift(
days=-30).float_timestamp) * 1000
trades = data_handler.trades_load(pair)
# TradesList columns are defined in constants.DEFAULT_TRADES_COLUMNS
# DEFAULT_TRADES_COLUMNS: 0 -> timestamp
# DEFAULT_TRADES_COLUMNS: 1 -> id
from_id = trades[-1][1] if trades else None
if trades and since < trades[-1][0]:
# Reset since to the last available point
# - 5 seconds (to ensure we're getting all trades)
since = trades[-1][0] - (5 * 1000)
logger.info(f"Using last trade date -5s - Downloading trades for {pair} "
f"since: {format_ms_time(since)}.")
logger.debug(f"Current Start: {format_ms_time(trades[0][0]) if trades else 'None'}")
logger.debug(f"Current End: {format_ms_time(trades[-1][0]) if trades else 'None'}")
logger.info(f"Current Amount of trades: {len(trades)}")
# Default since_ms to 30 days if nothing is given
new_trades = exchange.get_historic_trades(pair=pair,
since=since,
from_id=from_id,
)
trades.extend(new_trades[1])
# Remove duplicates to make sure we're not storing data we don't need
trades = trades_remove_duplicates(trades)
data_handler.trades_store(pair, data=trades)
logger.debug(f"New Start: {format_ms_time(trades[0][0])}")
logger.debug(f"New End: {format_ms_time(trades[-1][0])}")
logger.info(f"New Amount of trades: {len(trades)}")
return True
except Exception as e:
logger.error(
f'Failed to download historic trades for pair: "{pair}". '
f'Error: {e}'
)
return False
def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir: Path,
timerange: TimeRange, erase: bool = False,
data_format: str = 'jsongz') -> List[str]:
"""
Refresh stored trades data for backtesting and hyperopt operations.
Used by freqtrade download-data subcommand.
:return: List of pairs that are not available.
"""
pairs_not_available = []
data_handler = get_datahandler(datadir, data_format=data_format)
for pair in pairs:
if pair not in exchange.markets:
pairs_not_available.append(pair)
logger.info(f"Skipping pair {pair}...")
continue
if erase:
if data_handler.trades_purge(pair):
logger.info(f'Deleting existing data for pair {pair}.')
logger.info(f'Downloading trades for pair {pair}.')
_download_trades_history(exchange=exchange,
pair=pair,
timerange=timerange,
data_handler=data_handler)
return pairs_not_available
def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str],
datadir: Path, timerange: TimeRange, erase: bool = False,
data_format_ohlcv: str = 'json',
data_format_trades: str = 'jsongz') -> None:
"""
Convert stored trades data to ohlcv data
"""
data_handler_trades = get_datahandler(datadir, data_format=data_format_trades)
data_handler_ohlcv = get_datahandler(datadir, data_format=data_format_ohlcv)
for pair in pairs:
trades = data_handler_trades.trades_load(pair)
for timeframe in timeframes:
if erase:
if data_handler_ohlcv.ohlcv_purge(pair, timeframe):
logger.info(f'Deleting existing data for pair {pair}, interval {timeframe}.')
ohlcv = trades_to_ohlcv(trades, timeframe)
# Store ohlcv
data_handler_ohlcv.ohlcv_store(pair, timeframe, data=ohlcv)
def get_timerange(data: Dict[str, DataFrame]) -> Tuple[arrow.Arrow, arrow.Arrow]:
"""
Get the maximum common timerange for the given backtest data.
:param data: dictionary with preprocessed backtesting data
:return: tuple containing min_date, max_date
"""
timeranges = [
(arrow.get(frame['date'].min()), arrow.get(frame['date'].max()))
for frame in data.values()
]
return (min(timeranges, key=operator.itemgetter(0))[0],
max(timeranges, key=operator.itemgetter(1))[1])
def validate_backtest_data(data: DataFrame, pair: str, min_date: datetime,
max_date: datetime, timeframe_min: int) -> bool:
"""
Validates preprocessed backtesting data for missing values and shows warnings about it that.
:param data: preprocessed backtesting data (as DataFrame)
:param pair: pair used for log output.
:param min_date: start-date of the data
:param max_date: end-date of the data
:param timeframe_min: Timeframe in minutes
"""
# total difference in minutes / timeframe-minutes
expected_frames = int((max_date - min_date).total_seconds() // 60 // timeframe_min)
found_missing = False
dflen = len(data)
if dflen < expected_frames:
found_missing = True
logger.warning("%s has missing frames: expected %s, got %s, that's %s missing values",
pair, expected_frames, dflen, expected_frames - dflen)
return found_missing

View File

@@ -0,0 +1,248 @@
"""
Abstract datahandler interface.
It's subclasses handle and storing data from disk.
"""
import logging
from abc import ABC, abstractclassmethod, abstractmethod
from copy import deepcopy
from datetime import datetime, timezone
from pathlib import Path
from typing import List, Optional, Type
from pandas import DataFrame
from freqtrade.configuration import TimeRange
from freqtrade.data.converter import (clean_ohlcv_dataframe,
trades_remove_duplicates, trim_dataframe)
from freqtrade.exchange import timeframe_to_seconds
logger = logging.getLogger(__name__)
# Type for trades list
TradeList = List[List]
class IDataHandler(ABC):
def __init__(self, datadir: Path) -> None:
self._datadir = datadir
@abstractclassmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]:
"""
Returns a list of all pairs with ohlcv data available in this datadir
for the specified timeframe
:param datadir: Directory to search for ohlcv files
:param timeframe: Timeframe to search pairs for
:return: List of Pairs
"""
@abstractmethod
def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None:
"""
Store data in json format "values".
format looks as follows:
[[<date>,<open>,<high>,<low>,<close>]]
:param pair: Pair - used to generate filename
:timeframe: Timeframe - used to generate filename
:data: Dataframe containing OHLCV data
:return: None
"""
@abstractmethod
def _ohlcv_load(self, pair: str, timeframe: str,
timerange: Optional[TimeRange] = None,
) -> DataFrame:
"""
Internal method used to load data for one pair from disk.
Implements the loading and conversion to a Pandas dataframe.
Timerange trimming and dataframe validation happens outside of this method.
:param pair: Pair to load data
:param timeframe: Timeframe (e.g. "5m")
:param timerange: Limit data to be loaded to this timerange.
Optionally implemented by subclasses to avoid loading
all data where possible.
:return: DataFrame with ohlcv data, or empty DataFrame
"""
@abstractmethod
def ohlcv_purge(self, pair: str, timeframe: str) -> bool:
"""
Remove data for this pair
:param pair: Delete data for this pair.
:param timeframe: Timeframe (e.g. "5m")
:return: True when deleted, false if file did not exist.
"""
@abstractmethod
def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None:
"""
Append data to existing data structures
:param pair: Pair
:param timeframe: Timeframe this ohlcv data is for
:param data: Data to append.
"""
@abstractclassmethod
def trades_get_pairs(cls, datadir: Path) -> List[str]:
"""
Returns a list of all pairs for which trade data is available in this
:param datadir: Directory to search for ohlcv files
:return: List of Pairs
"""
@abstractmethod
def trades_store(self, pair: str, data: TradeList) -> None:
"""
Store trades data (list of Dicts) to file
:param pair: Pair - used for filename
:param data: List of Lists containing trade data,
column sequence as in DEFAULT_TRADES_COLUMNS
"""
@abstractmethod
def trades_append(self, pair: str, data: TradeList):
"""
Append data to existing files
:param pair: Pair - used for filename
:param data: List of Lists containing trade data,
column sequence as in DEFAULT_TRADES_COLUMNS
"""
@abstractmethod
def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList:
"""
Load a pair from file, either .json.gz or .json
:param pair: Load trades for this pair
:param timerange: Timerange to load trades for - currently not implemented
:return: List of trades
"""
@abstractmethod
def trades_purge(self, pair: str) -> bool:
"""
Remove data for this pair
:param pair: Delete data for this pair.
:return: True when deleted, false if file did not exist.
"""
def trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList:
"""
Load a pair from file, either .json.gz or .json
Removes duplicates in the process.
:param pair: Load trades for this pair
:param timerange: Timerange to load trades for - currently not implemented
:return: List of trades
"""
return trades_remove_duplicates(self._trades_load(pair, timerange=timerange))
def ohlcv_load(self, pair, timeframe: str,
timerange: Optional[TimeRange] = None,
fill_missing: bool = True,
drop_incomplete: bool = True,
startup_candles: int = 0,
warn_no_data: bool = True
) -> DataFrame:
"""
Load cached candle (OHLCV) data for the given pair.
:param pair: Pair to load data for
:param timeframe: Timeframe (e.g. "5m")
:param timerange: Limit data to be loaded to this timerange
:param fill_missing: Fill missing values with "No action"-candles
:param drop_incomplete: Drop last candle assuming it may be incomplete.
:param startup_candles: Additional candles to load at the start of the period
:param warn_no_data: Log a warning message when no data is found
:return: DataFrame with ohlcv data, or empty DataFrame
"""
# Fix startup period
timerange_startup = deepcopy(timerange)
if startup_candles > 0 and timerange_startup:
timerange_startup.subtract_start(timeframe_to_seconds(timeframe) * startup_candles)
pairdf = self._ohlcv_load(pair, timeframe,
timerange=timerange_startup)
if self._check_empty_df(pairdf, pair, timeframe, warn_no_data):
return pairdf
else:
enddate = pairdf.iloc[-1]['date']
if timerange_startup:
self._validate_pairdata(pair, pairdf, timerange_startup)
pairdf = trim_dataframe(pairdf, timerange_startup)
if self._check_empty_df(pairdf, pair, timeframe, warn_no_data):
return pairdf
# incomplete candles should only be dropped if we didn't trim the end beforehand.
pairdf = clean_ohlcv_dataframe(pairdf, timeframe,
pair=pair,
fill_missing=fill_missing,
drop_incomplete=(drop_incomplete and
enddate == pairdf.iloc[-1]['date']))
self._check_empty_df(pairdf, pair, timeframe, warn_no_data)
return pairdf
def _check_empty_df(self, pairdf: DataFrame, pair: str, timeframe: str, warn_no_data: bool):
"""
Warn on empty dataframe
"""
if pairdf.empty:
if warn_no_data:
logger.warning(
f'No history data for pair: "{pair}", timeframe: {timeframe}. '
'Use `freqtrade download-data` to download the data'
)
return True
return False
def _validate_pairdata(self, pair, pairdata: DataFrame, timerange: TimeRange):
"""
Validates pairdata for missing data at start end end and logs warnings.
:param pairdata: Dataframe to validate
:param timerange: Timerange specified for start and end dates
"""
if timerange.starttype == 'date':
start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc)
if pairdata.iloc[0]['date'] > start:
logger.warning(f"Missing data at start for pair {pair}, "
f"data starts at {pairdata.iloc[0]['date']:%Y-%m-%d %H:%M:%S}")
if timerange.stoptype == 'date':
stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc)
if pairdata.iloc[-1]['date'] < stop:
logger.warning(f"Missing data at end for pair {pair}, "
f"data ends at {pairdata.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}")
def get_datahandlerclass(datatype: str) -> Type[IDataHandler]:
"""
Get datahandler class.
Could be done using Resolvers, but since this may be called often and resolvers
are rather expensive, doing this directly should improve performance.
:param datatype: datatype to use.
:return: Datahandler class
"""
if datatype == 'json':
from .jsondatahandler import JsonDataHandler
return JsonDataHandler
elif datatype == 'jsongz':
from .jsondatahandler import JsonGzDataHandler
return JsonGzDataHandler
else:
raise ValueError(f"No datahandler for datatype {datatype} available.")
def get_datahandler(datadir: Path, data_format: str = None,
data_handler: IDataHandler = None) -> IDataHandler:
"""
:param datadir: Folder to save data
:data_format: dataformat to use
:data_handler: returns this datahandler if it exists or initializes a new one
"""
if not data_handler:
HandlerClass = get_datahandlerclass(data_format or 'json')
data_handler = HandlerClass(datadir)
return data_handler

View File

@@ -0,0 +1,191 @@
import logging
import re
from pathlib import Path
from typing import List, Optional
import numpy as np
from pandas import DataFrame, read_json, to_datetime
from freqtrade import misc
from freqtrade.configuration import TimeRange
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
from freqtrade.data.converter import trades_dict_to_list
from .idatahandler import IDataHandler, TradeList
logger = logging.getLogger(__name__)
class JsonDataHandler(IDataHandler):
_use_zip = False
_columns = DEFAULT_DATAFRAME_COLUMNS
@classmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]:
"""
Returns a list of all pairs with ohlcv data available in this datadir
for the specified timeframe
:param datadir: Directory to search for ohlcv files
:param timeframe: Timeframe to search pairs for
:return: List of Pairs
"""
_tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name)
for p in datadir.glob(f"*{timeframe}.{cls._get_file_extension()}")]
# Check if regex found something and only return these results
return [match[0].replace('_', '/') for match in _tmp if match]
def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None:
"""
Store data in json format "values".
format looks as follows:
[[<date>,<open>,<high>,<low>,<close>]]
:param pair: Pair - used to generate filename
:timeframe: Timeframe - used to generate filename
:data: Dataframe containing OHLCV data
:return: None
"""
filename = self._pair_data_filename(self._datadir, pair, timeframe)
_data = data.copy()
# Convert date to int
_data['date'] = _data['date'].astype(np.int64) // 1000 // 1000
# Reset index, select only appropriate columns and save as json
_data.reset_index(drop=True).loc[:, self._columns].to_json(
filename, orient="values",
compression='gzip' if self._use_zip else None)
def _ohlcv_load(self, pair: str, timeframe: str,
timerange: Optional[TimeRange] = None,
) -> DataFrame:
"""
Internal method used to load data for one pair from disk.
Implements the loading and conversion to a Pandas dataframe.
Timerange trimming and dataframe validation happens outside of this method.
:param pair: Pair to load data
:param timeframe: Timeframe (e.g. "5m")
:param timerange: Limit data to be loaded to this timerange.
Optionally implemented by subclasses to avoid loading
all data where possible.
:return: DataFrame with ohlcv data, or empty DataFrame
"""
filename = self._pair_data_filename(self._datadir, pair, timeframe)
if not filename.exists():
return DataFrame(columns=self._columns)
pairdata = read_json(filename, orient='values')
pairdata.columns = self._columns
pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float',
'low': 'float', 'close': 'float', 'volume': 'float'})
pairdata['date'] = to_datetime(pairdata['date'],
unit='ms',
utc=True,
infer_datetime_format=True)
return pairdata
def ohlcv_purge(self, pair: str, timeframe: str) -> bool:
"""
Remove data for this pair
:param pair: Delete data for this pair.
:param timeframe: Timeframe (e.g. "5m")
:return: True when deleted, false if file did not exist.
"""
filename = self._pair_data_filename(self._datadir, pair, timeframe)
if filename.exists():
filename.unlink()
return True
return False
def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None:
"""
Append data to existing data structures
:param pair: Pair
:param timeframe: Timeframe this ohlcv data is for
:param data: Data to append.
"""
raise NotImplementedError()
@classmethod
def trades_get_pairs(cls, datadir: Path) -> List[str]:
"""
Returns a list of all pairs for which trade data is available in this
:param datadir: Directory to search for ohlcv files
:return: List of Pairs
"""
_tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name)
for p in datadir.glob(f"*trades.{cls._get_file_extension()}")]
# Check if regex found something and only return these results to avoid exceptions.
return [match[0].replace('_', '/') for match in _tmp if match]
def trades_store(self, pair: str, data: TradeList) -> None:
"""
Store trades data (list of Dicts) to file
:param pair: Pair - used for filename
:param data: List of Lists containing trade data,
column sequence as in DEFAULT_TRADES_COLUMNS
"""
filename = self._pair_trades_filename(self._datadir, pair)
misc.file_dump_json(filename, data, is_zip=self._use_zip)
def trades_append(self, pair: str, data: TradeList):
"""
Append data to existing files
:param pair: Pair - used for filename
:param data: List of Lists containing trade data,
column sequence as in DEFAULT_TRADES_COLUMNS
"""
raise NotImplementedError()
def _trades_load(self, pair: str, timerange: Optional[TimeRange] = None) -> TradeList:
"""
Load a pair from file, either .json.gz or .json
# TODO: respect timerange ...
:param pair: Load trades for this pair
:param timerange: Timerange to load trades for - currently not implemented
:return: List of trades
"""
filename = self._pair_trades_filename(self._datadir, pair)
tradesdata = misc.file_load_json(filename)
if not tradesdata:
return []
if isinstance(tradesdata[0], dict):
# Convert trades dict to list
logger.info("Old trades format detected - converting")
tradesdata = trades_dict_to_list(tradesdata)
pass
return tradesdata
def trades_purge(self, pair: str) -> bool:
"""
Remove data for this pair
:param pair: Delete data for this pair.
:return: True when deleted, false if file did not exist.
"""
filename = self._pair_trades_filename(self._datadir, pair)
if filename.exists():
filename.unlink()
return True
return False
@classmethod
def _pair_data_filename(cls, datadir: Path, pair: str, timeframe: str) -> Path:
pair_s = misc.pair_to_filename(pair)
filename = datadir.joinpath(f'{pair_s}-{timeframe}.{cls._get_file_extension()}')
return filename
@classmethod
def _get_file_extension(cls):
return "json.gz" if cls._use_zip else "json"
@classmethod
def _pair_trades_filename(cls, datadir: Path, pair: str) -> Path:
pair_s = misc.pair_to_filename(pair)
filename = datadir.joinpath(f'{pair_s}-trades.{cls._get_file_extension()}')
return filename
class JsonGzDataHandler(JsonDataHandler):
_use_zip = True

View File

@@ -1,455 +1 @@
# pragma pylint: disable=W0603
""" Edge positioning package """
import logging
from pathlib import Path
from typing import Any, Dict, NamedTuple
import arrow
import numpy as np
import utils_find_1st as utf1st
from pandas import DataFrame
from freqtrade import constants, OperationalException
from freqtrade.configuration import TimeRange
from freqtrade.data import history
from freqtrade.strategy.interface import SellType
logger = logging.getLogger(__name__)
class PairInfo(NamedTuple):
stoploss: float
winrate: float
risk_reward_ratio: float
required_risk_reward: float
expectancy: float
nb_trades: int
avg_trade_duration: float
class Edge:
"""
Calculates Win Rate, Risk Reward Ratio, Expectancy
against historical data for a give set of markets and a strategy
it then adjusts stoploss and position size accordingly
and force it into the strategy
Author: https://github.com/mishaker
"""
config: Dict = {}
_cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs
def __init__(self, config: Dict[str, Any], exchange, strategy) -> None:
self.config = config
self.exchange = exchange
self.strategy = strategy
self.edge_config = self.config.get('edge', {})
self._cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs
self._final_pairs: list = []
# checking max_open_trades. it should be -1 as with Edge
# the number of trades is determined by position size
if self.config['max_open_trades'] != float('inf'):
logger.critical('max_open_trades should be -1 in config !')
if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT:
raise OperationalException('Edge works only with unlimited stake amount')
self._capital_percentage: float = self.edge_config.get('capital_available_percentage')
self._allowed_risk: float = self.edge_config.get('allowed_risk')
self._since_number_of_days: int = self.edge_config.get('calculate_since_number_of_days', 14)
self._last_updated: int = 0 # Timestamp of pairs last updated time
self._refresh_pairs = True
self._stoploss_range_min = float(self.edge_config.get('stoploss_range_min', -0.01))
self._stoploss_range_max = float(self.edge_config.get('stoploss_range_max', -0.05))
self._stoploss_range_step = float(self.edge_config.get('stoploss_range_step', -0.001))
# calculating stoploss range
self._stoploss_range = np.arange(
self._stoploss_range_min,
self._stoploss_range_max,
self._stoploss_range_step
)
self._timerange: TimeRange = TimeRange.parse_timerange("%s-" % arrow.now().shift(
days=-1 * self._since_number_of_days).format('YYYYMMDD'))
if config.get('fee'):
self.fee = config['fee']
else:
self.fee = self.exchange.get_fee()
def calculate(self) -> bool:
pairs = self.config['exchange']['pair_whitelist']
heartbeat = self.edge_config.get('process_throttle_secs')
if (self._last_updated > 0) and (
self._last_updated + heartbeat > arrow.utcnow().timestamp):
return False
data: Dict[str, Any] = {}
logger.info('Using stake_currency: %s ...', self.config['stake_currency'])
logger.info('Using local backtesting data (using whitelist in given config) ...')
data = history.load_data(
datadir=Path(self.config['datadir']),
pairs=pairs,
ticker_interval=self.strategy.ticker_interval,
refresh_pairs=self._refresh_pairs,
exchange=self.exchange,
timerange=self._timerange
)
if not data:
# Reinitializing cached pairs
self._cached_pairs = {}
logger.critical("No data found. Edge is stopped ...")
return False
preprocessed = self.strategy.tickerdata_to_dataframe(data)
# Print timeframe
min_date, max_date = history.get_timeframe(preprocessed)
logger.info(
'Measuring data from %s up to %s (%s days) ...',
min_date.isoformat(),
max_date.isoformat(),
(max_date - min_date).days
)
headers = ['date', 'buy', 'open', 'close', 'sell', 'high', 'low']
trades: list = []
for pair, pair_data in preprocessed.items():
# Sorting dataframe by date and reset index
pair_data = pair_data.sort_values(by=['date'])
pair_data = pair_data.reset_index(drop=True)
ticker_data = self.strategy.advise_sell(
self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy()
trades += self._find_trades_for_stoploss_range(ticker_data, pair, self._stoploss_range)
# If no trade found then exit
if len(trades) == 0:
logger.info("No trades found.")
return False
# Fill missing, calculable columns, profit, duration , abs etc.
trades_df = self._fill_calculable_fields(DataFrame(trades))
self._cached_pairs = self._process_expectancy(trades_df)
self._last_updated = arrow.utcnow().timestamp
return True
def stake_amount(self, pair: str, free_capital: float,
total_capital: float, capital_in_trade: float) -> float:
stoploss = self.stoploss(pair)
available_capital = (total_capital + capital_in_trade) * self._capital_percentage
allowed_capital_at_risk = available_capital * self._allowed_risk
max_position_size = abs(allowed_capital_at_risk / stoploss)
position_size = min(max_position_size, free_capital)
if pair in self._cached_pairs:
logger.info(
'winrate: %s, expectancy: %s, position size: %s, pair: %s,'
' capital in trade: %s, free capital: %s, total capital: %s,'
' stoploss: %s, available capital: %s.',
self._cached_pairs[pair].winrate,
self._cached_pairs[pair].expectancy,
position_size, pair,
capital_in_trade, free_capital, total_capital,
stoploss, available_capital
)
return round(position_size, 15)
def stoploss(self, pair: str) -> float:
if pair in self._cached_pairs:
return self._cached_pairs[pair].stoploss
else:
logger.warning('tried to access stoploss of a non-existing pair, '
'strategy stoploss is returned instead.')
return self.strategy.stoploss
def adjust(self, pairs) -> list:
"""
Filters out and sorts "pairs" according to Edge calculated pairs
"""
final = []
for pair, info in self._cached_pairs.items():
if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \
info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)) and \
pair in pairs:
final.append(pair)
if self._final_pairs != final:
self._final_pairs = final
if self._final_pairs:
logger.info(
'Minimum expectancy and minimum winrate are met only for %s,'
' so other pairs are filtered out.',
self._final_pairs
)
else:
logger.info(
'Edge removed all pairs as no pair with minimum expectancy '
'and minimum winrate was found !'
)
return self._final_pairs
def accepted_pairs(self) -> list:
"""
return a list of accepted pairs along with their winrate, expectancy and stoploss
"""
final = []
for pair, info in self._cached_pairs.items():
if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \
info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)):
final.append({
'Pair': pair,
'Winrate': info.winrate,
'Expectancy': info.expectancy,
'Stoploss': info.stoploss,
})
return final
def _fill_calculable_fields(self, result: DataFrame) -> DataFrame:
"""
The result frame contains a number of columns that are calculable
from other columns. These are left blank till all rows are added,
to be populated in single vector calls.
Columns to be populated are:
- Profit
- trade duration
- profit abs
:param result Dataframe
:return: result Dataframe
"""
# stake and fees
# stake = 0.015
# 0.05% is 0.0005
# fee = 0.001
# we set stake amount to an arbitrary amount.
# as it doesn't change the calculation.
# all returned values are relative. they are percentages.
stake = 0.015
fee = self.fee
open_fee = fee / 2
close_fee = fee / 2
result['trade_duration'] = result['close_time'] - result['open_time']
result['trade_duration'] = result['trade_duration'].map(
lambda x: int(x.total_seconds() / 60))
# Spends, Takes, Profit, Absolute Profit
# Buy Price
result['buy_vol'] = stake / result['open_rate'] # How many target are we buying
result['buy_fee'] = stake * open_fee
result['buy_spend'] = stake + result['buy_fee'] # How much we're spending
# Sell price
result['sell_sum'] = result['buy_vol'] * result['close_rate']
result['sell_fee'] = result['sell_sum'] * close_fee
result['sell_take'] = result['sell_sum'] - result['sell_fee']
# profit_percent
result['profit_percent'] = (result['sell_take'] - result['buy_spend']) / result['buy_spend']
# Absolute profit
result['profit_abs'] = result['sell_take'] - result['buy_spend']
return result
def _process_expectancy(self, results: DataFrame) -> Dict[str, Any]:
"""
This calculates WinRate, Required Risk Reward, Risk Reward and Expectancy of all pairs
The calulation will be done per pair and per strategy.
"""
# Removing pairs having less than min_trades_number
min_trades_number = self.edge_config.get('min_trade_number', 10)
results = results.groupby(['pair', 'stoploss']).filter(lambda x: len(x) > min_trades_number)
###################################
# Removing outliers (Only Pumps) from the dataset
# The method to detect outliers is to calculate standard deviation
# Then every value more than (standard deviation + 2*average) is out (pump)
#
# Removing Pumps
if self.edge_config.get('remove_pumps', False):
results = results.groupby(['pair', 'stoploss']).apply(
lambda x: x[x['profit_abs'] < 2 * x['profit_abs'].std() + x['profit_abs'].mean()])
##########################################################################
# Removing trades having a duration more than X minutes (set in config)
max_trade_duration = self.edge_config.get('max_trade_duration_minute', 1440)
results = results[results.trade_duration < max_trade_duration]
#######################################################################
if results.empty:
return {}
groupby_aggregator = {
'profit_abs': [
('nb_trades', 'count'), # number of all trades
('profit_sum', lambda x: x[x > 0].sum()), # cumulative profit of all winning trades
('loss_sum', lambda x: abs(x[x < 0].sum())), # cumulative loss of all losing trades
('nb_win_trades', lambda x: x[x > 0].count()) # number of winning trades
],
'trade_duration': [('avg_trade_duration', 'mean')]
}
# Group by (pair and stoploss) by applying above aggregator
df = results.groupby(['pair', 'stoploss'])['profit_abs', 'trade_duration'].agg(
groupby_aggregator).reset_index(col_level=1)
# Dropping level 0 as we don't need it
df.columns = df.columns.droplevel(0)
# Calculating number of losing trades, average win and average loss
df['nb_loss_trades'] = df['nb_trades'] - df['nb_win_trades']
df['average_win'] = df['profit_sum'] / df['nb_win_trades']
df['average_loss'] = df['loss_sum'] / df['nb_loss_trades']
# Win rate = number of profitable trades / number of trades
df['winrate'] = df['nb_win_trades'] / df['nb_trades']
# risk_reward_ratio = average win / average loss
df['risk_reward_ratio'] = df['average_win'] / df['average_loss']
# required_risk_reward = (1 / winrate) - 1
df['required_risk_reward'] = (1 / df['winrate']) - 1
# expectancy = (risk_reward_ratio * winrate) - (lossrate)
df['expectancy'] = (df['risk_reward_ratio'] * df['winrate']) - (1 - df['winrate'])
# sort by expectancy and stoploss
df = df.sort_values(by=['expectancy', 'stoploss'], ascending=False).groupby(
'pair').first().sort_values(by=['expectancy'], ascending=False).reset_index()
final = {}
for x in df.itertuples():
final[x.pair] = PairInfo(
x.stoploss,
x.winrate,
x.risk_reward_ratio,
x.required_risk_reward,
x.expectancy,
x.nb_trades,
x.avg_trade_duration
)
# Returning a list of pairs in order of "expectancy"
return final
def _find_trades_for_stoploss_range(self, ticker_data, pair, stoploss_range):
buy_column = ticker_data['buy'].values
sell_column = ticker_data['sell'].values
date_column = ticker_data['date'].values
ohlc_columns = ticker_data[['open', 'high', 'low', 'close']].values
result: list = []
for stoploss in stoploss_range:
result += self._detect_next_stop_or_sell_point(
buy_column, sell_column, date_column, ohlc_columns, round(stoploss, 6), pair
)
return result
def _detect_next_stop_or_sell_point(self, buy_column, sell_column, date_column,
ohlc_columns, stoploss, pair):
"""
Iterate through ohlc_columns in order to find the next trade
Next trade opens from the first buy signal noticed to
The sell or stoploss signal after it.
It then cuts OHLC, buy_column, sell_column and date_column.
Cut from (the exit trade index) + 1.
Author: https://github.com/mishaker
"""
result: list = []
start_point = 0
while True:
open_trade_index = utf1st.find_1st(buy_column, 1, utf1st.cmp_equal)
# Return empty if we don't find trade entry (i.e. buy==1) or
# we find a buy but at the end of array
if open_trade_index == -1 or open_trade_index == len(buy_column) - 1:
break
else:
# When a buy signal is seen,
# trade opens in reality on the next candle
open_trade_index += 1
stop_price_percentage = stoploss + 1
open_price = ohlc_columns[open_trade_index, 0]
stop_price = (open_price * stop_price_percentage)
# Searching for the index where stoploss is hit
stop_index = utf1st.find_1st(
ohlc_columns[open_trade_index:, 2], stop_price, utf1st.cmp_smaller)
# If we don't find it then we assume stop_index will be far in future (infinite number)
if stop_index == -1:
stop_index = float('inf')
# Searching for the index where sell is hit
sell_index = utf1st.find_1st(sell_column[open_trade_index:], 1, utf1st.cmp_equal)
# If we don't find it then we assume sell_index will be far in future (infinite number)
if sell_index == -1:
sell_index = float('inf')
# Check if we don't find any stop or sell point (in that case trade remains open)
# It is not interesting for Edge to consider it so we simply ignore the trade
# And stop iterating there is no more entry
if stop_index == sell_index == float('inf'):
break
if stop_index <= sell_index:
exit_index = open_trade_index + stop_index
exit_type = SellType.STOP_LOSS
exit_price = stop_price
elif stop_index > sell_index:
# If exit is SELL then we exit at the next candle
exit_index = open_trade_index + sell_index + 1
# Check if we have the next candle
if len(ohlc_columns) - 1 < exit_index:
break
exit_type = SellType.SELL_SIGNAL
exit_price = ohlc_columns[exit_index, 0]
trade = {'pair': pair,
'stoploss': stoploss,
'profit_percent': '',
'profit_abs': '',
'open_time': date_column[open_trade_index],
'close_time': date_column[exit_index],
'open_index': start_point + open_trade_index,
'close_index': start_point + exit_index,
'trade_duration': '',
'open_rate': round(open_price, 15),
'close_rate': round(exit_price, 15),
'exit_type': exit_type
}
result.append(trade)
# Giving a view of exit_index till the end of array
buy_column = buy_column[exit_index:]
sell_column = sell_column[exit_index:]
date_column = date_column[exit_index:]
ohlc_columns = ohlc_columns[exit_index:]
start_point += exit_index
return result
from .edge_positioning import Edge, PairInfo # noqa: F401

View File

@@ -0,0 +1,454 @@
# pragma pylint: disable=W0603
""" Edge positioning package """
import logging
from typing import Any, Dict, List, NamedTuple
import arrow
import numpy as np
import utils_find_1st as utf1st
from pandas import DataFrame
from freqtrade.configuration import TimeRange
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT
from freqtrade.exceptions import OperationalException
from freqtrade.data.history import get_timerange, load_data, refresh_data
from freqtrade.strategy.interface import SellType
logger = logging.getLogger(__name__)
class PairInfo(NamedTuple):
stoploss: float
winrate: float
risk_reward_ratio: float
required_risk_reward: float
expectancy: float
nb_trades: int
avg_trade_duration: float
class Edge:
"""
Calculates Win Rate, Risk Reward Ratio, Expectancy
against historical data for a give set of markets and a strategy
it then adjusts stoploss and position size accordingly
and force it into the strategy
Author: https://github.com/mishaker
"""
config: Dict = {}
_cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs
def __init__(self, config: Dict[str, Any], exchange, strategy) -> None:
self.config = config
self.exchange = exchange
self.strategy = strategy
self.edge_config = self.config.get('edge', {})
self._cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs
self._final_pairs: list = []
# checking max_open_trades. it should be -1 as with Edge
# the number of trades is determined by position size
if self.config['max_open_trades'] != float('inf'):
logger.critical('max_open_trades should be -1 in config !')
if self.config['stake_amount'] != UNLIMITED_STAKE_AMOUNT:
raise OperationalException('Edge works only with unlimited stake amount')
# Deprecated capital_available_percentage. Will use tradable_balance_ratio in the future.
self._capital_percentage: float = self.edge_config.get(
'capital_available_percentage', self.config['tradable_balance_ratio'])
self._allowed_risk: float = self.edge_config.get('allowed_risk')
self._since_number_of_days: int = self.edge_config.get('calculate_since_number_of_days', 14)
self._last_updated: int = 0 # Timestamp of pairs last updated time
self._refresh_pairs = True
self._stoploss_range_min = float(self.edge_config.get('stoploss_range_min', -0.01))
self._stoploss_range_max = float(self.edge_config.get('stoploss_range_max', -0.05))
self._stoploss_range_step = float(self.edge_config.get('stoploss_range_step', -0.001))
# calculating stoploss range
self._stoploss_range = np.arange(
self._stoploss_range_min,
self._stoploss_range_max,
self._stoploss_range_step
)
self._timerange: TimeRange = TimeRange.parse_timerange("%s-" % arrow.now().shift(
days=-1 * self._since_number_of_days).format('YYYYMMDD'))
if config.get('fee'):
self.fee = config['fee']
else:
self.fee = self.exchange.get_fee(symbol=self.config['exchange']['pair_whitelist'][0])
def calculate(self) -> bool:
pairs = self.config['exchange']['pair_whitelist']
heartbeat = self.edge_config.get('process_throttle_secs')
if (self._last_updated > 0) and (
self._last_updated + heartbeat > arrow.utcnow().timestamp):
return False
data: Dict[str, Any] = {}
logger.info('Using stake_currency: %s ...', self.config['stake_currency'])
logger.info('Using local backtesting data (using whitelist in given config) ...')
if self._refresh_pairs:
refresh_data(
datadir=self.config['datadir'],
pairs=pairs,
exchange=self.exchange,
timeframe=self.strategy.ticker_interval,
timerange=self._timerange,
)
data = load_data(
datadir=self.config['datadir'],
pairs=pairs,
timeframe=self.strategy.ticker_interval,
timerange=self._timerange,
startup_candles=self.strategy.startup_candle_count,
data_format=self.config.get('dataformat_ohlcv', 'json'),
)
if not data:
# Reinitializing cached pairs
self._cached_pairs = {}
logger.critical("No data found. Edge is stopped ...")
return False
preprocessed = self.strategy.ohlcvdata_to_dataframe(data)
# Print timeframe
min_date, max_date = get_timerange(preprocessed)
logger.info(
'Measuring data from %s up to %s (%s days) ...',
min_date.isoformat(),
max_date.isoformat(),
(max_date - min_date).days
)
headers = ['date', 'buy', 'open', 'close', 'sell', 'high', 'low']
trades: list = []
for pair, pair_data in preprocessed.items():
# Sorting dataframe by date and reset index
pair_data = pair_data.sort_values(by=['date'])
pair_data = pair_data.reset_index(drop=True)
df_analyzed = self.strategy.advise_sell(
self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy()
trades += self._find_trades_for_stoploss_range(df_analyzed, pair, self._stoploss_range)
# If no trade found then exit
if len(trades) == 0:
logger.info("No trades found.")
return False
# Fill missing, calculable columns, profit, duration , abs etc.
trades_df = self._fill_calculable_fields(DataFrame(trades))
self._cached_pairs = self._process_expectancy(trades_df)
self._last_updated = arrow.utcnow().timestamp
return True
def stake_amount(self, pair: str, free_capital: float,
total_capital: float, capital_in_trade: float) -> float:
stoploss = self.stoploss(pair)
available_capital = (total_capital + capital_in_trade) * self._capital_percentage
allowed_capital_at_risk = available_capital * self._allowed_risk
max_position_size = abs(allowed_capital_at_risk / stoploss)
position_size = min(max_position_size, free_capital)
if pair in self._cached_pairs:
logger.info(
'winrate: %s, expectancy: %s, position size: %s, pair: %s,'
' capital in trade: %s, free capital: %s, total capital: %s,'
' stoploss: %s, available capital: %s.',
self._cached_pairs[pair].winrate,
self._cached_pairs[pair].expectancy,
position_size, pair,
capital_in_trade, free_capital, total_capital,
stoploss, available_capital
)
return round(position_size, 15)
def stoploss(self, pair: str) -> float:
if pair in self._cached_pairs:
return self._cached_pairs[pair].stoploss
else:
logger.warning('tried to access stoploss of a non-existing pair, '
'strategy stoploss is returned instead.')
return self.strategy.stoploss
def adjust(self, pairs: List[str]) -> list:
"""
Filters out and sorts "pairs" according to Edge calculated pairs
"""
final = []
for pair, info in self._cached_pairs.items():
if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \
info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)) and \
pair in pairs:
final.append(pair)
if self._final_pairs != final:
self._final_pairs = final
if self._final_pairs:
logger.info(
'Minimum expectancy and minimum winrate are met only for %s,'
' so other pairs are filtered out.',
self._final_pairs
)
else:
logger.info(
'Edge removed all pairs as no pair with minimum expectancy '
'and minimum winrate was found !'
)
return self._final_pairs
def accepted_pairs(self) -> list:
"""
return a list of accepted pairs along with their winrate, expectancy and stoploss
"""
final = []
for pair, info in self._cached_pairs.items():
if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \
info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)):
final.append({
'Pair': pair,
'Winrate': info.winrate,
'Expectancy': info.expectancy,
'Stoploss': info.stoploss,
})
return final
def _fill_calculable_fields(self, result: DataFrame) -> DataFrame:
"""
The result frame contains a number of columns that are calculable
from other columns. These are left blank till all rows are added,
to be populated in single vector calls.
Columns to be populated are:
- Profit
- trade duration
- profit abs
:param result Dataframe
:return: result Dataframe
"""
# We set stake amount to an arbitrary amount, as it doesn't change the calculation.
# All returned values are relative, they are defined as ratios.
stake = 0.015
result['trade_duration'] = result['close_time'] - result['open_time']
result['trade_duration'] = result['trade_duration'].map(
lambda x: int(x.total_seconds() / 60))
# Spends, Takes, Profit, Absolute Profit
# Buy Price
result['buy_vol'] = stake / result['open_rate'] # How many target are we buying
result['buy_fee'] = stake * self.fee
result['buy_spend'] = stake + result['buy_fee'] # How much we're spending
# Sell price
result['sell_sum'] = result['buy_vol'] * result['close_rate']
result['sell_fee'] = result['sell_sum'] * self.fee
result['sell_take'] = result['sell_sum'] - result['sell_fee']
# profit_ratio
result['profit_ratio'] = (result['sell_take'] - result['buy_spend']) / result['buy_spend']
# Absolute profit
result['profit_abs'] = result['sell_take'] - result['buy_spend']
return result
def _process_expectancy(self, results: DataFrame) -> Dict[str, Any]:
"""
This calculates WinRate, Required Risk Reward, Risk Reward and Expectancy of all pairs
The calulation will be done per pair and per strategy.
"""
# Removing pairs having less than min_trades_number
min_trades_number = self.edge_config.get('min_trade_number', 10)
results = results.groupby(['pair', 'stoploss']).filter(lambda x: len(x) > min_trades_number)
###################################
# Removing outliers (Only Pumps) from the dataset
# The method to detect outliers is to calculate standard deviation
# Then every value more than (standard deviation + 2*average) is out (pump)
#
# Removing Pumps
if self.edge_config.get('remove_pumps', False):
results = results.groupby(['pair', 'stoploss']).apply(
lambda x: x[x['profit_abs'] < 2 * x['profit_abs'].std() + x['profit_abs'].mean()])
##########################################################################
# Removing trades having a duration more than X minutes (set in config)
max_trade_duration = self.edge_config.get('max_trade_duration_minute', 1440)
results = results[results.trade_duration < max_trade_duration]
#######################################################################
if results.empty:
return {}
groupby_aggregator = {
'profit_abs': [
('nb_trades', 'count'), # number of all trades
('profit_sum', lambda x: x[x > 0].sum()), # cumulative profit of all winning trades
('loss_sum', lambda x: abs(x[x < 0].sum())), # cumulative loss of all losing trades
('nb_win_trades', lambda x: x[x > 0].count()) # number of winning trades
],
'trade_duration': [('avg_trade_duration', 'mean')]
}
# Group by (pair and stoploss) by applying above aggregator
df = results.groupby(['pair', 'stoploss'])[['profit_abs', 'trade_duration']].agg(
groupby_aggregator).reset_index(col_level=1)
# Dropping level 0 as we don't need it
df.columns = df.columns.droplevel(0)
# Calculating number of losing trades, average win and average loss
df['nb_loss_trades'] = df['nb_trades'] - df['nb_win_trades']
df['average_win'] = df['profit_sum'] / df['nb_win_trades']
df['average_loss'] = df['loss_sum'] / df['nb_loss_trades']
# Win rate = number of profitable trades / number of trades
df['winrate'] = df['nb_win_trades'] / df['nb_trades']
# risk_reward_ratio = average win / average loss
df['risk_reward_ratio'] = df['average_win'] / df['average_loss']
# required_risk_reward = (1 / winrate) - 1
df['required_risk_reward'] = (1 / df['winrate']) - 1
# expectancy = (risk_reward_ratio * winrate) - (lossrate)
df['expectancy'] = (df['risk_reward_ratio'] * df['winrate']) - (1 - df['winrate'])
# sort by expectancy and stoploss
df = df.sort_values(by=['expectancy', 'stoploss'], ascending=False).groupby(
'pair').first().sort_values(by=['expectancy'], ascending=False).reset_index()
final = {}
for x in df.itertuples():
final[x.pair] = PairInfo(
x.stoploss,
x.winrate,
x.risk_reward_ratio,
x.required_risk_reward,
x.expectancy,
x.nb_trades,
x.avg_trade_duration
)
# Returning a list of pairs in order of "expectancy"
return final
def _find_trades_for_stoploss_range(self, df, pair, stoploss_range):
buy_column = df['buy'].values
sell_column = df['sell'].values
date_column = df['date'].values
ohlc_columns = df[['open', 'high', 'low', 'close']].values
result: list = []
for stoploss in stoploss_range:
result += self._detect_next_stop_or_sell_point(
buy_column, sell_column, date_column, ohlc_columns, round(stoploss, 6), pair
)
return result
def _detect_next_stop_or_sell_point(self, buy_column, sell_column, date_column,
ohlc_columns, stoploss, pair):
"""
Iterate through ohlc_columns in order to find the next trade
Next trade opens from the first buy signal noticed to
The sell or stoploss signal after it.
It then cuts OHLC, buy_column, sell_column and date_column.
Cut from (the exit trade index) + 1.
Author: https://github.com/mishaker
"""
result: list = []
start_point = 0
while True:
open_trade_index = utf1st.find_1st(buy_column, 1, utf1st.cmp_equal)
# Return empty if we don't find trade entry (i.e. buy==1) or
# we find a buy but at the end of array
if open_trade_index == -1 or open_trade_index == len(buy_column) - 1:
break
else:
# When a buy signal is seen,
# trade opens in reality on the next candle
open_trade_index += 1
open_price = ohlc_columns[open_trade_index, 0]
stop_price = (open_price * (stoploss + 1))
# Searching for the index where stoploss is hit
stop_index = utf1st.find_1st(
ohlc_columns[open_trade_index:, 2], stop_price, utf1st.cmp_smaller)
# If we don't find it then we assume stop_index will be far in future (infinite number)
if stop_index == -1:
stop_index = float('inf')
# Searching for the index where sell is hit
sell_index = utf1st.find_1st(sell_column[open_trade_index:], 1, utf1st.cmp_equal)
# If we don't find it then we assume sell_index will be far in future (infinite number)
if sell_index == -1:
sell_index = float('inf')
# Check if we don't find any stop or sell point (in that case trade remains open)
# It is not interesting for Edge to consider it so we simply ignore the trade
# And stop iterating there is no more entry
if stop_index == sell_index == float('inf'):
break
if stop_index <= sell_index:
exit_index = open_trade_index + stop_index
exit_type = SellType.STOP_LOSS
exit_price = stop_price
elif stop_index > sell_index:
# If exit is SELL then we exit at the next candle
exit_index = open_trade_index + sell_index + 1
# Check if we have the next candle
if len(ohlc_columns) - 1 < exit_index:
break
exit_type = SellType.SELL_SIGNAL
exit_price = ohlc_columns[exit_index, 0]
trade = {'pair': pair,
'stoploss': stoploss,
'profit_ratio': '',
'profit_abs': '',
'open_time': date_column[open_trade_index],
'close_time': date_column[exit_index],
'open_index': start_point + open_trade_index,
'close_index': start_point + exit_index,
'trade_duration': '',
'open_rate': round(open_price, 15),
'close_rate': round(exit_price, 15),
'exit_type': exit_type
}
result.append(trade)
# Giving a view of exit_index till the end of array
buy_column = buy_column[exit_index:]
sell_column = sell_column[exit_index:]
date_column = date_column[exit_index:]
ohlc_columns = ohlc_columns[exit_index:]
start_point += exit_index
return result

52
freqtrade/exceptions.py Normal file
View File

@@ -0,0 +1,52 @@
class FreqtradeException(Exception):
"""
Freqtrade base exception. Handled at the outermost level.
All other exception types are subclasses of this exception type.
"""
class OperationalException(FreqtradeException):
"""
Requires manual intervention and will stop the bot.
Most of the time, this is caused by an invalid Configuration.
"""
class DependencyException(FreqtradeException):
"""
Indicates that an assumed dependency is not met.
This could happen when there is currently not enough money on the account.
"""
class PricingError(DependencyException):
"""
Subclass of DependencyException.
Indicates that the price could not be determined.
Implicitly a buy / sell operation.
"""
class InvalidOrderException(FreqtradeException):
"""
This is returned when the order is not valid. Example:
If stoploss on exchange order is hit, then trying to cancel the order
should return this exception.
"""
class TemporaryError(FreqtradeException):
"""
Temporary network or exchange related error.
This could happen when an exchange is congested, unavailable, or the user
has networking problems. Usually resolves itself after a time.
"""
class StrategyError(FreqtradeException):
"""
Errors with custom user-code deteced.
Usually caused by errors in the strategy.
"""

View File

@@ -1,16 +1,20 @@
from freqtrade.exchange.exchange import Exchange, MAP_EXCHANGE_CHILDCLASS # noqa: F401
from freqtrade.exchange.exchange import (get_exchange_bad_reason, # noqa: F401
# flake8: noqa: F401
from freqtrade.exchange.common import MAP_EXCHANGE_CHILDCLASS
from freqtrade.exchange.exchange import Exchange
from freqtrade.exchange.exchange import (get_exchange_bad_reason,
is_exchange_bad,
is_exchange_known_ccxt,
is_exchange_officially_supported,
ccxt_exchanges,
available_exchanges)
from freqtrade.exchange.exchange import (timeframe_to_seconds, # noqa: F401
from freqtrade.exchange.exchange import (timeframe_to_seconds,
timeframe_to_minutes,
timeframe_to_msecs,
timeframe_to_next_date,
timeframe_to_prev_date)
from freqtrade.exchange.exchange import (market_is_active, # noqa: F401
from freqtrade.exchange.exchange import (market_is_active,
symbol_is_pair)
from freqtrade.exchange.kraken import Kraken # noqa: F401
from freqtrade.exchange.binance import Binance # noqa: F401
from freqtrade.exchange.kraken import Kraken
from freqtrade.exchange.binance import Binance
from freqtrade.exchange.bibox import Bibox
from freqtrade.exchange.ftx import Ftx

View File

@@ -0,0 +1,22 @@
""" Bibox exchange subclass """
import logging
from typing import Dict
from freqtrade.exchange import Exchange
logger = logging.getLogger(__name__)
class Bibox(Exchange):
"""
Bibox exchange class. Contains adjustments needed for Freqtrade to work
with this exchange.
Please note that this exchange is not included in the list of exchanges
officially supported by the Freqtrade development team. So some features
may still not work as expected.
"""
# fetchCurrencies API point requires authentication for Bibox,
# so switch it off for Freqtrade load_markets()
_ccxt_config: Dict = {"has": {"fetchCurrencies": False}}

View File

@@ -4,8 +4,8 @@ from typing import Dict
import ccxt
from freqtrade import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exceptions import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange import Exchange
logger = logging.getLogger(__name__)
@@ -20,7 +20,7 @@ class Binance(Exchange):
"trades_pagination_arg": "fromId",
}
def get_order_book(self, pair: str, limit: int = 100) -> dict:
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict:
"""
get order book level 2 from exchange
@@ -30,18 +30,28 @@ class Binance(Exchange):
# get next-higher step in the limit_range list
limit = min(list(filter(lambda x: limit <= x, limit_range)))
return super().get_order_book(pair, limit)
return super().fetch_l2_order_book(pair, limit)
def stoploss_limit(self, pair: str, amount: float, stop_price: float, rate: float) -> Dict:
def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool:
"""
Verify stop_loss against stoploss-order value (limit or price)
Returns True if adjustment is necessary.
"""
return order['type'] == 'stop_loss_limit' and stop_loss > float(order['info']['stopPrice'])
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
"""
creates a stoploss limit order.
this stoploss-limit is binance-specific.
It may work with a limited number of other exchanges, but this has not been tested yet.
"""
# Limit price threshold: As limit price should always be below stop-price
limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99)
rate = stop_price * limit_price_pct
ordertype = "stop_loss_limit"
stop_price = self.symbol_price_prec(pair, stop_price)
stop_price = self.price_to_precision(pair, stop_price)
# Ensure rate is less than stop price
if stop_price <= rate:
@@ -57,12 +67,12 @@ class Binance(Exchange):
params = self._params.copy()
params.update({'stopPrice': stop_price})
amount = self.symbol_amount_prec(pair, amount)
amount = self.amount_to_precision(pair, amount)
rate = self.symbol_price_prec(pair, rate)
rate = self.price_to_precision(pair, rate)
order = self._api.create_order(pair, ordertype, 'sell',
amount, rate, params)
order = self._api.create_order(symbol=pair, type=ordertype, side='sell',
amount=amount, price=rate, params=params)
logger.info('stoploss limit order added for %s. '
'stop price: %s. limit: %s', pair, stop_price, rate)
return order

View File

@@ -0,0 +1,124 @@
import logging
from freqtrade.exceptions import TemporaryError
logger = logging.getLogger(__name__)
API_RETRY_COUNT = 4
BAD_EXCHANGES = {
"bitmex": "Various reasons.",
"bitstamp": "Does not provide history. "
"Details in https://github.com/freqtrade/freqtrade/issues/1983",
"hitbtc": "This API cannot be used with Freqtrade. "
"Use `hitbtc2` exchange id to access this exchange.",
**dict.fromkeys([
'adara',
'anxpro',
'bigone',
'coinbase',
'coinexchange',
'coinmarketcap',
'lykke',
'xbtce',
], "Does not provide timeframes. ccxt fetchOHLCV: False"),
**dict.fromkeys([
'bcex',
'bit2c',
'bitbay',
'bitflyer',
'bitforex',
'bithumb',
'bitso',
'bitstamp1',
'bl3p',
'braziliex',
'btcbox',
'btcchina',
'btctradeim',
'btctradeua',
'bxinth',
'chilebit',
'coincheck',
'coinegg',
'coinfalcon',
'coinfloor',
'coingi',
'coinmate',
'coinone',
'coinspot',
'coolcoin',
'crypton',
'deribit',
'exmo',
'exx',
'flowbtc',
'foxbit',
'fybse',
# 'hitbtc',
'ice3x',
'independentreserve',
'indodax',
'itbit',
'lakebtc',
'latoken',
'liquid',
'livecoin',
'luno',
'mixcoins',
'negociecoins',
'nova',
'paymium',
'southxchange',
'stronghold',
'surbitcoin',
'therock',
'tidex',
'vaultoro',
'vbtc',
'virwox',
'yobit',
'zaif',
], "Does not provide timeframes. ccxt fetchOHLCV: emulated"),
}
MAP_EXCHANGE_CHILDCLASS = {
'binanceus': 'binance',
'binanceje': 'binance',
}
def retrier_async(f):
async def wrapper(*args, **kwargs):
count = kwargs.pop('count', API_RETRY_COUNT)
try:
return await f(*args, **kwargs)
except TemporaryError as ex:
logger.warning('%s() returned exception: "%s"', f.__name__, ex)
if count > 0:
count -= 1
kwargs.update({'count': count})
logger.warning('retrying %s() still for %s times', f.__name__, count)
return await wrapper(*args, **kwargs)
else:
logger.warning('Giving up retrying: %s()', f.__name__)
raise ex
return wrapper
def retrier(f):
def wrapper(*args, **kwargs):
count = kwargs.pop('count', API_RETRY_COUNT)
try:
return f(*args, **kwargs)
except TemporaryError as ex:
logger.warning('%s() returned exception: "%s"', f.__name__, ex)
if count > 0:
count -= 1
kwargs.update({'count': count})
logger.warning('retrying %s() still for %s times', f.__name__, count)
return wrapper(*args, **kwargs)
else:
logger.warning('Giving up retrying: %s()', f.__name__)
raise ex
return wrapper

File diff suppressed because it is too large Load Diff

14
freqtrade/exchange/ftx.py Normal file
View File

@@ -0,0 +1,14 @@
""" FTX exchange subclass """
import logging
from typing import Dict
from freqtrade.exchange import Exchange
logger = logging.getLogger(__name__)
class Ftx(Exchange):
_ft_has: Dict = {
"ohlcv_candle_limit": 1500,
}

View File

@@ -4,9 +4,10 @@ from typing import Dict
import ccxt
from freqtrade import OperationalException, TemporaryError
from freqtrade.exceptions import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange import Exchange
from freqtrade.exchange.exchange import retrier
from freqtrade.exchange.common import retrier
logger = logging.getLogger(__name__)
@@ -15,6 +16,7 @@ class Kraken(Exchange):
_params: Dict = {"trading_agreement": "agree"}
_ft_has: Dict = {
"stoploss_on_exchange": True,
"trades_pagination": "id",
"trades_pagination_arg": "since",
}
@@ -48,3 +50,51 @@ class Kraken(Exchange):
f'Could not get balance due to {e.__class__.__name__}. Message: {e}') from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool:
"""
Verify stop_loss against stoploss-order value (limit or price)
Returns True if adjustment is necessary.
"""
return order['type'] == 'stop-loss' and stop_loss > float(order['price'])
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
"""
Creates a stoploss market order.
Stoploss market orders is the only stoploss type supported by kraken.
"""
ordertype = "stop-loss"
stop_price = self.price_to_precision(pair, stop_price)
if self._config['dry_run']:
dry_order = self.dry_run_order(
pair, ordertype, "sell", amount, stop_price)
return dry_order
try:
params = self._params.copy()
amount = self.amount_to_precision(pair, amount)
order = self._api.create_order(symbol=pair, type=ordertype, side='sell',
amount=amount, price=stop_price, params=params)
logger.info('stoploss order added for %s. '
'stop price: %s.', pair, stop_price)
return order
except ccxt.InsufficientFunds as e:
raise DependencyException(
f'Insufficient funds to create {ordertype} sell order on market {pair}.'
f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
f'Message: {e}') from e
except ccxt.InvalidOrder as e:
raise InvalidOrderException(
f'Could not create {ordertype} sell order on market {pair}. '
f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
f'Message: {e}') from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not place sell order due to {e.__class__.__name__}. Message: {e}') from e
except ccxt.BaseError as e:
raise OperationalException(e) from e

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