Compare commits

...

1122 Commits

Author SHA1 Message Date
Matthias
ab7807cee5 Merge pull request #4004 from freqtrade/new_release
New release 2020.11
2020-11-27 17:11:29 +01:00
Matthias
1353c59f18 Version bump to 2020.11 2020-11-27 11:24:14 +01:00
Matthias
5d038552ae Merge branch 'stable' into new_release 2020-11-27 11:18:42 +01:00
Matthias
22ff67c8f8 Merge pull request #4002 from mrsegen/patch-3
[Documentation] Prevent unintended LaTeX rendering
2020-11-27 08:06:47 +01:00
Matthias
31449987c0 Fix mkdocs rendering 2020-11-27 07:35:12 +01:00
Matthias
cff0527919 Merge pull request #4001 from mrsegen/patch-2
[Documentation] Fix parameter name
2020-11-27 07:00:30 +01:00
Leif Segen
fce31447ed Prevent unintended LaTeX rendering 2020-11-26 19:38:20 -06:00
Leif Segen
98118f5e95 Fix parameter name
Correct which parameter name was referred to within the 2nd Note under "Amend last stake amount"
2020-11-26 18:46:36 -06:00
Matthias
dddbc799f9 have kraken stoploss-limit support trailing stop 2020-11-26 19:40:36 +01:00
Matthias
83f6259594 Merge pull request #3999 from hoeckxer/documentation_typo
Fixed a small typo in the pairlist documentation
2020-11-26 11:21:48 +01:00
hoeckxer
0b68402c10 Fixed a small typo in the pairlist documentation
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2020-11-26 10:24:48 +01:00
Matthias
1d56c87a34 Fully support kraken limit stoploss 2020-11-25 21:40:39 +01:00
Matthias
53231d94a9 Merge pull request #3975 from freqtrade/volatility_filter
RangeStabilityFilter filter - filter for pairs without much movement
2020-11-25 19:17:06 +01:00
Matthias
76539bc700 Merge pull request #3997 from freqtrade/kraken_limitsl
Kraken stoploss-limit
2020-11-25 16:58:34 +01:00
Matthias
d0d9921b42 Reorder mkdocs sequence 2020-11-25 16:27:41 +01:00
Matthias
c14c0f60a1 Add Support for kraken stoploss-limit 2020-11-25 16:27:27 +01:00
Matthias
8180393bbc Merge branch 'develop' into kraken_limitsl 2020-11-25 16:04:33 +01:00
Matthias
7f621416a1 Merge pull request #3996 from freqtrade/fix/doublelog
Fix/doublelog
2020-11-25 15:22:37 +01:00
Matthias
6810192992 Update docstring for new filter 2020-11-25 15:14:36 +01:00
Matthias
8ae604d473 Ensure we're not running off of empty dataframes 2020-11-25 15:14:36 +01:00
Matthias
0d349cb355 Small finetuning 2020-11-25 15:14:36 +01:00
Matthias
8f1d2ff070 Renamd volatilityFilter to RangeStabilityFilter 2020-11-25 15:14:29 +01:00
Matthias
46389e343b Skip filehandler test on windows - as that causes a permission-error 2020-11-25 15:10:17 +01:00
Matthias
b9980330a5 Add explicit test for FileHandler 2020-11-25 14:58:09 +01:00
Matthias
0104c9fde6 Fix double logging 2020-11-25 14:31:34 +01:00
Matthias
99b67348b2 Add test for double-logging 2020-11-25 14:30:58 +01:00
Matthias
ceb50a7807 use exception handler when downloading data
closes #3992
2020-11-25 07:57:27 +01:00
Matthias
bd98ff6332 Update docstring in all pairlists 2020-11-24 20:24:51 +01:00
Matthias
006436a18d Require use_sell_signal to be true for edge
Otherwise edge will have strange results, as
edge runs with sell signal, while the bot runs without sell signal,
causing results to be invalid

closes #3900
2020-11-24 07:47:35 +01:00
Matthias
730c9ce471 Add Max_open_trades to summary metrics 2020-11-24 06:57:26 +01:00
Matthias
82335027b7 Merge pull request #3979 from freqtrade/dependabot/pip/develop/aiohttp-3.7.3
Bump aiohttp from 3.7.2 to 3.7.3
2020-11-23 10:30:51 +01:00
dependabot[bot]
1ec99e6b76 Bump aiohttp from 3.7.2 to 3.7.3
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.7.2 to 3.7.3.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.7.2...v3.7.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-23 08:05:45 +00:00
Matthias
d325236f96 Merge pull request #3981 from freqtrade/dependabot/pip/develop/questionary-1.8.1
Bump questionary from 1.8.0 to 1.8.1
2020-11-23 07:44:12 +01:00
Matthias
421265243c Merge pull request #3978 from freqtrade/dependabot/pip/develop/ccxt-1.38.13
Bump ccxt from 1.37.69 to 1.38.13
2020-11-23 07:43:20 +01:00
Matthias
16899b9df1 Merge pull request #3983 from freqtrade/dependabot/pip/develop/coveralls-2.2.0
Bump coveralls from 2.1.2 to 2.2.0
2020-11-23 07:37:36 +01:00
Matthias
9427b5e924 Merge pull request #3982 from freqtrade/dependabot/pip/develop/python-rapidjson-0.9.4
Bump python-rapidjson from 0.9.3 to 0.9.4
2020-11-23 07:37:03 +01:00
Matthias
87a34b4306 Merge pull request #3980 from freqtrade/dependabot/pip/develop/mkdocs-material-6.1.6
Bump mkdocs-material from 6.1.5 to 6.1.6
2020-11-23 07:36:32 +01:00
dependabot[bot]
56629d882e Bump coveralls from 2.1.2 to 2.2.0
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 2.1.2 to 2.2.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/2.1.2...2.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-23 05:51:03 +00:00
dependabot[bot]
7c7a8190ab Bump python-rapidjson from 0.9.3 to 0.9.4
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 0.9.3 to 0.9.4.
- [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.9.3...v0.9.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-23 05:50:54 +00:00
dependabot[bot]
be4807d85c Bump questionary from 1.8.0 to 1.8.1
Bumps [questionary](https://github.com/tmbo/questionary) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/tmbo/questionary/releases)
- [Commits](https://github.com/tmbo/questionary/compare/1.8.0...1.8.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-23 05:50:52 +00:00
dependabot[bot]
83b4cd7b39 Bump mkdocs-material from 6.1.5 to 6.1.6
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.5 to 6.1.6.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.5...6.1.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-23 05:50:51 +00:00
dependabot[bot]
ec33011255 Bump ccxt from 1.37.69 to 1.38.13
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.37.69 to 1.38.13.
- [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.37.69...1.38.13)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-23 05:50:43 +00:00
Matthias
29c6a9263d Protect against 0 values 2020-11-22 15:50:44 +01:00
Matthias
7e4fe23bf9 Add VolatilityFilter to full config 2020-11-22 11:08:01 +01:00
Matthias
f12a8afd41 Add test for ohlcv_as_df 2020-11-22 10:56:19 +01:00
Matthias
2e1551a2eb Improve tests of volatilityfilter 2020-11-21 19:57:17 +01:00
Matthias
f8fab5c4f8 Add tests for failure cases 2020-11-21 15:51:39 +01:00
Matthias
6b672cd0b9 Document volatilityFilter 2020-11-21 15:43:29 +01:00
Matthias
191616e4e5 Add first tests for volatilityFilter 2020-11-21 15:39:04 +01:00
Matthias
109824c9a8 Add VolatilityFilter 2020-11-21 15:39:00 +01:00
Matthias
fb86d8f8ff Add get_historic_ohlcv_as_df to support VolatilityFilter 2020-11-21 15:28:50 +01:00
Matthias
73f0e6e704 Improve wording for discord server
fix link to correct docker install guide
2020-11-21 11:40:28 +01:00
Matthias
4d60a4cf4e Add warning to StochRSI in sample strategy
closes #2961
2020-11-21 11:32:46 +01:00
Matthias
8ffd6f2469 Merge pull request #3971 from freqtrade/fix/3967
Fix bug when converting trades do ohlcv and no trades are available.
2020-11-21 11:14:30 +01:00
Matthias
89ea8dbef2 Update slack invite 2020-11-21 11:13:44 +01:00
Matthias
e8e3ca0c3c Catch ValueError from trade_conversion
closes #3967
2020-11-21 10:57:19 +01:00
Matthias
83861fabde Fix #3967, move TradeList type to constants 2020-11-21 10:52:15 +01:00
Matthias
5ed85963a9 Allow forcebuy price to be a string by converting it to float
fix #3970
2020-11-21 10:39:49 +01:00
Matthias
aa0c3dced8 Improve order types documentation 2020-11-20 13:14:02 +01:00
Matthias
fa0fcfb492 Merge pull request #3939 from drdux/historic-pair
Historic pair
2020-11-19 19:46:08 +01:00
Matthias
97e58a42f4 Update documentation with new options 2020-11-19 19:17:31 +01:00
Matthias
f88fe5d950 Document new "allow_inactive" option 2020-11-19 19:14:43 +01:00
Matthias
37849f8496 Merge pull request #3965 from freqtrade/fix_hdf5trades
Convert np to None when loading hdf5 trades to allow duplicate detection
2020-11-19 11:22:25 +01:00
Matthias
52c9a2c37f Convert np to None when loading hdf5 trades to allow duplicate detection 2020-11-19 07:31:54 +01:00
Matthias
bf6682d37f Merge pull request #3962 from Samaoo/patch-2
Fix typo in windows installation docs
2020-11-17 14:49:04 +01:00
Samaoo
854d0c481f Update windows_installation.md 2020-11-17 14:14:42 +01:00
Samaoo
4a215821cd Fix typo in windows installation docs 2020-11-17 14:07:24 +01:00
Matthias
9621734adc Allow setting datafromat via configuration
closes #3953
2020-11-17 06:53:38 +01:00
Matthias
853bd06841 Merge pull request #3959 from freqtrade/dependabot/pip/develop/ccxt-1.37.69
Bump ccxt from 1.37.41 to 1.37.69
2020-11-16 11:02:53 +01:00
dependabot[bot]
3f2addb729 Bump ccxt from 1.37.41 to 1.37.69
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.37.41 to 1.37.69.
- [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.37.41...1.37.69)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 09:17:22 +00:00
Matthias
320dca19cb Merge pull request #3956 from freqtrade/dependabot/pip/develop/urllib3-1.26.2
Bump urllib3 from 1.25.11 to 1.26.2
2020-11-16 10:16:37 +01:00
dependabot[bot]
f092a92399 Bump urllib3 from 1.25.11 to 1.26.2
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.11 to 1.26.2.
- [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.11...1.26.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 07:51:10 +00:00
Matthias
d00a955af9 Merge pull request #3958 from freqtrade/dependabot/pip/develop/requests-2.25.0
Bump requests from 2.24.0 to 2.25.0
2020-11-16 07:33:39 +01:00
Matthias
d6bd018da4 Merge pull request #3957 from freqtrade/dependabot/pip/develop/flask-jwt-extended-3.25.0
Bump flask-jwt-extended from 3.24.1 to 3.25.0
2020-11-16 07:10:17 +01:00
Matthias
8c88173b74 Merge pull request #3955 from freqtrade/dependabot/pip/develop/mkdocs-material-6.1.5
Bump mkdocs-material from 6.1.4 to 6.1.5
2020-11-16 07:02:54 +01:00
dependabot[bot]
23947cf30b Bump requests from 2.24.0 to 2.25.0
Bumps [requests](https://github.com/psf/requests) from 2.24.0 to 2.25.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.24.0...v2.25.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 05:40:50 +00:00
dependabot[bot]
e52c181a2a Bump flask-jwt-extended from 3.24.1 to 3.25.0
Bumps [flask-jwt-extended](https://github.com/vimalloc/flask-jwt-extended) from 3.24.1 to 3.25.0.
- [Release notes](https://github.com/vimalloc/flask-jwt-extended/releases)
- [Commits](https://github.com/vimalloc/flask-jwt-extended/compare/3.24.1...3.25.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 05:40:35 +00:00
dependabot[bot]
6ebc2f3897 Bump mkdocs-material from 6.1.4 to 6.1.5
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.4 to 6.1.5.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.4...6.1.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 05:40:25 +00:00
Samaoo
ef4ab601a9 Update exchanges.md 2020-11-15 20:02:19 +01:00
Samaoo
26176d4c91 Update exchanges.md
According to 
https://blog.kraken.com/post/5282/stop-loss-limit-take-profit-limit-two-new-advanced-orders-go-live-on-kraken/
Stop Loss Limit orders are enabled again
2020-11-15 19:55:09 +01:00
Matthias
0612658ec7 Merge pull request #3952 from Samaoo/patch-1
Fix typo in windows installation docs
2020-11-15 15:56:20 +01:00
Matthias
34120f6eb8 Merge pull request #3950 from xsa-dev/patch-1
Update telegram-usage.md
2020-11-15 15:52:50 +01:00
Matthias
7b4c1ec3ce Small wording changes 2020-11-15 15:40:40 +01:00
Aleksey Savin
da16474b25 Update telegram-usage.md 2020-11-15 15:13:44 +03:00
SamVerhaegen
7243c8ee56 Fix typo in windows installation docs. 2020-11-15 13:06:05 +01:00
Matthias
ab85c5bb49 Merge pull request #3946 from freqtrade/plot_startup_candles
Plot startup candles
2020-11-14 19:28:38 +01:00
Matthias
05f0cc787c Plotting should use startup_candles too
closes #3943
2020-11-14 09:28:00 +01:00
Matthias
164105acf2 Adjust startup_candle_count of sample strategies 2020-11-14 08:25:57 +01:00
Matthias
c09b641860 Merge pull request #3944 from freqtrade/fix_aioexception
Catch asyncio.TimeoutError when reloading async markets
2020-11-13 16:04:14 +01:00
Matthias
08b52926c8 Catch asyncio.TimeoutError when reloading async markets 2020-11-13 10:43:48 +01:00
Matthias
4eb96cfc4f Allow locks to be gathered even when the bot is stopped 2020-11-13 06:51:45 +01:00
Daniel Goller
2d6bfe1592 only skip pair validation rather than all of it 2020-11-12 11:32:45 +00:00
Daniel Goller
2424ac94c2 skip the check for active markets with flag for existing StaticPairList 2020-11-12 11:29:46 +00:00
Daniel Goller
2640dfee93 Revert "Added ConstPairList handler to skip validation of pairs if you want to backtest a pair that's not live any more, e.g. expiring contracts."
This reverts commit 13da8f9368.
2020-11-12 11:27:30 +00:00
Daniel Goller
916776bb53 Option to skip exchange validation, required to backtest pairs that are not live on the exchange any more. 2020-11-09 08:37:38 +00:00
Daniel Goller
13da8f9368 Added ConstPairList handler to skip validation of pairs if you want to backtest a pair that's not live any more, e.g. expiring contracts. 2020-11-09 08:34:40 +00:00
Matthias
5f483acdd0 Merge pull request #3938 from freqtrade/dependabot/pip/develop/ccxt-1.37.41
Bump ccxt from 1.37.14 to 1.37.41
2020-11-09 09:03:31 +01:00
dependabot[bot]
59e846d554 Bump ccxt from 1.37.14 to 1.37.41
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.37.14 to 1.37.41.
- [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.37.14...1.37.41)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-09 07:48:14 +00:00
Matthias
4bc693c17c Merge pull request #3935 from freqtrade/dependabot/pip/develop/questionary-1.8.0
Bump questionary from 1.7.0 to 1.8.0
2020-11-09 07:27:49 +01:00
Matthias
d85fd3060a Merge pull request #3936 from freqtrade/dependabot/pip/develop/scipy-1.5.4
Bump scipy from 1.5.3 to 1.5.4
2020-11-09 07:03:35 +01:00
Matthias
52c147c88e Merge pull request #3934 from freqtrade/dependabot/pip/develop/numpy-1.19.4
Bump numpy from 1.19.3 to 1.19.4
2020-11-09 07:02:56 +01:00
Matthias
2a1835b165 Merge pull request #3933 from freqtrade/dependabot/pip/develop/mkdocs-material-6.1.4
Bump mkdocs-material from 6.1.2 to 6.1.4
2020-11-09 07:02:22 +01:00
dependabot[bot]
88b2f3f0d1 Bump scipy from 1.5.3 to 1.5.4
Bumps [scipy](https://github.com/scipy/scipy) from 1.5.3 to 1.5.4.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.5.3...v1.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-09 05:44:51 +00:00
dependabot[bot]
6063f2f91f Bump questionary from 1.7.0 to 1.8.0
Bumps [questionary](https://github.com/tmbo/questionary) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/tmbo/questionary/releases)
- [Commits](https://github.com/tmbo/questionary/compare/1.7.0...1.8.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-09 05:44:49 +00:00
dependabot[bot]
42d9e3a28f Bump numpy from 1.19.3 to 1.19.4
Bumps [numpy](https://github.com/numpy/numpy) from 1.19.3 to 1.19.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.19.3...v1.19.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-09 05:44:40 +00:00
dependabot[bot]
5243214a36 Bump mkdocs-material from 6.1.2 to 6.1.4
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.2 to 6.1.4.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.2...6.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-09 05:44:29 +00:00
Matthias
2af1c80fd5 Convert _rpc_show_config to static method 2020-11-08 11:26:02 +01:00
Matthias
b8f6f09de8 Merge pull request #3923 from freqtrade/rpc/combine_profit_fields
Rpc/combine profit fields
2020-11-03 19:22:27 +01:00
Matthias
7d2bd00f0c Update forgotten arrow.timestamp occurance 2020-11-03 09:23:07 +01:00
Matthias
b58d6d38b5 Use correct fields in telegram 2020-11-03 08:59:11 +01:00
Matthias
d1dab23283 Remove deprecated api fields 2020-11-03 08:59:11 +01:00
Matthias
cf89a773da Standardize trade api outputs
there should be no difference between current_profit and close_profit
 it's always profit, and the information if it's a closed trade is available elsewhere
2020-11-03 08:58:57 +01:00
Matthias
887d78171c Merge pull request #3857 from freqtrade/arrow_deprecation_timestamp
Convert timestamp to int_timestamp for all arrow occurances
2020-11-02 16:40:43 +01:00
Matthias
ac55215fca Merge pull request #3921 from freqtrade/dependabot/pip/develop/ccxt-1.37.14
Bump ccxt from 1.36.85 to 1.37.14
2020-11-02 15:39:03 +01:00
dependabot[bot]
d56da41679 Bump ccxt from 1.36.85 to 1.37.14
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.36.85 to 1.37.14.
- [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.36.85...1.37.14)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 13:50:07 +00:00
Matthias
894853b300 Merge pull request #3917 from freqtrade/dependabot/pip/develop/aiohttp-3.7.2
Bump aiohttp from 3.7.1 to 3.7.2
2020-11-02 14:49:25 +01:00
dependabot[bot]
74d8a985e2 Bump aiohttp from 3.7.1 to 3.7.2
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.7.1 to 3.7.2.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.7.1...v3.7.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 08:44:26 +00:00
Matthias
7e64a91720 Merge pull request #3919 from freqtrade/dependabot/pip/develop/pandas-1.1.4
Bump pandas from 1.1.3 to 1.1.4
2020-11-02 09:43:29 +01:00
dependabot[bot]
aed44ef6b3 Bump pandas from 1.1.3 to 1.1.4
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.1.3 to 1.1.4.
- [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.1.3...v1.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 07:46:28 +00:00
Matthias
a8c6c3e2fa Merge pull request #3920 from freqtrade/dependabot/pip/develop/pytest-6.1.2
Bump pytest from 6.1.1 to 6.1.2
2020-11-02 07:30:43 +01:00
Matthias
8cbc2ce18d Merge pull request #3916 from freqtrade/dependabot/pip/develop/numpy-1.19.3
Bump numpy from 1.19.2 to 1.19.3
2020-11-02 07:30:06 +01:00
Matthias
a87fd6fcc7 Merge pull request #3918 from freqtrade/dependabot/pip/develop/mkdocs-material-6.1.2
Bump mkdocs-material from 6.1.0 to 6.1.2
2020-11-02 07:29:31 +01:00
dependabot[bot]
21b22760a7 Bump pytest from 6.1.1 to 6.1.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.1.1 to 6.1.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/6.1.1...6.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 05:55:12 +00:00
dependabot[bot]
6c3753ac7f Bump mkdocs-material from 6.1.0 to 6.1.2
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.0 to 6.1.2.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.0...6.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 05:55:07 +00:00
dependabot[bot]
81fb0c5726 Bump numpy from 1.19.2 to 1.19.3
Bumps [numpy](https://github.com/numpy/numpy) from 1.19.2 to 1.19.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.19.2...v1.19.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 05:54:57 +00:00
Matthias
16572f90e3 Merge pull request #3913 from freqtrade/fix/dmmp
FIx bug with dmmp
2020-11-01 12:48:34 +01:00
Matthias
e73203acb8 FIx bug with dmmp 2020-11-01 10:51:07 +01:00
Matthias
a262618809 Merge pull request #3910 from matspi/dataformat-informative-pair
Dataformat informative pair
2020-10-31 15:47:40 +01:00
Matthias Spiller
0d11f0bd75 Add unit test for hdf5 dataformat for informative pairs 2020-10-31 11:45:46 +00:00
Matthias Spiller
78874fa865 informative_pairs does not honor dataformat 2020-10-31 10:53:51 +00:00
Matthias Spiller
38fc5d680b Enable usage of devcontainer for macOS users 2020-10-31 10:31:58 +00:00
Matthias
4d4471480b Merge pull request #3905 from freqtrade/new_release
New release 2020.10
2020-10-30 20:15:57 +01:00
Matthias
aaa6468983 Version bump to 2020.10 2020-10-30 07:48:05 +01:00
Matthias
55838b574c Merge branch 'stable' into new_release 2020-10-30 07:47:47 +01:00
Matthias
684de9c7d0 Merge pull request #3903 from freqtrade/download_data_stake
Download data remove stake_currency
2020-10-29 09:15:46 +01:00
Matthias
3ca97223f2 Improve test for test_pairlist 2020-10-29 08:09:50 +01:00
Matthias
d8ff79a2fa Improve tests of list commands 2020-10-29 07:54:42 +01:00
Matthias
f4d39f2a12 Improve test coverage of deploy_commands 2020-10-29 07:44:03 +01:00
Matthias
19fcbc92a7 Remove stake-currency for download-data - it's not needed 2020-10-29 07:43:40 +01:00
Matthias
0539bd5280 Merge pull request #3899 from freqtrade/improve_hyperopt_tests
Improve and refactor hyperopt tests
2020-10-28 19:35:41 +01:00
Matthias
86725847ed Add explicit test for check_int_nonzero 2020-10-28 16:58:39 +01:00
Matthias
ffa6797958 Improve test coverage 2020-10-28 16:29:08 +01:00
Matthias
e1e2829ef3 Improve and refactor hyperopt tests 2020-10-28 14:49:25 +01:00
Matthias
8e8f328bba Merge pull request #3898 from freqtrade/improve_hyperoptloss_missing
Improve error when hyperopt-loss-function is missing
2020-10-28 09:49:00 +01:00
Matthias
5cb3735a57 Improve error when hyperopt-loss-function is missing 2020-10-28 07:58:55 +01:00
Matthias
28d6c3419b Fix random test failure in pairlocks 2020-10-27 20:01:23 +01:00
Matthias
58a92dc3da Merge pull request #3895 from freqtrade/pairlock/middleware
Pairlock middleware
2020-10-27 19:44:13 +01:00
Matthias
72f61f4682 Remove optional, now is not optional 2020-10-27 10:08:24 +01:00
Matthias
5c8779b155 Sort imports 2020-10-27 08:11:57 +01:00
Matthias
6c913fa617 Fix locking - should round before storing to have a consistent picture 2020-10-27 08:01:31 +01:00
Matthias
9c54c9a2bf Use correct timezone for tests 2020-10-27 07:06:07 +01:00
Matthias
e602ac3406 Introduce Pairlocks middleware 2020-10-27 07:06:06 +01:00
Matthias
69e8da30e5 Ensure times that fall on a candle are also shifted 2020-10-27 07:04:04 +01:00
Matthias
09af776b66 Merge pull request #3890 from freqtrade/dependabot/pip/develop/ccxt-1.36.85
Bump ccxt from 1.36.66 to 1.36.85
2020-10-26 19:37:05 +01:00
Matthias
442e9d20e1 Remove pinned dependency of multidict 2020-10-26 16:28:08 +01:00
Matthias
835614517b Merge branch 'dependabot/pip/develop/aiohttp-3.7.1' into dependabot/pip/develop/ccxt-1.36.85 2020-10-26 16:24:54 +01:00
Matthias
0309b06b54 Merge pull request #3892 from freqtrade/dependabot/pip/develop/plotly-4.12.0
Bump plotly from 4.11.0 to 4.12.0
2020-10-26 08:22:38 +01:00
Matthias
f29b04b4d2 Merge pull request #3891 from freqtrade/dependabot/pip/develop/python-rapidjson-0.9.3
Bump python-rapidjson from 0.9.1 to 0.9.3
2020-10-26 08:22:12 +01:00
Matthias
4146b45c6e Merge pull request #3888 from freqtrade/dependabot/pip/develop/urllib3-1.25.11
Bump urllib3 from 1.25.10 to 1.25.11
2020-10-26 07:28:16 +01:00
dependabot[bot]
066ea45ce0 Bump plotly from 4.11.0 to 4.12.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.11.0 to 4.12.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.11.0...v4.12.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 05:45:39 +00:00
dependabot[bot]
95d11bd0d2 Bump python-rapidjson from 0.9.1 to 0.9.3
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 0.9.1 to 0.9.3.
- [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.9.1...v0.9.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 05:45:34 +00:00
dependabot[bot]
2831a78d0e Bump ccxt from 1.36.66 to 1.36.85
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.36.66 to 1.36.85.
- [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.36.66...1.36.85)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 05:45:33 +00:00
dependabot[bot]
df5e6aa58b Bump aiohttp from 3.6.3 to 3.7.1
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.6.3 to 3.7.1.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.6.3...v3.7.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 05:45:32 +00:00
dependabot[bot]
3439e6c5c4 Bump urllib3 from 1.25.10 to 1.25.11
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.10 to 1.25.11.
- [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.10...1.25.11)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 05:45:13 +00:00
Matthias
299dfe560a Merge pull request #3884 from freqtrade/fix/downloaddata_exception
Test if return value is an exception when downloading historic data
2020-10-23 14:27:31 +02:00
Matthias
b8c12f6576 Test if return value is an exception when downloading historic data 2020-10-23 07:50:40 +02:00
Matthias
2e7367d647 Merge pull request #3881 from apneamona/unfilledtimeout.buy/sell-addition
Update configuration.md
2020-10-22 15:18:37 +02:00
Matthias
9999017953 Fix small bug in case of duplicate locks 2020-10-22 08:04:48 +02:00
Matthias
71410a5a1e Merge pull request #3879 from freqtrade/persist_pairlocks
Persist pairlocks
2020-10-22 07:50:58 +02:00
Matthias
cd8610cb24 Update readme.md files 2020-10-22 07:50:09 +02:00
Matthias
ffcc47d8dd Cleanup sql cheatsheet 2020-10-22 07:42:47 +02:00
Matthias
cf1a726198 Rename table to be inline with other table naming 2020-10-22 07:35:59 +02:00
Matthias
a143f7bc43 Improve pairlock docstrings 2020-10-21 19:35:57 +02:00
Matthias
66efb5ccf1 Merge pull request #3880 from deeppaz/patch-1
update quick start steps
2020-10-21 19:27:01 +02:00
pure
42d9e2e7dc update quick start steps 2020-10-21 17:06:26 +03:00
Matthias
fd6018f67a Fix dependency sorting 2020-10-21 06:21:13 +02:00
Matthias
adffd402ea Replace some pointless occurances of arrow 2020-10-20 20:11:38 +02:00
Matthias
7a092271c5 Merge branch 'develop' into arrow_deprecation_timestamp 2020-10-20 20:01:54 +02:00
Matthias
5f63fdd8ad Use better lock message 2020-10-20 19:40:39 +02:00
Matthias
64e680d7ee Document new api method 2020-10-20 19:30:00 +02:00
Matthias
1156f5e686 Use constant for times 2020-10-20 19:21:13 +02:00
Matthias
0daf77f313 Don't check for lock start date 2020-10-20 19:21:13 +02:00
Matthias
cd2866eaec Add rest endpoint for /locks 2020-10-20 19:21:13 +02:00
Matthias
7a9768ffa6 Add /locks Telegram endpoint 2020-10-20 19:21:13 +02:00
Matthias
7caa6cfe31 Add tests for pairlock 2020-10-20 19:21:13 +02:00
Matthias
e513871fd5 Persist pairlocks
closes #3034
2020-10-20 19:21:13 +02:00
Matthias
6eab20e337 Use constant to format datetime 2020-10-20 19:21:13 +02:00
Matthias
2d04c2dd4f Fix small bug when cancel-order does not contain id
happens with kraken ...
2020-10-20 06:24:46 +02:00
Matthias
f6da9e358a Merge pull request #3878 from freqtrade/dependabot/pip/develop/ccxt-1.36.66
Bump ccxt from 1.36.12 to 1.36.66
2020-10-19 15:16:42 +02:00
dependabot[bot]
3e7c9bd485 Bump ccxt from 1.36.12 to 1.36.66
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.36.12 to 1.36.66.
- [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.36.12...1.36.66)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 11:57:03 +00:00
Matthias
06293b2489 Merge pull request #3875 from freqtrade/dependabot/pip/develop/questionary-1.7.0
Bump questionary from 1.6.0 to 1.7.0
2020-10-19 08:23:08 +02:00
Matthias
f799a81c44 Merge pull request #3876 from freqtrade/dependabot/pip/develop/mkdocs-material-6.1.0
Bump mkdocs-material from 6.0.2 to 6.1.0
2020-10-19 07:57:23 +02:00
Matthias
667f1b8b8c Merge pull request #3845 from freqtrade/feat/backtest_speedup_serialize
Backtesting should not double-loop for sell signals
2020-10-19 07:52:33 +02:00
Matthias
340f25bd42 Merge pull request #3874 from freqtrade/dependabot/pip/develop/scipy-1.5.3
Bump scipy from 1.5.2 to 1.5.3
2020-10-19 07:51:01 +02:00
dependabot[bot]
b7eec3fc82 Bump mkdocs-material from 6.0.2 to 6.1.0
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.0.2 to 6.1.0.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.0.2...6.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 05:37:57 +00:00
dependabot[bot]
8975558595 Bump questionary from 1.6.0 to 1.7.0
Bumps [questionary](https://github.com/tmbo/questionary) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/tmbo/questionary/releases)
- [Commits](https://github.com/tmbo/questionary/compare/1.6.0...1.7.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 05:37:54 +00:00
dependabot[bot]
7997298538 Bump scipy from 1.5.2 to 1.5.3
Bumps [scipy](https://github.com/scipy/scipy) from 1.5.2 to 1.5.3.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.5.2...v1.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 05:37:36 +00:00
Matthias
cf2ae788d7 Convert backtesting rows to Tuples for performance gains 2020-10-18 17:16:57 +02:00
Matthias
5d3a67d324 Don't debug-log during backtesting.
Even though log-messages are surpressed, calling "debug" will always
have to do something.
2020-10-18 16:38:16 +02:00
Matthias
b80a219d03 Improve typehints for backtesting 2020-10-18 16:35:23 +02:00
Matthias
380e6628e0 Merge branch 'develop' into feat/backtest_speedup_serialize 2020-10-18 16:19:04 +02:00
Matthias
2591a34db4 Don't use arrow objects for backtesting 2020-10-18 16:18:52 +02:00
Matthias
7a9208a8d7 Merge pull request #3873 from sanket-k/develop
updated discord link to documentation.
2020-10-17 15:17:29 +02:00
sanket-k
cd940daaf4 updated discord link to documentation. 2020-10-17 17:17:43 +05:30
Matthias
f64ed6b878 Merge pull request #3871 from freqtrade/persistence/renameinit
Rename persistence.init to init_db
2020-10-16 08:26:35 +02:00
Matthias
8cdc795a44 Rename persistence.init to init_db 2020-10-16 08:15:18 +02:00
Matthias
685d18940a specify min-version for arrow
int_timestamp was introduced in this version
2020-10-16 08:13:31 +02:00
Matthias
ec713ff5ae Convert _rpc_analysed_history_full to static method 2020-10-16 06:26:57 +02:00
Matthias
8ae193f638 Merge pull request #3868 from freqtrade/fix/3865
bittrex fetch_orderbook API change.
2020-10-14 20:28:04 +02:00
Matthias
07da21e633 Fix problem when limit is > max allowed limit 2020-10-13 20:38:02 +02:00
Matthias
8165cc11df Change get_next_limit_in_list to use list comprehension 2020-10-13 20:30:35 +02:00
Matthias
2ed20eee4e Configs should default to dry-run 2020-10-13 20:10:50 +02:00
Matthias
8962b6d5c9 Add Bittrex subclass to correctly handle L2 orderbook 2020-10-13 20:09:43 +02:00
Matthias
077374ac42 Implement generic solution for l2 limited limit 2020-10-13 20:02:47 +02:00
Matthias
886abe36c9 Merge pull request #3860 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.8
Bump prompt-toolkit from 3.0.7 to 3.0.8
2020-10-13 16:44:57 +02:00
Matthias
d7bbda9659 Merge pull request #3859 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.20
Bump sqlalchemy from 1.3.19 to 1.3.20
2020-10-13 16:38:06 +02:00
dependabot[bot]
6a0ab83684 Bump sqlalchemy from 1.3.19 to 1.3.20
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.19 to 1.3.20.
- [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[bot] <support@github.com>
2020-10-13 13:20:24 +00:00
Matthias
46f3ec1d0a Merge pull request #3864 from freqtrade/dependabot/pip/develop/ccxt-1.36.12
Bump ccxt from 1.36.2 to 1.36.12
2020-10-13 15:19:20 +02:00
dependabot[bot]
7c1402ef11 Bump prompt-toolkit from 3.0.7 to 3.0.8
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.7 to 3.0.8.
- [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/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 13:06:37 +00:00
Matthias
f231a08202 Merge pull request #3861 from freqtrade/dependabot/pip/develop/colorama-0.4.4
Bump colorama from 0.4.3 to 0.4.4
2020-10-13 15:05:30 +02:00
Matthias
a0718ad8cb Merge pull request #3862 from freqtrade/dependabot/pip/develop/isort-5.6.4
Bump isort from 5.6.3 to 5.6.4
2020-10-13 15:05:07 +02:00
dependabot[bot]
fd9c8df049 Bump ccxt from 1.36.2 to 1.36.12
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.36.2 to 1.36.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.36.2...1.36.12)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 12:39:47 +00:00
dependabot[bot]
5f5fc513fa Bump isort from 5.6.3 to 5.6.4
Bumps [isort](https://github.com/pycqa/isort) from 5.6.3 to 5.6.4.
- [Release notes](https://github.com/pycqa/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/pycqa/isort/compare/5.6.3...5.6.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 12:39:35 +00:00
dependabot[bot]
43532a2ffa Bump colorama from 0.4.3 to 0.4.4
Bumps [colorama](https://github.com/tartley/colorama) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/tartley/colorama/releases)
- [Changelog](https://github.com/tartley/colorama/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tartley/colorama/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 12:39:31 +00:00
Matthias
ecddaa663b Convert timestamp to int_timestamp for all arrow occurances 2020-10-13 06:24:01 +02:00
Matthias
5f0d1d609e Merge pull request #3855 from freqtrade/dependabot/pip/develop/python-telegram-bot-13.0
Bump python-telegram-bot from 12.8 to 13.0
2020-10-13 06:23:15 +02:00
Matthias
0b0b9c5d45 Merge branch 'develop' into dependabot/pip/develop/python-telegram-bot-13.0 2020-10-13 06:12:35 +02:00
Matthias
10651599dd Merge pull request #3854 from freqtrade/dependabot/pip/develop/mypy-0.790
Bump mypy from 0.782 to 0.790
2020-10-12 20:25:01 +02:00
Matthias
2a383f8785 Merge branch 'develop' into dependabot/pip/develop/mypy-0.790 2020-10-12 20:11:41 +02:00
Matthias
5aa0d3e05c Add multidict and aiohttp requirements 2020-10-12 20:08:40 +02:00
Matthias
a39898a5b3 Fix mock for telegram update 2020-10-12 19:54:31 +02:00
Matthias
44e374878c Fix mypy errors due to new version 2020-10-12 19:28:14 +02:00
dependabot[bot]
f299c4188b Bump python-telegram-bot from 12.8 to 13.0
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 12.8 to 13.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.8...v13.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 08:13:28 +00:00
Matthias
38cbf2f902 Merge pull request #3852 from freqtrade/dependabot/pip/develop/isort-5.6.3
Bump isort from 5.5.4 to 5.6.3
2020-10-12 10:12:56 +02:00
Matthias
94bc5356b7 Merge pull request #3856 from freqtrade/dependabot/pip/develop/ccxt-1.36.2
Bump ccxt from 1.35.22 to 1.36.2
2020-10-12 10:12:34 +02:00
dependabot[bot]
e39c2f4a96 Bump ccxt from 1.35.22 to 1.36.2
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.35.22 to 1.36.2.
- [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.35.22...1.36.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 07:35:11 +00:00
Matthias
9d2b3b2edb Merge pull request #3851 from freqtrade/dependabot/pip/develop/arrow-0.17.0
Bump arrow from 0.16.0 to 0.17.0
2020-10-12 09:34:14 +02:00
dependabot[bot]
623cee61e6 Bump isort from 5.5.4 to 5.6.3
Bumps [isort](https://github.com/pycqa/isort) from 5.5.4 to 5.6.3.
- [Release notes](https://github.com/pycqa/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/pycqa/isort/compare/5.5.4...5.6.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 07:31:08 +00:00
Matthias
2a2856e2dd Merge pull request #3853 from freqtrade/dependabot/pip/develop/nbconvert-6.0.7
Bump nbconvert from 6.0.6 to 6.0.7
2020-10-12 09:30:02 +02:00
Matthias
8363faf358 Merge pull request #3850 from freqtrade/dependabot/pip/develop/pandas-1.1.3
Bump pandas from 1.1.2 to 1.1.3
2020-10-12 09:29:24 +02:00
dependabot[bot]
80569c5f21 Bump mypy from 0.782 to 0.790
Bumps [mypy](https://github.com/python/mypy) from 0.782 to 0.790.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.782...v0.790)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 05:43:38 +00:00
dependabot[bot]
a33865e8c2 Bump nbconvert from 6.0.6 to 6.0.7
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.0.6 to 6.0.7.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/6.0.6...6.0.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 05:43:37 +00:00
dependabot[bot]
a2bc9d60a0 Bump arrow from 0.16.0 to 0.17.0
Bumps [arrow](https://github.com/arrow-py/arrow) from 0.16.0 to 0.17.0.
- [Release notes](https://github.com/arrow-py/arrow/releases)
- [Changelog](https://github.com/arrow-py/arrow/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/arrow-py/arrow/compare/0.16.0...0.17.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 05:43:23 +00:00
dependabot[bot]
491af5a0cb Bump pandas from 1.1.2 to 1.1.3
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.1.2 to 1.1.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.1.2...v1.1.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-12 05:43:19 +00:00
Matthias
fa7dc742d0 Plot-image should have freqtrade as entrypoint 2020-10-12 06:07:57 +02:00
Matthias
3d911557d1 Fix typo in docs 2020-10-11 08:37:47 +02:00
Matthias
23bad8fd9f Rename DefahltHyperoptLoss function to ShortTradeDurHyperOptLoss 2020-10-10 14:22:29 +02:00
Matthias
028dd8be3e Merge pull request #3842 from freqtrade/edge_docs
Fix example R calculation in edge documentation
2020-10-10 14:13:25 +02:00
Matthias
62859455f7 Merge pull request #3847 from freqtrade/edge_fix_nan
Implement division/0 checks for win and loss columns in edge
2020-10-09 10:27:41 +02:00
Matthias
8fdcb600bc Merge pull request #3849 from freqtrade/improve_docstructure
allow imports in Documentation
2020-10-09 09:28:21 +02:00
Matthias
cedddd02da Install mkdocs for ci 2020-10-09 09:18:25 +02:00
Matthias
f43bd250a2 Extract pairlists from configuration 2020-10-09 09:02:44 +02:00
Matthias
53984a059f Configure mkdocs to allow page includes 2020-10-09 09:02:20 +02:00
Matthias
59b00ad662 Add test for only-win scenario 2020-10-09 06:47:02 +02:00
Matthias
f676156ec7 Implement division/0 checks for win and loss columns in edge
closes #3839
2020-10-09 06:39:13 +02:00
Matthias
23278e52db remove obsolete logging statements 2020-10-08 20:22:59 +02:00
Matthias
e8f2c09f08 Extract handling of left open trades to seperate method 2020-10-08 20:11:45 +02:00
Matthias
d1db847612 Fix "storing information" documentation
closes #3843
2020-10-08 19:27:00 +02:00
Matthias
7f0afe1244 Fix calculation to not show losses > initial investment 2020-10-08 10:24:52 +02:00
Matthias
6bb045f565 Simplify stoploss calculation 2020-10-08 08:30:30 +02:00
Matthias
48750b0ef8 Improve wording in formula 2020-10-08 08:23:56 +02:00
Matthias
1b5cb3427e Fix example R calculation in edge documentation 2020-10-08 08:09:55 +02:00
Matthias
52502193c4 Backtesting should not double-loop for sell signals 2020-10-07 20:59:05 +02:00
Matthias
72337a0ab7 Merge pull request #3836 from freqtrade/hyperopt_remove_default_loss
Hyperopt remove default loss
2020-10-07 09:49:25 +02:00
apneamona
72cf3147b8 Update configuration.md 2020-10-06 20:17:05 +02:00
Matthias
1628a0a4f0 Merge pull request #3837 from freqtrade/update_actions
Update actions image to ubuntu20.04
2020-10-06 09:47:38 +02:00
Matthias
299285a7bb Update actions image to ubuntu20.04 2020-10-06 09:18:49 +02:00
Matthias
8c2f763193 Add test to ensure --hyperopt-loss is mandatory 2020-10-05 20:36:16 +02:00
Matthias
14e87ed4a1 Improvements to hyperopt docs 2020-10-05 20:13:09 +02:00
Matthias
a4a8abfdc0 Update hyperopt documentation 2020-10-05 20:06:34 +02:00
Matthias
fa1d1679f0 Adapt tests to work without default hyperoptloss 2020-10-05 19:33:50 +02:00
Matthias
378b214a56 Remove hyperopt-loss default option
Force users to make a concious choice on a hyperopt-loss function
2020-10-05 19:27:28 +02:00
Matthias
584d095295 Merge pull request #3835 from freqtrade/hyperopt_trailing_output
Fix Hyperopt trailing output
2020-10-05 19:09:02 +02:00
Matthias
11f1ce2d9f Merge pull request #3827 from freqtrade/dependabot/pip/develop/questionary-1.6.0
Bump questionary from 1.5.2 to 1.6.0
2020-10-05 16:33:43 +02:00
Matthias
1e782781a6 Merge pull request #3834 from freqtrade/dependabot/pip/develop/ta-lib-0.4.19
Bump ta-lib from 0.4.18 to 0.4.19
2020-10-05 16:23:55 +02:00
Matthias
b86a602ad4 Update typehint 2020-10-05 16:17:37 +02:00
Matthias
4b53c2bca4 Complete TA-lib update with new binary files 2020-10-05 16:12:41 +02:00
dependabot[bot]
14c66afecc Bump ta-lib from 0.4.18 to 0.4.19
Bumps [ta-lib](https://github.com/mrjbq7/ta-lib) from 0.4.18 to 0.4.19.
- [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.18...TA_Lib-0.4.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 07:11:13 +00:00
Matthias
0538af8875 Merge pull request #3833 from freqtrade/dependabot/pip/develop/joblib-0.17.0
Bump joblib from 0.16.0 to 0.17.0
2020-10-05 08:55:59 +02:00
Matthias
1ef702479b Merge pull request #3831 from freqtrade/dependabot/pip/develop/mkdocs-material-6.0.2
Bump mkdocs-material from 6.0.1 to 6.0.2
2020-10-05 08:55:25 +02:00
Matthias
09e9141e51 Merge pull request #3830 from freqtrade/dependabot/pip/develop/plotly-4.11.0
Bump plotly from 4.10.0 to 4.11.0
2020-10-05 08:52:25 +02:00
Matthias
d23ea36c05 Merge pull request #3832 from freqtrade/dependabot/pip/develop/pytest-6.1.1
Bump pytest from 6.1.0 to 6.1.1
2020-10-05 08:49:05 +02:00
Matthias
f4ab2dab4c Merge pull request #3829 from freqtrade/dependabot/pip/develop/pycoingecko-1.4.0
Bump pycoingecko from 1.3.0 to 1.4.0
2020-10-05 08:31:41 +02:00
Matthias
65e4c052f1 Merge pull request #3828 from freqtrade/dependabot/pip/develop/ccxt-1.35.22
Bump ccxt from 1.34.59 to 1.35.22
2020-10-05 08:21:26 +02:00
Matthias
2d6bc9aadc Merge pull request #3825 from freqtrade/dependabot/pip/develop/isort-5.5.4
Bump isort from 5.5.3 to 5.5.4
2020-10-05 08:20:27 +02:00
Matthias
482213fbb3 Merge pull request #3826 from freqtrade/dependabot/pip/develop/flake8-3.8.4
Bump flake8 from 3.8.3 to 3.8.4
2020-10-05 08:16:15 +02:00
Matthias
06759234b6 Add test to verify output of roi / trailing stop hyperopt 2020-10-05 08:07:53 +02:00
Matthias
40b61bbfe3 Adjust trailing-stop to be python compliant 2020-10-05 07:44:12 +02:00
dependabot[bot]
234f6c2f5e Bump joblib from 0.16.0 to 0.17.0
Bumps [joblib](https://github.com/joblib/joblib) from 0.16.0 to 0.17.0.
- [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.16.0...0.17.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:44 +00:00
dependabot[bot]
688442507e Bump mkdocs-material from 6.0.1 to 6.0.2
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.0.1...6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:44 +00:00
dependabot[bot]
64de911e16 Bump pytest from 6.1.0 to 6.1.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.1.0 to 6.1.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/6.1.0...6.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:44 +00:00
dependabot[bot]
56647bb498 Bump plotly from 4.10.0 to 4.11.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.10.0 to 4.11.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.10.0...v4.11.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:42 +00:00
dependabot[bot]
52b6f6b940 Bump pycoingecko from 1.3.0 to 1.4.0
Bumps [pycoingecko](https://github.com/man-c/pycoingecko) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/man-c/pycoingecko/releases)
- [Changelog](https://github.com/man-c/pycoingecko/blob/master/CHANGELOG.md)
- [Commits](https://github.com/man-c/pycoingecko/compare/1.3.0...1.4.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:40 +00:00
dependabot[bot]
0574a40693 Bump questionary from 1.5.2 to 1.6.0
Bumps [questionary](https://github.com/tmbo/questionary) from 1.5.2 to 1.6.0.
- [Release notes](https://github.com/tmbo/questionary/releases)
- [Commits](https://github.com/tmbo/questionary/compare/1.5.2...1.6.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:39 +00:00
dependabot[bot]
8d4f7ce84f Bump ccxt from 1.34.59 to 1.35.22
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.34.59 to 1.35.22.
- [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.34.59...1.35.22)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:39 +00:00
dependabot[bot]
80890e0f59 Bump flake8 from 3.8.3 to 3.8.4
Bumps [flake8](https://gitlab.com/pycqa/flake8) from 3.8.3 to 3.8.4.
- [Release notes](https://gitlab.com/pycqa/flake8/tags)
- [Commits](https://gitlab.com/pycqa/flake8/compare/3.8.3...3.8.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:37 +00:00
dependabot[bot]
887b2fdb5e Bump isort from 5.5.3 to 5.5.4
Bumps [isort](https://github.com/pycqa/isort) from 5.5.3 to 5.5.4.
- [Release notes](https://github.com/pycqa/isort/releases)
- [Changelog](https://github.com/PyCQA/isort/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/pycqa/isort/compare/5.5.3...5.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 05:41:23 +00:00
Matthias
301598bac9 Merge pull request #3818 from freqtrade/rpc/candlehistory
Rpc/candlehistory
2020-10-04 09:34:25 +02:00
Matthias
c9b3766fa3 Remove rest_dump
it's just a wrapper around jsonify with no benefits
2020-10-04 09:14:46 +02:00
Matthias
63e1cba597 fix some typos 2020-10-04 09:12:52 +02:00
Matthias
2d343c8f73 Merge pull request #3823 from freqtrade/fix/hyperoptoutput
Fix hyperopt output
2020-10-03 13:42:05 +02:00
Matthias
cb74c9bcde Fix hyperopt output 2020-10-03 13:27:06 +02:00
Matthias
176006da29 Sort imports 2020-10-02 07:00:45 +02:00
Matthias
66b77d2f53 Fix some types 2020-10-02 06:52:43 +02:00
Matthias
62110dc2fc Add buy / sell signal count to dataframe interface 2020-09-29 06:35:47 +02:00
Matthias
350fcc071e Don't use __code__
__code__ is a special method name used by python already
source:
https://docs.python.org/3/reference/datamodel.html#special-method-names
2020-09-29 06:35:47 +02:00
Matthias
b38f68b3b0 Add 404 when strategy is not found 2020-09-29 06:35:47 +02:00
Matthias
becccca3d1 Add test for __code__ loading 2020-09-29 06:35:47 +02:00
Matthias
ba10bd7756 Add strategy code to __code__ 2020-09-29 06:35:47 +02:00
Matthias
4b6b7f8343 Add timeframe to candle return values 2020-09-29 06:35:47 +02:00
Matthias
a3d0889dab Add alpha to endpoint documentation 2020-09-29 06:35:47 +02:00
Matthias
816c8295f1 Add test for pair_history 2020-09-29 06:35:47 +02:00
Matthias
f82d39e1b0 Enhance restclient and add tests for new api methods 2020-09-29 06:35:47 +02:00
Matthias
bb4993dc20 Add new endpoints to the documentation 2020-09-29 06:35:47 +02:00
Matthias
c0654f3caf Add resiliancy against not having a analyzed dataframe yet 2020-09-29 06:35:47 +02:00
Matthias
c59a1be154 show_config should not use freqtrade object 2020-09-29 06:35:47 +02:00
Matthias
1de248fe38 add list_available_pairs endpoint 2020-09-29 06:35:47 +02:00
Matthias
6a59740f83 Strategies should be a nested object 2020-09-29 06:35:47 +02:00
Matthias
32e6ea314c Return strategy with analyzed data 2020-09-29 06:35:47 +02:00
Matthias
18bbfdd341 Add /strategies endpoint 2020-09-29 06:35:47 +02:00
Matthias
f227f6a755 Use passed in config object to allow this to work in webserver mode 2020-09-29 06:35:47 +02:00
Matthias
bf0e75e2a5 Include data start and end date in dataframe api 2020-09-29 06:35:47 +02:00
Matthias
b93ad8840a Return date column unmodified 2020-09-29 06:35:47 +02:00
Matthias
482f1faa88 Don't fail if no buy-signal is present 2020-09-29 06:35:46 +02:00
Matthias
f5dc10e4ae Add pair_history endpoint 2020-09-29 06:35:46 +02:00
Matthias
677078350f Add plot_config endpoint 2020-09-29 06:35:46 +02:00
Matthias
d528c44974 Add test for pair_history 2020-09-29 06:35:46 +02:00
Matthias
133ca9c770 Convert types to support valid json 2020-09-29 06:35:46 +02:00
Matthias
a38b33cd9c Support limiting analyzed history 2020-09-29 06:35:46 +02:00
Matthias
9dfbc1a7ff Add analyzed_history endpoint 2020-09-29 06:35:46 +02:00
Matthias
d2111c088b Merge pull request #3815 from freqtrade/isort_config
Introduce isort to have clear way to sort imports
2020-09-29 06:27:23 +02:00
Matthias
6977ffdbf9 Merge branch 'develop' into isort_config 2020-09-28 20:21:55 +02:00
Matthias
c410599a52 Merge pull request #3807 from freqtrade/hyperopt_disablecontinue
Hyperopt disablecontinue
2020-09-28 20:13:38 +02:00
Matthias
2be8e8070a Add Python 3.8 to setup.py classifiers 2020-09-28 20:02:11 +02:00
Matthias
ace2879265 Don't run isort on windows - once is enough 2020-09-28 19:53:29 +02:00
Matthias
0ea56548e4 Try fix random test failure 2020-09-28 19:50:22 +02:00
Matthias
ce228f19dc Apply isort to setup.py 2020-09-28 19:43:32 +02:00
Matthias
9df366d943 Apply isort to tests 2020-09-28 19:43:15 +02:00
Matthias
253b7b763e Apply isort to freqtrade codebase 2020-09-28 19:40:46 +02:00
Matthias
201e714343 include isort to contributing 2020-09-28 17:37:14 +02:00
Matthias
287604efd2 Add isort to project dev dependencies 2020-09-28 17:35:04 +02:00
Matthias
7623691a5f PyPi Publis should only run for releases 2020-09-28 17:19:41 +02:00
Matthias
17e605e130 Make it clear in samples that strategy is mandatory 2020-09-28 15:22:06 +02:00
Matthias
fe588e5722 Merge pull request #3811 from freqtrade/dependabot/pip/develop/ccxt-1.34.59
Bump ccxt from 1.34.40 to 1.34.59
2020-09-28 09:56:24 +02:00
Matthias
98a2811605 Version bump 2020.9.1 2020-09-28 08:55:17 +02:00
Matthias
1f14c6bacd PyPi Publis should only run for releases 2020-09-28 08:54:32 +02:00
Matthias
44e8184519 Tag image before building next image 2020-09-28 08:54:24 +02:00
Matthias
700529fe06 Tag image before building next image 2020-09-28 08:36:40 +02:00
Matthias
f174c74094 Merge pull request #3812 from freqtrade/dependabot/pip/develop/nbconvert-6.0.6
Bump nbconvert from 6.0.4 to 6.0.6
2020-09-28 08:30:48 +02:00
Matthias
f3e1eddc91 Merge pull request #3813 from freqtrade/dependabot/pip/develop/mkdocs-material-6.0.1
Bump mkdocs-material from 5.5.13 to 6.0.1
2020-09-28 08:28:50 +02:00
Matthias
5e0fa21d60 Merge pull request #3810 from freqtrade/dependabot/pip/develop/pytest-6.1.0
Bump pytest from 6.0.2 to 6.1.0
2020-09-28 08:26:42 +02:00
Matthias
c14ff2bee1 Merge pull request #3805 from freqtrade/new_release
New release 2020.9
2020-09-28 07:48:54 +02:00
dependabot[bot]
dd4d458ca8 Bump mkdocs-material from 5.5.13 to 6.0.1
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.13 to 6.0.1.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.13...6.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-28 05:48:15 +00:00
dependabot[bot]
6d8fadd560 Bump nbconvert from 6.0.4 to 6.0.6
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.0.4 to 6.0.6.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/6.0.4...6.0.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-28 05:48:14 +00:00
dependabot[bot]
1dee0eed75 Bump ccxt from 1.34.40 to 1.34.59
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.34.40 to 1.34.59.
- [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.34.40...1.34.59)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-28 05:48:12 +00:00
dependabot[bot]
48347b49fd Bump pytest from 6.0.2 to 6.1.0
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.0.2 to 6.1.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/6.0.2...6.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-28 05:48:08 +00:00
Matthias
15bb0af1b3 Add some test-coverage 2020-09-28 00:36:13 +02:00
Matthias
f3de74f817 Mock all occurances of hyperopt.dump 2020-09-27 19:48:11 +02:00
Matthias
6e70ae6e95 Improve code quality 2020-09-27 19:40:55 +02:00
Matthias
5769b9244f Mock test correctly 2020-09-27 19:34:47 +02:00
Matthias
8de9c46110 Document hyperopt-filename usage 2020-09-27 17:09:33 +02:00
Matthias
3cb1a9a5a9 Support loading results from a specific hyperopt history file 2020-09-27 17:03:30 +02:00
Matthias
c42a924df8 Load latest file 2020-09-27 16:50:42 +02:00
Matthias
ff96cf154c Keep hyperopt result history 2020-09-27 16:33:26 +02:00
Matthias
7a652b07d5 UPdate documentation to remove --continue 2020-09-27 16:21:55 +02:00
Matthias
b736691e0e Remove hyperopt --continue 2020-09-27 16:18:28 +02:00
Matthias
17659001d8 Version bump to 2020.9 2020-09-27 09:51:19 +02:00
Matthias
45f4057d3c Merge branch 'stable' into new_release 2020-09-27 09:51:07 +02:00
Matthias
64c2b6c9a6 Merge pull request #3791 from freqtrade/rename_master_branch
Rename references to "master" branch to "stable"
2020-09-27 09:49:19 +02:00
Matthias
6a1b1eb75a Merge pull request #3803 from freqtrade/bt_params
Backtesting - handle mdifferent max_open_trades per strategy
2020-09-26 15:25:34 +02:00
Matthias
bb27b236ce Remove unused arguments 2020-09-26 14:55:12 +02:00
Matthias
c56dd487f2 Fix test failure 2020-09-25 21:00:58 +02:00
Matthias
ff3e2641ae generate_backtest_stats must take config options from the strategy
config

as a strategy can override certain options.
2020-09-25 20:47:37 +02:00
Matthias
fe45b79beb Merge pull request #3801 from freqtrade/dependabot/docker/python-3.8.6-slim-buster
Bump python from 3.8.5-slim-buster to 3.8.6-slim-buster
2020-09-25 08:02:52 +02:00
dependabot[bot]
d49488bf0e Bump python from 3.8.5-slim-buster to 3.8.6-slim-buster
Bumps python from 3.8.5-slim-buster to 3.8.6-slim-buster.

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-25 05:47:58 +00:00
Matthias
378f03a5b1 Add relevant parameters to stored backtest result 2020-09-25 06:37:40 +02:00
Matthias
fa18274e9a Merge pull request #3798 from freqtrade/fix/wallets_dont_reset
Fix wallets dont reset
2020-09-24 19:22:14 +02:00
Matthias
66ca596e7c Merge pull request #3787 from freqtrade/rpc/telegram_settings
Allow Notification finetuning for telegram messages
2020-09-23 10:20:43 +02:00
Matthias
bb56d392a9 Fix typo in documentation 2020-09-22 20:19:46 +02:00
Matthias
6b46a35b19 Fix bug of balances not disappearing 2020-09-22 19:37:31 +02:00
Matthias
4b06c9e0ae Add test verifying wrong behaviour 2020-09-22 19:37:18 +02:00
Matthias
d639290f7d Merge branch 'develop' into rename_master_branch 2020-09-21 19:31:25 +02:00
Matthias
87f6c7bbec Merge pull request #3794 from freqtrade/dependabot/pip/develop/ccxt-1.34.40
Bump ccxt from 1.34.25 to 1.34.40
2020-09-21 08:18:16 +02:00
Matthias
6f52faf328 Merge pull request #3795 from freqtrade/dependabot/pip/develop/nbconvert-6.0.4
Bump nbconvert from 6.0.2 to 6.0.4
2020-09-21 08:17:40 +02:00
Matthias
a9198c1f7e Merge pull request #3793 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.13
Bump mkdocs-material from 5.5.12 to 5.5.13
2020-09-21 08:17:21 +02:00
Matthias
6e32ac5b3a Merge pull request #3792 from freqtrade/add_devcontainer
Add devcontainer
2020-09-21 07:42:57 +02:00
dependabot[bot]
be33556838 Bump nbconvert from 6.0.2 to 6.0.4
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.0.2 to 6.0.4.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/6.0.2...6.0.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-21 05:40:00 +00:00
dependabot[bot]
d1b3a16c13 Bump ccxt from 1.34.25 to 1.34.40
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.34.25 to 1.34.40.
- [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.34.25...1.34.40)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-21 05:39:56 +00:00
dependabot[bot]
4cb5c9c85f Bump mkdocs-material from 5.5.12 to 5.5.13
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.12 to 5.5.13.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.12...5.5.13)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-21 05:39:56 +00:00
Matthias
50aec1d6d3 Jupyter service should be called differently 2020-09-20 20:19:07 +02:00
Matthias
7dadca421a Update location of docker files 2020-09-20 16:26:48 +02:00
Matthias
261b267160 Don't build devcontainer on push 2020-09-20 16:20:17 +02:00
Matthias
3c460d37b6 Document existence of PLOT image 2020-09-20 16:20:01 +02:00
Matthias
8ff1429e68 Add user_data to backtesting 2020-09-20 15:39:50 +02:00
Matthias
b02c0904b6 Use buildarg to use correct parent variable 2020-09-20 15:17:54 +02:00
Matthias
ab190f7a5b Document jupyter with docker usage 2020-09-20 15:12:30 +02:00
Matthias
30c1253f75 Use correct ports for jupyter compose file 2020-09-20 15:02:07 +02:00
Matthias
f9efbed076 Ignore userdata from docker build 2020-09-20 14:59:13 +02:00
Matthias
40132bbea4 Add this branch to CI 2020-09-20 14:58:37 +02:00
Matthias
85ab6e43ba Build _plot dockerfile 2020-09-20 14:58:27 +02:00
Matthias
129cbf5ef5 Add more Dockerfiles 2020-09-20 14:58:15 +02:00
Matthias
096079a595 Install autopep8 2020-09-20 12:41:17 +00:00
Matthias
4355f36cd6 Add gitconfig to devcontainer 2020-09-20 12:36:47 +00:00
Matthias
0a7b6f73c9 Move devcontainer stuff to .devcontainer 2020-09-20 12:35:08 +00:00
Matthias
cf85a178f3 Update developer documentation related to devcontainer 2020-09-20 12:34:57 +00:00
Matthias
20e5c1b388 Update Developer documentation related to docker 2020-09-20 12:16:58 +00:00
Matthias
7ead4f9fa3 Update devcontainer settings 2020-09-20 14:16:36 +02:00
Matthias
8ff7ce8b17 Introduce devcontainer 2020-09-20 11:40:16 +00:00
Matthias
b72cccae3c Add note about download-data in combination with startup period
closes #2673
2020-09-20 13:09:34 +02:00
Matthias
a8a9fb5c6a Merge pull request #3790 from BlueSkyTrading/patch-3
1M and 1y timeframes added
2020-09-20 13:00:16 +02:00
Matthias
637fe35549 Fix typo in release documentation 2020-09-20 11:53:47 +02:00
Matthias
b3f0bfd77f Fix a few random typos 2020-09-20 11:51:12 +02:00
Matthias
2b1d0b4ab5 Rename references to "master" branch to "stable"
closes #2496
2020-09-20 11:45:08 +02:00
Matthias
c349499985 Also add 2w (supported by kraken) 2020-09-20 11:18:45 +02:00
Matthias
80f6f6dcbc Merge branch 'pr/BlueSkyTrading/3788' into pr/BlueSkyTrading/3790 2020-09-20 11:15:32 +02:00
Matthias
d5b2ffae7a Merge pull request #3789 from BlueSkyTrading/patch-2
changed epochs from 5000 to 500
2020-09-20 08:15:38 +02:00
HumanBot
f51f445011 1M and 1y timeframes added
Huobi Pro timeframes added
2020-09-19 14:45:36 -04:00
Matthias
a31de431ed Explicitly convert to type to string 2020-09-19 20:38:42 +02:00
HumanBot
8c9a600dec changed epochs from 5000 to 500
5000 is an overkill for the hyperopt process, repetitive 500 produce better predictions
2020-09-19 14:36:12 -04:00
HumanBot
a95dbdbde4 Added 1M and 1y timeframes
Huobi Pro allows monthly and yearly data downloading
2020-09-19 14:31:23 -04:00
Matthias
2554dc48e4 Add test for notification settings 2020-09-19 20:29:44 +02:00
Matthias
413d7ddf70 Document telegram notification settings 2020-09-19 19:42:56 +02:00
Matthias
e53b88bde3 Introduce notification_settings for telegram 2020-09-19 19:38:33 +02:00
Matthias
2a7935e35e Rename custom_notification to startup_notification 2020-09-19 17:51:31 +02:00
Matthias
6674285b12 Merge pull request #3756 from allenday/patch-1
prettify hyperopt console output
2020-09-19 17:43:05 +02:00
Matthias
f0d7f18cf9 Pad wins / draws / losses for hyperopt with spaces instead of 0's 2020-09-19 17:32:22 +02:00
Matthias
476319da45 Clarify --timerange documentation 2020-09-19 17:21:56 +02:00
Matthias
934abb0094 Merge pull request #3786 from freqtrade/download_data_timerange
Download data should support absolute starting point
2020-09-19 17:19:45 +02:00
Matthias
a559611c15 Merge pull request #3682 from freqtrade/db_keep_orders
Keep order history in the database
2020-09-19 17:12:14 +02:00
Matthias
bf95fe2e5c have the 2 timerange arguments next to each other 2020-09-19 11:33:55 +02:00
Matthias
5daaed1449 Help endpoint does not make sense for the rest api server.
therefore, remove the TODO.
2020-09-19 11:25:00 +02:00
Matthias
1f086e1466 Modify test loglevel 2020-09-19 09:46:32 +02:00
Matthias
77d0189695 Remove not needed argument in update_trade_state 2020-09-19 09:37:11 +02:00
Matthias
2f6b00555a Document support for --timerange in download-data 2020-09-19 09:13:43 +02:00
Matthias
35857b3dde Datetime should support --timerange too 2020-09-19 09:10:34 +02:00
Matthias
bfd0e3553a Don't build this branch anymore in CI 2020-09-19 08:42:37 +02:00
Matthias
254875e6b3 Add test for new close functionality
* Don't updates close_date if the trade was already closed
2020-09-19 08:42:15 +02:00
Matthias
dd87938a5e Fix bug causing close_date to be set again 2020-09-19 08:34:06 +02:00
Matthias
ec01f20bf8 Add ratio to sell reason stats 2020-09-16 20:27:28 +02:00
Matthias
962fed24b0 Readd refind_order logic 2020-09-14 17:34:13 +02:00
Matthias
b4443fdb1f Merge pull request #3777 from freqtrade/dependabot/pip/develop/ccxt-1.34.25
Bump ccxt from 1.34.11 to 1.34.25
2020-09-14 09:24:22 +02:00
Matthias
49d0bd4832 Merge pull request #3779 from freqtrade/dependabot/pip/develop/nbconvert-6.0.2
Bump nbconvert from 5.6.1 to 6.0.2
2020-09-14 09:07:47 +02:00
dependabot[bot]
6d30740b55 Bump ccxt from 1.34.11 to 1.34.25
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.34.11 to 1.34.25.
- [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.34.11...1.34.25)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-14 07:07:14 +00:00
Matthias
c510b6012d Merge pull request #3778 from freqtrade/dependabot/pip/develop/plotly-4.10.0
Bump plotly from 4.9.0 to 4.10.0
2020-09-14 09:05:28 +02:00
Matthias
3aa34c411d Merge pull request #3776 from freqtrade/dependabot/pip/develop/numpy-1.19.2
Bump numpy from 1.19.1 to 1.19.2
2020-09-14 09:01:12 +02:00
Matthias
78555adecd Merge pull request #3775 from freqtrade/dependabot/pip/develop/pytest-6.0.2
Bump pytest from 6.0.1 to 6.0.2
2020-09-14 08:49:36 +02:00
dependabot[bot]
23c1ae5d4a Bump nbconvert from 5.6.1 to 6.0.2
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 5.6.1 to 6.0.2.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/5.6.1...6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-14 06:35:41 +00:00
dependabot[bot]
9d3caae9e3 Bump plotly from 4.9.0 to 4.10.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.9.0 to 4.10.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.9.0...v4.10.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-14 06:35:36 +00:00
dependabot[bot]
3c76945d5e Bump numpy from 1.19.1 to 1.19.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.19.1 to 1.19.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.19.1...v1.19.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-14 06:35:14 +00:00
dependabot[bot]
60538368ac Bump pytest from 6.0.1 to 6.0.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.0.1 to 6.0.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/6.0.1...6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-14 06:35:00 +00:00
Matthias
7e28896c5c Merge pull request #3774 from freqtrade/reduce_requirements_files
Reduce requirements files
2020-09-14 07:44:24 +02:00
Matthias
07ccda9146 Fix syntax for released CI 2020-09-13 19:38:41 +02:00
Matthias
d65d886d7d add branch to CI - change branch-detection to support tags as well 2020-09-13 16:54:21 +02:00
Matthias
ba8e93e2a1 Remove requirements-common.txt
in an attempt to simplify installation
2020-09-13 16:43:22 +02:00
Matthias
dcedc1480f Merge pull request #3764 from Blackhawke/develop
Added full virtualenv command to quick start
2020-09-12 08:43:59 +02:00
Matthias
503d5db113 Merge branch 'develop' into pr/Blackhawke/3764 2020-09-12 08:33:46 +02:00
Blackhawke
3f52b6d6d5 Move "source" restored ".env/" 2020-09-11 12:01:45 -07:00
Matthias
77c28187a6 Don't run refind order on stoploss 2020-09-11 20:06:05 +02:00
Matthias
977ccaac16 Merge branch 'develop' into db_keep_orders 2020-09-11 20:01:28 +02:00
Matthias
50f0483d9a FIx fluky test in test_api_logs 2020-09-11 20:00:36 +02:00
Matthias
13994fac92 Merge pull request #3770 from freqtrade/api_closesessions
scoped sessions should be closed after requests
2020-09-11 19:49:03 +02:00
Matthias
a18305ffe7 Merge pull request #3771 from caudurodev/develop
FIX: Docs: added missing ( to SQLite insert statement to avoid error.
2020-09-11 10:01:31 +02:00
caudurodev
90d97c536d FIX: added missing ) for SQLite insert 2020-09-11 08:42:42 +02:00
caudurodev
0c9301e74a FIX: added missing ) for SQLite insert 2020-09-11 08:41:33 +02:00
Matthias
aa8832f70e Convert select_order to use ft_is_open flag 2020-09-11 07:12:10 +02:00
Matthias
41942e3af1 Update docstring for select_order 2020-09-11 06:59:07 +02:00
Matthias
b8773de5b0 scoped sessions should be closed after requests 2020-09-11 06:44:20 +02:00
Matthias
85d90645c7 Remove duplciate check for buy orders 2020-09-10 15:42:34 +02:00
Matthias
4db8c779fc Fix formatting issues 2020-09-10 08:19:40 +02:00
Matthias
6a08fee25b Fix wrong import in documentation 2020-09-10 08:04:04 +02:00
Matthias
23f569ea38 Add test for sell order refind, improve overall test for this function 2020-09-10 08:03:26 +02:00
Matthias
3c521f55b2 Add 6th mock trade 2020-09-10 07:40:19 +02:00
Blackhawke
c3e0397743 Added full "source" command to virtualenv in easy install 2020-09-09 09:16:11 -07:00
Matthias
6b22b4e4c7 Merge pull request #3760 from freqtrade/dependabot/pip/develop/progressbar2-3.53.1
Bump progressbar2 from 3.52.1 to 3.53.1
2020-09-09 16:06:21 +02:00
Matthias
beb8692231 Merge pull request #3763 from freqtrade/dependabot/pip/develop/pandas-1.1.2
Bump pandas from 1.1.1 to 1.1.2
2020-09-09 15:56:48 +02:00
Matthias
511dc254ff Merge pull request #3762 from freqtrade/dependabot/pip/develop/ccxt-1.34.11
Bump ccxt from 1.34.3 to 1.34.11
2020-09-09 15:51:32 +02:00
Matthias
d28d663175 Merge pull request #3761 from freqtrade/dependabot/pip/develop/blosc-1.9.2
Bump blosc from 1.9.1 to 1.9.2
2020-09-09 15:46:59 +02:00
Matthias
4480b3b393 Fix error in documentation (wrong sequence of steps) 2020-09-09 15:39:35 +02:00
dependabot[bot]
8c97b83b8c Bump pandas from 1.1.1 to 1.1.2
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.1.1 to 1.1.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.1.1...v1.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-09 13:29:36 +00:00
dependabot[bot]
d8dae46544 Bump ccxt from 1.34.3 to 1.34.11
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.34.3 to 1.34.11.
- [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.34.3...1.34.11)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-09 13:29:31 +00:00
dependabot[bot]
986e767d6c Bump blosc from 1.9.1 to 1.9.2
Bumps [blosc](https://github.com/blosc/python-blosc) from 1.9.1 to 1.9.2.
- [Release notes](https://github.com/blosc/python-blosc/releases)
- [Changelog](https://github.com/Blosc/python-blosc/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/blosc/python-blosc/compare/v1.9.1...v1.9.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-09 13:29:27 +00:00
dependabot[bot]
4cf66e2fba Bump progressbar2 from 3.52.1 to 3.53.1
Bumps [progressbar2](https://github.com/WoLpH/python-progressbar) from 3.52.1 to 3.53.1.
- [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.52.1...v3.53.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-09 13:29:22 +00:00
Matthias
083c358044 Fix wrong sequence in test 2020-09-09 07:57:02 +02:00
Matthias
25938efee6 Add partial test for refind_order 2020-09-09 07:50:52 +02:00
Matthias
98840eef3c Add 5th mock trade 2020-09-09 07:01:43 +02:00
Matthias
caf0476717 Add test for handle_insufficient_funds 2020-09-09 06:49:29 +02:00
Matthias
8af610b543 Add Test for reupdate_buy_order_fees 2020-09-09 06:42:36 +02:00
Matthias
aa2d1e9cca Merge pull request #3744 from freqtrade/fix/infomrativesample
fix Informative pair documentation
2020-09-08 16:38:08 +02:00
Allen Day
3fe2ed0e18 zero pad in test 2020-09-07 23:38:51 +08:00
Allen Day
f63a378967 Update hyperopt.py
zero pad wins/draws/losses (W/D/L) column to preserve alignment in console pretty print
2020-09-07 23:26:55 +08:00
Matthias
4c34934258 Merge pull request #3668 from freqtrade/dependabot/pip/develop/scikit-learn-0.23.2
Bump scikit-learn from 0.23.1 to 0.23.2
2020-09-07 09:50:40 +02:00
Matthias
384b966265 Merge pull request #3751 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.12
Bump mkdocs-material from 5.5.11 to 5.5.12
2020-09-07 09:48:29 +02:00
dependabot[bot]
f20318fad1 Bump scikit-learn from 0.23.1 to 0.23.2
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.23.1 to 0.23.2.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.23.1...0.23.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-07 07:37:12 +00:00
Matthias
eb06ffc908 Merge pull request #3753 from freqtrade/dependabot/pip/develop/scikit-optimize-0.8.1
Bump scikit-optimize from 0.7.4 to 0.8.1
2020-09-07 09:35:55 +02:00
Matthias
d8fdbd656b Merge pull request #3752 from freqtrade/dependabot/pip/develop/ccxt-1.34.3
Bump ccxt from 1.33.72 to 1.34.3
2020-09-07 09:35:32 +02:00
dependabot[bot]
ff0e73a9e5 Bump scikit-optimize from 0.7.4 to 0.8.1
Bumps [scikit-optimize](https://github.com/scikit-optimize/scikit-optimize) from 0.7.4 to 0.8.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.7.4...v0.8.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-07 07:09:23 +00:00
dependabot[bot]
534404c284 Bump ccxt from 1.33.72 to 1.34.3
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.33.72 to 1.34.3.
- [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.33.72...1.34.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-07 07:09:22 +00:00
dependabot[bot]
014fcb36f4 Bump mkdocs-material from 5.5.11 to 5.5.12
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.11 to 5.5.12.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.11...5.5.12)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-07 07:09:07 +00:00
Matthias
7852feab05 support smaller timeframes 2020-09-07 09:06:43 +02:00
Matthias
f3e0370d4d Stylistic fixes 2020-09-07 07:54:55 +02:00
Matthias
6518e7a789 Add test for update_closed_trades_without_fees 2020-09-07 07:47:38 +02:00
Matthias
26a5cc5959 Add return-type for select_order 2020-09-07 07:41:58 +02:00
Matthias
f113b45036 Refactor test to not duplicate order info 2020-09-07 06:53:11 +02:00
Matthias
da0ceb7d87 Extract orders for mock trades 2020-09-07 06:48:34 +02:00
Matthias
cad0275b32 Extract mock_trade generation to sepearate file 2020-09-07 06:39:48 +02:00
Matthias
f6ebe51314 Add test for update_open_orders 2020-09-06 19:32:00 +02:00
Matthias
a0fd7f4644 Update tests to merged version 2020-09-06 15:27:16 +02:00
Matthias
5fba446e9a Merge branch 'develop' into db_keep_orders 2020-09-06 15:22:13 +02:00
Matthias
b4da36d6e9 Fix small typo and add small testcase 2020-09-06 15:05:47 +02:00
Matthias
7c1f111ddf Add insufficient_funds_test 2020-09-06 14:59:43 +02:00
Matthias
cec98ad407 Test stoploss insufficient funds handling 2020-09-06 14:51:48 +02:00
Matthias
68d51a9787 Don't raise OperationalException when orderid's dont' match 2020-09-06 14:33:45 +02:00
Matthias
a78d61150c Deleting must delete orders first 2020-09-06 14:28:24 +02:00
Matthias
b7662722ba Add tests for Order object parsing 2020-09-06 14:17:45 +02:00
Matthias
b4c3529135 Add orders to mock_trades fixture 2020-09-06 14:05:15 +02:00
Matthias
8c9297e1f0 Don't crash if a strategy imports something wrongly 2020-09-05 16:51:19 +02:00
Matthias
c18441f36f Fix typo in reloading_conf 2020-09-05 16:44:23 +02:00
Matthias
71af64af94 Move comment to the right place 2020-09-04 20:10:43 +02:00
Matthias
cc684c5141 Correctly handle identical timerame merges 2020-09-04 20:09:02 +02:00
Matthias
7bc8927914 Add documentation for merge_informative_pair helper 2020-09-04 20:02:31 +02:00
Matthias
bd4f3d838a Implement merge_informative_pairs helper 2020-09-04 19:44:35 +02:00
Matthias
3ecd23f853 Merge pull request #3745 from silvavn/develop
Updating Edge Positioning Doc.
2020-09-04 10:39:39 +02:00
Matthias
848a94d62e Merge branch 'develop' into pr/silvavn/3745 2020-09-04 07:56:10 +02:00
Matthias
bc5cc48f67 Adjust windows docs, fix failing doc-test 2020-09-04 07:28:21 +02:00
Matthias
1406691945 Rename files to have clearer paths 2020-09-04 07:12:08 +02:00
silvavn
32005b886a small typo 2020-09-03 13:39:38 -06:00
silvavn
275d853432 Updated W, L Formulas 2020-09-03 13:38:46 -06:00
silvavn
34b27d2f96 Moving stuff around
- Mac troubleshooting to the end
- optional master checkout
- Anaconda moved to the end
2020-09-03 13:32:07 -06:00
silvavn
29fe2ffff7 Added that the user can edit docker-compose.yml 2020-09-03 13:22:22 -06:00
silvavn
e6058b716b removes prolixity docker-compose 2020-09-03 13:19:05 -06:00
silvavn
66505bd9bf Fixes Raspberri Pi Image config 2020-09-03 13:18:15 -06:00
silvavn
f6a8dda8e5 Reorganize structure
- Quickstart moved out of installation
- Installation now contains only advanced modes.
- Joined quickstart with Docker
2020-09-03 13:12:43 -06:00
silvavn
714264701c Fixes typos 2020-09-03 13:11:04 -06:00
Victor Silva
47f0e69072 Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:57:15 -06:00
Victor Silva
93d1ad5ed9 Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:56:54 -06:00
Victor Silva
1f13a8b91d Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:55:49 -06:00
Victor Silva
08e3546120 Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:55:07 -06:00
Victor Silva
5f9c449d8e Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:53:33 -06:00
Victor Silva
70eaf971cd Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:50:23 -06:00
Victor Silva
69349a9d8d Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:49:54 -06:00
Victor Silva
ec9b51d60a Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-09-03 12:49:32 -06:00
Matthias
27362046d4 Add documentation section about running docs locally 2020-09-03 19:33:34 +02:00
Matthias
5c5cf782f5 Fix small bug with /daily if close_profit_abs is not yet filled 2020-09-03 19:29:48 +02:00
silvavn
47352e1721 Address issue #2487
Breakdown insllation instructions
Make installation instructions shorter
Separate Windows from the remainder
Use tabs for better navigation
Minor language improvements
2020-09-02 20:37:45 -06:00
silvavn
295ecaa9b2 Updating Edge Positioning Doc.
Integrated MathJax
Included worked out examples
Changed Language to achieve a middle ground.
Minor formatting improvements
2020-09-02 16:58:54 -06:00
Matthias
79ea8cf771 Improve wording 2020-09-02 20:02:41 +02:00
Matthias
e268bd192e Fix informative sample documentation 2020-09-02 19:59:04 +02:00
Matthias
f54fecaeba Expose helpermethods thorugh freqtrade.strategy 2020-09-02 19:58:26 +02:00
Matthias
10c5b230b4 Merge pull request #3742 from freqtrade/remove_trailingstop_config
Remove trailing_stop from default config example - it'll be misleading
2020-09-01 20:16:54 +02:00
Matthias
dff0ac2768 Remove trailing_stop from default config example - it'll be misleading 2020-09-01 19:18:19 +02:00
Matthias
43035a3f76 Merge pull request #3724 from freqtrade/fix/3084
Forcesell should use the available methods for handling a trade correctly
2020-09-01 15:11:05 +02:00
Matthias
451a18c444 Merge pull request #3740 from freqtrade/remove_deprecated_volumepairlistkeys
Remove deprectead volumepairlist options
2020-09-01 10:51:45 +02:00
Matthias
d444182829 Reinstate wrongly removed pairlist test 2020-09-01 10:31:11 +02:00
Matthias
3bc6cb36c6 Remove deprectead volumepairlist options 2020-09-01 08:04:02 +02:00
Matthias
d6d3a02a23 Merge branch 'develop' into db_keep_orders 2020-09-01 07:51:16 +02:00
Matthias
a4e3edbcc5 Fix stoploss_last_update beein updated with date object in wrong
timezone
2020-09-01 07:10:48 +02:00
Matthias
38c52c7eee Merge pull request #3626 from freqtrade/feat/hdf5
Introduce HDF5 Datahandler
2020-08-31 16:10:24 +02:00
Matthias
24df8d6bf5 Sort imports 2020-08-31 15:46:31 +02:00
Matthias
8b664644c0 Merge pull request #3733 from freqtrade/docs/clock
Move clock warning to installation pages
2020-08-31 11:24:12 +02:00
Matthias
feb3ae87f7 Merge pull request #3739 from freqtrade/dependabot/pip/develop/pytest-mock-3.3.1
Bump pytest-mock from 3.3.0 to 3.3.1
2020-08-31 09:36:55 +02:00
Matthias
8bb3b6baf3 Merge pull request #3738 from freqtrade/dependabot/pip/develop/ccxt-1.33.72
Bump ccxt from 1.33.52 to 1.33.72
2020-08-31 09:25:19 +02:00
Matthias
96f95c340d Merge pull request #3737 from freqtrade/dependabot/pip/develop/progressbar2-3.52.1
Bump progressbar2 from 3.51.4 to 3.52.1
2020-08-31 09:24:43 +02:00
Matthias
34e586243a Merge pull request #3736 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.11
Bump mkdocs-material from 5.5.8 to 5.5.11
2020-08-31 09:23:35 +02:00
Matthias
aa839c3d2f Merge pull request #3735 from freqtrade/dependabot/pip/develop/flask-cors-3.0.9
Bump flask-cors from 3.0.8 to 3.0.9
2020-08-31 09:23:11 +02:00
Matthias
fbd68dd190 Merge pull request #3734 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.7
Bump prompt-toolkit from 3.0.6 to 3.0.7
2020-08-31 09:22:41 +02:00
dependabot[bot]
c5b8993e9d Bump ccxt from 1.33.52 to 1.33.72
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.33.52 to 1.33.72.
- [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.33.52...1.33.72)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-31 06:38:56 +00:00
dependabot[bot]
8969ab4aa3 Bump pytest-mock from 3.3.0 to 3.3.1
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.3.0 to 3.3.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/v3.3.0...v3.3.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-31 06:38:55 +00:00
dependabot[bot]
55a49bfc53 Bump progressbar2 from 3.51.4 to 3.52.1
Bumps [progressbar2](https://github.com/WoLpH/python-progressbar) from 3.51.4 to 3.52.1.
- [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.4...v3.52.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-31 06:38:38 +00:00
dependabot[bot]
821af9be9e Bump mkdocs-material from 5.5.8 to 5.5.11
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.8 to 5.5.11.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.8...5.5.11)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-31 06:38:36 +00:00
dependabot[bot]
4adf012ee6 Bump flask-cors from 3.0.8 to 3.0.9
Bumps [flask-cors](https://github.com/corydolphin/flask-cors) from 3.0.8 to 3.0.9.
- [Release notes](https://github.com/corydolphin/flask-cors/releases)
- [Changelog](https://github.com/corydolphin/flask-cors/blob/master/CHANGELOG.md)
- [Commits](https://github.com/corydolphin/flask-cors/compare/3.0.8...3.0.9)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-31 06:38:35 +00:00
dependabot[bot]
f83633ff4e Bump prompt-toolkit from 3.0.6 to 3.0.7
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.6 to 3.0.7.
- [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.6...3.0.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-31 06:38:24 +00:00
Matthias
7f74ff53b1 Move clock warning to installation pages 2020-08-31 07:34:43 +02:00
Matthias
cb37166086 Merge pull request #3731 from freqtrade/release_2020.8
Release 2020.8
2020-08-31 06:52:49 +02:00
Matthias
7cbe3cd452 Merge pull request #3730 from freqtrade/allow_pairlists_in_backtesting
[minor] Allow pairlists in backtesting
2020-08-30 10:34:49 +02:00
Matthias
3d39f05c8f Improve release documetation 2020-08-30 10:23:14 +02:00
Matthias
77f2d46e29 Version bump to 2020.8 2020-08-30 10:11:57 +02:00
Matthias
b8aa07a6e8 Merge branch 'master' into release_2020.8 2020-08-30 10:11:45 +02:00
Matthias
842eff95eb Add simple verification to ensure pairlists is iitialized 2020-08-30 10:07:58 +02:00
Matthias
284d39930f Allow using pairlists through dataprovider in backtesting 2020-08-30 10:07:28 +02:00
Matthias
2ae04af694 Improve some doc wording 2020-08-29 10:26:26 +02:00
Matthias
a595d23bf1 Improve comment in test 2020-08-29 10:14:49 +02:00
Matthias
289425a434 Add test for dry-run-cancel order 2020-08-29 10:07:02 +02:00
Matthias
9c20d488a9 Merge branch 'develop' into fix/3084 2020-08-28 15:43:24 +02:00
Matthias
a9e7ee8113 Merge pull request #3683 from freqtrade/logging_endpoints
Logging endpoints
2020-08-27 15:11:17 +02:00
Matthias
dc6d71f651 Improve comment formatting 2020-08-27 14:41:31 +02:00
Matthias
cf719bc5d3 Fix logformat to use epoch timestamp in ms 2020-08-27 12:04:55 +02:00
Matthias
bf5a082358 bufferhandler should log right from the beginning 2020-08-27 11:37:20 +02:00
Matthias
b2373fccfd Adjust tests as send_msg is only called once 2020-08-27 06:35:28 +02:00
Matthias
9c0a3fffd7 Avoid double notifications in case of partially filled buy orders 2020-08-26 22:17:43 +02:00
Matthias
5e75caa917 Adjust tests to new forcesell 2020-08-26 21:55:31 +02:00
Matthias
85e71275d3 Simplify forcesell method by using freqtrade methods 2020-08-26 21:27:09 +02:00
Matthias
add78414e4 Don't overwrite cancel_reason 2020-08-26 21:24:47 +02:00
Matthias
d161b94d72 Allow simulating cancelled orders in dry-run 2020-08-26 21:22:36 +02:00
Matthias
309ea1246a Update config to use single quotes 2020-08-26 20:52:09 +02:00
Matthias
d1fe3c1a3d Merge pull request #3719 from freqtrade/fix/crossed_numpy_types
Allow numpy numbers as comparisons, too
2020-08-26 10:02:55 +02:00
Matthias
9d4ecb625a Allow numpy numbers as comparisons, too 2020-08-26 07:16:29 +02:00
Matthias
21f4aba4e3 Merge pull request #3055 from yazeed/verify_date_on_new_candle_on_get_signal
Verify date on last candle before producing signal
2020-08-25 20:22:48 +02:00
Matthias
605ed90567 Merge pull request #3592 from freqtrade/stoploss_distance
Add stoploss-distance (to current price) to /status output
2020-08-25 19:56:23 +02:00
Matthias
c6ead02da0 Merge pull request #3705 from mschultheiss83/update_bad_exchanges
update bad exchanges
2020-08-25 11:47:51 +02:00
Matthias
3bb69bc1bd Add returns statement to docstring 2020-08-24 17:31:00 +02:00
Matthias
fca11160e4 Improve docstring of is_pair_locked 2020-08-24 17:18:57 +02:00
Matthias
354a406248 Sort imports in interface.py 2020-08-24 11:45:38 +02:00
Matthias
b613fb7bc5 Merge pull request #3707 from freqtrade/update_sandbox_docs
Update sandbox documentation
2020-08-24 11:41:54 +02:00
Matthias
502e21b2cb Add unfilled explanation for sandboxes 2020-08-24 11:17:43 +02:00
Matthias
c272944834 Lock pair until a new candle arrives 2020-08-24 11:09:09 +02:00
Matthias
da097aea6a Merge pull request #3713 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.19
Bump sqlalchemy from 1.3.18 to 1.3.19
2020-08-24 09:29:30 +02:00
dependabot[bot]
7ece7294b2 Bump sqlalchemy from 1.3.18 to 1.3.19
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.18 to 1.3.19.
- [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[bot] <support@github.com>
2020-08-24 07:18:00 +00:00
Matthias
496a9cfb20 Merge pull request #3714 from freqtrade/dependabot/pip/develop/pandas-1.1.1
Bump pandas from 1.1.0 to 1.1.1
2020-08-24 09:13:02 +02:00
Matthias
c3523daa09 Merge pull request #3711 from freqtrade/dependabot/pip/develop/arrow-0.16.0
Bump arrow from 0.15.8 to 0.16.0
2020-08-24 09:04:42 +02:00
Matthias
c1b464f53c Merge pull request #3712 from freqtrade/dependabot/pip/develop/ccxt-1.33.52
Bump ccxt from 1.33.18 to 1.33.52
2020-08-24 09:01:05 +02:00
Matthias
7953c69922 Merge pull request #3709 from freqtrade/dependabot/pip/develop/pytest-mock-3.3.0
Bump pytest-mock from 3.2.0 to 3.3.0
2020-08-24 08:55:36 +02:00
Matthias
c83d6bd1e2 Merge pull request #3708 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.8
Bump mkdocs-material from 5.5.7 to 5.5.8
2020-08-24 08:55:09 +02:00
dependabot[bot]
f22fc8ef3e Bump pandas from 1.1.0 to 1.1.1
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.1.0 to 1.1.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.1.0...v1.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-24 06:45:20 +00:00
dependabot[bot]
0e20b8f530 Bump ccxt from 1.33.18 to 1.33.52
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.33.18 to 1.33.52.
- [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.33.18...1.33.52)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-24 06:45:12 +00:00
dependabot[bot]
74c97369d9 Bump arrow from 0.15.8 to 0.16.0
Bumps [arrow](https://github.com/arrow-py/arrow) from 0.15.8 to 0.16.0.
- [Release notes](https://github.com/arrow-py/arrow/releases)
- [Changelog](https://github.com/arrow-py/arrow/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/arrow-py/arrow/compare/0.15.8...0.16.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-24 06:44:54 +00:00
dependabot[bot]
4c48fe96ed Bump pytest-mock from 3.2.0 to 3.3.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.2.0 to 3.3.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.2.0...v3.3.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-24 06:44:52 +00:00
dependabot[bot]
5799cc51f2 Bump mkdocs-material from 5.5.7 to 5.5.8
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.7 to 5.5.8.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.7...5.5.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-24 06:44:50 +00:00
Matthias
8b767eedfd Merge branch 'develop' into pr/yazeed/3055 2020-08-24 07:21:48 +02:00
Matthias
26f45c8323 Improve logmessage for trailing stoploss 2020-08-24 06:56:56 +02:00
Matthias
38809acde8 Don't rerun for known closed orders 2020-08-24 06:50:43 +02:00
Matthias
8478e083dc Improve wording of sandbox documentation 2020-08-23 21:16:44 +02:00
Matthias
8940ba828f Update sandbox documentation 2020-08-23 21:14:00 +02:00
Matthias
311b55fc24 Merge branch 'develop' into db_keep_orders 2020-08-23 19:31:59 +02:00
Matthias
a55dd8444d Fix loglevel of using_cached-rate 2020-08-23 19:31:35 +02:00
Matthias
c3a367e4f0 Merge branch 'develop' into db_keep_orders 2020-08-23 19:14:57 +02:00
Matthias
ec94961437 Reduce loglevel of "using cached rate" 2020-08-23 19:14:28 +02:00
Matthias
9ba9f73706 Improve logging, don't search for buy orders in refind_lost_order 2020-08-23 16:04:32 +02:00
Matthias
4ecb67d1d1 Merge branch 'develop' into db_keep_orders 2020-08-23 10:36:56 +02:00
Matthias
92d8adf36c Merge pull request #3706 from freqtrade/fix_api_dates
Dates should be changed to UTC to provide the correct timestamp
2020-08-23 10:33:02 +02:00
Matthias
05ec56d906 Dates should be changed to UTC to provide the correct timestamp 2020-08-23 10:16:28 +02:00
Matthias
73417f11f1 Fix rendering issue on readthedocs 2020-08-23 09:11:52 +02:00
Martin Schultheiss
2701a7cb12 update bad exchanges 2020-08-23 09:11:34 +02:00
Matthias
c2707bdd9b Merge pull request #3688 from freqtrade/Fredrik81-stoploss.md
Update stoploss.md
2020-08-23 09:09:26 +02:00
Matthias
d8a6410fd1 Fix small bug when using max-open-trades -1 in backtesting 2020-08-23 09:00:57 +02:00
Matthias
674b510d23 Parametrize fetch_order retry counts 2020-08-22 17:35:42 +02:00
Matthias
3d7e800ff2 Remove test code 2020-08-22 16:08:54 +02:00
Matthias
11e69bdd65 Update open trades too 2020-08-22 15:49:32 +02:00
Matthias
fd33282eb1 Add handle_insufficient exception 2020-08-22 15:48:00 +02:00
Matthias
637147f89c Update sql cheatsheet parentheses 2020-08-22 09:33:35 +02:00
Matthias
3b4446339e Use fetch_order_or_stoploss order 2020-08-22 09:30:25 +02:00
Matthias
f2b390a271 Add fetch_order_or_stoploss wrapper 2020-08-22 09:28:36 +02:00
Matthias
fc2104bfad Fix bug with time when updating order_date 2020-08-22 09:12:09 +02:00
Matthias
39beb5c837 Add method to update fees on closed trades 2020-08-22 08:59:54 +02:00
Matthias
fc42d552ab Convert logs to fstrings 2020-08-22 08:59:50 +02:00
Matthias
2d6bcbb454 Fix small error in trades updating 2020-08-21 19:51:31 +02:00
Fredrik81
0e368b16ab Update stoploss.md 2020-08-21 18:25:45 +02:00
Matthias
3d93236709 Remove unused import 2020-08-21 14:55:47 +02:00
Matthias
301f74fd1b Merge pull request #3418 from freqtrade/hyperopt_colorama_init
Test colorama init again (after the fixes done to progressbar)
2020-08-21 14:54:35 +02:00
Matthias
fa0c8fa0b3 Readd note about windows hyperopt color output 2020-08-21 14:26:23 +02:00
Matthias
357d7714ec Add docstring to update_trade_state 2020-08-21 07:31:22 +02:00
Matthias
3be14933d4 Add comment explaining update_open_orders 2020-08-21 07:24:49 +02:00
Matthias
0b6014fae3 update_trade_state should take the order id directly - not from the trade object 2020-08-21 07:17:52 +02:00
Matthias
838985f6a0 Don't reset open-order-id just yet
it's needed to get the fees
2020-08-21 07:13:13 +02:00
Matthias
c4e597977c Merge pull request #3701 from freqtrade/fix/optimize_reports
Fix bug in backtesting
2020-08-20 20:21:38 +02:00
Matthias
4f1179d85c Test for empty case 2020-08-20 20:11:58 +02:00
Matthias
f5a9001dc0 Handle backtest results without any trades 2020-08-20 19:51:36 +02:00
Matthias
bca24c8b6b Clarify hyperopt dataprovider usage 2020-08-20 19:35:40 +02:00
Fredrik81
55c6e56762 Update stoploss.md 2020-08-19 23:07:03 +02:00
Matthias
42273ae042 Merge pull request #3695 from freqtrade/fix_daily_rpc
Fix daily rpc for webservice
2020-08-19 14:16:24 +02:00
Matthias
3d515ed5bf Merge pull request #3558 from freqtrade/bt_add_maxdrawdown
Revise backtesting export format, add some metrics
2020-08-19 06:39:47 +02:00
Matthias
e206cc9c21 Adjust tests 2020-08-18 20:15:41 +02:00
Matthias
375e671aaf Move formatting of /daily to telegram
so /daily can return numbers in the API
2020-08-18 20:12:14 +02:00
Matthias
d8e1f97465 Fix documentation typo 2020-08-18 19:44:44 +02:00
Matthias
9982ad2f36 Add profit to backtest summary output 2020-08-18 16:59:24 +02:00
Matthias
668d167adc Add docstring to store_backtest_stats 2020-08-18 16:15:24 +02:00
Matthias
4eb17b4daf Remove unneeded function 2020-08-18 15:20:37 +02:00
Matthias
aa866294cd Reformulate documentation 2020-08-18 14:02:22 +02:00
Matthias
ce15c55185 Add libffi-dev to rpi image 2020-08-17 20:24:30 +02:00
Matthias
e0fa549bb4 Merge pull request #3692 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.6
Bump prompt-toolkit from 3.0.5 to 3.0.6
2020-08-17 09:08:59 +02:00
Matthias
53ea6e0a86 Merge pull request #3693 from freqtrade/dependabot/pip/develop/coveralls-2.1.2
Bump coveralls from 2.1.1 to 2.1.2
2020-08-17 09:08:41 +02:00
Matthias
0f5dd6d0fa Merge pull request #3690 from freqtrade/dependabot/pip/develop/pytest-cov-2.10.1
Bump pytest-cov from 2.10.0 to 2.10.1
2020-08-17 08:58:38 +02:00
Matthias
70e213751d Merge pull request #3691 from freqtrade/dependabot/pip/develop/ccxt-1.33.18
Bump ccxt from 1.32.88 to 1.33.18
2020-08-17 08:58:00 +02:00
Matthias
161417b6f4 Merge pull request #3689 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.7
Bump mkdocs-material from 5.5.3 to 5.5.7
2020-08-17 08:57:41 +02:00
dependabot[bot]
30a2df14cb Bump coveralls from 2.1.1 to 2.1.2
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 2.1.1 to 2.1.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/2.1.1...2.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-17 06:25:10 +00:00
dependabot[bot]
c8ddd5654a Bump prompt-toolkit from 3.0.5 to 3.0.6
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.5 to 3.0.6.
- [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.5...3.0.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-17 06:25:04 +00:00
dependabot[bot]
988bff9eae Bump ccxt from 1.32.88 to 1.33.18
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.32.88 to 1.33.18.
- [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.32.88...1.33.18)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-17 06:24:54 +00:00
dependabot[bot]
7af7fb261b Bump pytest-cov from 2.10.0 to 2.10.1
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 2.10.0 to 2.10.1.
- [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.10.0...v2.10.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-17 06:24:50 +00:00
dependabot[bot]
da6672841a Bump mkdocs-material from 5.5.3 to 5.5.7
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.3 to 5.5.7.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.3...5.5.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-17 06:24:49 +00:00
Matthias
a6dac9acf3 Merge pull request #3667 from freqtrade/hyperopt_enable_dataprovider
Hyperopt enable dataprovider
2020-08-17 07:00:48 +02:00
Matthias
1f153f51ee Merge pull request #3660 from freqtrade/hyperopt_default_tests
Move DefaultHyperopt to tests
2020-08-17 06:49:55 +02:00
Fredrik81
d6ea442588 Update stoploss.md 2020-08-17 02:10:56 +02:00
Fredrik81
2a6faaae64 Update stoploss.md 2020-08-17 02:07:32 +02:00
Fredrik81
4619a50097 Update configuration.md 2020-08-17 02:07:25 +02:00
Fredrik81
bd308889fc Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 14:58:06 +02:00
Fredrik81
f8efb87a67 Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 14:57:53 +02:00
Fredrik81
ddba999fe2 Update stoploss.md 2020-08-16 13:44:32 +02:00
Fredrik81
81a75c97cf Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:17:11 +02:00
Fredrik81
5091767276 Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:17:01 +02:00
Fredrik81
8b348fc247 Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:16:35 +02:00
Fredrik81
67e9721274 Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:14:50 +02:00
Fredrik81
4a0c988b67 Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:13:54 +02:00
Fredrik81
e30a38932f Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:13:40 +02:00
Fredrik81
902d40a32a Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:13:27 +02:00
Fredrik81
4ade3daa1e Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:09:19 +02:00
Fredrik81
1ce392f652 Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:05:38 +02:00
Fredrik81
c60192e4bd Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:05:07 +02:00
Fredrik81
bae8e5ed1a Update docs/stoploss.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-16 13:03:56 +02:00
Matthias
cffac3f7b6 Merge pull request #3619 from hroff-1902/cleanup_agefilter
Cleanup AgeFilter, PriceFilter
2020-08-16 09:13:11 +02:00
Fredrik81
b9e46a3c5a Update stoploss.md
Updated documentation to simplify examples
2020-08-16 03:02:10 +02:00
Matthias
56ca37fd8b Also provide stacktrace via log endpoints 2020-08-15 20:15:02 +02:00
Matthias
c2573c998b Remove Hyperopt note about windows 2020-08-15 16:26:47 +02:00
Matthias
cc91d51389 Fix wording in configuration.md 2020-08-15 09:18:00 +02:00
Matthias
142f87b68c Adjust tests to new wordings 2020-08-15 09:11:46 +02:00
Matthias
1cb10d8f8e Merge branch 'develop' into pr/hroff-1902/3619 2020-08-15 09:08:59 +02:00
Matthias
9dd2800b98 Apply some review changes 2020-08-15 09:08:50 +02:00
Matthias
89b9a8cb1f Merge pull request #3396 from freqtrade/fix/broken_getpairs
Use dict for symbol_is_pair
2020-08-15 08:58:53 +02:00
Matthias
f3d4b114bb Skip windows test failure 2020-08-15 08:47:09 +02:00
Matthias
1ffa3d1ae0 Improve telegram message formatting 2020-08-15 08:31:36 +02:00
Matthias
f5863a1c6f Fix mypy errors 2020-08-15 08:15:47 +02:00
Matthias
9659e516c8 Remove queue import
Improve tests
2020-08-14 20:35:15 +02:00
Matthias
c4f78203ab Initialize streamhandler early to have it apply to all logs 2020-08-14 20:08:55 +02:00
Matthias
cdfcdb86c9 Increase logfile size 2020-08-14 20:00:09 +02:00
Matthias
251eb5aa96 Test for bufferingHandler too 2020-08-14 19:51:50 +02:00
Matthias
122c0e8ddc Readd accidentally dropped StreamHandler 2020-08-14 19:50:56 +02:00
Matthias
200de312fe Merge pull request #3677 from Blackhawke/develop
improve Edge documentation
2020-08-14 19:43:10 +02:00
Matthias
9ad8e74247 Add tests for log-endpoints 2020-08-14 19:41:27 +02:00
Matthias
5d691b5ee3 Fix warning box typo 2020-08-14 19:34:22 +02:00
Blackhawke
f3cedc849a Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-14 09:27:04 -07:00
Blackhawke
a14ce9d7d9 Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-14 09:26:28 -07:00
Blackhawke
47b215fe0a Update docs/edge.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-08-14 09:25:53 -07:00
Matthias
904c4ecc23 Document /logs endpoints 2020-08-14 15:44:52 +02:00
Matthias
5f79caa307 Implement /logs endpoints in telegram and restAPI 2020-08-14 15:44:36 +02:00
Matthias
b989ba0f82 Simplify setup of handlers 2020-08-14 14:53:21 +02:00
Matthias
48944fd4cb Logging with queueHandler 2020-08-14 14:41:46 +02:00
Matthias
06125df10c Remove unused import 2020-08-14 11:31:02 +02:00
Matthias
d8fdd32b54 FIx migrations 2020-08-14 11:25:40 +02:00
Matthias
cfa352ecf2 Disable refind_lost_order for now 2020-08-14 11:25:20 +02:00
Matthias
b25267ad3d Build docker image for db_keep_orders branch 2020-08-14 11:13:55 +02:00
Matthias
552aaf7945 add refind order logic 2020-08-14 10:59:55 +02:00
Matthias
22af82631a Introduce InsufficientFundsError exception 2020-08-14 09:57:13 +02:00
Matthias
a6fc922f28 Introduce insufficientFunds Exception 2020-08-14 09:56:48 +02:00
Matthias
8458a380b8 Improve order catchup 2020-08-14 09:52:47 +02:00
Matthias
95efc0d688 Add open_order_updater 2020-08-14 09:52:47 +02:00
Matthias
c4d7aff5c3 Order should have a "is_open" flag 2020-08-14 09:52:47 +02:00
Matthias
da2a515d0b Add delete cascade to alchemy model 2020-08-14 09:52:46 +02:00
Matthias
1a305ea8b0 Fix migrations to use unique key 2020-08-14 09:52:46 +02:00
Matthias
2ca6547baf Update tests to have unique ordernumbers 2020-08-14 09:52:46 +02:00
Matthias
4434a54d59 Add unique key to order-Model 2020-08-14 09:52:46 +02:00
Matthias
ebd755e36a Improve order handling 2020-08-14 09:52:46 +02:00
Matthias
0af9e913d4 Timestamps are in ms 2020-08-14 09:52:46 +02:00
Matthias
73182bb2dd Update migrations to populate Orders table for open orders 2020-08-14 09:52:46 +02:00
Matthias
396e781bf4 Update orders 2020-08-14 09:52:46 +02:00
Matthias
4924d8487e Extract "update order from ccxt" to it's onw function 2020-08-14 09:52:46 +02:00
Matthias
ee7b235cdc Improve tests to use open_order mock where applicable 2020-08-14 09:52:46 +02:00
Matthias
420a8c2b1c Improve tests for rpc/forcebuy 2020-08-14 09:52:46 +02:00
Matthias
a66a3d047f Remove unneeded mocks 2020-08-14 09:52:46 +02:00
Matthias
ed87abd93a Allow selecting only a certain table range in migration 2020-08-14 09:52:46 +02:00
Matthias
171a52b21a Introduce Order database model 2020-08-14 09:52:46 +02:00
Matthias
7d03a067ee Extract migrations ot seperate module 2020-08-14 09:52:46 +02:00
Matthias
044df880e6 Move persistence into it's own submodule 2020-08-14 09:52:46 +02:00
Matthias
93717cfef1 Merge pull request #3008 from yazeed/more_info_hyperopt_fixed
Wins/draws/losses/median profit in hyperopt output
2020-08-14 09:25:12 +02:00
Matthias
b98107375e Improve formatting of result string to be a bit conciser 2020-08-14 07:31:14 +02:00
Matthias
d76ee43246 Show wins / draws / losses in hyperopt table 2020-08-14 07:14:10 +02:00
Matthias
22f6e884ed Merge pull request #3676 from freqtrade/stoploss_remove_unused_argument
[minor] Cleanup and exception hierarchy documentation
2020-08-14 07:11:56 +02:00
Matthias
05bd099f51 Merge branch 'develop' into pr/yazeed/3008 2020-08-14 06:58:09 +02:00
Matthias
4109b31dac Update wording in documentation 2020-08-14 06:46:34 +02:00
Matthias
067d1fd72a Merge pull request #3553 from qkum/patch-3
Update faq.md
2020-08-13 08:20:03 +02:00
Matthias
6b85b1a34d Don't only recommend pycharm, but keep it open to other editors too. 2020-08-13 08:06:57 +02:00
Matthias
e45e41adb4 Improve docs test to catch !!! errors 2020-08-13 08:05:05 +02:00
Matthias
1dabade883 small rewording of FAQ documentation 2020-08-13 08:02:36 +02:00
Matthias
c6741ea6c3 Merge branch 'develop' into fix/broken_getpairs 2020-08-12 20:13:06 +02:00
Matthias
5d61c56650 Merge pull request #3597 from freqtrade/fix/3579
consistently use filled before amount from orders
2020-08-12 19:56:57 +02:00
Blackhawke
827c31d4bc Re-arranged the introduction to better explain the theory of operation and the limitations of Edge. Added paragraphs at the bottom of "running edge independently" to better explain Edge's order of operations processing and potential differences between historical output and live/dry-run operation. 2020-08-12 09:42:16 -07:00
Matthias
3afd5b631e Remove erroneous import 2020-08-12 15:34:29 +02:00
Matthias
815d88fd4a Fix test after merge, fix forgotten 'amount' 2020-08-12 15:32:56 +02:00
Matthias
9999d0ffb5 Merge branch 'develop' into fix/3579 2020-08-12 15:28:51 +02:00
Matthias
faa2bbb555 Document exception hierarchy 2020-08-12 14:29:14 +02:00
Matthias
6dfa159a91 Small comment adjustments in exchange class 2020-08-12 14:11:19 +02:00
Matthias
7cf3e15e54 Merge pull request #3091 from yazeed/min-max-objective
--min-objective and --max-objective for hyperopt-list
2020-08-12 14:05:05 +02:00
Matthias
1f1a819b29 Remove unused 3rd argument to create_stoploss call 2020-08-12 11:21:00 +02:00
Matthias
2fed066e76 Simplify objective code formatting 2020-08-12 10:40:44 +02:00
Matthias
2dc36bb79e Remove inversion of min/max objective selection 2020-08-11 20:52:18 +02:00
Matthias
56655b97cf Refactor hyperopt_filter method 2020-08-11 20:37:01 +02:00
Matthias
f51c03aa86 Revert changes to color using --no-color 2020-08-11 20:29:47 +02:00
Matthias
77541935a8 Fix small merge mistake 2020-08-11 20:18:49 +02:00
Matthias
688d657fe2 Merge branch 'develop' into pr/yazeed/3091 2020-08-11 20:04:43 +02:00
Matthias
dda78677a0 Merge pull request #3649 from freqtrade/improve_cancel_order_handling
Better handle cancelled buy orders
2020-08-11 19:58:05 +02:00
Matthias
d77c53960d Show API backoff in logs to better investigate eventual problems) 2020-08-11 19:27:25 +02:00
Matthias
c9c43d2f0b Move log-message of retrying before decrementing count
Otherwise the message is always one round "late".
2020-08-11 15:27:41 +02:00
Matthias
064928a0eb Merge branch 'develop' into improve_cancel_order_handling 2020-08-11 15:25:47 +02:00
Matthias
52eae04945 Merge pull request #3670 from freqtrade/dependabot/pip/develop/ccxt-1.32.88
Bump ccxt from 1.32.45 to 1.32.88
2020-08-10 20:37:40 +02:00
Matthias
0d96a311f7 Merge pull request #3669 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.3
Bump mkdocs-material from 5.5.1 to 5.5.3
2020-08-10 20:23:02 +02:00
dependabot[bot]
1afe4df7be Bump ccxt from 1.32.45 to 1.32.88
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.32.45 to 1.32.88.
- [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.32.45...1.32.88)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-10 06:17:36 +00:00
dependabot[bot]
17613f203a Bump mkdocs-material from 5.5.1 to 5.5.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.1 to 5.5.3.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.1...5.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-10 06:17:04 +00:00
Matthias
2663aede24 Update test to reflect new column naming 2020-08-09 10:28:11 +02:00
Matthias
b576e1d463 Merge branch 'develop' into bt_add_maxdrawdown 2020-08-09 10:25:57 +02:00
Matthias
87e4a82041 Merge branch 'develop' into bt_add_maxdrawdown 2020-08-09 08:34:36 +02:00
Matthias
fca41a44bb Also logg timeframe 2020-08-08 20:20:58 +02:00
Matthias
3670be5dd2 Merge pull request #3641 from freqtrade/fix/edgeremovebumps
Fix edge with removebumps enabled
2020-08-08 17:33:08 +02:00
Matthias
2afe1d5b11 Add link to full sample 2020-08-08 17:30:31 +02:00
Matthias
09aa954b68 Update strategy-customization documentation 2020-08-08 17:24:19 +02:00
Matthias
5e1032c4af Simplify strategy documentation, move "substrategies" to advanced page 2020-08-08 17:08:38 +02:00
Matthias
dd430455e4 Enable dataprovier for hyperopt 2020-08-08 17:04:32 +02:00
Matthias
e2643103b6 Merge pull request #3611 from thopd88/telegram-delete-command
Add telegram /delete command
2020-08-08 15:19:40 +02:00
Matthias
f3ce54150e Simplify Telegram table 2020-08-08 15:06:13 +02:00
Matthias
02810adcf7 Merge pull request #3662 from freqtrade/Fredrik81-patch-1
Update strategy_methods_advanced.j2
2020-08-07 06:23:22 +02:00
Fredrik81
eba73307e4 Update strategy_methods_advanced.j2
Fix def confirm_trade_exit arguments
2020-08-07 01:13:36 +02:00
Matthias
d01070dba8 Increase coverage of edge_cli 2020-08-06 09:22:41 +02:00
Matthias
995d3e1ed5 Don't search internal path for Hyperopt files 2020-08-06 09:07:48 +02:00
Matthias
59370672b8 Fix more tests 2020-08-06 09:00:28 +02:00
Matthias
081625c5dc Have hyperopt tests use new hyperopt location 2020-08-06 08:51:01 +02:00
Matthias
8b6d10daf1 Move DefaultHyperopt to test folder (aligned to strategy) 2020-08-06 08:50:41 +02:00
Matthias
5082acc33f Fix typos in documentation 2020-08-06 07:54:54 +02:00
Matthias
767332405e Merge pull request #3642 from freqtrade/new_release
New release 2020.7
2020-08-06 06:50:08 +02:00
Matthias
8ed3b81c61 Implement /delete in rest client 2020-08-04 19:57:28 +02:00
Matthias
075c73b9e3 Improve formatting of telegram message 2020-08-04 19:56:49 +02:00
Matthias
817f5289db /delete should Cancel open orders (and stoploss orders) 2020-08-04 19:43:22 +02:00
Matthias
9163c7f3d3 Improve api response 2020-08-04 19:43:05 +02:00
Matthias
b954af33cf Fix type erorr in callable 2020-08-04 16:01:41 +02:00
Matthias
4b0164770c Add test for /delete 2020-08-04 14:49:59 +02:00
Matthias
26c7341b7d Add test for api-server DELETE trade 2020-08-04 14:41:38 +02:00
Matthias
215972c68f Implement /delete for api-server 2020-08-04 14:41:22 +02:00
Matthias
c0083c4244 Merge branch 'develop' into pr/thopd88/3611 2020-08-04 07:00:54 +02:00
Matthias
b22fabe1f3 Merge pull request #3651 from freqtrade/dependabot/pip/develop/pytest-6.0.1
Bump pytest from 5.4.3 to 6.0.1
2020-08-03 21:31:31 +02:00
Matthias
a3688b159f Improve formatting 2020-08-03 19:28:57 +02:00
Matthias
a33346c6b6 Fix testing errors - which surfaced with pytest 6.0.1 2020-08-03 19:22:07 +02:00
Matthias
55233db07e Merge pull request #3654 from freqtrade/dependabot/pip/develop/ccxt-1.32.45
Bump ccxt from 1.32.7 to 1.32.45
2020-08-03 09:42:57 +02:00
Matthias
54bee1d183 Merge pull request #3653 from freqtrade/dependabot/pip/develop/pandas-1.1.0
Bump pandas from 1.0.5 to 1.1.0
2020-08-03 09:40:24 +02:00
Matthias
45256763ca Merge pull request #3652 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.1
Bump mkdocs-material from 5.5.0 to 5.5.1
2020-08-03 09:36:01 +02:00
dependabot[bot]
b3f04d89d2 Bump ccxt from 1.32.7 to 1.32.45
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.32.7 to 1.32.45.
- [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.32.7...1.32.45)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-03 07:17:50 +00:00
dependabot[bot]
1855a444fa Bump pandas from 1.0.5 to 1.1.0
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.0.5 to 1.1.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/v1.0.5...v1.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-03 07:17:32 +00:00
dependabot[bot]
809b3ddafc Bump mkdocs-material from 5.5.0 to 5.5.1
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.5.0 to 5.5.1.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.5.0...5.5.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-03 07:17:31 +00:00
dependabot[bot]
5ff09a06c7 Bump pytest from 5.4.3 to 6.0.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.4.3 to 6.0.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.4.3...6.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-03 07:17:30 +00:00
Matthias
3915101d2d Add more backoff to fetch_order endpoint 2020-08-02 10:32:17 +02:00
Matthias
6c77feee85 Improve some exchange logs 2020-08-02 10:18:19 +02:00
Matthias
99bfa839eb Improve logging for sell exception 2020-08-02 10:12:15 +02:00
Matthias
071e82043a Better handle cancelled buy orders 2020-08-01 15:59:50 +02:00
Matthias
7263f83f78 Version bump 2020.7 2020-07-28 19:53:05 +02:00
Matthias
653bbc292b Merge branch 'master' into new_release 2020-07-28 19:52:44 +02:00
Matthias
d1cbc567e4 Fix filtering for bumped pairs 2020-07-28 13:41:09 +02:00
Matthias
14cb29aae1 Add test for remove_pumps in edge 2020-07-28 08:16:55 +02:00
Matthias
f3af02c06f Merge pull request #3635 from freqtrade/dependabot/pip/develop/ccxt-1.32.7
Bump ccxt from 1.32.3 to 1.32.7
2020-07-27 09:23:23 +02:00
dependabot[bot]
7318d02ebc Bump ccxt from 1.32.3 to 1.32.7
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.32.3 to 1.32.7.
- [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.32.3...1.32.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-27 07:05:17 +00:00
Matthias
aab5596fa6 Convert trade open / close to timestamp
(to allow uniform analysis of backtest and real trade data - while
giving control of date-formatting to the endsystem.
2020-07-27 07:20:40 +02:00
Matthias
977a6d4e9c Add profit_total to results line 2020-07-26 16:10:48 +02:00
Matthias
454046f745 Add stake_currency and max_opeN_trades to backtest result 2020-07-26 15:55:54 +02:00
Matthias
8d0f338bf2 Timestamps should be in ms 2020-07-26 15:23:21 +02:00
Matthias
9ed5fed887 Fix output format to be of an identical type 2020-07-26 15:17:54 +02:00
Matthias
902e8fa62f Fix wrong spelling in one subcomponent 2020-07-26 14:39:00 +02:00
Matthias
65755989b4 Merge pull request #3631 from freqtrade/dependabot/pip/develop/mkdocs-material-5.5.0
Bump mkdocs-material from 5.4.0 to 5.5.0
2020-07-26 14:00:00 +02:00
Matthias
7a51bfbaba Merge pull request #3628 from freqtrade/dependabot/pip/develop/scipy-1.5.2
Bump scipy from 1.5.1 to 1.5.2
2020-07-26 13:28:42 +02:00
Matthias
fe27d2c10d Merge pull request #3629 from freqtrade/dependabot/pip/develop/urllib3-1.25.10
Bump urllib3 from 1.25.9 to 1.25.10
2020-07-26 13:27:42 +02:00
Matthias
90034a8e5e Merge pull request #3632 from freqtrade/dependabot/pip/develop/ccxt-1.32.3
Bump ccxt from 1.31.37 to 1.32.3
2020-07-26 11:23:26 +02:00
Matthias
1cfbbfb433 Merge pull request #3633 from freqtrade/dependabot/pip/develop/plotly-4.9.0
Bump plotly from 4.8.2 to 4.9.0
2020-07-26 11:11:54 +02:00
Matthias
73042781f4 Merge pull request #3630 from freqtrade/dependabot/pip/develop/numpy-1.19.1
Bump numpy from 1.19.0 to 1.19.1
2020-07-26 11:11:23 +02:00
dependabot[bot]
dbcccac6cd Bump ccxt from 1.31.37 to 1.32.3
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.31.37 to 1.32.3.
- [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.31.37...1.32.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-26 08:53:51 +00:00
dependabot[bot]
b4d22f1000 Bump urllib3 from 1.25.9 to 1.25.10
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.25.9 to 1.25.10.
- [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.9...1.25.10)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-26 08:53:36 +00:00
Matthias
364295d2b3 Merge pull request #3627 from freqtrade/dependabot/pip/develop/arrow-0.15.8
Bump arrow from 0.15.7 to 0.15.8
2020-07-26 10:52:50 +02:00
dependabot[bot]
63e7490a55 Bump plotly from 4.8.2 to 4.9.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.8.2 to 4.9.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.8.2...v4.9.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-26 08:37:45 +00:00
dependabot[bot]
838743bf01 Bump mkdocs-material from 5.4.0 to 5.5.0
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/5.4.0...5.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-26 08:37:25 +00:00
dependabot[bot]
2ff03e173d Bump numpy from 1.19.0 to 1.19.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.19.0 to 1.19.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.19.0...v1.19.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-26 08:37:17 +00:00
dependabot[bot]
d1d6f69e43 Bump scipy from 1.5.1 to 1.5.2
Bumps [scipy](https://github.com/scipy/scipy) from 1.5.1 to 1.5.2.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.5.1...v1.5.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-26 08:37:13 +00:00
dependabot[bot]
6ce4fd7aff Bump arrow from 0.15.7 to 0.15.8
Bumps [arrow](https://github.com/arrow-py/arrow) from 0.15.7 to 0.15.8.
- [Release notes](https://github.com/arrow-py/arrow/releases)
- [Changelog](https://github.com/arrow-py/arrow/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/arrow-py/arrow/compare/0.15.7...0.15.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-26 08:37:10 +00:00
Matthias
bad89307dd Fix mypy error 2020-07-25 17:19:41 +02:00
Matthias
119bf2a8ea Document hdf5 dataformat 2020-07-25 17:06:58 +02:00
Matthias
db8f3a9e9b Merge pull request #3609 from thopd88/develop
Add telegram /trades command
2020-07-25 16:45:09 +02:00
Matthias
edb582e522 Add more tests 2020-07-24 20:40:07 +02:00
Matthias
ae1c99bdd0 more tests 2020-07-24 20:36:30 +02:00
Matthias
ed33d4781d Add more hdf5 tests 2020-07-24 20:19:34 +02:00
Matthias
d9b339ee18 Add some more tests for hdf5 2020-07-24 20:09:59 +02:00
Matthias
0a28818b46 Add some tests for hdf5 2020-07-24 19:37:37 +02:00
Matthias
e26e658f99 Improve a few tests 2020-07-24 19:33:27 +02:00
Matthias
6a0c84b649 Add tests for hdf5 2020-07-24 19:23:56 +02:00
Matthias
861e7099cc Rename hdf5handler to hdf5DataHandler 2020-07-24 19:23:37 +02:00
Matthias
3171ad33b7 Add blosc compression 2020-07-24 17:44:29 +02:00
Matthias
0f08addfbe Don't store empty arrays 2020-07-24 17:37:07 +02:00
Matthias
31df42e737 Implement get_available_data 2020-07-24 17:31:43 +02:00
Matthias
d4540c846a Add trades_load method 2020-07-23 19:33:23 +02:00
Matthias
55591e287c First version of hdf5handler - no proper support for trades yet 2020-07-23 19:33:23 +02:00
Matthias
0614e59966 Add tables dependency 2020-07-23 19:33:23 +02:00
Matthias
e0c14e6214 Add /trades to help (so users know about it) 2020-07-23 07:56:05 +02:00
Matthias
fdc84eef59 /trades shall only return closed trades 2020-07-23 07:50:45 +02:00
Matthias
8300eb59d4 Extend create_mock_trades to create 4 trades
2 closed, and 2 open trades
2020-07-23 07:50:28 +02:00
Matthias
0f18b2a0d4 Add test and fix case where no trades were closed yet 2020-07-23 07:12:14 +02:00
thopd88
0bad55637e fix flake8 indent error 2020-07-23 10:12:52 +07:00
thopd88
a3daf8e41c Fix line too long 2020-07-23 09:47:53 +07:00
thopd88
0502fe0496 New /trades 3 columns and exclude open trades 2020-07-23 09:36:05 +07:00
hroff-1902
f48250b414 Make flake happy 2020-07-22 22:56:24 +03:00
hroff-1902
50767cd569 Adjust tests for AgeFilter 2020-07-22 22:48:29 +03:00
hroff-1902
5c2481082e Add tests for PriceFilter 2020-07-22 22:46:30 +03:00
hroff-1902
c78199d3d9 Add checks for parameters of PriceFilter 2020-07-22 22:45:46 +03:00
hroff-1902
a1e292f56a Improve docs 2020-07-22 22:09:30 +03:00
hroff-1902
daee414d7a Fix docs formatting 2020-07-22 21:51:25 +03:00
hroff-1902
5213abf510 AgeFilter is always enabled 2020-07-22 21:44:39 +03:00
hroff-1902
f6bde8bd9c Improve exception message wordings 2020-07-22 21:43:15 +03:00
Matthias
7e980037a4 Merge pull request #3554 from jblestang/Fix_#3544
Adding a dataprovider to the strategy before plotting
2020-07-22 15:56:16 +02:00
Matthias
f5f529cace Use correct initialization of DataProvider 2020-07-22 15:17:45 +02:00
Matthias
b060164b1f Merge pull request #3618 from freqtrade/dependabot/docker/python-3.8.5-slim-buster
Bump python from 3.8.4-slim-buster to 3.8.5-slim-buster
2020-07-22 08:41:26 +02:00
dependabot[bot]
2a5f8d8895 Bump python from 3.8.4-slim-buster to 3.8.5-slim-buster
Bumps python from 3.8.4-slim-buster to 3.8.5-slim-buster.

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-22 06:22:45 +00:00
hroff-1902
dbf4d1a694 Merge pull request #3616 from freqtrade/fix/pairfilter
Fix pairfilter crash
2020-07-21 23:09:06 +03:00
Matthias
6a10c715fa Fix 0 division (if last = 0, something went wrong!) 2020-07-21 20:34:29 +02:00
Matthias
939f91734f Test confirming 0 division ... 2020-07-21 20:34:19 +02:00
hroff-1902
d8fa17cee8 Merge pull request #3614 from freqtrade/info_message_hyperopt
[minor] Reduce severity of hyperopt "does not provide" messages
2020-07-21 00:14:18 +03:00
hroff-1902
844ff1e068 Merge pull request #3613 from freqtrade/webhook/trade_id
Add trade_id to webhooks
2020-07-21 00:10:53 +03:00
Matthias
7d6708fc6a Reduce severity of hyperopt "does not provide" messages
closes #3371
2020-07-20 20:04:23 +02:00
Matthias
21dcef1134 Add trade_id to webhooks
allowing for easier corelation of different messages
2020-07-20 19:57:05 +02:00
Matthias
4774896169 Evaluate average before price in order returns 2020-07-20 19:39:12 +02:00
Matthias
4c97527b04 FIx failing test 2020-07-20 19:11:15 +02:00
hroff-1902
22c8f845ec Merge pull request #3606 from freqtrade/docs/informative
Improve informative pair sample
2020-07-20 19:22:48 +03:00
hroff-1902
b7c6f868b2 Merge pull request #3478 from hroff-1902/exchange-cosmetics-5
Minor: Exchange cosmetics
2020-07-20 18:58:46 +03:00
Matthias
3955fc6190 Merge pull request #3612 from freqtrade/fix-doc-sqlrequest
missing coma in sql request
2020-07-20 08:58:13 +02:00
gautier pialat
811028ae92 missing coma in sql request 2020-07-20 07:17:34 +02:00
thopd88
eaa7370174 add /delete command 2020-07-20 11:08:18 +07:00
thopd88
28f4a1101e Revert "Add telegram /delete command to delete tradeid"
This reverts commit 08fdd7d863.
2020-07-20 10:54:17 +07:00
Matthias
263dcd221d Merge pull request #3608 from thopd88/patch-1
Fix SQL syntax error when compare pair strings in rpc_forcebuy
2020-07-19 19:28:08 +02:00
Matthias
772473e93e Merge pull request #3610 from pan-long/develop
Correct a typo in stop loss doc.
2020-07-19 19:20:24 +02:00
Pan Long
37a9edfa35 Correct a typo in stop loss doc. 2020-07-20 00:37:06 +08:00
thopd88
08fdd7d863 Add telegram /delete command to delete tradeid
code inspired from _rpc_forcesell
2020-07-19 22:10:59 +07:00
thopd88
dd3a2675b5 Add telegram trades command to list recent trades 2020-07-19 22:02:53 +07:00
Alex Pham
3271c773a7 Fix SQL syntax error when compare pair strings
First happens in Postgres
2020-07-19 21:30:55 +07:00
Matthias
49395601e9 Improve informative pair sample 2020-07-19 10:02:06 +02:00
Matthias
ea1ddeb87d Merge pull request #3570 from gambcl/develop
Added range checks to min_days_listed in AgeFilter
2020-07-19 09:37:17 +02:00
Matthias
d849b32a02 Merge pull request #3601 from freqtrade/dependabot/pip/develop/ccxt-1.31.37
Bump ccxt from 1.30.93 to 1.31.37
2020-07-16 09:46:31 +02:00
dependabot[bot]
cd7ba99528 Bump ccxt from 1.30.93 to 1.31.37
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.30.93 to 1.31.37.
- [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.30.93...1.31.37)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-16 07:23:16 +00:00
Matthias
288a2bdbb0 Merge pull request #3599 from freqtrade/dependabot/add-v2-config-file
Update Dependabot config file
2020-07-16 09:22:29 +02:00
dependabot-preview[bot]
eaf2b53d59 Update Dependabot config file 2020-07-16 05:10:46 +00:00
Matthias
de46744aa9 Use filled before amount for order data
closes #3579
2020-07-15 21:08:16 +02:00
Matthias
98f2e79f27 Adjust tests to use correctly trimmed amount 2020-07-15 20:55:33 +02:00
Matthias
3721736aaf Convert to real amount before placing order
to keep the correct amount in the database
2020-07-15 20:28:07 +02:00
Matthias
c1c018d8fe Fix tests that require amount_requested 2020-07-15 20:27:00 +02:00
Matthias
eafab38db3 Complete implementation of amount_requested 2020-07-15 20:20:14 +02:00
Matthias
c826f7a707 Add amount_requested to database 2020-07-15 20:15:29 +02:00
hroff-1902
18a5822a33 Merge pull request #3596 from freqtrade/fix/0fee
Allow 0 fee value by correctly checking for None
2020-07-15 20:52:32 +03:00
Matthias
d13cb4c055 Introduce safe_value_fallback_2 2020-07-15 19:50:09 +02:00
Matthias
5cebc9f39d Move stoploss_on_exchange_limit_ratio to configuration schema 2020-07-15 19:28:40 +02:00
Matthias
c1191400a4 Allow 0 fee value by correctly checking for None 2020-07-15 19:20:20 +02:00
gambcl
1051ab917a Replaced logging with OperationalException when AgeFilter given invalid parameters 2020-07-15 12:40:54 +01:00
Matthias
82c68f07cd Add stoploss-distance (to current price) to /status output 2020-07-14 20:16:18 +02:00
Matthias
bdf611352e Update summary-metrics output 2020-07-14 19:34:01 +02:00
Matthias
2417898d00 Apply documentation suggestions from code review
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-07-14 19:27:52 +02:00
hroff-1902
0f4fc67b83 Merge pull request #3582 from freqtrade/data/list
List available backtesting data
2020-07-14 19:38:32 +03:00
Matthias
0228b63418 Don't print empty table 2020-07-14 16:42:47 +02:00
Matthias
0ca81480d4 Merge pull request #3590 from freqtrade/dependabot/docker/python-3.8.4-slim-buster
Bump python from 3.8.3-slim-buster to 3.8.4-slim-buster
2020-07-14 09:48:51 +02:00
dependabot-preview[bot]
ae55d54967 Bump python from 3.8.3-slim-buster to 3.8.4-slim-buster
Bumps python from 3.8.3-slim-buster to 3.8.4-slim-buster.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-14 06:33:57 +00:00
Matthias
62c55b1863 Enhance formatting, Add pair filter 2020-07-14 06:55:34 +02:00
hroff-1902
43a1fe6d08 Merge pull request #3589 from freqtrade/api/timeframe_ms
[minor] Send timeframe min and ms in show_config response
2020-07-13 23:24:30 +03:00
Matthias
01f325a9e4 Send timeframe min and ms in show_config response 2020-07-13 21:15:33 +02:00
Matthias
0b36693acc Add filter for stoploss_on_exchange_limit_ratio to constants 2020-07-13 19:48:21 +02:00
Matthias
c2acf4bb82 Merge pull request #3584 from freqtrade/dependabot/pip/develop/pytest-mock-3.2.0
Bump pytest-mock from 3.1.1 to 3.2.0
2020-07-13 12:22:51 +02:00
Matthias
89c634c70d Merge pull request #3586 from freqtrade/dependabot/pip/develop/ccxt-1.30.93
Bump ccxt from 1.30.64 to 1.30.93
2020-07-13 12:22:21 +02:00
Matthias
e4b5bbe117 Merge pull request #3587 from freqtrade/dependabot/pip/develop/coveralls-2.1.1
Bump coveralls from 2.0.0 to 2.1.1
2020-07-13 12:21:53 +02:00
Matthias
b0b76091c8 Merge pull request #3585 from freqtrade/dependabot/pip/develop/pycoingecko-1.3.0
Bump pycoingecko from 1.2.0 to 1.3.0
2020-07-13 12:21:26 +02:00
dependabot-preview[bot]
50573bd397 Bump coveralls from 2.0.0 to 2.1.1
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 2.0.0 to 2.1.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/2.0.0...2.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 09:02:07 +00:00
dependabot-preview[bot]
d1e4e463ae Bump ccxt from 1.30.64 to 1.30.93
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.30.64 to 1.30.93.
- [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.30.64...1.30.93)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 09:01:58 +00:00
dependabot-preview[bot]
58eb26d73a Bump pycoingecko from 1.2.0 to 1.3.0
Bumps [pycoingecko](https://github.com/man-c/pycoingecko) from 1.2.0 to 1.3.0.
- [Release notes](https://github.com/man-c/pycoingecko/releases)
- [Changelog](https://github.com/man-c/pycoingecko/blob/master/CHANGELOG.md)
- [Commits](https://github.com/man-c/pycoingecko/compare/1.2.0...1.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 09:01:14 +00:00
dependabot-preview[bot]
79af6180bd Bump pytest-mock from 3.1.1 to 3.2.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.1.1 to 3.2.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.1.1...v3.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-13 09:00:50 +00:00
Matthias
6ee6e51ab4 Merge branch 'develop' into pr/hroff-1902/3478 2020-07-13 07:22:43 +02:00
Matthias
3811f4692b Merge pull request #3577 from freqtrade/fix/doctypo
[minor] Fix typo in docs, install sqlite3 in docker image
2020-07-12 12:50:04 +02:00
Matthias
ed2e35ba5d Update docs/sql_cheatsheet.md
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-07-12 12:36:16 +02:00
Matthias
b035d9e267 Update return type comment 2020-07-12 10:23:09 +02:00
Matthias
33c3990972 Add documentation for list-data command 2020-07-12 10:05:47 +02:00
Matthias
5bb81abce2 Add test for start_list_data 2020-07-12 10:01:51 +02:00
Matthias
02afde857d Add list-data command 2020-07-12 09:57:00 +02:00
Matthias
d4fc52d2d5 Add tests for ohlcv_get_available_data 2020-07-12 09:56:46 +02:00
Matthias
422825ea1b Add ohlcv_get_available_data to find available data 2020-07-12 09:50:53 +02:00
hroff-1902
a4b0e8117a Merge pull request #3580 from BlueSkyTrading/patch-2
removed duplicate
2020-07-11 22:37:52 +03:00
HumanBot
f0a1a1720f removed duplicate
removed duplicate word using using
2020-07-11 15:21:54 -04:00
Matthias
ecbca3fab0 Add sqlite3 to dockerfile 2020-07-11 09:13:39 +02:00
Matthias
588043af86 Fix documentation brackets, add delete trade hints 2020-07-11 07:29:11 +02:00
Matthias
40bdc93653 Add test for short_desc of priceFilter 2020-07-10 20:28:29 +02:00
gambcl
14eab9be04 Added min_price, max_price to PriceFilter 2020-07-08 22:02:04 +01:00
gambcl
091285ba43 Fix flake8 error in test_pairlist.py 2020-07-08 18:32:14 +01:00
gambcl
2e45859aef Added range checks to min_days_listed in AgeFilter 2020-07-08 18:06:30 +01:00
Matthias
86cf6201c8 Merge pull request #3560 from freqtrade/dependabot/pip/develop/scipy-1.5.1
Bump scipy from 1.5.0 to 1.5.1
2020-07-07 21:54:01 +02:00
Matthias
e0c767614f Merge pull request #3561 from freqtrade/dependabot/pip/develop/ccxt-1.30.64
Bump ccxt from 1.30.48 to 1.30.64
2020-07-07 21:53:31 +02:00
dependabot-preview[bot]
deb34d2879 Bump scipy from 1.5.0 to 1.5.1
Bumps [scipy](https://github.com/scipy/scipy) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.5.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-06 19:58:28 +00:00
Matthias
779a8401a8 Merge pull request #3563 from freqtrade/dependabot/pip/develop/joblib-0.16.0
Bump joblib from 0.15.1 to 0.16.0
2020-07-06 21:57:14 +02:00
Matthias
087a38ab78 Merge pull request #3562 from freqtrade/dependabot/pip/develop/mkdocs-material-5.4.0
Bump mkdocs-material from 5.3.3 to 5.4.0
2020-07-06 21:53:47 +02:00
dependabot-preview[bot]
93dd70c77d Bump joblib from 0.15.1 to 0.16.0
Bumps [joblib](https://github.com/joblib/joblib) from 0.15.1 to 0.16.0.
- [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.15.1...0.16.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-06 09:13:05 +00:00
dependabot-preview[bot]
4c8bee1e5d Bump mkdocs-material from 5.3.3 to 5.4.0
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 5.3.3 to 5.4.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/5.3.3...5.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-06 09:12:15 +00:00
dependabot-preview[bot]
f63045b0e9 Bump ccxt from 1.30.48 to 1.30.64
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.30.48 to 1.30.64.
- [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.30.48...1.30.64)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-06 09:11:49 +00:00
hroff-1902
839b3340e6 Merge pull request #3497 from freqtrade/keep_dataframe_noapi
Analyze dataframe and keep it until the next analysis
2020-07-05 13:46:02 +03:00
Matthias
75318525a9 Update docs/strategy-advanced.md
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-07-04 16:41:19 +02:00
Matthias
c4a9a79be0 Apply suggested documentation changes from code review
Co-authored-by: hroff-1902 <47309513+hroff-1902@users.noreply.github.com>
2020-07-04 09:43:49 +02:00
Matthias
1fc4451d2f Avoid \ linebreak 2020-07-03 20:32:04 +02:00
Matthias
ea5e47657a Remove ticker_interval from jupyter notebook 2020-07-03 20:27:32 +02:00
Matthias
0d15a87af8 Remove old store_backtest method 2020-07-03 20:21:32 +02:00
Matthias
523437d970 Add tst for daily stats 2020-07-03 20:03:33 +02:00
Matthias
987188e41f Add avgduration for winners and losers 2020-07-03 19:58:02 +02:00
Matthias
8e0ff4bd86 Add Win / draw / losing days 2020-07-03 19:45:45 +02:00
Matthias
42868ad24a Add best / worst day to statistics 2020-07-03 19:30:29 +02:00
Matthias
804c42933d Document summary-statistics 2020-07-03 08:02:27 +02:00
Matthias
d56f9655e2 Update notebook with new statistics example 2020-07-03 07:20:43 +02:00
Matthias
619eb183fe Allow strategy for plot-profit
to allow loading of multi-backtest files
2020-07-03 07:03:43 +02:00
Matthias
16a842f9f6 Have plotting support folder-based exportfilename 2020-07-03 06:58:27 +02:00
Matthias
d999fa2a7e Test autogetting result filename 2020-07-03 06:58:27 +02:00
Matthias
7c5587aeaa exportfilename can be a file or directory 2020-07-03 06:58:27 +02:00
Matthias
2ed808da1f Extract .last_result.json to constant 2020-07-03 06:58:27 +02:00
Matthias
59e0ca0aaa Add pairlist to backtest-result 2020-07-03 06:58:27 +02:00
Matthias
59ac4b9c9a Test writing statistics 2020-07-03 06:58:27 +02:00
Matthias
5b1a7ba00f Test multistrat loading 2020-07-03 06:58:27 +02:00
Matthias
f952f74bf1 Add test for new format 2020-07-03 06:58:27 +02:00
Matthias
573502d972 Update test for load_trades_from_db 2020-07-03 06:58:27 +02:00
Matthias
afefe92523 Add multi-strategy loading logic 2020-07-03 06:58:27 +02:00
Matthias
c13ec4a1d4 implement fallback loading for load_backtest_data 2020-07-03 06:58:27 +02:00
Matthias
1339479882 Have sell_type stringify correctly 2020-07-03 06:58:27 +02:00
Matthias
04eaf2c39c Add test for get_last_backtest_Result 2020-07-03 06:58:27 +02:00
Matthias
7727292861 Rename duration to trade_duration 2020-07-03 06:58:27 +02:00
Matthias
f368aabcc7 Add amount to backtest-result 2020-07-03 06:58:27 +02:00
Matthias
6e94734678 Add fee to backtestresult 2020-07-03 06:58:27 +02:00
Matthias
03ab61959b Add test for generate_backtest_stats 2020-07-03 06:58:27 +02:00
Matthias
af9a9592b7 Remove unnecessary statement 2020-07-03 06:58:27 +02:00
Matthias
075eb0a161 Fix sequence of saving 2020-07-03 06:58:27 +02:00
Matthias
dacb40a976 Add get_latest_backtest_filename 2020-07-03 06:58:27 +02:00
Matthias
0fa56be9d2 remove openIndex and closeIndex from backtest-report 2020-07-03 06:58:27 +02:00
Matthias
04cbc2cde5 Shorten variable 2020-07-03 06:58:27 +02:00
Matthias
2881718733 Adapt tests for new column names 2020-07-03 06:58:27 +02:00
Matthias
b068e7c564 Rename open_time and close_time to *date 2020-07-03 06:58:27 +02:00
Matthias
415853583b Save backtest-stats 2020-07-03 06:58:27 +02:00
Matthias
81c8e8677d use 0 as profit mean, not nan 2020-07-03 06:58:27 +02:00
Matthias
480c5117f1 Handle empty return strings 2020-07-03 06:58:27 +02:00
Matthias
5fce7f3b22 Add market Change
closes #2524 and #3518
2020-07-03 06:58:27 +02:00
Matthias
cf044d166e Tests should use new Datetime format too 2020-07-03 06:58:27 +02:00
Matthias
fbddfaeacf Introduce DatetimePrintFormat 2020-07-03 06:58:27 +02:00
Matthias
cbcf3dbb43 Add more metrics to summarytable 2020-07-03 06:58:27 +02:00
Matthias
6922fbc3aa Add max_drawdown error handler 2020-07-03 06:58:27 +02:00
Matthias
455b26ea48 Add max drawdown to backtesting 2020-07-03 06:58:27 +02:00
Matthias
5a189ae202 Merge pull request #3552 from Theagainmen/Minor_issues
API server FIAT init fix
2020-07-03 06:30:42 +02:00
Jean-Baptiste LE STANG
da1b37b917 Merge branch 'Fix_#3544' of https://github.com/jblestang/freqtrade into Fix_#3544 2020-07-02 21:16:30 +02:00
Jean-Baptiste LE STANG
20e8a29262 Adding a dataprovider to the strategy before plotting
Fix flake8
2020-07-02 21:14:31 +02:00
Jean-Baptiste LE STANG
23c0db925e Adding a dataprovider to the strategy before plotting 2020-07-02 20:55:16 +02:00
Theagainmen
f32e522bd7 Update API test, removed 'ANY' 2020-07-02 20:03:15 +02:00
Theagainmen
39fa589735 Update API test, currently just with 'ANY' 2020-07-02 13:39:02 +02:00
Theagainmen
db965332b9 Update tests for AgeFilter message 2020-07-02 11:38:38 +02:00
Theagainmen
99ac2659f3 Init FIAT converter in api_server.py 2020-07-02 11:27:33 +02:00
Theagainmen
81850b5fdf AgeFilter add actual amount of days in log message (debug info) 2020-07-02 11:26:52 +02:00
Matthias
d9d999eaea Merge pull request #3545 from BlueSkyTrading/patch-1
fixed --export trades command
2020-06-30 19:45:48 +02:00
HumanBot
61ae471eef fixed --export trades command
refers to issue 3413 @ https://github.com/freqtrade/freqtrade/issues/3413
2020-06-30 10:13:27 -04:00
Confucius-The-Great
2f759825e4 Update faq.md
Major changes :)
2020-06-30 11:01:00 +02:00
Matthias
cf1bbb1afb Merge pull request #3517 from freqtrade/rpc/winlossratio
Show winning vs. losing trades
2020-06-30 07:48:18 +02:00
Matthias
cf26ab1dd8 Merge pull request #3527 from Theagainmen/Warning_message2
Warning message bot is stopped and left open trades
2020-06-30 07:48:02 +02:00
Matthias
c2a6f70b4c Merge branch 'develop' into keep_dataframe_noapi 2020-06-30 07:46:52 +02:00
Matthias
efd6e4a875 Add test for check_for_open_trades 2020-06-30 07:16:27 +02:00
hroff-1902
8a2f631ddd Merge pull request #3531 from freqtrade/exchange_errorhandling
Improve exchange errorhandling and API backoff
2020-06-30 07:53:09 +03:00
Matthias
b95065d701 Log backoff 2020-06-29 20:00:42 +02:00
Matthias
4d9ecf137b Fix failing test in python 3.7
can't use Magicmock in 3.7 (works in 3.8 though).
2020-06-28 20:38:28 +02:00
Matthias
c6124180fe Fix bug when fetching orders fails 2020-06-28 19:45:42 +02:00
Matthias
6362bfc36e Fix calculate_backoff implementation 2020-06-28 19:41:21 +02:00
Matthias
cbcbb4bdb5 Rename get_stoploss_order to fetch_stoploss_order (align with fetch_order) 2020-06-28 16:30:24 +02:00
Matthias
92c70fb903 Rename get_order to fetch_order (to align to ccxt naming) 2020-06-28 16:27:35 +02:00
Matthias
e040c518ca Dynamic backoff on DDos errors 2020-06-28 16:19:12 +02:00
Matthias
29d3ff1bc9 Adjust tests to work with ExchangeError 2020-06-28 16:04:04 +02:00
Matthias
bf61bc9d83 Introduce ExchangeError 2020-06-28 16:01:40 +02:00
Matthias
e74d2af857 Have TemporaryError a subCategory of DependencyException
so it's safe to raise out of the exchange
2020-06-28 15:44:58 +02:00
Matthias
5bd4798ed0 Add retrier to stoploss calls (but without retrying) 2020-06-28 11:56:29 +02:00
Matthias
2c45114a64 Implement DDos backoff (1s) 2020-06-28 11:17:06 +02:00
Theagainmen
118f051171 Added message in cleanup and fixes 2020-06-28 11:02:50 +02:00
Theagainmen
e5676867a8 Trying to fix flake8 errors 2020-06-27 21:53:12 +02:00
Theagainmen
b938c536fa Trying to fix flake8 errors 2020-06-27 21:46:53 +02:00
Theagainmen
48289e8ca7 Added exchange name, removed capital letters 2020-06-27 20:24:50 +02:00
Theagainmen
0642ab76bf Added information to the new function 2020-06-27 18:40:44 +02:00
Theagainmen
e813573f27 Warning message for open trades when stopping bot 2020-06-27 18:35:46 +02:00
Matthias
6734269bfc Use >= to compare for winning trades 2020-06-25 19:22:50 +02:00
Matthias
0509b9a8fc Show winning vs. losing trades 2020-06-24 06:43:19 +02:00
Matthias
f976905728 Fix more exchange message typos 2020-06-18 20:00:18 +02:00
Matthias
45ffb26910 Merge branch 'develop' into pr/hroff-1902/3478 2020-06-18 19:54:46 +02:00
Matthias
eef3c01da7 Fix function header formatting 2020-06-18 19:49:05 +02:00
Matthias
f1993fb2f4 Pass analyzed dataframe to get_signal 2020-06-18 08:09:52 +02:00
Matthias
48225e0d80 Improve interface docstrings for analyze functions 2020-06-18 07:54:00 +02:00
Matthias
f2a778d294 Combine tests for empty dataframe 2020-06-18 07:03:30 +02:00
Matthias
8472fcfff9 Add empty to documentation 2020-06-18 06:50:06 +02:00
Matthias
ab9382434f Add test for get_analyzed_dataframe 2020-06-18 06:50:06 +02:00
Matthias
e5f7610b5d Add bot basics documentation 2020-06-18 06:50:06 +02:00
Matthias
8b186dbe0e Add additional test scenarios 2020-06-18 06:50:06 +02:00
Matthias
1c1a7150ae ensure confirm_trade_entry is called and has the desired effect 2020-06-18 06:50:06 +02:00
Matthias
7c3fb111f2 Confirm execute_sell calls confirm_trade_exit 2020-06-18 06:50:06 +02:00
Matthias
6d6e7196f4 Test trade entry / exit is called correctly 2020-06-18 06:50:06 +02:00
Matthias
84329ad2ca Add confirm_trade* methods to abort buying or selling 2020-06-18 06:50:06 +02:00
Matthias
de676bcaba Document get_analyzed_dataframe for dataprovider 2020-06-18 06:50:06 +02:00
Matthias
910100f1c8 Improve docstring comment 2020-06-18 06:50:06 +02:00
Matthias
dea7e3db01 Use supress_errors in strategy wrapper - ensure it's called once 2020-06-18 06:50:06 +02:00
Matthias
c047e48a47 Add errorsupression to safe wrapper 2020-06-18 06:50:06 +02:00
Matthias
bc821c7c20 Add documentation for bot_loop_start 2020-06-18 06:50:06 +02:00
Matthias
77056a3119 Add bot_loop_start callback 2020-06-18 06:50:06 +02:00
Matthias
7da955556d Add test for empty pair case 2020-06-18 06:50:06 +02:00
Matthias
8166b37253 Explicitly check if dp is available 2020-06-18 06:50:06 +02:00
Matthias
55fa514ec9 Adapt most tests 2020-06-18 06:50:05 +02:00
Matthias
273aaaff12 Introduce .analyze() function for Strategy
Fixing a few tests along the way
2020-06-18 06:50:05 +02:00
Matthias
95f3ac08d4 Update some comments 2020-06-18 06:50:05 +02:00
Matthias
9794914838 store dataframe updated as tuple 2020-06-18 06:50:05 +02:00
Matthias
fd97ad9b76 Cache analyzed dataframe 2020-06-18 06:50:05 +02:00
Matthias
0b2982caed Merge branch 'develop' into hyperopt_colorama_init 2020-06-16 10:16:41 +02:00
Matthias
9dba2a34f9 Add note for hyperopt color support on windows 2020-06-16 10:16:23 +02:00
hroff-1902
de36f3d850 Cosmetics in freqtradebot 2020-06-14 01:42:45 +03:00
hroff-1902
4660909e95 Validate stoploss_on_exchange_limit_ratio at startup time 2020-06-14 01:07:00 +03:00
hroff-1902
1bf333d320 Minor: fix test 2020-06-14 00:57:13 +03:00
hroff-1902
be03c22dba Minor: Fix exception message 2020-06-14 00:35:58 +03:00
Matthias
08049d23b4 Use "market_is_tradable" for whitelist validation 2020-06-02 20:41:29 +02:00
Matthias
b74a3addc6 Update tests 2020-06-02 20:30:31 +02:00
Matthias
b22e3a67d8 rename symbol_is_pair to market_is_tradable
Make it part of the exchange class, so subclasses can override this
2020-06-02 20:29:50 +02:00
Matthias
f6edb32a33 Run hyperopt with --print-all 2020-06-01 09:55:52 +02:00
Matthias
d9afef8fe1 Move colorama_init to where it was 2020-06-01 09:37:10 +02:00
Matthias
ffa93377b4 Test colorama init again (after the fixes done to progressbar) 2020-06-01 09:34:03 +02:00
Matthias
f3824d970b Use dict for symbol_is_pair 2020-05-29 20:20:06 +02:00
hroff-1902
bfa55f31c0 Remove wrong comment 2020-05-20 17:45:27 +03:00
hroff-1902
8bf38443c2 Merge branch 'develop' into verify_date_on_new_candle_on_get_signal 2020-05-20 14:05:21 +03:00
hroff-1902
7b2bb73a12 Merge branch 'develop' into verify_date_on_new_candle_on_get_signal 2020-05-19 21:34:58 +03:00
Yazeed Al Oyoun
c9711678fd fixed indent 2020-04-25 11:31:51 +02:00
Yazeed Al Oyoun
181b12b3a8 added wins/draws/losses 2020-04-25 11:31:51 +02:00
Yazeed Al Oyoun
72b088d85f added test 2020-04-25 11:31:51 +02:00
Yazeed Al Oyoun
6147498fd4 fixed indent 2020-04-25 11:31:51 +02:00
Yazeed Al Oyoun
2fb3d94938 added wins/draws/losses 2020-04-25 11:31:51 +02:00
Yazeed Al Oyoun
ef4426a65c added comma 2020-03-27 03:01:51 +01:00
Yazeed Al Oyoun
0a87fe76a3 unified language 2020-03-23 11:17:56 +01:00
Yazeed Al Oyoun
7143cac64f fixed wording of all in cli_options 2020-03-23 09:41:01 +01:00
Yazeed Al Oyoun
bf96ef08e0 added # flake8: noqa C901 2020-03-22 09:39:38 +01:00
Yazeed Al Oyoun
1976aaf13e initial push 2020-03-22 02:22:06 +01:00
Yazeed Al Oyoun
d752586b32 added test 2020-03-11 17:44:03 +01:00
Yazeed Al Oyoun
1395f65872 meh 2020-03-11 17:29:22 +01:00
Yazeed Al Oyoun
c442913feb final 2020-03-11 17:28:03 +01:00
Yazeed Al Oyoun
ba596af636 final? 2020-03-11 17:26:57 +01:00
Yazeed Al Oyoun
65a305c9ef fixed log message 2020-03-11 17:24:15 +01:00
Yazeed Al Oyoun
d25cf1395b fixed log message 2020-03-11 17:23:22 +01:00
Yazeed Al Oyoun
2e679ee2eb fixed log message 2020-03-11 17:22:21 +01:00
Yazeed Al Oyoun
dbe3c8654e fixed all, i hope 2020-03-11 17:16:21 +01:00
Yazeed Al Oyoun
7754742459 fix tests 2020-03-11 17:13:39 +01:00
Yazeed Al Oyoun
d667acb308 fixed typo 2020-03-11 17:10:57 +01:00
Yazeed Al Oyoun
a82cdf0add fixed test 2020-03-11 17:04:51 +01:00
Yazeed Al Oyoun
a85d17327b fix 2020-03-11 16:54:27 +01:00
Yazeed Al Oyoun
d239e99904 removed old code from create_trade 2020-03-11 16:49:37 +01:00
Yazeed Al Oyoun
4e45abbf13 added return false, false 2020-03-11 16:44:45 +01:00
Yazeed Al Oyoun
54bde6ac11 verify date on new candle before producing signal 2020-03-11 16:34:23 +01:00
219 changed files with 10375 additions and 3864 deletions

View File

@@ -1,17 +0,0 @@
version: 1
update_configs:
- package_manager: "python"
directory: "/"
update_schedule: "weekly"
allowed_updates:
- match:
update_type: "all"
target_branch: "develop"
- package_manager: "docker"
directory: "/"
update_schedule: "daily"
allowed_updates:
- match:
update_type: "all"

18
.devcontainer/Dockerfile Normal file
View File

@@ -0,0 +1,18 @@
FROM freqtradeorg/freqtrade:develop
# Install dependencies
COPY requirements-dev.txt /freqtrade/
RUN apt-get update \
&& apt-get -y install git sudo vim \
&& apt-get clean \
&& pip install autopep8 -r docs/requirements-docs.txt -r requirements-dev.txt --no-cache-dir \
&& useradd -u 1000 -U -m ftuser \
&& mkdir -p /home/ftuser/.vscode-server /home/ftuser/.vscode-server-insiders /home/ftuser/commandhistory \
&& echo "export PROMPT_COMMAND='history -a'" >> /home/ftuser/.bashrc \
&& echo "export HISTFILE=~/commandhistory/.bash_history" >> /home/ftuser/.bashrc \
&& chown ftuser: -R /home/ftuser/
USER ftuser
# Empty the ENTRYPOINT to allow all commands
ENTRYPOINT []

View File

@@ -0,0 +1,44 @@
{
"name": "freqtrade Develop",
"dockerComposeFile": [
"docker-compose.yml"
],
"service": "ft_vscode",
"workspaceFolder": "/freqtrade/",
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"editor.insertSpaces": true,
"files.trimTrailingWhitespace": true,
"[markdown]": {
"files.trimTrailingWhitespace": false,
},
"python.pythonPath": "/usr/local/bin/python",
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker",
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Uncomment the next line if you want start specific services in your Docker Compose config.
// "runServices": [],
// Uncomment the next line if you want to keep your containers running after VS Code shuts down.
// "shutdownAction": "none",
// Uncomment the next line to run commands after the container is created - for example installing curl.
// "postCreateCommand": "sudo apt-get update && apt-get install -y git",
// Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "ftuser"
}

View File

@@ -0,0 +1,24 @@
---
version: '3'
services:
ft_vscode:
build:
context: ..
dockerfile: ".devcontainer/Dockerfile"
volumes:
# Allow git usage within container
- "${HOME}/.ssh:/home/ftuser/.ssh:ro"
- "${HOME}/.gitconfig:/home/ftuser/.gitconfig:ro"
- ..:/freqtrade:cached
# Persist bash-history
- freqtrade-vscode-server:/home/ftuser/.vscode-server
- freqtrade-bashhistory:/home/ftuser/commandhistory
# Expose API port
ports:
- "127.0.0.1:8080:8080"
command: /bin/sh -c "while sleep 1000; do :; done"
volumes:
freqtrade-vscode-server:
freqtrade-bashhistory:

View File

@@ -13,3 +13,4 @@ CONTRIBUTING.md
MANIFEST.in
README.md
freqtrade.service
user_data

13
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: docker
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: pip
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
target-branch: develop

View File

@@ -4,11 +4,11 @@ on:
push:
branches:
- master
- stable
- develop
- github_actions_tests
tags:
release:
types: [published]
release:
types: [published]
pull_request:
schedule:
- cron: '0 5 * * 4'
@@ -19,14 +19,14 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-18.04, macos-latest ]
os: [ ubuntu-18.04, ubuntu-20.04, macos-latest ]
python-version: [3.7, 3.8]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
@@ -70,7 +70,7 @@ jobs:
pytest --random-order --cov=freqtrade --cov-config=.coveragerc
- name: Coveralls
if: (startsWith(matrix.os, 'ubuntu') && matrix.python-version == '3.8')
if: (startsWith(matrix.os, 'ubuntu-20') && 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
@@ -88,12 +88,16 @@ jobs:
run: |
cp config.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Flake8
run: |
flake8
- name: Sort imports (isort)
run: |
isort --check .
- name: Mypy
run: |
mypy freqtrade scripts
@@ -121,7 +125,7 @@ jobs:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
@@ -150,7 +154,7 @@ jobs:
run: |
cp config.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Flake8
run: |
@@ -172,7 +176,7 @@ jobs:
url: ${{ secrets.SLACK_WEBHOOK }}
docs_check:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
@@ -180,6 +184,17 @@ jobs:
run: |
./tests/test_docs.sh
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Documentation build
run: |
pip install -r docs/requirements-docs.txt
pip install mkdocs
mkdocs build
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
@@ -190,18 +205,18 @@ jobs:
url: ${{ secrets.SLACK_WEBHOOK }}
cleanup-prior-runs:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
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'"
if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/stable' && 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
runs-on: ubuntu-20.04
steps:
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
@@ -214,19 +229,19 @@ jobs:
deploy:
needs: [ build, build_windows, docs_check ]
runs-on: ubuntu-18.04
runs-on: ubuntu-20.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
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
id: extract_branch
- name: Build distribution
@@ -236,7 +251,7 @@ jobs:
- name: Publish to PyPI (Test)
uses: pypa/gh-action-pypi-publish@master
if: (steps.extract_branch.outputs.branch == 'master' || github.event_name == 'release')
if: (github.event_name == 'release')
with:
user: __token__
password: ${{ secrets.pypi_test_password }}
@@ -244,7 +259,7 @@ jobs:
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@master
if: (steps.extract_branch.outputs.branch == 'master' || github.event_name == 'release')
if: (github.event_name == 'release')
with:
user: __token__
password: ${{ secrets.pypi_password }}

View File

@@ -2,7 +2,7 @@ name: Update Docker Hub Description
on:
push:
branches:
- master
- stable
jobs:
dockerHubDescription:

View File

@@ -33,7 +33,7 @@ jobs:
- script:
- cp config.json.example config.json
- freqtrade create-userdir --userdir user_data
- freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt
- freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt --hyperopt-loss SharpeHyperOptLossDaily
name: hyperopt
- script: flake8
name: flake8

View File

@@ -8,17 +8,17 @@ Issues labeled [good first issue](https://github.com/freqtrade/freqtrade/labels/
Few pointers for contributions:
- Create your PR against the `develop` branch, not `master`.
- New features need to contain unit tests and must be PEP8 conformant (max-line-length = 100).
- Create your PR against the `develop` branch, not `stable`.
- New features need to contain unit tests, must conform to PEP8 (max-line-length = 100) and should be documented with the introduction PR.
- PR's can be declared as `[WIP]` - which signify Work in Progress Pull Requests (which are not finished).
If you are unsure, discuss the feature on our [Slack](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE)
or in a [issue](https://github.com/freqtrade/freqtrade/issues) before a PR.
If you are unsure, discuss the feature on our [discord server](https://discord.gg/MA9v74M), on [Slack](https://join.slack.com/t/highfrequencybot/shared_invite/zt-jaut7r4m-Y17k4x5mcQES9a9swKuxbg) or in a [issue](https://github.com/freqtrade/freqtrade/issues) before a PR.
## Getting started
Best start by reading the [documentation](https://www.freqtrade.io/) to get a feel for what is possible with the bot, or head straight to the [Developer-documentation](https://www.freqtrade.io/en/latest/developer/) (WIP) which should help you getting started.
## Before sending the PR:
## Before sending the PR
### 1. Run unit tests
@@ -64,6 +64,14 @@ Guide for installing them is [here](http://flake8.pycqa.org/en/latest/user/using
mypy freqtrade
```
### 4. Ensure all imports are correct
#### Run isort
``` bash
isort .
```
## (Core)-Committer Guide
### Process: Pull Requests
@@ -114,6 +122,6 @@ Contributors may be given commit privileges. Preference will be given to those w
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 `stable` 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,7 +1,7 @@
FROM python:3.8.3-slim-buster
FROM python:3.8.6-slim-buster
RUN apt-get update \
&& apt-get -y install curl build-essential libssl-dev \
&& apt-get -y install curl build-essential libssl-dev sqlite3 \
&& apt-get clean \
&& pip install --upgrade pip
@@ -16,13 +16,14 @@ 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 requirements-hyperopt.txt /freqtrade/
COPY requirements.txt requirements-hyperopt.txt /freqtrade/
RUN pip install numpy --no-cache-dir \
&& pip install -r requirements-hyperopt.txt --no-cache-dir
# Install and execute
COPY . /freqtrade/
RUN pip install -e . --no-cache-dir
RUN pip install -e . --no-cache-dir \
&& mkdir /freqtrade/user_data/
ENTRYPOINT ["freqtrade"]
# Default to trade mode
CMD [ "trade" ]

View File

@@ -1,7 +1,7 @@
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 -y install curl build-essential libssl-dev libffi-dev libatlas3-base libgfortran5 sqlite3 \
&& apt-get clean \
&& pip install --upgrade pip \
&& echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > /etc/pip.conf
@@ -17,7 +17,7 @@ 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/
COPY requirements.txt /freqtrade/
RUN pip install numpy --no-cache-dir \
&& pip install -r requirements.txt --no-cache-dir

View File

@@ -55,9 +55,8 @@ Please find the complete documentation on our [website](https://www.freqtrade.io
Freqtrade provides a Linux/macOS script to install all dependencies and help you to configure the bot.
```bash
git clone git@github.com:freqtrade/freqtrade.git
git clone -b develop https://github.com/freqtrade/freqtrade.git
cd freqtrade
git checkout develop
./setup.sh --install
```
@@ -111,35 +110,35 @@ optional arguments:
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
- `/status [table]`: Lists all open trades
- `/count`: Displays number of open trades
- `/start`: Starts the trader.
- `/stop`: Stops the trader.
- `/stopbuy`: Stop entering new trades.
- `/status [table]`: Lists all open trades.
- `/profit`: Lists cumulative profit from all finished trades
- `/forcesell <trade_id>|all`: Instantly sells the given trade (Ignoring `minimum_roi`).
- `/performance`: Show performance of each finished trade grouped by pair
- `/balance`: Show account balance per currency
- `/daily <n>`: Shows profit or loss per day, over the last n days
- `/help`: Show help message
- `/version`: Show version
- `/balance`: Show account balance per currency.
- `/daily <n>`: Shows profit or loss per day, over the last n days.
- `/help`: Show help message.
- `/version`: Show version.
## Development branches
The project is currently setup in two main branches:
- `develop` - This branch has often new features, but might also cause breaking changes.
- `master` - This branch contains the latest stable release. The bot 'should' be stable on this branch, and is generally well tested.
- `develop` - This branch has often new features, but might also contain breaking changes. We try hard to keep this branch as stable as possible.
- `stable` - This branch contains the latest stable release. This branch 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.
## Support
### Help / Slack
### Help / Discord / Slack
For any questions not covered by the documentation or for further
information about the bot, we encourage you to join our slack channel.
For any questions not covered by the documentation or for further information about the bot, or to simply engage with like-minded individuals, we encourage you to join our slack channel.
- [Click here to join Slack channel](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE).
Please check out our [discord server](https://discord.gg/MA9v74M).
You can also join our [Slack channel](https://join.slack.com/t/highfrequencybot/shared_invite/zt-jaut7r4m-Y17k4x5mcQES9a9swKuxbg).
### [Bugs / Issues](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue)
@@ -167,18 +166,18 @@ Please read our
[Contributing document](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md)
to understand the requirements before sending your pull-requests.
Coding is not a neccessity to contribute - maybe start with improving our documentation?
Coding is not a necessity to contribute - maybe start with improving our documentation?
Issues labeled [good first issue](https://github.com/freqtrade/freqtrade/labels/good%20first%20issue) can be good first contributions, and will help get you familiar with the codebase.
**Note** before starting any major new feature work, *please open an issue describing what you are planning to do* or talk to us on [Slack](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE). This will ensure that interested parties can give valuable feedback on the feature, and let others know that you are working on it.
**Note** before starting any major new feature work, *please open an issue describing what you are planning to do* or talk to us on [discord](https://discord.gg/MA9v74M) or [Slack](https://join.slack.com/t/highfrequencybot/shared_invite/zt-jaut7r4m-Y17k4x5mcQES9a9swKuxbg). This will ensure that interested parties can give valuable feedback on the feature, and let others know that you are working on it.
**Important:** Always create your PR against the `develop` branch, not `master`.
**Important:** Always create your PR against the `develop` branch, not `stable`.
## Requirements
### Uptodate clock
### Up-to-date clock
The clock must be accurate, syncronized to a NTP server very frequently to avoid problems with communication to the exchanges.
The clock must be accurate, synchronized to a NTP server very frequently to avoid problems with communication to the exchanges.
### Min hardware required

Binary file not shown.

Binary file not shown.

View File

@@ -7,10 +7,10 @@ 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
pip install build_helpers\TA_Lib-0.4.19-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 build_helpers\TA_Lib-0.4.19-cp38-cp38-win_amd64.whl
}
pip install -r requirements-dev.txt

View File

@@ -2,6 +2,7 @@
# Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot
echo "Running for ${TAG}"
# Add commit and commit_message to docker container
@@ -16,6 +17,12 @@ else
docker pull ${IMAGE_NAME}:${TAG}
docker build --cache-from ${IMAGE_NAME}:${TAG} -t freqtrade:${TAG} .
fi
# Tag image for upload and next build step
docker tag freqtrade:$TAG ${IMAGE_NAME}:$TAG
docker build --cache-from freqtrade:${TAG} --build-arg sourceimage=${TAG} -t freqtrade:${TAG_PLOT} -f docker/Dockerfile.plot .
docker tag freqtrade:$TAG_PLOT ${IMAGE_NAME}:$TAG_PLOT
if [ $? -ne 0 ]; then
echo "failed building image"
@@ -30,8 +37,6 @@ if [ $? -ne 0 ]; then
return 1
fi
# Tag image for upload
docker tag freqtrade:$TAG ${IMAGE_NAME}:$TAG
if [ $? -ne 0 ]; then
echo "failed tagging image"
return 1

View File

@@ -5,16 +5,15 @@
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD",
"timeframe": "5m",
"dry_run": false,
"dry_run": true,
"cancel_open_orders_on_exit": false,
"trailing_stop": false,
"unfilledtimeout": {
"buy": 10,
"sell": 30
},
"bid_strategy": {
"ask_last_balance": 0.0,
"use_order_book": false,
"ask_last_balance": 0.0,
"order_book_top": 1,
"check_depth_of_market": {
"enabled": false,

View File

@@ -7,7 +7,6 @@
"timeframe": "5m",
"dry_run": true,
"cancel_open_orders_on_exit": false,
"trailing_stop": false,
"unfilledtimeout": {
"buy": 10,
"sell": 30

View File

@@ -7,7 +7,7 @@
"amount_reserve_percent": 0.05,
"amend_last_stake_amount": false,
"last_stake_amount_min_ratio": 0.5,
"dry_run": false,
"dry_run": true,
"cancel_open_orders_on_exit": false,
"timeframe": "5m",
"trailing_stop": false,
@@ -66,8 +66,14 @@
},
{"method": "AgeFilter", "min_days_listed": 10},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01},
{"method": "SpreadFilter", "max_spread_ratio": 0.005}
{"method": "PriceFilter", "low_price_ratio": 0.01, "min_price": 0.00000010},
{"method": "SpreadFilter", "max_spread_ratio": 0.005},
{
"method": "RangeStabilityFilter",
"lookback_days": 10,
"min_rate_of_change": 0.01,
"refresh_period": 1440
}
],
"exchange": {
"name": "bittrex",
@@ -116,7 +122,16 @@
"telegram": {
"enabled": true,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id"
"chat_id": "your_telegram_chat_id",
"notification_settings": {
"status": "on",
"warning": "on",
"startup": "on",
"buy": "on",
"sell": "on",
"buy_cancel": "on",
"sell_cancel": "on"
}
},
"api_server": {
"enabled": false,

View File

@@ -7,7 +7,6 @@
"timeframe": "5m",
"dry_run": true,
"cancel_open_orders_on_exit": false,
"trailing_stop": false,
"unfilledtimeout": {
"buy": 10,
"sell": 30
@@ -28,12 +27,11 @@
"use_sell_signal": true,
"sell_profit_only": false,
"ignore_roi_if_buy_signal": false
},
"exchange": {
"name": "kraken",
"key": "",
"secret": "",
"key": "your_exchange_key",
"secret": "your_exchange_key",
"ccxt_config": {"enableRateLimit": true},
"ccxt_async_config": {
"enableRateLimit": true,

View File

@@ -1,20 +0,0 @@
---
version: '3'
services:
freqtrade_develop:
build:
context: .
dockerfile: "./Dockerfile.develop"
volumes:
- ".:/freqtrade"
entrypoint:
- "freqtrade"
freqtrade_bash:
build:
context: .
dockerfile: "./Dockerfile.develop"
volumes:
- ".:/freqtrade"
entrypoint:
- "/bin/bash"

View File

@@ -2,8 +2,10 @@
version: '3'
services:
freqtrade:
image: freqtradeorg/freqtrade:master
image: freqtradeorg/freqtrade:stable
# image: freqtradeorg/freqtrade:develop
# Use plotting image
# image: freqtradeorg/freqtrade:develop_plot
# Build step - only needed when additional dependencies are needed
# build:
# context: .

View File

@@ -2,6 +2,7 @@ FROM freqtradeorg/freqtrade:develop
# Install dependencies
COPY requirements-dev.txt /freqtrade/
RUN pip install numpy --no-cache-dir \
&& pip install -r requirements-dev.txt --no-cache-dir

View File

@@ -0,0 +1,7 @@
FROM freqtradeorg/freqtrade:develop_plot
RUN pip install jupyterlab --no-cache-dir
# Empty the ENTRYPOINT to allow all commands
ENTRYPOINT []

7
docker/Dockerfile.plot Normal file
View File

@@ -0,0 +1,7 @@
ARG sourceimage=develop
FROM freqtradeorg/freqtrade:${sourceimage}
# Install dependencies
COPY requirements-plot.txt /freqtrade/
RUN pip install -r requirements-plot.txt --no-cache-dir

View File

@@ -0,0 +1,16 @@
---
version: '3'
services:
ft_jupyterlab:
build:
context: ..
dockerfile: docker/Dockerfile.jupyter
restart: unless-stopped
container_name: freqtrade
ports:
- "127.0.0.1:8888:8888"
volumes:
- "./user_data:/freqtrade/user_data"
# Default command used when running `docker compose up`
command: >
jupyter lab --port=8888 --ip 0.0.0.0 --allow-root

View File

@@ -27,9 +27,9 @@ class MyAwesomeHyperOpt2(MyAwesomeHyperOpt):
and then quickly switch between hyperopt classes, running optimization process with hyperopt class you need in each particular case:
```
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt ...
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt --hyperopt-loss SharpeHyperOptLossDaily --strategy MyAwesomeStrategy ...
or
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt2 ...
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt2 --hyperopt-loss SharpeHyperOptLossDaily --strategy MyAwesomeStrategy ...
```
## Creating and using a custom loss function

View File

@@ -66,7 +66,7 @@ Where `SampleStrategy1` and `AwesomeStrategy` refer to class names of strategies
#### Exporting trades to file
```bash
freqtrade backtesting --export trades
freqtrade backtesting --export trades --config config.json --strategy SampleStrategy
```
The exported trades can be used for [further analysis](#further-backtest-result-analysis), or can be used by the plotting script `plot_dataframe.py` in the scripts directory.
@@ -157,17 +157,34 @@ A backtesting result will look like that:
| 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 |
=============== SUMMARY METRICS ===============
| Metric | Value |
|-----------------------+---------------------|
| Backtesting from | 2019-01-01 00:00:00 |
| Backtesting to | 2019-05-01 00:00:00 |
| Max open trades | 3 |
| | |
| Total trades | 429 |
| First trade | 2019-01-01 18:30:00 |
| First trade Pair | EOS/USDT |
| Total Profit % | 152.41% |
| Trades per day | 3.575 |
| Best day | 25.27% |
| Worst day | -30.67% |
| Avg. Duration Winners | 4:23:00 |
| Avg. Duration Loser | 6:55:00 |
| | |
| Max Drawdown | 50.63% |
| Drawdown Start | 2019-02-15 14:10:00 |
| Drawdown End | 2019-04-11 18:15:00 |
| Market change | -5.88% |
===============================================
```
### Backtesting report table
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.
These trades are also included in the first table, but are extracted separately for clarity.
The last line will give you the overall performance of your strategy,
here:
@@ -196,6 +213,61 @@ On the other hand, if you set a too high `minimal_roi` like `"0": 0.55`
(55%), there is almost no chance that the bot will ever reach this profit.
Hence, keep in mind that your performance is an integral mix of all different elements of the strategy, your configuration, and the crypto-currency pairs you have set up.
### Sell reasons table
The 2nd table contains a recap of sell reasons.
This table can tell you which area needs some additional work (e.g. all or many of the `sell_signal` trades are losses, so you should work on improving the sell signal, or consider disabling it).
### Left open trades table
The 3rd table contains all trades the bot had to `forcesell` at the end of the backtesting period to present you the full picture.
This is necessary to simulate realistic behavior, since the backtest period has to end at some point, while realistically, you could leave the bot running forever.
These trades are also included in the first table, but are also shown separately in this table for clarity.
### Summary metrics
The last element of the backtest report is the summary metrics table.
It contains some useful key metrics about performance of your strategy on backtesting data.
```
=============== SUMMARY METRICS ===============
| Metric | Value |
|-----------------------+---------------------|
| Backtesting from | 2019-01-01 00:00:00 |
| Backtesting to | 2019-05-01 00:00:00 |
| Max open trades | 3 |
| | |
| Total trades | 429 |
| First trade | 2019-01-01 18:30:00 |
| First trade Pair | EOS/USDT |
| Total Profit % | 152.41% |
| Trades per day | 3.575 |
| Best day | 25.27% |
| Worst day | -30.67% |
| Avg. Duration Winners | 4:23:00 |
| Avg. Duration Loser | 6:55:00 |
| | |
| Max Drawdown | 50.63% |
| Drawdown Start | 2019-02-15 14:10:00 |
| Drawdown End | 2019-04-11 18:15:00 |
| Market change | -5.88% |
===============================================
```
- `Backtesting from` / `Backtesting to`: Backtesting range (usually defined with the `--timerange` option).
- `Max open trades`: Setting of `max_open_trades` (or `--max-open-trades`) - to clearly see settings for this.
- `Total trades`: Identical to the total trades of the backtest output table.
- `First trade`: First trade entered.
- `First trade pair`: Which pair was part of the first trade.
- `Total Profit %`: Total profit per stake amount. Aligned to the TOTAL column of the first table.
- `Trades per day`: Total trades divided by the backtesting duration in days (this will give you information about how many trades to expect from the strategy).
- `Best day` / `Worst day`: Best and worst day based on daily profit.
- `Avg. Duration Winners` / `Avg. Duration Loser`: Average durations for winning and losing trades.
- `Max Drawdown`: Maximum drawdown experienced. For example, the value of 50% means that from highest to subsequent lowest point, a 50% drop was experienced).
- `Drawdown Start` / `Drawdown End`: Start and end datetime for this largest drawdown (can also be visualized via the `plot-dataframe` sub-command).
- `Market change`: Change of the market during the backtest period. Calculated as average of all pairs changes from the first to the last candle using the "close" column.
### Assumptions made by backtesting
Since backtesting lacks some detailed information about what happens within a candle, it needs to take a few assumptions:

58
docs/bot-basics.md Normal file
View File

@@ -0,0 +1,58 @@
# Freqtrade basics
This page provides you some basic concepts on how Freqtrade works and operates.
## Freqtrade terminology
* Trade: Open position.
* Open Order: Order which is currently placed on the exchange, and is not yet complete.
* Pair: Tradable pair, usually in the format of Quote/Base (e.g. XRP/USDT).
* Timeframe: Candle length to use (e.g. `"5m"`, `"1h"`, ...).
* Indicators: Technical indicators (SMA, EMA, RSI, ...).
* Limit order: Limit orders which execute at the defined limit price or better.
* Market order: Guaranteed to fill, may move price depending on the order size.
## Fee handling
All profit calculations of Freqtrade include fees. For Backtesting / Hyperopt / Dry-run modes, the exchange default fee is used (lowest tier on the exchange). For live operations, fees are used as applied by the exchange (this includes BNB rebates etc.).
## Bot execution logic
Starting freqtrade in dry-run or live mode (using `freqtrade trade`) will start the bot and start the bot iteration loop.
By default, loop runs every few seconds (`internals.process_throttle_secs`) and does roughly the following in the following sequence:
* Fetch open trades from persistence.
* Calculate current list of tradable pairs.
* Download ohlcv data for the pairlist including all [informative pairs](strategy-customization.md#get-data-for-non-tradeable-pairs)
This step is only executed once per Candle to avoid unnecessary network traffic.
* Call `bot_loop_start()` strategy callback.
* Analyze strategy per pair.
* Call `populate_indicators()`
* Call `populate_buy_trend()`
* Call `populate_sell_trend()`
* Check timeouts for open orders.
* Calls `check_buy_timeout()` strategy callback for open buy orders.
* Calls `check_sell_timeout()` strategy callback for open sell orders.
* Verifies existing positions and eventually places sell orders.
* Considers stoploss, ROI and sell-signal.
* Determine sell-price based on `ask_strategy` configuration setting.
* Before a sell order is placed, `confirm_trade_exit()` strategy callback is called.
* Check if trade-slots are still available (if `max_open_trades` is reached).
* Verifies buy signal trying to enter new positions.
* Determine buy-price based on `bid_strategy` configuration setting.
* Before a buy order is placed, `confirm_trade_entry()` strategy callback is called.
This loop will be repeated again and again until the bot is stopped.
## Backtesting / Hyperopt execution logic
[backtesting](backtesting.md) or [hyperopt](hyperopt.md) do only part of the above logic, since most of the trading operations are fully simulated.
* Load historic data for configured pairlist.
* Calculate indicators (calls `populate_indicators()`).
* Calls `populate_buy_trend()` and `populate_sell_trend()`
* Loops per candle simulating entry and exit points.
* Generate backtest report output
!!! Note
Both Backtesting and Hyperopt include exchange default Fees in the calculation. Custom fees can be passed to backtesting / hyperopt by specifying the `--fee` argument.

View File

@@ -5,6 +5,9 @@ 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.
!!! Warning "Up-to-date clock"
The clock on the system running the bot must be accurate, synchronized to a NTP server frequently enough to avoid problems with communication to the exchanges.
## Bot commands
```
@@ -300,7 +303,7 @@ usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--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]
[--hyperopt-loss NAME]
optional arguments:
-h, --help show this help message and exit
@@ -346,18 +349,14 @@ optional arguments:
reproducible hyperopt results.
--min-trades INT Set minimal desired number of trades for evaluations
in the hyperopt optimization path (default: 1).
--continue Continue hyperopt from previous runs. By default,
temporary files will be removed and hyperopt will
start from scratch.
--hyperopt-loss NAME 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,
Hyperopt-loss-functions are: ShortTradeDurHyperOptLoss,
OnlyProfitHyperOptLoss, SharpeHyperOptLoss,
SharpeHyperOptLossDaily, SortinoHyperOptLoss,
SortinoHyperOptLossDaily.(default:
`DefaultHyperOptLoss`).
SortinoHyperOptLossDaily.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).

View File

@@ -55,12 +55,12 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `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 as ratio 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 as ratio of the stoploss 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_stop` | Enables trailing stoploss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md#trailing-stop-loss). [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#trailing-stop-loss-custom-positive-loss). [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#trailing-stop-loss-only-once-the-trade-has-reached-a-certain-offset). [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
| `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 and repeated at current (new) price, as long as there is a signal. [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 and repeated at current (new) price, as long as there is a signal. [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
@@ -87,6 +87,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `exchange.ccxt_sync_config` | Additional CCXT parameters passed to the regular (sync) 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
| `exchange.skip_pair_validation` | Skip pairlist validation on startup.<br>*Defaults to `false`<br> **Datatype:** Boolean
| `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
@@ -176,7 +177,7 @@ In the example above this would mean:
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.
The minimum last stake amount can be configured using `last_stake_amount_min_ratio` - 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
@@ -275,27 +276,16 @@ the static list of pairs) if we should buy.
The `order_types` configuration parameter maps actions (`buy`, `sell`, `stoploss`, `emergencysell`) to order-types (`market`, `limit`, ...) as well as configures stoploss to be on the exchange and defines stoploss on exchange update interval in seconds.
This allows to buy using limit orders, sell using
limit-orders, and create stoplosses using using market orders. It also allows to set the
limit-orders, and create stoplosses using market orders. It also allows to set the
stoploss "on exchange" which means stoploss order would be placed immediately once
the buy order is fulfilled.
If `stoploss_on_exchange` and `trailing_stop` are both set, then the bot will use `stoploss_on_exchange_interval` to check and update the stoploss on exchange periodically.
`order_types` can be set in the configuration file or in the strategy.
`order_types` set in the configuration file overwrites values set in the strategy as a whole, so you need to configure the whole `order_types` dictionary in one place.
If this is configured, the following 4 values (`buy`, `sell`, `stoploss` and
`stoploss_on_exchange`) need to be present, otherwise the bot will fail to start.
`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.
Not all Exchanges support `stoploss_on_exchange`. If an exchange supports both limit and market stoploss orders, then the value of `stoploss` will be used to determine the stoploss type.
If `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$.
For information on (`emergencysell`,`stoploss_on_exchange`,`stoploss_on_exchange_interval`,`stoploss_on_exchange_limit_ratio`) please see stop loss documentation [stop loss on exchange](stoploss.md)
Syntax for Strategy:
@@ -324,22 +314,21 @@ Configuration:
}
```
!!! Note
!!! Note "Market order support"
Not all exchanges support "market" orders.
The following message will be shown if your exchange does not support market orders:
`"Exchange <yourexchange> does not support market orders."`
`"Exchange <yourexchange> does not support market orders."` and the bot will refuse to start.
!!! Note
Stoploss on exchange interval is not mandatory. Do not change its value if you are
!!! Warning "Using market orders"
Please carefully read the section [Market order pricing](#market-order-pricing) section when using market orders.
!!! Note "Stoploss on exchange"
`stoploss_on_exchange_interval` is not mandatory. Do not change its value if you are
unsure of what you are doing. For more information about how stoploss works please
refer to [the stoploss documentation](stoploss.md).
!!! Note
If `stoploss_on_exchange` is enabled and the stoploss is cancelled manually on the exchange, then the bot will create a new stoploss order.
!!! Warning "Using market orders"
Please read the section [Market order pricing](#market-order-pricing) section when using market orders.
!!! 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.
@@ -386,7 +375,7 @@ Freqtrade is based on [CCXT library](https://github.com/ccxt/ccxt) that supports
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 by the development team with only Bittrex, Binance and Kraken,
so the these are the only officially supported exhanges:
so the these are the only officially supported exchanges:
- [Bittrex](https://bittrex.com/): "bittrex"
- [Binance](https://www.binance.com/): "binance"
@@ -585,131 +574,7 @@ Assuming both buy and sell are using market orders, a configuration similar to t
```
Obviously, if only one side is using limit orders, different pricing combinations can be used.
## 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, [`AgeFilter`](#agefilter), [`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)
* [`AgeFilter`](#agefilter)
* [`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. It 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,
}],
```
#### AgeFilter
Removes pairs that have been listed on the exchange for less than `min_days_listed` days (defaults to `10`).
When pairs are first listed on an exchange they can suffer huge price drops and volatility
in the first few days while the pair goes through its price-discovery period. Bots can often
be caught out buying before the pair has finished dropping in price.
This filter allows freqtrade to ignore pairs until they have been listed for at least `min_days_listed` days.
#### 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": "AgeFilter", "min_days_listed": 10},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01},
{"method": "SpreadFilter", "max_spread_ratio": 0.005},
{"method": "ShuffleFilter", "seed": 42}
],
```
--8<-- "includes/pairlists.md"
## Switch to Dry-run mode

View File

@@ -1,12 +1,22 @@
# Analyzing bot data with Jupyter notebooks
You can analyze the results of backtests and trading history easily using Jupyter notebooks. Sample notebooks are located at `user_data/notebooks/`.
You can analyze the results of backtests and trading history easily using Jupyter notebooks. Sample notebooks are located at `user_data/notebooks/` after initializing the user directory with `freqtrade create-userdir --userdir user_data`.
## Pro tips
## Quick start with docker
Freqtrade provides a docker-compose file which starts up a jupyter lab server.
You can run this server using the following command: `docker-compose -f docker/docker-compose-jupyter.yml up`
This will create a dockercontainer running jupyter lab, which will be accessible using `https://127.0.0.1:8888/lab`.
Please use the link that's printed in the console after startup for simplified login.
For more information, Please visit the [Data analysis with Docker](docker_quickstart.md#data-analayis-using-docker-compose) section.
### Pro tips
* See [jupyter.org](https://jupyter.org/documentation) for usage instructions.
* 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.
* Copy the example notebook before use so your changes don't get overwritten with the next freqtrade update.
### Using virtual environment with system-wide Jupyter installation
@@ -28,10 +38,8 @@ ipython kernel install --user --name=freqtrade
!!! 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.
!!! Warning
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.
## Recommended workflow

View File

@@ -8,82 +8,121 @@ 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.
You can use a relative timerange (`--days 20`) or an absolute starting point (`--timerange 20200101`). For incremental downloads, the relative approach should be used.
!!! 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.
Be careful 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} ...]]
usage: freqtrade download-data [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[-p PAIRS [PAIRS ...]] [--pairs-file FILE]
[--days INT] [--timerange TIMERANGE]
[--dl-trades] [--exchange EXCHANGE]
[-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...]]
[--erase]
[--data-format-ohlcv {json,jsongz,hdf5}]
[--data-format-trades {json,jsongz,hdf5}]
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}
--pairs-file FILE File containing a list of pairs to download.
--days INT Download data for given number of days.
--timerange TIMERANGE
Specify what timerange of data to use.
--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,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...]
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,hdf5}
Storage format for downloaded candle (OHLCV) data.
(default: `json`).
--data-format-trades {json,jsongz,hdf5}
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:
`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.
```
!!! Note "Startup period"
`download-data` is a strategy-independent command. The idea is to download a big chunk of data once, and then iteratively increase the amount of data stored.
For that reason, `download-data` does not care about the "startup-period" defined in a strategy. It's up to the user to download additional days if the backtest should start at a specific point in time (while respecting startup period).
### Data format
Freqtrade currently supports 3 data-formats for both OHLCV and trades data:
* `json` (plain "text" json files)
* `jsongz` (a gzip-zipped version of json files)
* `hdf5` (a high performance datastore)
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` command line arguments respectively.
To persist this change, you can should also add the following snippet to your configuration, so you don't have to insert the above arguments each time:
``` jsonc
// ...
"dataformat_ohlcv": "hdf5",
"dataformat_trades": "hdf5",
// ...
```
If the default data-format 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](#sub-command-convert-data) and [convert-trade-data](#sub-command-convert-trade-data) methods.
#### Sub-command convert data
```
usage: freqtrade convert-data [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[-p PAIRS [PAIRS ...]] --format-from
{json,jsongz,hdf5} --format-to
{json,jsongz,hdf5} [--erase]
[-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...]]
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,hdf5}
Source format for data conversion.
--format-to {json,jsongz}
--format-to {json,jsongz,hdf5}
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} ...]
-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...]
Specify which tickers to download. Space-separated
list. Default: `1m 5m`.
@@ -94,9 +133,10 @@ Common arguments:
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
@@ -112,23 +152,23 @@ It'll also remove original json data files (`--erase` parameter).
freqtrade convert-data --format-from json --format-to jsongz --datadir ~/.freqtrade/data/binance -t 5m 15m --erase
```
#### Subcommand convert-trade data
#### Sub-command 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]
{json,jsongz,hdf5} --format-to
{json,jsongz,hdf5} [--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}
--format-from {json,jsongz,hdf5}
Source format for data conversion.
--format-to {json,jsongz}
--format-to {json,jsongz,hdf5}
Destination format for data conversion.
--erase Clean all existing data for the selected
exchange/pairs/timeframes.
@@ -140,13 +180,15 @@ Common arguments:
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.
```
##### Example converting trades
@@ -158,6 +200,59 @@ It'll also remove original jsongz data files (`--erase` parameter).
freqtrade convert-trade-data --format-from jsongz --format-to json --datadir ~/.freqtrade/data/kraken --erase
```
### Sub-command list-data
You can get a list of downloaded data using the `list-data` sub-command.
```
usage: freqtrade list-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [--exchange EXCHANGE]
[--data-format-ohlcv {json,jsongz,hdf5}]
[-p PAIRS [PAIRS ...]]
optional arguments:
-h, --help show this help message and exit
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no
config is provided.
--data-format-ohlcv {json,jsongz,hdf5}
Storage format for downloaded candle (OHLCV) data.
(default: `json`).
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
Show profits for only these pairs. Pairs are space-
separated.
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.
```
#### Example list-data
```bash
> freqtrade list-data --userdir ~/.freqtrade/user_data/
Found 33 pair / timeframe combinations.
pairs timeframe
---------- -----------------------------------------
ADA/BTC 5m, 15m, 30m, 1h, 2h, 4h, 6h, 12h, 1d
ADA/ETH 5m, 15m, 30m, 1h, 2h, 4h, 6h, 12h, 1d
ETH/BTC 5m, 15m, 30m, 1h, 2h, 4h, 6h, 12h, 1d
ETH/USDT 5m, 15m, 30m, 1h, 2h, 4h
```
### Pairs file
In alternative to the whitelist from `config.json`, a `pairs.json` file can be used.
@@ -197,15 +292,16 @@ This will download historical candle (OHLCV) data for all the currency pairs you
### 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 historical data from, 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 rate limits etc.)
- To use `pairs.json` from some other directory, use `--pairs-file some_other_dir/pairs.json`.
- To download historical candle (OHLCV) data for only 10 days, use `--days 10` (defaults to 30 days).
- To download historical candle (OHLCV) data from a fixed starting point, use `--timerange 20200101-` - which will download all data from January 1st, 2020. Eventually set end dates are ignored.
- 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
By default, `download-data` subcommand downloads Candles (OHLCV) data. Some exchanges also provide historic trade-data via their API.
By default, `download-data` sub-command downloads Candles (OHLCV) data. Some exchanges also provide historic trade-data via their API.
This data can be useful if you need many different timeframes, since it is only downloaded once, and then resampled locally to the desired timeframes.
Since this data is large by default, the files use gzip by default. They are stored in your data-directory with the naming convention of `<pair>-trades.json.gz` (`ETH_BTC-trades.json.gz`). Incremental mode is also supported, as for historic OHLCV data, so downloading the data once per week with `--days 8` will create an incremental data-repository.

View File

@@ -9,21 +9,20 @@ and are no longer supported. Please avoid their usage in your configuration.
### the `--refresh-pairs-cached` command line option
`--refresh-pairs-cached` in the context of backtesting, hyperopt and edge allows to refresh candle data for backtesting.
Since this leads to much confusion, and slows down backtesting (while not being part of backtesting) this has been singled out
as a seperate freqtrade subcommand `freqtrade download-data`.
Since this leads to much confusion, and slows down backtesting (while not being part of backtesting) this has been singled out as a separate freqtrade sub-command `freqtrade download-data`.
This command line option was deprecated in 2019.7-dev (develop branch) and removed in 2019.9 (master branch).
This command line option was deprecated in 2019.7-dev (develop branch) and removed in 2019.9.
### The **--dynamic-whitelist** command line option
This command line option was deprecated in 2018 and removed freqtrade 2019.6-dev (develop branch)
and in freqtrade 2019.7 (master branch).
and in freqtrade 2019.7.
### the `--live` command line option
`--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)
Removed in 2019-7-dev (develop branch) and in freqtrade 2019.8.
### Allow running multiple pairlists in sequence
@@ -31,6 +30,6 @@ The former `"pairlist"` section in the configuration has been removed, and is re
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
### deprecation of bidVolume and askVolume from volume-pairlist
Since only quoteVolume can be compared between assets, the other options (bidVolume, askVolume) have been deprecated in 2020.4.
Since only quoteVolume can be compared between assets, the other options (bidVolume, askVolume) have been deprecated in 2020.4, and have been removed in 2020.9.

View File

@@ -2,7 +2,7 @@
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.
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 on [discord](https://discord.gg/MA9v74M) or [slack](https://join.slack.com/t/highfrequencybot/shared_invite/zt-jaut7r4m-Y17k4x5mcQES9a9swKuxbg) where you can ask questions.
## Documentation
@@ -10,13 +10,35 @@ Documentation is available at [https://freqtrade.io](https://www.freqtrade.io/)
Special fields for the documentation (like Note boxes, ...) can be found [here](https://squidfunk.github.io/mkdocs-material/extensions/admonition/).
To test the documentation locally use the following commands.
``` bash
pip install -r docs/requirements-docs.txt
mkdocs serve
```
This will spin up a local server (usually on port 8000) so you can see if everything looks as you'd like it to.
## Developer setup
To configure a development environment, best use the `setup.sh` script and answer "y" when asked "Do you want to install dependencies for dev [y/N]? ".
Alternatively (if your system is not supported by the setup.sh script), follow the manual installation process and run `pip3 install -e .[all]`.
To configure a development environment, you can either use the provided [DevContainer](#devcontainer-setup), or use the `setup.sh` script and answer "y" when asked "Do you want to install dependencies for dev [y/N]? ".
Alternatively (e.g. if your system is not supported by the setup.sh script), follow the manual installation process and run `pip3 install -e .[all]`.
This will install all required tools for development, including `pytest`, `flake8`, `mypy`, and `coveralls`.
### Devcontainer setup
The fastest and easiest way to get started is to use [VSCode](https://code.visualstudio.com/) with the Remote container extension.
This gives developers the ability to start the bot with all required dependencies *without* needing to install any freqtrade specific dependencies on your local machine.
#### Devcontainer dependencies
* [VSCode](https://code.visualstudio.com/)
* [docker](https://docs.docker.com/install/)
* [Remote container extension documentation](https://code.visualstudio.com/docs/remote)
For more information about the [Remote container extension](https://code.visualstudio.com/docs/remote), best consult the documentation.
### Tests
New code should be covered by basic unittests. Depending on the complexity of the feature, Reviewers may request more in-depth unittests.
@@ -41,53 +63,40 @@ def test_method_to_test(caplog):
```
### Local docker usage
## ErrorHandling
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.
Freqtrade Exceptions all inherit from `FreqtradeException`.
This general class of error should however not be used directly. Instead, multiple specialized sub-Exceptions exist.
#### Install
Below is an outline of exception inheritance hierarchy:
* [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
``` bash
docker-compose up
+ FreqtradeException
|
+---+ OperationalException
|
+---+ DependencyException
| |
| +---+ PricingError
| |
| +---+ ExchangeError
| |
| +---+ TemporaryError
| |
| +---+ DDosProtection
| |
| +---+ InvalidOrderException
| |
| +---+ RetryableOrderError
| |
| +---+ InsufficientFundsError
|
+---+ StrategyError
```
![Docker compose up](https://user-images.githubusercontent.com/419355/65456322-47f63a80-de06-11e9-90c6-3c74d1bad0b8.png)
##### Rebuilding
``` bash
docker-compose build
```
##### Execing (effectively SSH into the container)
The `exec` command requires that the container already be running, if you want to start it
that can be effected by `docker-compose up` or `docker-compose run freqtrade_develop`
``` bash
docker-compose exec freqtrade_develop /bin/bash
```
![image](https://user-images.githubusercontent.com/419355/65456522-ba671a80-de06-11e9-9598-df9ca0d8dcac.png)
## Modules
### Dynamic Pairlist
### Pairlists
You have a great idea for a new pair selection algorithm you would like to try out? Great.
Hopefully you also want to contribute this back upstream.
@@ -98,7 +107,7 @@ First of all, have a look at the [VolumePairList](https://github.com/freqtrade/f
This is a simple Handler, which however serves as a good example on how to start developing.
Next, modify the classname of the Handler (ideally align this with the module filename).
Next, modify the class-name of the Handler (ideally align this with the module filename).
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.
@@ -118,7 +127,7 @@ Configuration for the chain of Pairlist Handlers is done in the bot configuratio
By convention, `"number_assets"` is used to specify the maximum number of pairs to keep in the pairlist. Please follow this to ensure a consistent user experience.
Additional parameters can be configured as needed. For instance, `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.
Additional parameters can be configured as needed. For instance, `VolumePairList` uses `"sort_key"` to specify the sorting value - however feel free to specify whatever is necessary for your great algorithm to be successful and dynamic.
#### short_desc
@@ -134,7 +143,7 @@ This is called with each iteration of the bot (only if the Pairlist Handler is a
It must return the resulting pairlist (which may then be passed into the chain of Pairlist Handlers).
Validations are optional, the parent class exposes a `_verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filtering. Use this if you limit your result to a certain number of pairs - so the endresult is not shorter than expected.
Validations are optional, the parent class exposes a `_verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filtering. Use this if you limit your result to a certain number of pairs - so the end-result is not shorter than expected.
#### filter_pairlist
@@ -142,13 +151,13 @@ This method is called for each Pairlist Handler in the chain by the pairlist man
This is called with each iteration of the bot - so consider implementing caching for compute/network heavy calculations.
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()`.
It gets passed a pairlist (which can be the result of previous pairlists) as well as `tickers`, a pre-fetched version of `get_tickers()`.
The default implementation in the base class simply calls the `_validate_pair()` method for each pair in the pairlist, but you may override it. So you should either implement the `_validate_pair()` in your Pairlist Handler or override `filter_pairlist()` to do something else.
If overridden, it must return the resulting pairlist (which may then be passed into the next Pairlist Handler in the chain).
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.
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 end result is not shorter than expected.
In `VolumePairList`, this implements different methods of sorting, does early validation so only the expected number of pairs is returned.
@@ -172,7 +181,7 @@ Most exchanges supported by CCXT should work out of the box.
Check if the new exchange supports Stoploss on Exchange orders through their API.
Since CCXT does not provide unification for Stoploss On Exchange yet, we'll need to implement the exchange-specific parameters ourselfs. Best look at `binance.py` for an example implementation of this. You'll need to dig through the documentation of the Exchange's API on how exactly this can be done. [CCXT Issues](https://github.com/ccxt/ccxt/issues) may also provide great help, since others may have implemented something similar for their projects.
Since CCXT does not provide unification for Stoploss On Exchange yet, we'll need to implement the exchange-specific parameters ourselves. Best look at `binance.py` for an example implementation of this. You'll need to dig through the documentation of the Exchange's API on how exactly this can be done. [CCXT Issues](https://github.com/ccxt/ccxt/issues) may also provide great help, since others may have implemented something similar for their projects.
### Incomplete candles
@@ -222,13 +231,14 @@ jupyter nbconvert --ClearOutputPreprocessor.enabled=True --to markdown freqtrade
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 are build for the branches `stable` and `develop`.
* Docker images containing Plot dependencies are also available as `stable_plot` and `develop_plot`.
* Raspberry PI Docker images are postfixed with `_pi` - so tags will be `:stable_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`.
* All tests must pass for a PR to be merged to `stable` or `develop`.
## Creating a release
@@ -245,21 +255,22 @@ git checkout -b new_release <commitid>
Determine if crucial bugfixes have been made between this commit and the current state, and eventually cherry-pick these.
* Merge the release branch (stable) into this branch.
* Edit `freqtrade/__init__.py` and add the version matching the current date (for example `2019.7` for July 2019). Minor versions can be `2019.7.1` should we need to do a second release that month. Version numbers must follow allowed versions from PEP0440 to avoid failures pushing to pypi.
* Commit this part
* push that branch to the remote and create a PR against the master branch
* push that branch to the remote and create a PR against the stable branch
### Create changelog from git commits
!!! Note
Make sure that the master branch is uptodate!
Make sure that the `stable` branch is up-to-date!
``` bash
# Needs to be done before merging / pulling that branch.
git log --oneline --no-decorate --no-merges master..new_release
git log --oneline --no-decorate --no-merges stable..new_release
```
To keep the release-log short, best wrap the full git changelog into a collapsible details secction.
To keep the release-log short, best wrap the full git changelog into a collapsible details section.
```markdown
<details>
@@ -272,17 +283,20 @@ To keep the release-log short, best wrap the full git changelog into a collapsib
### Create github release / tag
Once the PR against master is merged (best right after merging):
Once the PR against stable is merged (best right after merging):
* 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 "stable" as reference (this step comes after the above PR is merged).
* Use the above changelog as release comment (as codeblock)
## Releases
### pypi
!!! Note
This process is now automated as part of Github Actions.
To create a pypi release, please run the following commands:
Additional requirement: `wheel`, `twine` (for uploading), account on pypi with proper permissions.

View File

@@ -1,145 +1,7 @@
# Using Freqtrade with Docker
## Install Docker
Start by downloading and installing Docker CE for your platform:
* [Mac](https://docs.docker.com/docker-for-mac/install/)
* [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.
## 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.
The below documentation is provided for completeness and assumes that you are familiar with running docker containers. If you're just starting out with Docker, we recommend to follow the [Quickstart](docker.md) instructions.
### Download the official Freqtrade docker image
@@ -148,9 +10,9 @@ Pull the image from docker hub.
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
docker pull freqtradeorg/freqtrade:stable
# Optionally tag the repository so the run-commands remain shorter
docker tag freqtradeorg/freqtrade:develop freqtrade
docker tag freqtradeorg/freqtrade:stable freqtrade
```
To update the image, simply run the above commands again and restart your running container.
@@ -158,7 +20,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"
The official docker images with tags `master`, `develop` and `latest` are automatically rebuild once a week to keep the base image uptodate.
The official docker images with tags `stable`, `develop` and `latest` are automatically rebuild once a week to keep the base image up-to-date.
In addition to that, every merge to `develop` will trigger a rebuild for `develop` and `latest`.
### Prepare the configuration files
@@ -190,39 +52,38 @@ cp -n config.json.example config.json
#### Create your database file
Production
=== "Dry-Run"
``` bash
touch tradesv3.dryrun.sqlite
```
```bash
touch tradesv3.sqlite
````
=== "Production"
``` bash
touch tradesv3.sqlite
```
Dry-Run
```bash
touch tradesv3.dryrun.sqlite
```
!!! Note
Make sure to use the path to this file when starting the bot in docker.
!!! Warning "Database File Path"
Make sure to use the path to the correct database file when starting the bot in Docker.
### Build your own Docker image
Best start by pulling the official docker image from dockerhub as explained [here](#download-the-official-docker-image) to speed up building.
To add additional libraries to your docker image, best check out [Dockerfile.technical](https://github.com/freqtrade/freqtrade/blob/develop/Dockerfile.technical) which adds the [technical](https://github.com/freqtrade/technical) module to the image.
To add additional libraries to your docker image, best check out [Dockerfile.technical](https://github.com/freqtrade/freqtrade/blob/develop/docker/Dockerfile.technical) which adds the [technical](https://github.com/freqtrade/technical) module to the image.
```bash
docker build -t freqtrade -f Dockerfile.technical .
docker build -t freqtrade -f docker/Dockerfile.technical .
```
If you are developing using Docker, use `Dockerfile.develop` to build a dev Docker image, which will also set up develop dependencies:
If you are developing using Docker, use `docker/Dockerfile.develop` to build a dev Docker image, which will also set up develop dependencies:
```bash
docker build -f Dockerfile.develop -t freqtrade-dev .
docker build -f docker/Dockerfile.develop -t freqtrade-dev .
```
!!! Note
For security reasons, your configuration file will not be included in the image, you will need to bind mount it. It is also advised to bind mount an SQLite database file (see the "5. Run a restartable docker image" section) to keep it between updates.
!!! Warning "Include your config file manually"
For security reasons, your configuration file will not be included in the image, you will need to bind mount it. It is also advised to bind mount an SQLite database file (see [5. Run a restartable docker image](#run-a-restartable-docker-image)") to keep it between updates.
#### Verify the Docker image
@@ -243,37 +104,36 @@ docker run --rm -v `pwd`/config.json:/freqtrade/config.json -it freqtrade
```
!!! Warning
In this example, the database will be created inside the docker instance and will be lost when you will refresh your image.
In this example, the database will be created inside the docker instance and will be lost when you refresh your image.
#### Adjust timezone
By default, the container will use UTC timezone.
Should you find this irritating please add the following to your docker commands:
If you would like to change the timezone use the following commands:
##### Linux
=== "Linux"
``` bash
-v /etc/timezone:/etc/timezone:ro
``` bash
-v /etc/timezone:/etc/timezone:ro
# Complete command:
docker run --rm -v /etc/timezone:/etc/timezone:ro -v `pwd`/config.json:/freqtrade/config.json -it freqtrade
```
# Complete command:
docker run --rm -v /etc/timezone:/etc/timezone:ro -v `pwd`/config.json:/freqtrade/config.json -it freqtrade
```
=== "MacOS"
```bash
docker run --rm -e TZ=`ls -la /etc/localtime | cut -d/ -f8-9` -v `pwd`/config.json:/freqtrade/config.json -it freqtrade
```
##### MacOS
There is known issue in OSX Docker versions after 17.09.1, whereby `/etc/localtime` cannot be shared causing Docker to not start. A work-around for this is to start with the following cmd.
```bash
docker run --rm -e TZ=`ls -la /etc/localtime | cut -d/ -f8-9` -v `pwd`/config.json:/freqtrade/config.json -it freqtrade
```
More information on this docker issue and work-around can be read [here](https://github.com/docker/for-mac/issues/2396).
!!! Note "MacOS Issues"
The OSX Docker versions after 17.09.1 have a known issue whereby `/etc/localtime` cannot be shared causing Docker to not start.<br>
A work-around for this is to start with the MacOS command above
More information on this docker issue and work-around can be read [here](https://github.com/docker/for-mac/issues/2396).
### Run a restartable docker image
To run a restartable instance in the background (feel free to place your configuration and database files wherever it feels comfortable on your filesystem).
#### Move your config file and database
#### 1. Move your config file and database
The following will assume that you place your configuration / database files to `~/.freqtrade`, which is a hidden directory in your home directory. Feel free to use a different directory and replace the directory in the upcomming commands.
@@ -283,7 +143,7 @@ mv config.json ~/.freqtrade
mv tradesv3.sqlite ~/.freqtrade
```
#### Run the docker image
#### 2. Run the docker image
```bash
docker run -d \

191
docs/docker_quickstart.md Normal file
View File

@@ -0,0 +1,191 @@
# Using Freqtrade with Docker
## Install Docker
Start by downloading and installing Docker CE for your platform:
* [Mac](https://docs.docker.com/docker-for-mac/install/)
* [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.
## 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` are installed and available to the logged in user.
- All below commands use relative directories and will have to be executed from the directory containing the `docker-compose.yml` file.
### 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.
=== "PC/MAC/Linux"
``` bash
mkdir ft_userdata
cd ft_userdata/
# Download the docker-compose file from the repository
curl https://raw.githubusercontent.com/freqtrade/freqtrade/stable/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
```
=== "RaspberryPi"
``` bash
mkdir ft_userdata
cd ft_userdata/
# Download the docker-compose file from the repository
curl https://raw.githubusercontent.com/freqtrade/freqtrade/stable/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
```
!!! Note "Change your docker Image"
You have to change the docker image in the docker-compose file for your Raspberry build to work properly.
``` yml
image: freqtradeorg/freqtrade:stable_pi
# image: freqtradeorg/freqtrade:develop_pi
```
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.
!!! Question "How to edit the bot configuration?"
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.
You can also change the both Strategy and commands by editing the `docker-compose.yml` file.
#### Adding a custom strategy
1. The configuration is now available as `user_data/config.json`
2. Copy a custom strategy to the directory `user_data/strategies/`
3. add the Strategy' class name to the `docker-compose.yml` file
The `SampleStrategy` is run by default.
!!! Warning "`SampleStrategy` is just a demo!"
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 located at: `user_data/logs/freqtrade.log`.
You can check the latest log with the command `docker-compose logs -f`.
#### Database
The database will be at: `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.
!!! Warning "Check the Changelog"
You should always check the changelog for breaking changes / manual interventions required and make sure the bot starts correctly after the update.
### Editing the docker-compose file
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 [docker/Dockerfile.technical](https://github.com/freqtrade/freqtrade/blob/develop/docker/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.
## Plotting with docker-compose
Commands `freqtrade plot-profit` and `freqtrade plot-dataframe` ([Documentation](plotting.md)) are available by changing the image to `*_plot` in your docker-compose.yml file.
You can then use these commands as follows:
``` bash
docker-compose run --rm freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --timerange=20180801-20180805
```
The output will be stored in the `user_data/plot` directory, and can be opened with any modern browser.
## Data analayis using docker compose
Freqtrade provides a docker-compose file which starts up a jupyter lab server.
You can run this server using the following command:
``` bash
docker-compose --rm -f docker/docker-compose-jupyter.yml up
```
This will create a dockercontainer running jupyter lab, which will be accessible using `https://127.0.0.1:8888/lab`.
Please use the link that's printed in the console after startup for simplified login.
Since part of this image is built on your machine, it is recommended to rebuild the image from time to time to keep freqtrade (and dependencies) uptodate.
``` bash
docker-compose -f docker/docker-compose-jupyter.yml build --no-cache
```

View File

@@ -1,95 +1,160 @@
# 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.
The `Edge Positioning` module uses probability to calculate your win rate and risk reward ration. It will use these statistics to control your strategy trade entry points, position side and, stoploss.
!!! Warning
Edge positioning is not compatible with dynamic (volume-based) whitelist.
`Edge positioning` is not compatible with dynamic (volume-based) whitelist.
!!! Note
Edge does not consider anything else than buy/sell/stoploss signals. So trailing stoploss, ROI, and everything else are ignored in its calculation.
`Edge Positioning` only considers *its own* buy/sell/stoploss signals. It ignores the stoploss, trailing stoploss, and ROI settings in the strategy configuration file.
`Edge Positioning` improves the performance of some trading strategies and *decreases* the performance of others.
## 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.
Trading strategies are not perfect. They are frameworks that are susceptible to the market and its indicators. Because the market is not at all predictable, sometimes a strategy will win and sometimes the same strategy will 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?
To obtain an edge in the market, a strategy has to make more money than it loses. Making money in trading is not only about *how often* the strategy makes or loses money.
But let's say the probability that we have heads is 80% (because our coin has the displaced distribution of mass or other defect), and the probability that we have tails is 20%. Now it is becoming interesting...
!!! tip "It doesn't matter how often, but how much!"
A bad strategy might make 1 penny in *ten* transactions but lose 1 dollar in *one* transaction. If one only checks the number of winning trades, it would be misleading to think that the strategy is actually making a profit.
That means 10$ X 80% versus 10$ X 20%. 8$ versus 2$. That means over time you will win 8$ risking only 2$ on each toss of coin.
The Edge Positioning module seeks to improve a strategy's winning probability and the money that the strategy will make *on the long run*.
Let's complicate it more: you win 80% of the time but only 2$, I win 20% of the time but 8$. The calculation is: 80% X 2$ versus 20% X 8$. It is becoming boring again because overtime you win $1.6$ (80% X 2$) and me $1.6 (20% X 8$) too.
We raise the following question[^1]:
The question is: How do you calculate that? How do you know if you wanna play?
!!! Question "Which trade is a better option?"
a) A trade with 80% of chance of losing $100 and 20% chance of winning $200<br/>
b) A trade with 100% of chance of losing $30
The answer comes to two factors:
???+ Info "Answer"
The expected value of *a)* is smaller than the expected value of *b)*.<br/>
Hence, *b*) represents a smaller loss in the long run.<br/>
However, the answer is: *it depends*
- Win Rate
- Risk Reward Ratio
Another way to look at it is to ask a similar question:
### Win Rate
!!! Question "Which trade is a better option?"
a) A trade with 80% of chance of winning 100 and 20% chance of losing $200<br/>
b) A trade with 100% of chance of winning $30
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).
Edge positioning tries to answer the hard questions about risk/reward and position size automatically, seeking to minimizes the chances of losing of a given strategy.
```
W = (Number of winning trades) / (Total number of trades) = (Number of winning trades) / N
```
### Trading, winning and losing
Complementary Loss Rate (*L*) is defined as
Let's call $o$ the return of a single transaction $o$ where $o \in \mathbb{R}$. The collection $O = \{o_1, o_2, ..., o_N\}$ is the set of all returns of transactions made during a trading session. We say that $N$ is the cardinality of $O$, or, in lay terms, it is the number of transactions made in a trading session.
```
L = (Number of losing trades) / (Total number of trades) = (Number of losing trades) / N
```
!!! Example
In a session where a strategy made three transactions we can say that $O = \{3.5, -1, 15\}$. That means that $N = 3$ and $o_1 = 3.5$, $o_2 = -1$, $o_3 = 15$.
or, which is the same, as
A winning trade is a trade where a strategy *made* money. Making money means that the strategy closed the position in a value that returned a profit, after all deducted fees. Formally, a winning trade will have a return $o_i > 0$. Similarly, a losing trade will have a return $o_j \leq 0$. With that, we can discover the set of all winning trades, $T_{win}$, as follows:
```
L = 1 W
```
$$ T_{win} = \{ o \in O | o > 0 \} $$
Similarly, we can discover the set of losing trades $T_{lose}$ as follows:
$$ T_{lose} = \{o \in O | o \leq 0\} $$
!!! Example
In a section where a strategy made three transactions $O = \{3.5, -1, 15, 0\}$:<br>
$T_{win} = \{3.5, 15\}$<br>
$T_{lose} = \{-1, 0\}$<br>
### Win Rate and Lose Rate
The win rate $W$ is the proportion of winning trades with respect to all the trades made by a strategy. We use the following function to compute the win rate:
$$W = \frac{|T_{win}|}{N}$$
Where $W$ is the win rate, $N$ is the number of trades and, $T_{win}$ is the set of all trades where the strategy made money.
Similarly, we can compute the rate of losing trades:
$$
L = \frac{|T_{lose}|}{N}
$$
Where $L$ is the lose rate, $N$ is the amount of trades made and, $T_{lose}$ is the set of all trades where the strategy lost money. Note that the above formula is the same as calculating $L = 1 W$ or $W = 1 L$
### 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:
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. Formally:
```
R = Profit / Loss
```
$$ R = \frac{\text{potential_profit}}{\text{potential_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:
???+ Example "Worked example of $R$ calculation"
Let's say that you think that the price of *stonecoin* today is $10.0. You believe that, because they will start mining stonecoin, it will go up to $15.0 tomorrow. There is the risk that the stone is too hard, and the GPUs can't mine it, so the price might go to $0 tomorrow. You are planning to invest $100, which will give you 10 shares (100 / 10).
```
Average profit = (Sum of profits) / (Number of winning trades)
Your potential profit is calculated as:
Average loss = (Sum of losses) / (Number of losing trades)
$\begin{aligned}
\text{potential_profit} &= (\text{potential_price} - \text{entry_price}) * \frac{\text{investment}}{\text{entry_price}} \\
&= (15 - 10) * (100 / 10) \\
&= 50
\end{aligned}$
Since the price might go to $0, the $100 dollars invested could turn into 0.
We do however use a stoploss of 15% - so in the worst case, we'll sell 15% below entry price (or at 8.5$).
$\begin{aligned}
\text{potential_loss} &= (\text{entry_price} - \text{stoploss}) * \frac{\text{investment}}{\text{entry_price}} \\
&= (10 - 8.5) * (100 / 10)\\
&= 15
\end{aligned}$
We can compute the Risk Reward Ratio as follows:
$\begin{aligned}
R &= \frac{\text{potential_profit}}{\text{potential_loss}}\\
&= \frac{50}{15}\\
&= 3.33
\end{aligned}$<br>
What it effectively means is that the strategy have the potential to make 3.33$ for each $1 invested.
On a long horizon, that is, on many trades, we can calculate the risk reward by dividing the strategy' average profit on winning trades by the strategy' average loss on losing trades. We can calculate the average profit, $\mu_{win}$, as follows:
$$ \text{average_profit} = \mu_{win} = \frac{\text{sum_of_profits}}{\text{count_winning_trades}} = \frac{\sum^{o \in T_{win}} o}{|T_{win}|} $$
Similarly, we can calculate the average loss, $\mu_{lose}$, as follows:
$$ \text{average_loss} = \mu_{lose} = \frac{\text{sum_of_losses}}{\text{count_losing_trades}} = \frac{\sum^{o \in T_{lose}} o}{|T_{lose}|} $$
Finally, we can calculate the Risk Reward ratio, $R$, as follows:
$$ R = \frac{\text{average_profit}}{\text{average_loss}} = \frac{\mu_{win}}{\mu_{lose}}\\ $$
???+ Example "Worked example of $R$ calculation using mean profit/loss"
Let's say the strategy that we are using makes an average win $\mu_{win} = 2.06$ and an average loss $\mu_{loss} = 4.11$.<br>
We calculate the risk reward ratio as follows:<br>
$R = \frac{\mu_{win}}{\mu_{loss}} = \frac{2.06}{4.11} = 0.5012...$
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:
By combining the Win Rate $W$ and and the Risk Reward ratio $R$ to create an expectancy ratio $E$. A expectance ratio is the expected return of the investment made in a trade. We can compute the value of $E$ as follows:
```
Expectancy Ratio = (Risk Reward Ratio X Win Rate) Loss Rate = (R X W) L
```
$$E = R * W - L$$
So lets say your Win rate is 28% and your Risk Reward Ratio is 5:
!!! Example "Calculating $E$"
Let's say that a strategy has a win rate $W = 0.28$ and a risk reward ratio $R = 5$. What this means is that the strategy is expected to make 5 times the investment around on 28% of the trades it makes. Working out the example:<br>
$E = R * W - L = 5 * 0.28 - 0.72 = 0.68$
<br>
```
Expectancy = (5 X 0.28) 0.72 = 0.68
```
The expectancy worked out in the example above means that, on average, this strategy' trades will return 1.68 times the size of its losses. Said another way, the strategy makes $1.68 for every $1 it loses, on average.
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.
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.
You can also use this value to evaluate the effectiveness of modifications to this system.
**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.
!!! Note
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:
Edge combines dynamic stoploss, dynamic positions, and whitelist generation into one isolated module which is then applied to the trading strategy. 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 |
|----------|:-------------:|-------------:|------------------:|-----------:|
@@ -98,13 +163,13 @@ If enabled in config, Edge will go through historical data with a range of stopl
| XZC/ETH | -0.03 | 0.52 |1.359670 | 0.228 |
| XZC/ETH | -0.04 | 0.51 |1.234539 | 0.117 |
The goal here is to find the best stoploss for the strategy in order to have the maximum expectancy. In the above example stoploss at 3% leads to the maximum expectancy according to historical data.
The goal here is to find the best stoploss for the strategy in order to have the maximum expectancy. In the above example stoploss at $3%$ leads to the maximum expectancy according to historical data.
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:
Edge dictates the amount at stake for each trade to the bot according to the following factors:
- Allowed capital at risk
- Stoploss
@@ -115,9 +180,9 @@ Allowed capital at risk is calculated as follows:
Allowed capital at risk = (Capital available_percentage) X (Allowed risk per trade)
```
Stoploss is calculated as described above against historical data.
Stoploss is calculated as described above with respect to historical data.
Your position size then will be:
The position size is calculated as follows:
```
Position size = (Allowed capital at risk) / Stoploss
@@ -125,19 +190,23 @@ Position size = (Allowed capital at risk) / Stoploss
Example:
Let's say the stake currency is ETH and you have 10 ETH on the exchange, your capital available percentage is 50% and you would allow 1% of risk for each trade. thus your available capital for trading is **10 x 0.5 = 5 ETH** and allowed capital at risk would be **5 x 0.01 = 0.05 ETH**.
Let's say the stake currency is **ETH** and there is $10$ **ETH** on the wallet. The capital available percentage is $50%$ and the allowed risk per trade is $1\%$. Thus, the available capital for trading is $10 * 0.5 = 5$ **ETH** and the allowed capital at risk would be $5 * 0.01 = 0.05$ **ETH**.
Let's assume Edge has calculated that for **XLM/ETH** market your stoploss should be at 2%. So your position size will be **0.05 / 0.02 = 2.5 ETH**.
- **Trade 1:** The strategy detects a new buy signal in the **XLM/ETH** market. `Edge Positioning` calculates a stoploss of $2\%$ and a position of $0.05 / 0.02 = 2.5$ **ETH**. The bot takes a position of $2.5$ **ETH** in the **XLM/ETH** market.
Bot takes a position of 2.5 ETH on XLM/ETH (call it trade 1). Up next, you receive another buy signal while trade 1 is still open. This time on **BTC/ETH** market. Edge calculated stoploss for this market at 4%. So your position size would be 0.05 / 0.04 = 1.25 ETH (call it trade 2).
- **Trade 2:** The strategy detects a buy signal on the **BTC/ETH** market while **Trade 1** is still open. `Edge Positioning` calculates the stoploss of $4\%$ on this market. Thus, **Trade 2** position size is $0.05 / 0.04 = 1.25$ **ETH**.
Note that available capital for trading didnt change for trade 2 even if you had already trade 1. The available capital doesnt mean the free amount on your wallet.
!!! Tip "Available Capital $\neq$ Available in wallet"
The available capital for trading didn't change in **Trade 2** even with **Trade 1** still open. The available capital **is not** the free amount in the wallet.
Now you have two trades open. The bot receives yet another buy signal for another market: **ADA/ETH**. This time the stoploss is calculated at 1%. So your position size is **0.05 / 0.01 = 5 ETH**. But there are already 3.75 ETH blocked in two previous trades. So the position size for this third trade would be **5 3.75 = 1.25 ETH**.
- **Trade 3:** The strategy detects a buy signal in the **ADA/ETH** market. `Edge Positioning` calculates a stoploss of $1\%$ and a position of $0.05 / 0.01 = 5$ **ETH**. Since **Trade 1** has $2.5$ **ETH** blocked and **Trade 2** has $1.25$ **ETH** blocked, there is only $5 - 1.25 - 2.5 = 1.25$ **ETH** available. Hence, the position size of **Trade 3** is $1.25$ **ETH**.
Available capital doesnt change before a position is sold. Lets assume that trade 1 receives a sell signal and it is sold with a profit of 1 ETH. Your total capital on exchange would be 11 ETH and the available capital for trading becomes 5.5 ETH.
!!! Tip "Available Capital Updates"
The available capital does not change before a position is sold. After a trade is closed the Available Capital goes up if the trade was profitable or goes down if the trade was a loss.
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**.
- The strategy detects a sell signal in the **XLM/ETH** market. The bot exits **Trade 1** for a profit of $1$ **ETH**. The total capital in the wallet becomes $11$ **ETH** and the available capital for trading becomes $5.5$ **ETH**.
- **Trade 4** The strategy detects a new buy signal int the **XLM/ETH** market. `Edge Positioning` calculates the stoploss of $2%$, and the position size of $0.055 / 0.02 = 2.75$ **ETH**.
## Configurations
@@ -168,23 +237,29 @@ freqtrade edge
An example of its output:
| pair | stoploss | win rate | risk reward ratio | required risk reward | expectancy | total number of trades | average duration (min) |
|:----------|-----------:|-----------:|--------------------:|-----------------------:|-------------:|-------------------------:|-------------------------:|
| AGI/BTC | -0.02 | 0.64 | 5.86 | 0.56 | 3.41 | 14 | 54 |
| NXS/BTC | -0.03 | 0.64 | 2.99 | 0.57 | 1.54 | 11 | 26 |
| LEND/BTC | -0.02 | 0.82 | 2.05 | 0.22 | 1.50 | 11 | 36 |
| VIA/BTC | -0.01 | 0.55 | 3.01 | 0.83 | 1.19 | 11 | 48 |
| MTH/BTC | -0.09 | 0.56 | 2.82 | 0.80 | 1.12 | 18 | 52 |
| ARDR/BTC | -0.04 | 0.42 | 3.14 | 1.40 | 0.73 | 12 | 42 |
| BCPT/BTC | -0.01 | 0.71 | 1.34 | 0.40 | 0.67 | 14 | 30 |
| WINGS/BTC | -0.02 | 0.56 | 1.97 | 0.80 | 0.65 | 27 | 42 |
| VIBE/BTC | -0.02 | 0.83 | 0.91 | 0.20 | 0.59 | 12 | 35 |
| MCO/BTC | -0.02 | 0.79 | 0.97 | 0.27 | 0.55 | 14 | 31 |
| GNT/BTC | -0.02 | 0.50 | 2.06 | 1.00 | 0.53 | 18 | 24 |
| HOT/BTC | -0.01 | 0.17 | 7.72 | 4.81 | 0.50 | 209 | 7 |
| SNM/BTC | -0.03 | 0.71 | 1.06 | 0.42 | 0.45 | 17 | 38 |
| APPC/BTC | -0.02 | 0.44 | 2.28 | 1.27 | 0.44 | 25 | 43 |
| NEBL/BTC | -0.03 | 0.63 | 1.29 | 0.58 | 0.44 | 19 | 59 |
| **pair** | **stoploss** | **win rate** | **risk reward ratio** | **required risk reward** | **expectancy** | **total number of trades** | **average duration (min)** |
|:----------|-----------:|-----------:|--------------------:|-----------------------:|-------------:|-----------------:|---------------:|
| **AGI/BTC** | -0.02 | 0.64 | 5.86 | 0.56 | 3.41 | 14 | 54 |
| **NXS/BTC** | -0.03 | 0.64 | 2.99 | 0.57 | 1.54 | 11 | 26 |
| **LEND/BTC** | -0.02 | 0.82 | 2.05 | 0.22 | 1.50 | 11 | 36 |
| **VIA/BTC** | -0.01 | 0.55 | 3.01 | 0.83 | 1.19 | 11 | 48 |
| **MTH/BTC** | -0.09 | 0.56 | 2.82 | 0.80 | 1.12 | 18 | 52 |
| **ARDR/BTC** | -0.04 | 0.42 | 3.14 | 1.40 | 0.73 | 12 | 42 |
| **BCPT/BTC** | -0.01 | 0.71 | 1.34 | 0.40 | 0.67 | 14 | 30 |
| **WINGS/BTC** | -0.02 | 0.56 | 1.97 | 0.80 | 0.65 | 27 | 42 |
| **VIBE/BTC** | -0.02 | 0.83 | 0.91 | 0.20 | 0.59 | 12 | 35 |
| **MCO/BTC** | -0.02 | 0.79 | 0.97 | 0.27 | 0.55 | 14 | 31 |
| **GNT/BTC** | -0.02 | 0.50 | 2.06 | 1.00 | 0.53 | 18 | 24 |
| **HOT/BTC** | -0.01 | 0.17 | 7.72 | 4.81 | 0.50 | 209 | 7 |
| **SNM/BTC** | -0.03 | 0.71 | 1.06 | 0.42 | 0.45 | 17 | 38 |
| **APPC/BTC** | -0.02 | 0.44 | 2.28 | 1.27 | 0.44 | 25 | 43 |
| **NEBL/BTC** | -0.03 | 0.63 | 1.29 | 0.58 | 0.44 | 19 | 59 |
Edge produced the above table by comparing `calculate_since_number_of_days` to `minimum_expectancy` to find `min_trade_number` historical information based on the config file. The timerange Edge uses for its comparisons can be further limited by using the `--timerange` switch.
In live and dry-run modes, after the `process_throttle_secs` has passed, Edge will again process `calculate_since_number_of_days` against `minimum_expectancy` to find `min_trade_number`. If no `min_trade_number` is found, the bot will return "whitelist empty". Depending on the trade strategy being deployed, "whitelist empty" may be return much of the time - or *all* of the time. The use of Edge may also cause trading to occur in bursts, though this is rare.
If you encounter "whitelist empty" a lot, condsider tuning `calculate_since_number_of_days`, `minimum_expectancy` and `min_trade_number` to align to the trading frequency of your strategy.
### Update cached pairs with the latest data
@@ -211,3 +286,6 @@ The full timerange specification:
* Use tickframes since 2018/01/31: `--timerange=20180131-`
* Use tickframes since 2018/01/31 till 2018/03/01 : `--timerange=20180131-20180301`
* Use tickframes between POSIX timestamps 1527595200 1527618600: `--timerange=1527595200-1527618600`
[^1]: Question extracted from MIT Opencourseware S096 - Mathematics with applications in Finance: https://ocw.mit.edu/courses/mathematics/18-s096-topics-in-mathematics-with-applications-in-finance-fall-2013/

View File

@@ -23,7 +23,8 @@ Binance has been split into 3, and users must use the correct ccxt exchange ID f
## 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.
Kraken supports `stoploss_on_exchange` and can use both stop-loss-market and stop-loss-limit orders. It provides great advantages, so we recommend to benefit from it.
You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide which type to use.
### Historic Kraken data
@@ -75,8 +76,7 @@ print(res)
!!! Tip "Stoploss on Exchange"
FTX supports `stoploss_on_exchange` and can use both stop-loss-market and stop-loss-limit orders. It provides great advantages, so we recommend to benefit from it.
You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide.
You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide which type of stoploss shall be used.
### Using subaccounts
@@ -99,10 +99,10 @@ To use subaccounts with FTX, you need to edit the configuration and add the foll
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
```

View File

@@ -1,5 +1,9 @@
# Freqtrade FAQ
## Beginner Tips & Tricks
* When you work with your strategy & hyperopt file you should use a proper code editor like vscode or Pycharm. A good code editor will provide syntax highlighting as well as line numbers, making it easy to find syntax errors (most likely, pointed out by Freqtrade during startup).
## Freqtrade common issues
### The bot does not start
@@ -15,10 +19,12 @@ This could have the following reasons:
### I have waited 5 minutes, why hasn't the bot made any trades yet?!
Depending on the buy strategy, the amount of whitelisted coins, the
* Depending on the buy strategy, the amount of whitelisted coins, the
situation of the market etc, it can take up to hours to find good entry
position for a trade. Be patient!
* Or it may because of a configuration error? Best check the logs, it's usually telling you if the bot is simply not getting buy signals (only heartbeat messages), or if there is something wrong (errors / exceptions in the log).
### I have made 12 trades already, why is my total profit negative?!
I understand your disappointment but unfortunately 12 trades is just
@@ -83,7 +89,7 @@ Same fix should be done in the configuration file, if order types are defined in
### 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.
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 sub-commands, 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
@@ -108,7 +114,7 @@ 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:
or even on the fly, as the bot works and the log file grows:
```shell
$ tail -f /path/to/mylogfile.log | grep 'something'
```
@@ -129,25 +135,21 @@ to find a great result (unless if you are very lucky), so you probably
have to run it for 10.000 or more. But it will take an eternity to
compute.
We recommend you to run it at least 10.000 epochs:
Since hyperopt uses Bayesian search, running for too many epochs may not produce greater results.
It's therefore recommended to run between 500-1000 epochs over and over until you hit at least 10.000 epochs in total (or are satisfied with the result). You can best judge by looking at the results - if the bot keeps discovering better strategies, it's best to keep on going.
```bash
freqtrade hyperopt -e 10000
freqtrade hyperopt --hyperop SampleHyperopt --hyperopt-loss SharpeHyperOptLossDaily --strategy SampleStrategy -e 1000
```
or if you want intermediate result to see
### Why does it take a long time to run hyperopt?
```bash
for i in {1..100}; do freqtrade hyperopt -e 100; done
```
* Discovering a great strategy with Hyperopt takes time. Study www.freqtrade.io, the Freqtrade Documentation page, join the Freqtrade [Slack community](https://join.slack.com/t/highfrequencybot/shared_invite/zt-jaut7r4m-Y17k4x5mcQES9a9swKuxbg) - or the Freqtrade [discord community](https://discord.gg/X89cVG). While you patiently wait for the most advanced, free crypto bot in the world, to hand you a possible golden strategy specially designed just for you.
### Why it is so long to run hyperopt?
* If you wonder why it can take from 20 minutes to days to do 1000 epochs here are some answers:
Finding a great Hyperopt results takes time.
If you wonder why it takes a while to find great hyperopt results
This answer was written during the under the release 0.15.1, when we had:
This answer was written during the release 0.15.1, when we had:
- 8 triggers
- 9 guards: let's say we evaluate even 10 values from each
@@ -157,7 +159,14 @@ The following calculation is still very rough and not very precise
but it will give the idea. With only these triggers and guards there is
already 8\*10^9\*10 evaluations. A roughly total of 80 billion evals.
Did you run 100 000 evals? Congrats, you've done roughly 1 / 100 000 th
of the search space.
of the search space, assuming that the bot never tests the same parameters more than once.
* The time it takes to run 1000 hyperopt epochs depends on things like: The available cpu, hard-disk, ram, timeframe, timerange, indicator settings, indicator count, amount of coins that hyperopt test strategies on and the resulting trade count - which can be 650 trades in a year or 10.0000 trades depending if the strategy aims for big profits by trading rarely or for many low profit trades.
Example: 4% profit 650 times vs 0,3% profit a trade 10.000 times in a year. If we assume you set the --timerange to 365 days.
Example:
`freqtrade --config config.json --strategy SampleStrategy --hyperopt SampleHyperopt -e 1000 --timerange 20190601-20200601`
## Edge module
@@ -165,7 +174,7 @@ of the search space.
The Edge module is mostly a result of brainstorming of [@mishaker](https://github.com/mishaker) and [@creslinux](https://github.com/creslinux) freqtrade team members.
You can find further info on expectancy, winrate, risk management and position size in the following sources:
You can find further info on expectancy, win rate, risk management and position size in the following sources:
- https://www.tradeciety.com/ultimate-math-guide-for-traders/
- http://www.vantharp.com/tharp-concepts/expectancy.asp

View File

@@ -37,12 +37,20 @@ pip install -r requirements-hyperopt.txt
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/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.
Configuring hyperopt is similar to writing your own strategy, and many tasks will be similar.
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`.
!!! Tip "About this page"
For this page, we will be using a fictional strategy called `AwesomeStrategy` - which will be optimized using the `AwesomeHyperopt` class.
### Checklist on all tasks / possibilities in hyperopt
The simplest way to get started is to use the following, command, which will create a new hyperopt file from a template, which will be located under `user_data/hyperopts/AwesomeHyperopt.py`.
``` bash
freqtrade new-hyperopt --hyperopt AwesomeHyperopt
```
### Hyperopt checklist
Checklist on all tasks / possibilities in hyperopt
Depending on the space you want to optimize, only some of the below are required:
@@ -54,17 +62,15 @@ Depending on the space you want to optimize, only some of the below are required
!!! 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:
Optional in hyperopt - can also be loaded from a strategy (recommended):
* 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.
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.
Rarely you may also need to override:
@@ -80,17 +86,20 @@ Rarely you may also need to override:
# 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
freqtrade hyperopt --hyperopt EmptyHyperopt --hyperopt-loss SharpeHyperOptLossDaily --spaces roi stoploss trailing --strategy MyWorkingStrategy --config config.json -e 100
```
### 1. Install a Custom Hyperopt File
### Create a Custom Hyperopt File
Put your hyperopt file into the directory `user_data/hyperopts`.
Let assume you want a hyperopt file `AwesomeHyperopt.py`:
Let assume you want a hyperopt file `awesome_hyperopt.py`:
Copy the file `user_data/hyperopts/sample_hyperopt.py` into `user_data/hyperopts/awesome_hyperopt.py`
``` bash
freqtrade new-hyperopt --hyperopt AwesomeHyperopt
```
### 2. Configure your Guards and Triggers
This command will create a new hyperopt file from a template, allowing you to get started quickly.
### Configure your Guards and Triggers
There are two places you need to change in your hyperopt file to add a new buy hyperopt for testing:
@@ -102,14 +111,16 @@ 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".
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
!!! Hint "Guards and Triggers"
Technically, there is no difference between Guards and Triggers.
However, this guide will make this distinction to make it clear that signals should not be "sticking".
Sticking signals are signals that are active for multiple candles. This can lead into buying a signal late (right before the signal disappears - which means that the chance of success is a lot lower than right at the beginning).
Hyper-optimization will, for each epoch 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
ADX > 10*".
If you have updated the buy strategy, i.e. changed the contents of
`populate_buy_trend()` method, you have to update the `guards` and
`triggers` your hyperopt must use correspondingly.
If you have updated the buy strategy, i.e. changed the contents of `populate_buy_trend()` method, you have to update the `guards` and `triggers` your hyperopt must use correspondingly.
#### Sell optimization
@@ -126,7 +137,7 @@ To avoid naming collisions in the search-space, please prefix all sell-spaces wi
The Strategy class exposes the timeframe value as the `self.timeframe` attribute.
The same value is available as class-attribute `HyperoptName.timeframe`.
In the case of the linked sample-value this would be `SampleHyperOpt.timeframe`.
In the case of the linked sample-value this would be `AwesomeHyperopt.timeframe`.
## Solving a Mystery
@@ -192,27 +203,25 @@ So let's write the buy strategy using these values:
return populate_buy_trend
```
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 parameter combination produced the best profits.
Hyperopt will now call `populate_buy_trend()` many times (`epochs`) with different value combinations.
It will use the given historical data and make buys based on the buy signals generated with the above function.
Based on the results, hyperopt will tell you which parameter combination produced the best results (based on the configured [loss function](#loss-functions)).
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 your custom hyperopt file.
!!! Note
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 your strategy or 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.
A different loss function can be specified by using the `--hyperopt-loss <Class-name>` argument.
A loss function must be specified via the `--hyperopt-loss <Class-name>` argument (or optionally via the configuration under the `"hyperopt_loss"` key).
This class should be in its own file within the `user_data/hyperopts/` directory.
Currently, the following loss functions are builtin:
* `DefaultHyperOptLoss` (default legacy Freqtrade hyperoptimization loss function)
* `ShortTradeDurHyperOptLoss` (default legacy Freqtrade hyperoptimization loss function) - Mostly for short trade duration and avoiding losses.
* `OnlyProfitHyperOptLoss` (which takes only amount of profit into consideration)
* `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)
@@ -229,21 +238,20 @@ 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 hyperopt --config config.json --hyperopt <hyperoptname> -e 5000 --spaces all
freqtrade hyperopt --config config.json --hyperopt <hyperoptname> --hyperopt-loss <hyperoptlossname> --strategy <strategyname> -e 500 --spaces all
```
Use `<hyperoptname>` as the name of the custom hyperopt used.
The `-e` option will set how many evaluations hyperopt will do. We recommend
running at least several thousand evaluations.
The `-e` option will set how many evaluations hyperopt will do. Since hyperopt uses Bayesian search, running too many epochs at once may not produce greater results. Experience has shown that best results are usually not improving much after 500-1000 epochs.
Doing multiple runs (executions) with a few 1000 epochs and different random state will most likely produce different results.
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`.
!!! Warning
When switching parameters or changing configuration options, make sure to not use the argument `--continue` so temporary results can be removed.
Hyperopt will store hyperopt results with the timestamp of the hyperopt start time.
Reading commands (`hyperopt-list`, `hyperopt-show`) can use `--hyperopt-filename <filename>` to read and display older hyperopt results.
You can find a list of filenames with `ls -l user_data/hyperopt_results/`.
### Execute Hyperopt with different historical data source
@@ -251,13 +259,13 @@ If you would like to hyperopt parameters using an alternate historical data set
you have on-disk, use the `--datadir PATH` option. By default, hyperopt
uses data from directory `user_data/data`.
### Running Hyperopt with Smaller Testset
### Running Hyperopt with a smaller test-set
Use the `--timerange` argument to change how much of the testset you want to use.
Use the `--timerange` argument to change how much of the test-set you want to use.
For example, to use one month of data, pass the following parameter to the hyperopt call:
```bash
freqtrade hyperopt --timerange 20180401-20180501
freqtrade hyperopt --hyperopt <hyperoptname> --strategy <strategyname> --timerange 20180401-20180501
```
### Running Hyperopt using methods from a strategy
@@ -265,16 +273,15 @@ freqtrade hyperopt --timerange 20180401-20180501
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 --hyperopt SampleHyperopt
freqtrade hyperopt --hyperopt AwesomeHyperopt --hyperopt-loss SharpeHyperOptLossDaily --strategy AwesomeStrategy
```
### Running Hyperopt with Smaller Search Space
Use the `--spaces` option to limit the search space used by hyperopt.
Letting Hyperopt optimize everything is a huuuuge search space. Often it
might make more sense to start by just searching for initial buy algorithm.
Or maybe you just want to optimize your stoploss or roi table for that awesome
new buy strategy you have.
Letting Hyperopt optimize everything is a huuuuge search space.
Often it might make more sense to start by just searching for initial buy algorithm.
Or maybe you just want to optimize your stoploss or roi table for that awesome new buy strategy you have.
Legal values are:
@@ -318,7 +325,7 @@ The initial state for generation of these random values (random state) is contro
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.
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 hyper-optimization results with same random state value used.
## Understand the Hyperopt Result
@@ -370,6 +377,9 @@ By default, hyperopt prints colorized results -- epochs with positive profit are
You can use the `--print-all` command line option if you would like to see all results in the hyperopt output, not only the best ones. When `--print-all` is used, current best results are also colorized by default -- they are printed in bold (bright) style. This can also be switched off with the `--no-color` command line option.
!!! Note "Windows and color output"
Windows does not support color-output natively, therefore it is automatically disabled. To have color-output for hyperopt running under windows, please consider using WSL.
### Understand Hyperopt ROI results
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:
@@ -416,7 +426,9 @@ These ranges should be sufficient in most cases. The minutes in the steps (ROI d
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/freqtrade/templates/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 [sample_hyperopt_advanced.py](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_advanced.py).
### Understand Hyperopt Stoploss results
@@ -438,7 +450,7 @@ Stoploss: -0.27996
In order to use this best stoploss value found by Hyperopt in backtesting and for live trades/dry-run, copy-paste it as the value of the `stoploss` attribute of your custom strategy:
```
``` python
# Optimal stoploss designed for the strategy
# This attribute will be overridden if the config file contains "stoploss"
stoploss = -0.27996
@@ -472,7 +484,7 @@ Trailing stop:
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:
```
``` python
# Trailing stop
# These attributes will be overridden if the config file contains corresponding values.
trailing_stop = True
@@ -491,15 +503,14 @@ Override the `trailing_space()` method and define the desired range in it if you
## 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.
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` sub-commands. The usage of these sub-commands 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.
To achieve same results (number of trades, their durations, profit, etc.) than during Hyperopt, please use same set of arguments `--dmmp`/`--disable-max-market-positions` and `--eps`/`--enable-position-stacking` for Backtesting.
To achieve same results (number of trades, their durations, profit, etc.) than during Hyperopt, please use same configuration and parameters (timerange, timeframe, ...) used for hyperopt `--dmmp`/`--disable-max-market-positions` and `--eps`/`--enable-position-stacking` for Backtesting.
## Next Step
Now you have a perfect bot and want to control it from Telegram. Your
next step is to learn the [Telegram usage](telegram-usage.md).
Should results don't match, please double-check to make sure you transferred all conditions correctly.
Pay special care to the stoploss (and trailing stoploss) parameters, as these are often set in configuration files, which override changes to the strategy.
You should also carefully review the log of your backtest to ensure that there were no parameters inadvertently set by the configuration (like `stoploss` or `trailing_stop`).

170
docs/includes/pairlists.md Normal file
View File

@@ -0,0 +1,170 @@
## 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).
Additionally, [`AgeFilter`](#agefilter), [`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)
* [`AgeFilter`](#agefilter)
* [`PrecisionFilter`](#precisionfilter)
* [`PriceFilter`](#pricefilter)
* [`ShuffleFilter`](#shufflefilter)
* [`SpreadFilter`](#spreadfilter)
* [`RangeStabilityFilter`](#rangestabilityfilter)
!!! Tip "Testing pairlists"
Pairlist configurations can be quite tricky to get right. Best use the [`test-pairlist`](utils.md#test-pairlist) utility sub-command 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"}
],
```
By default, only currently enabled pairs are allowed.
To skip pair validation against active markets, set `"allow_inactive": true` within the `StaticPairList` configuration.
This can be useful for backtesting expired pairs (like quarterly spot-markets).
This option must be configured along with `exchange.skip_pair_validation` in the exchange configuration.
#### Volume Pair List
`VolumePairList` employs sorting/filtering of pairs by their trading volume. It 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
}],
```
#### AgeFilter
Removes pairs that have been listed on the exchange for less than `min_days_listed` days (defaults to `10`).
When pairs are first listed on an exchange they can suffer huge price drops and volatility
in the first few days while the pair goes through its price-discovery period. Bots can often
be caught out buying before the pair has finished dropping in price.
This filter allows freqtrade to ignore pairs until they have been listed for at least `min_days_listed` days.
#### PrecisionFilter
Filters low-value coins which would not allow setting stoplosses.
#### PriceFilter
The `PriceFilter` allows filtering of pairs by price. Currently the following price filters are supported:
* `min_price`
* `max_price`
* `low_price_ratio`
The `min_price` setting removes pairs where the price is below the specified price. This is useful if you wish to avoid trading very low-priced pairs.
This option is disabled by default, and will only apply if set to > 0.
The `max_price` setting removes pairs where the price is above the specified price. This is useful if you wish to trade only low-priced pairs.
This option is disabled by default, and will only apply if set to > 0.
The `low_price_ratio` setting removes pairs where a raise of 1 price unit (pip) is above the `low_price_ratio` ratio.
This option is disabled by default, and will only apply if set to > 0.
For `PriceFiler` at least one of its `min_price`, `max_price` or `low_price_ratio` settings must be applied.
Calculation example:
Min price precision for SHITCOIN/BTC is 8 decimals. If its price is 0.00000011 - one price step above would be 0.00000012, which is ~9% higher than the previous price value. You may filter out this pair by using PriceFilter with `low_price_ratio` set to 0.09 (9%) or with `min_price` set to 0.00000011, correspondingly.
!!! Warning "Low priced pairs"
Low priced pairs with high "1 pip movements" are dangerous since they are often illiquid and it may also be impossible to place the desired stoploss, which can often result in high losses since price needs to be rounded to the next tradable price - so instead of having a stoploss of -5%, you could end up with a stoploss of -9% simply due to price rounding.
#### 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.
#### RangeStabilityFilter
Removes pairs where the difference between lowest low and highest high over `lookback_days` days is below `min_rate_of_change`. Since this is a filter that requires additional data, the results are cached for `refresh_period`.
In the below example:
If the trading range over the last 10 days is <1%, remove the pair from the whitelist.
```json
"pairlists": [
{
"method": "RangeStabilityFilter",
"lookback_days": 10,
"min_rate_of_change": 0.01,
"refresh_period": 1440
}
]
```
!!! Tip
This Filter can be used to automatically remove stable coin pairs, which have a very low trading range, and are therefore extremely difficult to trade with profit.
### 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 price unit 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": "AgeFilter", "min_days_listed": 10},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01},
{"method": "SpreadFilter", "max_spread_ratio": 0.005},
{
"method": "RangeStabilityFilter",
"lookback_days": 10,
"min_rate_of_change": 0.01,
"refresh_period": 1440
},
{"method": "ShuffleFilter", "seed": 42}
],
```

View File

@@ -8,7 +8,7 @@
<!-- Place this tag where you want the button to render. -->
<a class="github-button" href="https://github.com/freqtrade/freqtrade/fork" data-icon="octicon-repo-forked" data-size="large" aria-label="Fork freqtrade/freqtrade on GitHub">Fork</a>
<!-- Place this tag where you want the button to render. -->
<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>
<a class="github-button" href="https://github.com/freqtrade/freqtrade/archive/stable.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>
@@ -37,13 +37,9 @@ Freqtrade is a crypto-currency algorithmic trading software developed in python
## Requirements
### Up to date clock
The clock on the system running the bot must be accurate, synchronized to a NTP server frequently enough to avoid problems with communication to the exchanges.
### Hardware requirements
To run this bot we recommend you a cloud instance with a minimum of:
To run this bot we recommend you a linux cloud instance with a minimum of:
- 2GB RAM
- 1GB disk space
@@ -63,11 +59,14 @@ Alternatively
## Support
### 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.
### Help / Discord / Slack
Click [here](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) to join the Freqtrade Slack channel.
For any questions not covered by the documentation or for further information about the bot, or to simply engage with like-minded individuals, we encourage you to join our slack channel.
Please check out our [discord server](https://discord.gg/MA9v74M).
You can also join our [Slack channel](https://join.slack.com/t/highfrequencybot/shared_invite/zt-jaut7r4m-Y17k4x5mcQES9a9swKuxbg).
## Ready to try?
Begin by reading our installation guide [for docker](docker.md), or for [installation without docker](installation.md).
Begin by reading our installation guide [for docker](docker_quickstart.md) (recommended), or for [installation without docker](installation.md).

View File

@@ -18,6 +18,9 @@ Click each one for install guide:
We also recommend a [Telegram bot](telegram-usage.md#setup-your-telegram-bot), which is optional but recommended.
!!! Warning "Up-to-date clock"
The clock on the system running the bot must be accurate, synchronized to a NTP server frequently enough to avoid problems with communication to the exchanges.
## Quick start
Freqtrade provides the Linux/MacOS Easy Installation script to install all dependencies and help you configure the bot.
@@ -28,7 +31,7 @@ Freqtrade provides the Linux/MacOS Easy Installation script to install all depen
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.
!!! 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).
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 `stable` 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.
@@ -38,11 +41,11 @@ 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)
# git checkout stable # 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.
(1) This command switches the cloned repository to the use of the `stable` 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 stable`/`git checkout develop` commands.
## Easy Installation Script (Linux/MacOS)
@@ -53,7 +56,7 @@ $ ./setup.sh
usage:
-i,--install Install freqtrade from scratch
-u,--update Command git pull to update.
-r,--reset Hard reset your develop/master branch.
-r,--reset Hard reset your develop/stable branch.
-c,--config Easy config generator (Will override your existing file).
```
@@ -73,12 +76,16 @@ This option will pull the last version of your current branch and update your vi
** --reset **
This option will hard reset your branch (only if you are on either `master` or `develop`) and recreate your virtualenv.
This option will hard reset your branch (only if you are on either `stable` or `develop`) and recreate your virtualenv.
** --config **
DEPRECATED - use `freqtrade new-config -c config.json` instead.
### Activate your virtual environment
Each time you open a new terminal, you must run `source .env/bin/activate`.
------
## Custom Installation
@@ -89,36 +96,34 @@ OS Specific steps are listed first, the [Common](#common) section below is neces
!!! Note
Python3.6 or higher and the corresponding pip are assumed to be available.
### Linux - Ubuntu 16.04
=== "Ubuntu 16.04"
#### Install necessary dependencies
#### Install necessary dependencies
```bash
sudo apt-get update
sudo apt-get install build-essential git
```
```bash
sudo apt-get update
sudo apt-get install build-essential git
```
=== "RaspberryPi/Raspbian"
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.
### Raspberry Pi / Raspbian
Tested using a Raspberry Pi 3 with the Raspbian Buster lite image, all updates applied.
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.
``` bash
sudo apt-get install python3-venv libatlas-base-dev
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
Tested using a Raspberry Pi 3 with the Raspbian Buster lite image, all updates applied.
bash setup.sh -i
```
``` bash
sudo apt-get install python3-venv libatlas-base-dev
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
!!! Note "Installation duration"
Depending on your internet speed and the Raspberry Pi version, installation can take multiple hours to complete.
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
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.
!!! Note
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
@@ -169,12 +174,7 @@ 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:
```bash
git checkout master
git checkout stable
```
#### 4. Install python dependencies
@@ -212,72 +212,18 @@ On Linux, as an optional post-installation task, you may wish to setup the bot t
------
## Using Conda
### Anaconda
Freqtrade can also be installed using Anaconda (or Miniconda).
!!! Note
This requires the [ta-lib](#1-install-ta-lib) C-library to be installed first. See below.
``` bash
conda env create -f environment.yml
```
!!! Note
This requires the [ta-lib](#1-install-ta-lib) C-library to be installed first.
## Windows
We recommend that Windows users use [Docker](docker.md) as this will work much easier and smoother (also more secure).
If that is not possible, try using the Windows Linux subsystem (WSL) - for which the Ubuntu instructions should work.
If that is not available on your system, feel free to try the instructions below, which led to success for some.
### 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
git clone https://github.com/freqtrade/freqtrade.git
```
#### Install ta-lib
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.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.18cp38cp38win_amd64.whl
>pip install -r requirements.txt
>pip install -e .
>freqtrade
```
> Thanks [Owdr](https://github.com/Owdr) for the commands. Source: [Issue #222](https://github.com/freqtrade/freqtrade/issues/222)
#### Error during installation under Windows
``` bash
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
```
Unfortunately, many packages requiring compilation don't provide a pre-build wheel. It is therefore mandatory to have a C/C++ compiler installed and available for your python environment to use.
The easiest way is to download install Microsoft Visual Studio Community [here](https://visualstudio.microsoft.com/downloads/) and make sure to install "Common Tools for Visual C++" to enable building c code on Windows. Unfortunately, this is a heavy download / dependency (~4Gb) so you might want to consider WSL or [docker](docker.md) first.
---
Now you have an environment ready, the next step is
[Bot Configuration](configuration.md).
-----
## Troubleshooting
### MacOS installation error
@@ -291,4 +237,9 @@ For MacOS 10.14, this can be accomplished with the below command.
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.
If this file is inexistent, then you're probably on a different version of MacOS, so you may need to consult the internet for specific resolution details.
-----
Now you have an environment ready, the next step is
[Bot Configuration](configuration.md).

View File

@@ -0,0 +1,12 @@
window.MathJax = {
tex: {
inlineMath: [["\\(", "\\)"]],
displayMath: [["\\[", "\\]"]],
processEscapes: true,
processEnvironments: true
},
options: {
ignoreHtmlClass: ".*|",
processHtmlClass: "arithmatex"
}
};

View File

@@ -224,7 +224,8 @@ Possible options for the `freqtrade plot-profit` subcommand:
```
usage: freqtrade plot-profit [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-p PAIRS [PAIRS ...]]
[-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-p PAIRS [PAIRS ...]]
[--timerange TIMERANGE] [--export EXPORT]
[--export-filename PATH] [--db-url PATH]
[--trade-source {DB,file}] [-i TIMEFRAME]
@@ -270,6 +271,11 @@ Common arguments:
--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.
```
The `-p/--pairs` argument, can be used to limit the pairs that are considered for this calculation.
@@ -279,7 +285,7 @@ Examples:
Use custom backtest-export file
``` bash
freqtrade plot-profit -p LTC/BTC --export-filename user_data/backtest_results/backtest-result-Strategy005.json
freqtrade plot-profit -p LTC/BTC --export-filename user_data/backtest_results/backtest-result.json
```
Use custom database

View File

@@ -1,2 +1,3 @@
mkdocs-material==5.3.3
mkdocs-material==6.1.6
mdx_truly_sane_lists==1.2
pymdown-extensions==8.0.1

View File

@@ -46,7 +46,7 @@ secrets.token_hex()
### 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.
If you run your bot using docker, you'll need to have the bot listen to incoming connections. The security is then handled by docker.
``` json
"api_server": {
@@ -104,28 +104,42 @@ By default, the script assumes `127.0.0.1` (localhost) and port `8080` to be use
python3 scripts/rest_client.py --config rest_config.json <command> [optional parameters]
```
## Available commands
## Available endpoints
| Command | Default | Description |
|----------|---------|-------------|
| `start` | | Starts the trader
| `stop` | | Stops the trader
| `stopbuy` | | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `reload_config` | | 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
| `forcesell <trade_id>` | | Instantly sells the given trade (Ignoring `minimum_roi`).
| `forcesell all` | | Instantly sells all open trades (Ignoring `minimum_roi`).
| `forcebuy <pair> [rate]` | | Instantly buys the given pair. Rate is optional. (`forcebuy_enable` must be set to True)
| `performance` | | Show performance of each finished trade grouped by pair
| `balance` | | Show account balance per currency
| `daily <n>` | 7 | Shows profit or loss per day, over the last n days
| `whitelist` | | Show the current whitelist
| `blacklist [pair]` | | Show the current blacklist, or adds a pair to the blacklist.
| `edge` | | Show validated pairs by Edge if it is enabled.
| `version` | | Show version
| Command | Description |
|----------|-------------|
| `ping` | Simple command testing the API Readiness - requires no authentication.
| `start` | Starts the trader.
| `stop` | Stops the trader.
| `stopbuy` | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `reload_config` | Reloads the configuration file.
| `trades` | List last trades.
| `delete_trade <trade_id>` | Remove trade from the database. Tries to close open orders. Requires manual handling of this trade on the exchange.
| `show_config` | Shows part of the current configuration with relevant settings to operation.
| `logs` | Shows last log messages.
| `status` | Lists all open trades.
| `count` | Displays number of trades used and available.
| `locks` | Displays currently locked pairs.
| `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`).
| `forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`).
| `forcebuy <pair> [rate]` | Instantly buys the given pair. Rate is optional. (`forcebuy_enable` must be set to True)
| `performance` | Show performance of each finished trade grouped by pair.
| `balance` | Show account balance per currency.
| `daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7).
| `whitelist` | Show the current whitelist.
| `blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist.
| `edge` | Show validated pairs by Edge if it is enabled.
| `pair_candles` | Returns dataframe for a pair / timeframe combination while the bot is running. **Alpha**
| `pair_history` | Returns an analyzed dataframe for a given timerange, analyzed by a given strategy. **Alpha**
| `plot_config` | Get plot config from the strategy (or nothing if not configured). **Alpha**
| `strategies` | List strategies in strategy directory. **Alpha**
| `strategy <strategy>` | Get specific Strategy content. **Alpha**
| `available_pairs` | List available backtest data. **Alpha**
| `version` | Show version.
!!! Warning "Alpha status"
Endpoints labeled with *Alpha status* above may change at any time without notice.
Possible commands can be listed from the rest-client script using the `help` command.
@@ -135,78 +149,114 @@ python3 scripts/rest_client.py help
``` output
Possible commands:
available_pairs
Return available pair (backtest data) based on timeframe / stake_currency selection
:param timeframe: Only pairs with this timeframe available.
:param stake_currency: Only pairs that include this timeframe
balance
Get the account balance
:returns: json object
Get the account balance.
blacklist
Show the current blacklist
Show the current blacklist.
:param add: List of coins to add (example: "BNB/BTC")
:returns: json object
count
Returns the amount of open trades
:returns: json object
Return the amount of open trades.
daily
Returns the amount of open trades
:returns: json object
Return the amount of open trades.
delete_trade
Delete trade from the database.
Tries to close open orders. Requires manual handling of this asset on the exchange.
:param trade_id: Deletes the trade with this ID from the database.
edge
Returns information about edge
:returns: json object
Return information about edge.
forcebuy
Buy an asset
Buy an asset.
:param pair: Pair to buy (ETH/BTC)
:param price: Optional - price to buy
:returns: json object of the trade
forcesell
Force-sell a trade
Force-sell a trade.
:param tradeid: Id of the trade (can be received via status command)
:returns: json object
logs
Show latest logs.
:param limit: Limits log messages to the last <limit> logs. No limit to get all the trades.
pair_candles
Return live dataframe for <pair><timeframe>.
:param pair: Pair to get data for
:param timeframe: Only pairs with this timeframe available.
:param limit: Limit result to the last n candles.
pair_history
Return historic, analyzed dataframe
:param pair: Pair to get data for
:param timeframe: Only pairs with this timeframe available.
:param strategy: Strategy to analyze and get values for
:param timerange: Timerange to get data for (same format than --timerange endpoints)
performance
Returns the performance of the different coins
:returns: json object
Return the performance of the different coins.
plot_config
Return plot configuration if the strategy defines one.
profit
Returns the profit summary
:returns: json object
Return the profit summary.
reload_config
Reload configuration
:returns: json object
Reload configuration.
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
Start the bot if it's in the stopped state.
status
Get the status of open trades
:returns: json object
Get the status of open trades.
stop
Stop the bot. Use start to restart
:returns: json object
Stop the bot. Use `start` to restart.
stopbuy
Stop buying (but handle sells gracefully).
use reload_config to reset
:returns: json object
Stop buying (but handle sells gracefully). Use `reload_config` to reset.
strategies
Lists available strategies
strategy
Get strategy details
:param strategy: Strategy class name
trades
Return trades history.
:param limit: Limits trades to the X last trades. No limit to get all the trades.
version
Returns the version of the bot
:returns: json object containing the version
Return the version of the bot.
whitelist
Show the current whitelist
:returns: json object
Show the current whitelist.
```
## Advanced API usage using JWT tokens

View File

@@ -1,104 +1,59 @@
# Sandbox API testing
Where an exchange provides a sandbox for risk-free integration, or end-to-end, testing CCXT provides access to these.
Some exchanges provide sandboxes or testbeds for risk-free testing, while running the bot against a real exchange.
With some configuration, freqtrade (in combination with ccxt) provides access to these.
This document is a *light overview of configuring Freqtrade and GDAX sandbox.
This can be useful to developers and trader alike as Freqtrade is quite customisable.
This document is an overview to configure Freqtrade to be used with sandboxes.
This can be useful to developers and trader alike.
When testing your API connectivity, make sure to use the following URLs.
***Website**
https://public.sandbox.gdax.com
***REST API**
https://api-public.sandbox.gdax.com
## Exchanges known to have a sandbox / testnet
* [binance](https://testnet.binance.vision/)
* [coinbasepro](https://public.sandbox.pro.coinbase.com)
* [gemini](https://exchange.sandbox.gemini.com/)
* [huobipro](https://www.testnet.huobi.pro/)
* [kucoin](https://sandbox.kucoin.com/)
* [phemex](https://testnet.phemex.com/)
!!! Note
We did not test correct functioning of all of the above testnets. Please report your experiences with each sandbox.
---
# Configure a Sandbox account on Gdax
## Configure a Sandbox account
Aim of this document section
When testing your API connectivity, make sure to use the appropriate sandbox / testnet URL.
- An sanbox account
- create 2FA (needed to create an API)
- Add test 50BTC to account
- Create :
- - API-KEY
- - API-Secret
- - API Password
In general, you should follow these steps to enable an exchange's sandbox:
## Acccount
* Figure out if an exchange has a sandbox (most likely by using google or the exchange's support documents)
* Create a sandbox account (often the sandbox-account requires separate registration)
* [Add some test assets to account](#add-test-funds)
* Create API keys
This link will redirect to the sandbox main page to login / create account dialogues:
https://public.sandbox.pro.coinbase.com/orders/
### Add test funds
After registration and Email confimation you wil be redirected into your sanbox account. It is easy to verify you're in sandbox by checking the URL bar.
> https://public.sandbox.pro.coinbase.com/
Usually, sandbox exchanges allow depositing funds directly via web-interface.
You should make sure to have a realistic amount of funds available to your test-account, so results are representable of your real account funds.
## Enable 2Fa (a prerequisite to creating sandbox API Keys)
!!! Warning
Test exchanges will **NEVER** require your real credit card or banking details!
From within sand box site select your profile, top right.
>Or as a direct link: https://public.sandbox.pro.coinbase.com/profile
## Configure freqtrade to use a exchange's sandbox
From the menu panel to the left of the screen select
> Security: "*View or Update*"
In the new site select "enable authenticator" as typical google Authenticator.
- open Google Authenticator on your phone
- scan barcode
- enter your generated 2fa
## Enable API Access
From within sandbox select profile>api>create api-keys
>or as a direct link: https://public.sandbox.pro.coinbase.com/profile/api
Click on "create one" and ensure **view** and **trade** are "checked" and sumbit your 2FA
- **Copy and paste the Passphase** into a notepade this will be needed later
- **Copy and paste the API Secret** popup into a notepad this will needed later
- **Copy and paste the API Key** into a notepad this will needed later
## Add 50 BTC test funds
To add funds, use the web interface deposit and withdraw buttons.
To begin select 'Wallets' from the top menu.
> Or as a direct link: https://public.sandbox.pro.coinbase.com/wallets
- Deposits (bottom left of screen)
- - Deposit Funds Bitcoin
- - - Coinbase BTC Wallet
- - - - Max (50 BTC)
- - - - - Deposit
*This process may be repeated for other currencies, ETH as example*
---
# Configure Freqtrade to use Gax Sandbox
The aim of this document section
- Enable sandbox URLs in Freqtrade
- Configure API
- - secret
- - key
- - passphrase
## Sandbox URLs
### Sandbox URLs
Freqtrade makes use of CCXT which in turn provides a list of URLs to Freqtrade.
These include `['test']` and `['api']`.
- `[Test]` if available will point to an Exchanges sandbox.
- `[Api]` normally used, and resolves to live API target on the exchange
* `[Test]` if available will point to an Exchanges sandbox.
* `[Api]` normally used, and resolves to live API target on the exchange.
To make use of sandbox / test add "sandbox": true, to your config.json
```json
"exchange": {
"name": "gdax",
"name": "coinbasepro",
"sandbox": true,
"key": "5wowfxemogxeowo;heiohgmd",
"secret": "/ZMH1P62rCVmwefewrgcewX8nh4gob+lywxfwfxwwfxwfNsH1ySgvWCUR/w==",
@@ -106,36 +61,57 @@ To make use of sandbox / test add "sandbox": true, to your config.json
"outdated_offset": 5
"pair_whitelist": [
"BTC/USD"
]
},
"datadir": "user_data/data/coinbasepro_sandbox"
```
Also insert your
Also the following information:
- api-key (noted earlier)
- api-secret (noted earlier)
- password (the passphrase - noted earlier)
* api-key (created for the sandbox webpage)
* api-secret (noted earlier)
* password (the passphrase - noted earlier)
!!! Tip "Different data directory"
We also recommend to set `datadir` to something identifying downloaded data as sandbox data, to avoid having sandbox data mixed with data from the real exchange.
This can be done by adding the `"datadir"` key to the configuration.
Now, whenever you use this configuration, your data directory will be set to this directory.
---
## You should now be ready to test your sandbox
Ensure Freqtrade logs show the sandbox URL, and trades made are shown in sandbox.
** Typically the BTC/USD has the most activity in sandbox to test against.
Ensure Freqtrade logs show the sandbox URL, and trades made are shown in sandbox. Also make sure to select a pair which shows at least some decent value (which very often is BTC/<somestablecoin>).
## GDAX - Old Candles problem
## Common problems with sandbox exchanges
It is my experience that GDAX sandbox candles may be 20+- minutes out of date. This can cause trades to fail as one of Freqtrades safety checks.
Sandbox exchange instances often have very low volume, which can cause some problems which usually are not seen on a real exchange instance.
To disable this check, add / change the `"outdated_offset"` parameter in the exchange section of your configuration to adjust for this delay.
Example based on the above configuration:
### Old Candles problem
```json
"exchange": {
"name": "gdax",
"sandbox": true,
"key": "5wowfxemogxeowo;heiohgmd",
"secret": "/ZMH1P62rCVmwefewrgcewX8nh4gob+lywxfwfxwwfxwfNsH1ySgvWCUR/w==",
"password": "1bkjfkhfhfu6sr",
"outdated_offset": 30
"pair_whitelist": [
"BTC/USD"
```
Since Sandboxes often have low volume, candles can be quite old and show no volume.
To disable the error "Outdated history for pair ...", best increase the parameter `"outdated_offset"` to a number that seems realistic for the sandbox you're using.
### Unfilled orders
Sandboxes often have very low volumes - which means that many trades can go unfilled, or can go unfilled for a very long time.
To mitigate this, you can try to match the first order on the opposite orderbook side using the following configuration:
``` jsonc
"order_types": {
"buy": "limit",
"sell": "limit"
// ...
},
"bid_strategy": {
"price_side": "ask",
// ...
},
"ask_strategy":{
"price_side": "bid",
// ...
},
```
The configuration is similar to the suggested configuration for market orders - however by using limit-orders you can avoid moving the price too much, and you can set the worst price you might get.

View File

@@ -13,6 +13,15 @@ Feel free to use a visual Database editor like SqliteBrowser if you feel more co
sudo apt-get install sqlite3
```
### Using sqlite3 via docker-compose
The freqtrade docker image does contain sqlite3, so you can edit the database without having to install anything on the host system.
``` bash
docker-compose exec freqtrade /bin/bash
sqlite3 <databasefile>.sqlite
```
## Open the DB
```bash
@@ -34,52 +43,6 @@ sqlite3
.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_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,
timeframe 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
```sql
@@ -89,19 +52,19 @@ SELECT * FROM trades;
## Fix trade still open after a manual sell on the exchange
!!! 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.
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.
!!! Note
This should not be necessary after /forcesell, as forcesell orders are closed automatically by the bot on the next iteration.
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,
close_profit_abs = (amount * <close_rate> * (1 - fee_close) - (amount * open_rate * 1 - fee_open)),
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>;
```
@@ -111,24 +74,28 @@ WHERE id=<trade_ID_to_update>;
```sql
UPDATE trades
SET is_open=0,
close_date='2017-12-20 03:08:45.103418',
close_date='2020-06-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))
close_profit_abs = (amount * 0.19638016 * (1 - fee_close) - (amount * (open_rate * (1 - fee_open)))),
sell_reason='force_sell'
WHERE id=31;
```
## Insert manually a new trade
## Remove trade from the database
!!! Tip "Use RPC Methods to delete trades"
Consider using `/delete <tradeid>` via telegram or rest API. That's the recommended way to deleting trades.
If you'd still like to remove a trade from the database directly, you can use the below query.
```sql
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, <open_rate>, <stake_amount>, <amount>, '<datetime>')
DELETE FROM trades WHERE id = <tradeid>;
```
##### Example:
```sql
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')
DELETE FROM trades WHERE id = 31;
```
!!! Warning
This will remove this trade from the database. Please make sure you got the correct id and **NEVER** run this query without the `where` clause.

View File

@@ -6,7 +6,69 @@ For example, value `-0.10` will cause immediate sell if the profit dips below -1
Most of the strategy files already include the optimal `stoploss` value.
!!! 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.
All stoploss properties mentioned in this file can be set in the Strategy, or in the configuration.
<ins>Configuration values will override the strategy values.</ins>
## Stop Loss On-Exchange/Freqtrade
Those stoploss modes can be *on exchange* or *off exchange*.
These modes can be configured with these values:
``` python
'emergencysell': 'market',
'stoploss_on_exchange': False
'stoploss_on_exchange_interval': 60,
'stoploss_on_exchange_limit_ratio': 0.99
```
!!! Note
Stoploss on exchange is only supported for Binance (stop-loss-limit), Kraken (stop-loss-market, stop-loss-limit) and FTX (stop limit and stop-market) as of now.
<ins>Do not set too low/tight stoploss value if using stop loss on exchange!</ins>
If set to low/tight then you have greater risk of missing fill on the order and stoploss will not work.
### stoploss_on_exchange and stoploss_on_exchange_limit_ratio
Enable or Disable stop loss on 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.
If `stoploss_on_exchange` uses limit orders, the exchange needs 2 prices, the stoploss_price and the Limit price.
`stoploss` defines the stop-price where the limit order is placed - and limit should be slightly below this.
If an exchange supports both limit and market stoploss orders, then the value of `stoploss` will be used to determine the stoploss type.
Calculation example: we bought the asset at 100\$.
Stop-price is 95\$, then limit would be `95 * 0.99 = 94.05$` - so the limit order fill can happen between 95$ and 94.05$.
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.
!!! Note
If `stoploss_on_exchange` is enabled and the stoploss is cancelled manually on the exchange, then the bot will create a new stoploss order.
### stoploss_on_exchange_interval
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.
The bot cannot do these 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.
### emergencysell
`emergencysell` is an optional value, which defaults to `market` and is used when creating stop loss on exchange orders fails.
The below is the default which is used if not changed in strategy or configuration file.
Example from strategy file:
``` python
order_types = {
'buy': 'limit',
'sell': 'limit',
'emergencysell': 'market',
'stoploss': 'market',
'stoploss_on_exchange': True,
'stoploss_on_exchange_interval': 60,
'stoploss_on_exchange_limit_ratio': 0.99
}
```
## Stop Loss Types
@@ -17,29 +79,30 @@ At this stage the bot contains the following stoploss support modes:
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
Stoploss on exchange is only supported for Binance (stop-loss-limit), Kraken (stop-loss-market) and FTX (stop limit and stop-market) as of now.
## Static Stop Loss
### Static Stop 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
Example of stop loss:
``` python
stoploss = -0.10
```
For example, simplified math:
* the bot buys an asset at a price of 100$
* the stop loss is defined at -10%
* the stop loss would get triggered once the asset drops below 90$
### Trailing Stop Loss
The initial value for this is `stoploss`, just as you would define your static Stop loss.
To enable trailing stoploss:
``` python
trailing_stop = True
stoploss = -0.10
trailing_stop = True
```
This will now activate an algorithm, which automatically moves the stop loss up every time the price of your asset increases.
@@ -47,35 +110,43 @@ This will now activate an algorithm, which automatically moves the stop loss up
For example, simplified math:
* 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$
* the stop loss is defined at -10%
* the stop loss would get triggered once the asset drops below 90$
* 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$.
* the stop loss will now be -10% of 102$ = 91.8$
* now the asset drops in value to 101\$, the stop loss will still be 91.8$ and would trigger at 91.8$.
In summary: The stoploss will be adjusted to be always be 2% of the highest observed price.
In summary: The stoploss will be adjusted to be always be -10% of the highest observed price.
### Custom positive stoploss
### Trailing stop loss, custom positive loss
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.
It is also possible to have a default stop loss, when you are in the red with your buy (buy - fee), but once you hit positive result the system will utilize a new stop loss, which can have a different value.
For example, your default stop loss is -10%, but once you have more than 0% profit (example 0.1%) a different trailing stoploss will be used.
Both values require `trailing_stop` to be set to true.
!!! Note
If you want the stoploss to only be changed when you break even of making a profit (what most users want) please refer to next section with [offset enabled](#Trailing-stop-loss-only-once-the-trade-has-reached-a-certain-offset).
Both values require `trailing_stop` to be set to true and `trailing_stop_positive` with a value.
``` python
trailing_stop_positive = 0.01
trailing_stop_positive_offset = 0.011
stoploss = -0.10
trailing_stop = True
trailing_stop_positive = 0.02
```
The 0.01 would translate to a 1% stop loss, once you hit 1.1% profit.
For example, simplified math:
* the bot buys an asset at a price of 100$
* the stop loss is defined at -10%
* the stop loss would get triggered once the asset drops below 90$
* assuming the asset now increases to 102$
* the stop loss will now be -2% of 102$ = 99.96$ (99.96$ stop loss will be locked in and will follow asset price increments with -2%)
* now the asset drops in value to 101\$, the stop loss will still be 99.96$ and would trigger at 99.96$
The 0.02 would translate to a -2% stop loss.
Before this, `stoploss` is used for the trailing stoploss.
Read the [next section](#trailing-only-once-offset-is-reached) to keep stoploss at 5% of the entry point.
!!! 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
### Trailing stop loss only once the trade has reached a certain offset
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.
@@ -84,20 +155,31 @@ This option can be used with or without `trailing_stop_positive`, but uses `trai
``` python
trailing_stop_positive_offset = 0.011
trailing_only_offset_is_reached = true
trailing_only_offset_is_reached = True
```
Simplified example:
Configuration (offset is buy-price + 3%):
``` python
stoploss = 0.05
stoploss = -0.10
trailing_stop = True
trailing_stop_positive = 0.02
trailing_stop_positive_offset = 0.03
trailing_only_offset_is_reached = True
```
For example, simplified math:
* 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%
* the stop loss is defined at -10%
* the stop loss would get triggered once the asset drops below 90$
* stoploss will remain at 90$ unless asset increases to or above our configured offset
* assuming the asset now increases to 103$ (where we have the offset configured)
* the stop loss will now be -2% of 103$ = 100.94$
* now the asset drops in value to 101\$, the stop loss will still be 100.94$ and would trigger at 100.94$
!!! 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.
## Changing stoploss on open trades

View File

@@ -1,7 +1,12 @@
# 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.
If you're just getting started, please be familiar with the methods described in the [Strategy Customization](strategy-customization.md) documentation and with the [Freqtrade basics](bot-basics.md) first.
[Freqtrade basics](bot-basics.md) describes in which sequence each method described below is called, which can be helpful to understand which method to use for your custom needs.
!!! Note
All callback methods described below should only be implemented in a strategy if they are actually used.
## Custom order timeout rules
@@ -89,3 +94,129 @@ class Awesomestrategy(IStrategy):
return True
return False
```
## Bot loop start callback
A simple callback which is called once at the start of every bot throttling iteration.
This can be used to perform calculations which are pair independent (apply to all pairs), loading of external data, etc.
``` python
import requests
class Awesomestrategy(IStrategy):
# ... populate_* methods
def bot_loop_start(self, **kwargs) -> None:
"""
Called at the start of the bot iteration (one loop).
Might be used to perform pair-independent tasks
(e.g. gather some remote resource for comparison)
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
"""
if self.config['runmode'].value in ('live', 'dry_run'):
# Assign this to the class by using self.*
# can then be used by populate_* methods
self.remote_data = requests.get('https://some_remote_source.example.com')
```
## Bot order confirmation
### Trade entry (buy order) confirmation
`confirm_trade_entry()` can be used to abort a trade entry at the latest second (maybe because the price is not what we expect).
``` python
class Awesomestrategy(IStrategy):
# ... populate_* methods
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, **kwargs) -> bool:
"""
Called right before placing a buy order.
Timing for this function is critical, so avoid doing heavy computations or
network requests in this method.
For full documentation please go to https://www.freqtrade.io/en/latest/strategy-advanced/
When not implemented by a strategy, returns True (always confirming).
:param pair: Pair that's about to be bought.
:param order_type: Order type (as configured in order_types). usually limit or market.
:param amount: Amount in target (quote) currency that's going to be traded.
:param rate: Rate that's going to be used when using limit orders
:param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled).
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return bool: When True is returned, then the buy-order is placed on the exchange.
False aborts the process
"""
return True
```
### Trade exit (sell order) confirmation
`confirm_trade_exit()` can be used to abort a trade exit (sell) at the latest second (maybe because the price is not what we expect).
``` python
from freqtrade.persistence import Trade
class Awesomestrategy(IStrategy):
# ... populate_* methods
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str, **kwargs) -> bool:
"""
Called right before placing a regular sell order.
Timing for this function is critical, so avoid doing heavy computations or
network requests in this method.
For full documentation please go to https://www.freqtrade.io/en/latest/strategy-advanced/
When not implemented by a strategy, returns True (always confirming).
:param pair: Pair that's about to be sold.
:param order_type: Order type (as configured in order_types). usually limit or market.
:param amount: Amount in quote currency.
:param rate: Rate that's going to be used when using limit orders
:param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled).
:param sell_reason: Sell reason.
Can be any of ['roi', 'stop_loss', 'stoploss_on_exchange', 'trailing_stop_loss',
'sell_signal', 'force_sell', 'emergency_sell']
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return bool: When True is returned, then the sell-order is placed on the exchange.
False aborts the process
"""
if sell_reason == 'force_sell' and trade.calc_profit_ratio(rate) < 0:
# Reject force-sells with negative profit
# This is just a sample, please adjust to your needs
# (this does not necessarily make sense, assuming you know when you're force-selling)
return False
return True
```
## 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.

View File

@@ -1,6 +1,8 @@
# Strategy Customization
This page explains where to customize your strategies, and add new indicators.
This page explains how to customize your strategies, add new indicators and set up trading rules.
Please familiarize yourself with [Freqtrade basics](bot-basics.md) first, which provides overall info on how the bot operates.
## Install a custom strategy file
@@ -56,12 +58,12 @@ file as reference.**
!!! 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.
that during backtesting the full time range 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 "Warning: Using future data"
Since backtesting passes the full time interval to the `populate_*()` methods, the strategy author
Since backtesting passes the full time range 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.
@@ -249,7 +251,7 @@ minimal_roi = {
While technically not completely disabled, this would sell once the trade reaches 10000% Profit.
To use times based on candle duration (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 ...)
This will allow you to change the timeframe 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
@@ -283,7 +285,7 @@ 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).
### Timeframe (ticker interval)
### Timeframe (formerly 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.
@@ -310,12 +312,17 @@ The name of the variable can be chosen at will, but should be prefixed with `cus
class Awesomestrategy(IStrategy):
# Create custom dictionary
cust_info = {}
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Check if the entry already exists
if not metadata["pair"] in self._cust_info:
# Create empty entry for this pair
self._cust_info[metadata["pair"]] = {}
if "crosstime" in self.cust_info[metadata["pair"]:
self.cust_info[metadata["pair"]["crosstime"] += 1
self.cust_info[metadata["pair"]]["crosstime"] += 1
else:
self.cust_info[metadata["pair"]["crosstime"] = 1
self.cust_info[metadata["pair"]]["crosstime"] = 1
```
!!! Warning
@@ -326,15 +333,15 @@ class Awesomestrategy(IStrategy):
***
### Additional data (informative_pairs)
## Additional data (informative_pairs)
#### Get data for non-tradeable 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 below).
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.
The pairs need to be specified as tuples in the format `("pair", "timeframe")`, with pair as the first and timeframe as the second argument.
Sample:
@@ -345,15 +352,17 @@ def informative_pairs(self):
]
```
A full sample can be found [in the DataProvider section](#complete-data-provider-sample).
!!! Warning
As these pairs will be refreshed as part of the regular whitelist refresh, it's best to keep this list short.
All intervals and all pairs can be specified as long as they are available (and active) on the used exchange.
It is however better to use resampling to longer time-intervals when possible
All timeframes and all pairs can be specified as long as they are available (and active) on the used exchange.
It is however better to use resampling to longer timeframes whenever possible
to avoid hammering the exchange with too many requests and risk being blocked.
***
### Additional data (DataProvider)
## Additional data (DataProvider)
The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy.
@@ -361,11 +370,16 @@ 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
!!! Warning "Hyperopt"
Dataprovider is available during hyperopt, however it can only be used in `populate_indicators()` within a strategy.
It is not available in `populate_buy()` and `populate_sell()` methods, nor in `populate_indicators()`, if this method located in the hyperopt file.
- [`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)
### Possible options for DataProvider
- [`available_pairs`](#available_pairs) - Property with tuples listing cached pairs with their timeframe (pair, timeframe).
- [`current_whitelist()`](#current_whitelist) - Returns a current list of whitelisted pairs. Useful for accessing dynamic whitelists (i.e. 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).
- [`get_analyzed_dataframe(pair, timeframe)`](#get_analyzed_dataframepair-timeframe) - Returns the analyzed dataframe (after calling `populate_indicators()`, `populate_buy()`, `populate_sell()`) and the time of the latest analysis.
- `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.
@@ -373,9 +387,9 @@ Please always check the mode of operation to select the correct method to get da
- [`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:
### Example Usages
#### *available_pairs*
### *available_pairs*
``` python
if self.dp:
@@ -383,27 +397,21 @@ if self.dp:
print(f"available {pair}, {timeframe}")
```
#### *current_whitelist()*
### *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.*
*Scan through the top 10 pairs by volume using the `VolumePairList` every 5 minutes and use a 14 day RSI 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!
Due to the limited available data, it's very difficult to resample our `5m` candles into daily candles for use in a 14 day RSI. 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...
timeframe = '5m'
# more strategy init stuff..
def informative_pairs(self):
# get access to all pairs available in whitelist.
@@ -411,16 +419,9 @@ class SampleStrategy(IStrategy):
# 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)*
### *get_pair_dataframe(pair, timeframe)*
``` python
# fetch live / historical candle (OHLCV) data for the first informative pair
@@ -431,14 +432,27 @@ if self.dp:
```
!!! Warning "Warning about backtesting"
Be carefull when using dataprovider in backtesting. `historic_ohlcv()` (and `get_pair_dataframe()`
Be careful 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).
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.
### *get_analyzed_dataframe(pair, timeframe)*
#### *orderbook(pair, maximum)*
This method is used by freqtrade internally to determine the last signal.
It can also be used in specific callbacks to get the signal that caused the action (see [Advanced Strategy Documentation](strategy-advanced.md) for more details on available callbacks).
``` python
# fetch current dataframe
if self.dp:
dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=metadata['pair'],
timeframe=self.timeframe)
```
!!! Note "No data available"
Returns an empty dataframe if the requested pair was not cached.
This should not happen when using whitelisted pairs.
### *orderbook(pair, maximum)*
``` python
if self.dp:
@@ -449,10 +463,9 @@ if self.dp:
```
!!! Warning
The order book is not part of the historic data which means backtesting and hyperopt will not work if this
method is used.
The order book is not part of the historic data which means backtesting and hyperopt will not work correctly if this method is used.
#### *ticker(pair)*
### *ticker(pair)*
``` python
if self.dp:
@@ -469,8 +482,138 @@ if self.dp:
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.
!!! Warning "Warning about backtesting"
This method will always return up-to-date values - so usage during backtesting / hyperopt will lead to wrong results.
### Complete Data-provider sample
```python
from freqtrade.strategy import IStrategy, merge_informative_pair
from pandas import DataFrame
class SampleStrategy(IStrategy):
# strategy init stuff...
timeframe = '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]
# Optionally Add additional "static" pairs
informative_pairs += [("ETH/USDT", "5m"),
("BTC/TUSD", "15m"),
]
return informative_pairs
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
if not self.dp:
# Don't do anything if DataProvider is not available.
return dataframe
inf_tf = '1d'
# Get the informative pair
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=inf_tf)
# Get the 14 day rsi
informative['rsi'] = ta.RSI(informative, timeperiod=14)
# Use the helper function merge_informative_pair to safely merge the pair
# Automatically renames the columns and merges a shorter timeframe dataframe and a longer timeframe informative pair
# use ffill to have the 1d value available in every row throughout the day.
# Without this, comparisons between columns of the original and the informative pair would only work once per day.
# Full documentation of this method, see below
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, inf_tf, ffill=True)
# Calculate rsi of the original dataframe (5m timeframe)
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
# Do other stuff
# ...
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30
(dataframe['rsi_1d'] < 30) & # Ensure daily RSI is < 30
(dataframe['volume'] > 0) # Ensure this candle had volume (important for backtesting)
),
'buy'] = 1
```
***
### Additional data (Wallets)
## Helper functions
### *merge_informative_pair()*
This method helps you merge an informative pair to a regular dataframe without lookahead bias.
It's there to help you merge the dataframe in a safe and consistent way.
Options:
- Rename the columns for you to create unique columns
- Merge the dataframe without lookahead bias
- Forward-fill (optional)
All columns of the informative dataframe will be available on the returning dataframe in a renamed fashion:
!!! Example "Column renaming"
Assuming `inf_tf = '1d'` the resulting columns will be:
``` python
'date', 'open', 'high', 'low', 'close', 'rsi' # from the original dataframe
'date_1d', 'open_1d', 'high_1d', 'low_1d', 'close_1d', 'rsi_1d' # from the informative dataframe
```
??? Example "Column renaming - 1h"
Assuming `inf_tf = '1h'` the resulting columns will be:
``` python
'date', 'open', 'high', 'low', 'close', 'rsi' # from the original dataframe
'date_1h', 'open_1h', 'high_1h', 'low_1h', 'close_1h', 'rsi_1h' # from the informative dataframe
```
??? Example "Custom implementation"
A custom implementation for this is possible, and can be done as follows:
``` python
# Shift date by 1 candle
# This is necessary since the data is always the "open date"
# and a 15m candle starting at 12:15 should not know the close of the 1h candle from 12:00 to 13:00
minutes = timeframe_to_minutes(inf_tf)
# Only do this if the timeframes are different:
informative['date_merge'] = informative["date"] + pd.to_timedelta(minutes, 'm')
# Rename columns to be unique
informative.columns = [f"{col}_{inf_tf}" for col in informative.columns]
# Assuming inf_tf = '1d' - then the columns will now be:
# date_1d, open_1d, high_1d, low_1d, close_1d, rsi_1d
# Combine the 2 dataframes
# all indicators on the informative sample MUST be calculated before this point
dataframe = pd.merge(dataframe, informative, left_on='date', right_on=f'date_merge_{inf_tf}', how='left')
# FFill to have the 1d value available in every row throughout the day.
# Without this, comparisons would only work once per day.
dataframe = dataframe.ffill()
```
!!! Warning "Informative timeframe < timeframe"
Using informative timeframes smaller than the dataframe timeframe is not recommended with this method, as it will not use any of the additional information this would provide.
To use the more detailed information properly, more advanced methods should be applied (which are out of scope for freqtrade documentation, as it'll depend on the respective need).
***
## Additional data (Wallets)
The strategy provides access to the `Wallets` object. This contains the current balances on the exchange.
@@ -486,14 +629,15 @@ if self.wallets:
total_eth = self.wallets.get_total('ETH')
```
#### Possible options for Wallets
### Possible options for Wallets
- `get_free(asset)` - currently available balance to trade
- `get_used(asset)` - currently tied up balance (open orders)
- `get_total(asset)` - total available balance - sum of the 2 above
***
### Additional data (Trades)
## Additional data (Trades)
A history of Trades can be retrieved in the strategy by querying the database.
@@ -539,30 +683,30 @@ Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of
!!! Warning
Trade history is not available during backtesting or hyperopt.
### Prevent trades from happening for a specific pair
## 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
### 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.
Freqtrade has an easy method to do this from within the strategy, by calling `self.lock_pair(pair, until, [reason])`.
`until` must be a datetime object in the future, after which trading will be re-enabled for that pair, while `reason` is an optional string detailing why the pair was locked.
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_config` will reset locked pairs.
Locked pairs will always be rounded up to the next candle. So assuming a `5m` timeframe, a lock with `until` set to 10:18 will lock the pair until the candle from 10:15-10:20 will be finished.
!!! Warning
Locking pairs is not functioning during backtesting.
Locking pairs is not available during backtesting.
##### Pair locking example
#### Pair locking example
``` python
from freqtrade.persistence import Trade
@@ -584,7 +728,7 @@ if self.config['runmode'].value in ('live', 'dry_run'):
self.lock_pair(metadata['pair'], until=datetime.now(timezone.utc) + timedelta(hours=12))
```
### Print created dataframe
## Print created dataframe
To inspect the created dataframe, you can issue a print-statement in either `populate_buy_trend()` or `populate_sell_trend()`.
You may also want to print the pair so it's clear what data is currently shown.
@@ -608,36 +752,7 @@ 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).
### Specify custom strategy location
If you want to use a strategy from a different directory you can pass `--strategy-path`
```bash
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
## 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.
This is a common pain-point, which can cause huge differences between backtesting and dry/live run methods, since they all use data which is not available during dry/live runs, so these strategies will perform well during backtesting, but will fail / perform badly in real conditions.
@@ -649,14 +764,12 @@ The following lists some common patterns which should be avoided to prevent frus
- don't use `dataframe['volume'].mean()`. This uses the full DataFrame for backtesting, including data from the future. Use `dataframe['volume'].rolling(<window>).mean()` instead
- don't use `.resample('1h')`. This uses the left border of the interval, so moves data from an hour to the start of the hour. Use `.resample('1h', label='right')` instead.
### Further strategy ideas
## Further strategy ideas
To get additional Ideas for strategies, head over to our [strategy repository](https://github.com/freqtrade/freqtrade-strategies). Feel free to use them as they are - but results will depend on the current market situation, pairs used etc. - therefore please backtest the strategy for your exchange/desired pairs first, evaluate carefully, use at your own risk.
Feel free to use any of them as inspiration for your own strategies.
We're happy to accept Pull Requests containing new Strategies to that repo.
We also got a *strategy-sharing* channel in our [Slack community](https://join.slack.com/t/highfrequencybot/shared_invite/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) which is a great place to get and/or share ideas.
## Next step
Now you have a perfect strategy you probably want to backtest it.

View File

@@ -85,10 +85,44 @@ Analyze a trades dataframe (also used below for plotting)
```python
from freqtrade.data.btanalysis import load_backtest_data
from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats
# Load backtest results
trades = load_backtest_data(config["user_data_dir"] / "backtest_results/backtest-result.json")
# if backtest_dir points to a directory, it'll automatically load the last backtest file.
backtest_dir = config["user_data_dir"] / "backtest_results"
# backtest_dir can also point to a specific file
# backtest_dir = config["user_data_dir"] / "backtest_results/backtest-result-2020-07-01_20-04-22.json"
```
```python
# You can get the full backtest statistics by using the following command.
# This contains all information used to generate the backtest result.
stats = load_backtest_stats(backtest_dir)
strategy = 'SampleStrategy'
# All statistics are available per strategy, so if `--strategy-list` was used during backtest, this will be reflected here as well.
# Example usages:
print(stats['strategy'][strategy]['results_per_pair'])
# Get pairlist used for this backtest
print(stats['strategy'][strategy]['pairlist'])
# Get market change (average change of all pairs from start to end of the backtest period)
print(stats['strategy'][strategy]['market_change'])
# Maximum drawdown ()
print(stats['strategy'][strategy]['max_drawdown'])
# Maximum drawdown start and end
print(stats['strategy'][strategy]['drawdown_start'])
print(stats['strategy'][strategy]['drawdown_end'])
# Get strategy comparison (only relevant if multiple strategies were compared)
print(stats['strategy_comparison'])
```
```python
# Load backtested trades as dataframe
trades = load_backtest_data(backtest_dir)
# Show value-counts per pair
trades.groupby("pair")["sell_reason"].value_counts()

View File

@@ -35,40 +35,89 @@ Copy the API Token (`22222222:APITOKEN` in the above example) and keep use it fo
Don't forget to start the conversation with your bot, by clicking `/START` button
### 2. Get your user id
### 2. Telegram user_id
#### Get your user id
Talk to the [userinfobot](https://telegram.me/userinfobot)
Get your "Id", you will use it for the config parameter `chat_id`.
#### Use Group id
You can use bots in telegram groups by just adding them to the group. You can find the group id by first adding a [RawDataBot](https://telegram.me/rawdatabot) to your group. The Group id is shown as id in the `"chat"` section, which the RawDataBot will send to you:
``` json
"chat":{
"id":-1001332619709
}
```
For the Freqtrade configuration, you can then use the the full value (including `-` if it's there) as string:
```json
"chat_id": "-1001332619709"
```
## Control telegram noise
Freqtrade provides means to control the verbosity of your telegram bot.
Each setting has the following possible values:
* `on` - Messages will be sent, and user will be notified.
* `silent` - Message will be sent, Notification will be without sound / vibration.
* `off` - Skip sending a message-type all together.
Example configuration showing the different settings:
``` json
"telegram": {
"enabled": true,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id",
"notification_settings": {
"status": "silent",
"warning": "on",
"startup": "off",
"buy": "silent",
"sell": "on",
"buy_cancel": "silent",
"sell_cancel": "on"
}
},
```
## Telegram commands
Per default, the Telegram bot shows predefined commands. Some commands
are only available by sending them to the bot. The table below list the
official commands. You can ask at any moment for help with `/help`.
| Command | Default | Description |
|----------|---------|-------------|
| `/start` | | Starts the trader
| `/stop` | | Stops the trader
| `/stopbuy` | | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `/reload_config` | | 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. 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`).
| `/forcesell all` | | Instantly sells all open trades (Ignoring `minimum_roi`).
| `/forcebuy <pair> [rate]` | | Instantly buys the given pair. Rate is optional. (`forcebuy_enable` must be set to True)
| `/performance` | | Show performance of each finished trade grouped by pair
| `/balance` | | Show account balance per currency
| `/daily <n>` | 7 | Shows profit or loss per day, over the last n days
| `/whitelist` | | Show the current whitelist
| `/blacklist [pair]` | | Show the current blacklist, or adds a pair to the blacklist.
| `/edge` | | Show validated pairs by Edge if it is enabled.
| `/help` | | Show help message
| `/version` | | Show version
| Command | Description |
|----------|-------------|
| `/start` | Starts the trader
| `/stop` | Stops the trader
| `/stopbuy` | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `/reload_config` | Reloads the configuration file
| `/show_config` | Shows part of the current configuration with relevant settings to operation
| `/logs [limit]` | Show last log messages.
| `/status` | Lists all open trades
| `/status table` | List all open trades in a table format. Pending buy orders are marked with an asterisk (*) Pending sell orders are marked with a double asterisk (**)
| `/trades [limit]` | List all recently closed trades in a table format.
| `/delete <trade_id>` | Delete a specific trade from the Database. Tries to close open orders. Requires manual handling of this trade on the exchange.
| `/count` | Displays number of trades used and available
| `/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`).
| `/forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`).
| `/forcebuy <pair> [rate]` | Instantly buys the given pair. Rate is optional. (`forcebuy_enable` must be set to True)
| `/performance` | Show performance of each finished trade grouped by pair
| `/balance` | Show account balance per currency
| `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7)
| `/whitelist` | Show the current whitelist
| `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist.
| `/edge` | Show validated pairs by Edge if it is enabled.
| `/help` | Show help message
| `/version` | Show version
## Telegram commands in action
@@ -113,6 +162,7 @@ For each open trade, the bot will send you the following message.
### /status table
Return the status of all open trades in a table format.
```
ID Pair Since Profit
---- -------- ------- --------
@@ -123,6 +173,7 @@ Return the status of all open trades in a table format.
### /count
Return the number of trades used and available.
```
current max
--------- -----
@@ -208,7 +259,7 @@ Shows the current whitelist
Shows the current blacklist.
If Pair is set, then this pair will be added to the pairlist.
Also supports multiple pairs, seperated by a space.
Also supports multiple pairs, separated by a space.
Use `/reload_config` to reset the blacklist.
> Using blacklist `StaticPairList` with 2 pairs
@@ -216,7 +267,7 @@ Use `/reload_config` to reset the blacklist.
### /edge
Shows pairs validated by Edge along with their corresponding winrate, expectancy and stoploss values.
Shows pairs validated by Edge along with their corresponding win-rate, expectancy and stoploss values.
> **Edge only validated following pairs:**
```

View File

@@ -423,7 +423,7 @@ 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.
You can list the hyperoptimization epochs the Hyperopt module evaluated previously with the `hyperopt-list` sub-command.
```
usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
@@ -433,9 +433,10 @@ usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[--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]
[--max-total-profit FLOAT]
[--min-objective FLOAT] [--max-objective FLOAT]
[--no-color] [--print-json] [--no-details]
[--hyperopt-filename PATH] [--export-csv FILE]
optional arguments:
-h, --help show this help message and exit
@@ -443,20 +444,27 @@ optional arguments:
--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-time FLOAT Select epochs above average time.
--max-avg-time FLOAT Select epochs below average time.
--min-avg-profit FLOAT
Select epochs on above average profit.
Select epochs above average profit.
--max-avg-profit FLOAT
Select epochs on below average profit.
Select epochs below average profit.
--min-total-profit FLOAT
Select epochs on above total profit.
Select epochs above total profit.
--max-total-profit FLOAT
Select epochs on below total profit.
Select epochs below total profit.
--min-objective FLOAT
Select epochs above objective.
--max-objective FLOAT
Select epochs below objective.
--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 output in JSON format.
--no-details Do not print best epoch details.
--hyperopt-filename FILENAME
Hyperopt result filename.Example: `--hyperopt-
filename=hyperopt_results_2020-09-27_16-20-48.pickle`
--export-csv FILE Export to CSV-File. This will disable table print.
Example: --export-csv hyperopt.csv
@@ -477,6 +485,10 @@ Common arguments:
Path to userdata directory.
```
!!! Note
`hyperopt-list` will automatically use the latest available hyperopt results file.
You can override this using the `--hyperopt-filename` argument, and specify another, available filename (without path!).
### Examples
List all results, print details of the best result at the end:
@@ -497,17 +509,41 @@ You can show the details of any hyperoptimization epoch previously evaluated by
usage: freqtrade hyperopt-show [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--best]
[--profitable] [-n INT] [--print-json]
[--no-header]
[--hyperopt-filename PATH] [--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.
--print-json Print output in JSON format.
--hyperopt-filename FILENAME
Hyperopt result filename.Example: `--hyperopt-
filename=hyperopt_results_2020-09-27_16-20-48.pickle`
--no-header Do not print epoch details header.
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.
```
!!! Note
`hyperopt-show` will automatically use the latest available hyperopt results file.
You can override this using the `--hyperopt-filename` argument, and specify another, available filename (without path!).
### 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):

View File

@@ -47,6 +47,7 @@ Different payloads can be configured for different events. Not all fields are ne
The fields in `webhook.webhookbuy` are filled when the bot executes a buy. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
* `exchange`
* `pair`
* `limit`
@@ -63,6 +64,7 @@ Possible parameters are:
The fields in `webhook.webhookbuycancel` are filled when the bot cancels a buy order. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
* `exchange`
* `pair`
* `limit`
@@ -79,6 +81,7 @@ Possible parameters are:
The fields in `webhook.webhooksell` are filled when the bot sells a trade. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
* `exchange`
* `pair`
* `gain`
@@ -100,6 +103,7 @@ Possible parameters are:
The fields in `webhook.webhooksellcancel` are filled when the bot cancels a sell order. Parameters are filled using string.format.
Possible parameters are:
* `trade_id`
* `exchange`
* `pair`
* `gain`

View File

@@ -0,0 +1,57 @@
We **strongly** recommend that Windows users use [Docker](docker.md) as this will work much easier and smoother (also more secure).
If that is not possible, try using the Windows Linux subsystem (WSL) - for which the Ubuntu instructions should work.
Otherwise, 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 [Anaconda installation section](installation.md#Anaconda) in this document for more information.
### 1. Clone the git repository
```bash
git clone https://github.com/freqtrade/freqtrade.git
```
### 2. Install ta-lib
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.19cp38cp38win_amd64.whl` (make sure to use the version matching your python version)
Freqtrade provides these dependencies for the latest 2 Python versions (3.7 and 3.8) and for 64bit Windows.
Other versions must be downloaded from the above link.
``` powershell
cd \path\freqtrade
python -m venv .env
.env\Scripts\activate.ps1
# optionally install ta-lib from wheel
# Eventually adjust the below filename to match the downloaded wheel
pip install build_helpers/TA_Lib-0.4.19-cp38-cp38-win_amd64.whl
pip install -r requirements.txt
pip install -e .
freqtrade
```
!!! Note "Use Powershell"
The above installation script assumes you're using powershell on a 64bit windows.
Commands for the legacy CMD windows console may differ.
> Thanks [Owdr](https://github.com/Owdr) for the commands. Source: [Issue #222](https://github.com/freqtrade/freqtrade/issues/222)
### Error during installation on Windows
``` bash
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
```
Unfortunately, many packages requiring compilation don't provide a pre-built wheel. It is therefore mandatory to have a C/C++ compiler installed and available for your python environment to use.
The easiest way is to download install Microsoft Visual Studio Community [here](https://visualstudio.microsoft.com/downloads/) and make sure to install "Common Tools for Visual C++" to enable building C code on Windows. Unfortunately, this is a heavy download / dependency (~4Gb) so you might want to consider WSL or [docker](docker.md) first.
---

View File

@@ -1,5 +1,5 @@
""" Freqtrade bot """
__version__ = '2020.6'
__version__ = '2020.11'
if __version__ == 'develop':

View File

@@ -8,5 +8,6 @@ To launch Freqtrade as a module
from freqtrade import main
if __name__ == '__main__':
main.main()

View File

@@ -8,22 +8,15 @@ Note: Be careful with file-scoped imports in these subfiles.
"""
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,
from freqtrade.commands.data_commands import (start_convert_data, start_download_data,
start_list_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.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.plot_commands import start_plot_dataframe, start_plot_profit
from freqtrade.commands.trade_commands import start_trading

View File

@@ -9,13 +9,14 @@ 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 = ["timeframe", "timerange",
ARGS_COMMON_OPTIMIZE = ["timeframe", "timerange", "dataformat_ohlcv",
"max_open_trades", "stake_amount", "fee"]
ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_positions",
@@ -26,7 +27,7 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
"use_max_market_positions", "print_all",
"print_colorized", "print_json", "hyperopt_jobs",
"hyperopt_random_state", "hyperopt_min_trades",
"hyperopt_continue", "hyperopt_loss"]
"hyperopt_loss"]
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
@@ -54,7 +55,9 @@ 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",
ARGS_LIST_DATA = ["exchange", "dataformat_ohlcv", "pairs"]
ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "timerange", "download_trades", "exchange",
"timeframes", "erase", "dataformat_ohlcv", "dataformat_trades"]
ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit",
@@ -71,14 +74,15 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable",
"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",
"hyperopt_list_min_objective", "hyperopt_list_max_objective",
"print_colorized", "print_json", "hyperopt_list_no_details",
"export_csv"]
"hyperoptexportfilename", "export_csv"]
ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index",
"print_json", "hyperopt_show_no_header"]
"print_json", "hyperoptexportfilename", "hyperopt_show_no_header"]
NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes",
"list-markets", "list-pairs", "list-strategies",
"list-markets", "list-pairs", "list-strategies", "list-data",
"list-hyperopts", "hyperopt-list", "hyperopt-show",
"plot-dataframe", "plot-profit", "show-trades"]
@@ -158,16 +162,14 @@ class Arguments:
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,
from freqtrade.commands import (start_backtesting, start_convert_data, start_create_userdir,
start_download_data, start_edge, start_hyperopt,
start_hyperopt_list, start_hyperopt_show, start_list_data,
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)
start_list_timeframes, start_new_config, start_new_hyperopt,
start_new_strategy, start_plot_dataframe, start_plot_profit,
start_show_trades, start_test_pairlist, start_trading)
subparsers = self.parser.add_subparsers(dest='command',
# Use custom message when no subhandler is added
@@ -233,6 +235,15 @@ class Arguments:
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 list-data subcommand
list_data_cmd = subparsers.add_parser(
'list-data',
help='List downloaded data.',
parents=[_common_parser],
)
list_data_cmd.set_defaults(func=start_list_data)
self._build_args(optionlist=ARGS_LIST_DATA, parser=list_data_cmd)
# Add backtesting subcommand
backtesting_cmd = subparsers.add_parser('backtesting', help='Backtesting module.',
parents=[_common_parser, _strategy_parser])
@@ -354,7 +365,7 @@ class Arguments:
plot_profit_cmd = subparsers.add_parser(
'plot-profit',
help='Generate plot showing profits.',
parents=[_common_parser],
parents=[_common_parser, _strategy_parser],
)
plot_profit_cmd.set_defaults(func=start_plot_profit)
self._build_args(optionlist=ARGS_PLOT_PROFIT, parser=plot_profit_cmd)

View File

@@ -1,13 +1,15 @@
import logging
from pathlib import Path
from typing import Any, Dict
from typing import Any, Dict, List
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
from freqtrade.exchange import MAP_EXCHANGE_CHILDCLASS, available_exchanges
from freqtrade.misc import render_template
logger = logging.getLogger(__name__)
@@ -46,7 +48,7 @@ def ask_user_config() -> Dict[str, Any]:
Interactive questions built using https://github.com/tmbo/questionary
:returns: Dict with keys to put into template
"""
questions = [
questions: List[Dict[str, Any]] = [
{
"type": "confirm",
"name": "dry_run",

View File

@@ -4,6 +4,7 @@ Definition of cli arguments used in arguments.py
from argparse import ArgumentTypeError
from freqtrade import __version__, constants
from freqtrade.constants import HYPEROPT_LOSS_BUILTIN
def check_int_positive(value: str) -> int:
@@ -252,23 +253,19 @@ AVAILABLE_CLI_OPTIONS = {
metavar='INT',
default=1,
),
"hyperopt_continue": Arg(
"--continue",
help="Continue hyperopt from previous runs. "
"By default, temporary files will be removed and hyperopt will start from scratch.",
default=False,
action='store_true',
),
"hyperopt_loss": Arg(
'--hyperopt-loss',
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, SharpeHyperOptLossDaily, '
'SortinoHyperOptLoss, SortinoHyperOptLossDaily.'
'(default: `%(default)s`).',
f'{", ".join(HYPEROPT_LOSS_BUILTIN)}',
metavar='NAME',
default=constants.DEFAULT_HYPEROPT_LOSS,
),
"hyperoptexportfilename": Arg(
'--hyperopt-filename',
help='Hyperopt result filename.'
'Example: `--hyperopt-filename=hyperopt_results_2020-09-27_16-20-48.pickle`',
metavar='FILENAME',
),
# List exchanges
"print_one_column": Arg(
@@ -357,13 +354,11 @@ AVAILABLE_CLI_OPTIONS = {
'--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',
@@ -375,7 +370,7 @@ AVAILABLE_CLI_OPTIONS = {
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'],
'6h', '8h', '12h', '1d', '3d', '1w', '2w', '1M', '1y'],
default=['1m', '5m'],
nargs='+',
),
@@ -455,37 +450,49 @@ AVAILABLE_CLI_OPTIONS = {
),
"hyperopt_list_min_avg_time": Arg(
'--min-avg-time',
help='Select epochs on above average time.',
help='Select epochs above average time.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_max_avg_time": Arg(
'--max-avg-time',
help='Select epochs on under average time.',
help='Select epochs below average time.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_min_avg_profit": Arg(
'--min-avg-profit',
help='Select epochs on above average profit.',
help='Select epochs above average profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_max_avg_profit": Arg(
'--max-avg-profit',
help='Select epochs on below average profit.',
help='Select epochs below average profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_min_total_profit": Arg(
'--min-total-profit',
help='Select epochs on above total profit.',
help='Select epochs above total profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_max_total_profit": Arg(
'--max-total-profit',
help='Select epochs on below total profit.',
help='Select epochs below total profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_min_objective": Arg(
'--min-objective',
help='Select epochs above objective.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_max_objective": Arg(
'--max-objective',
help='Select epochs below objective.',
type=float,
metavar='FLOAT',
),

View File

@@ -1,19 +1,19 @@
import logging
import sys
from collections import defaultdict
from datetime import datetime, timedelta
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,
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.exchange import timeframe_to_minutes
from freqtrade.resolvers import ExchangeResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -23,18 +23,27 @@ def start_download_data(args: Dict[str, Any]) -> None:
"""
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
if 'days' in config and 'timerange' in config:
raise OperationalException("--days and --timerange are mutually exclusive. "
"You can only specify one or the other.")
timerange = TimeRange()
if 'days' in config:
time_since = arrow.utcnow().shift(days=-config['days']).strftime("%Y%m%d")
time_since = (datetime.now() - timedelta(days=config['days'])).strftime("%Y%m%d")
timerange = TimeRange.parse_timerange(f'{time_since}-')
if 'timerange' in config:
timerange = timerange.parse_timerange(config['timerange'])
# Remove stake-currency to skip checks which are not relevant for datadownload
config['stake_currency'] = ''
if 'pairs' not in config:
raise OperationalException(
"Downloading data requires a list of pairs. "
"Please check the documentation on how to configure this.")
logger.info(f'About to download pairs: {config["pairs"]}, '
f'intervals: {config["timeframes"]} to {config["datadir"]}')
logger.info(f"About to download pairs: {config['pairs']}, "
f"intervals: {config['timeframes']} to {config['datadir']}")
pairs_not_available: List[str] = []
@@ -49,21 +58,21 @@ def start_download_data(args: Dict[str, Any]) -> None:
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")),
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")),
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")),
exchange, pairs=config['pairs'], timeframes=config['timeframes'],
datadir=config['datadir'], timerange=timerange, erase=bool(config.get('erase')),
data_format=config['dataformat_ohlcv'])
except KeyboardInterrupt:
@@ -88,3 +97,31 @@ def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None:
convert_trades_format(config,
convert_from=args['format_from'], convert_to=args['format_to'],
erase=args['erase'])
def start_list_data(args: Dict[str, Any]) -> None:
"""
List available backtest data
"""
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
from tabulate import tabulate
from freqtrade.data.history.idatahandler import get_datahandler
dhc = get_datahandler(config['datadir'], config['dataformat_ohlcv'])
paircombs = dhc.ohlcv_get_available_data(config['datadir'])
if args['pairs']:
paircombs = [comb for comb in paircombs if comb[0] in args['pairs']]
print(f"Found {len(paircombs)} pair / timeframe combinations.")
groupedpair = defaultdict(list)
for pair, timeframe in sorted(paircombs, key=lambda x: (x[0], timeframe_to_minutes(x[1]))):
groupedpair[pair].append(timeframe)
if groupedpair:
print(tabulate([(pair, ', '.join(timeframes)) for pair, timeframes in groupedpair.items()],
headers=("Pair", "Timeframe"),
tablefmt='psql', stralign='right'))

View File

@@ -4,13 +4,13 @@ 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.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__)
@@ -75,7 +75,7 @@ def start_new_strategy(args: Dict[str, Any]) -> None:
if args["strategy"] == "DefaultStrategy":
raise OperationalException("DefaultStrategy is not allowed as name.")
new_path = config['user_data_dir'] / USERPATH_STRATEGIES / (args["strategy"] + ".py")
new_path = config['user_data_dir'] / USERPATH_STRATEGIES / (args['strategy'] + '.py')
if new_path.exists():
raise OperationalException(f"`{new_path}` already exists. "
@@ -125,15 +125,15 @@ 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":
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")
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.")
"Please choose another Hyperopt Name.")
deploy_new_hyperopt(args['hyperopt'], new_path, args['template'])
else:
raise OperationalException("`new-hyperopt` requires --hyperopt to be set.")

View File

@@ -5,9 +5,11 @@ from typing import Any, Dict, List
from colorama import init as colorama_init
from freqtrade.configuration import setup_utils_configuration
from freqtrade.data.btanalysis import get_latest_hyperopt_file
from freqtrade.exceptions import OperationalException
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -35,17 +37,20 @@ def start_hyperopt_list(args: Dict[str, Any]) -> 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)
'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None),
'filter_min_objective': config.get('hyperopt_list_min_objective', None),
'filter_max_objective': config.get('hyperopt_list_max_objective', None),
}
results_file = (config['user_data_dir'] /
'hyperopt_results' / 'hyperopt_results.pickle')
results_file = get_latest_hyperopt_file(
config['user_data_dir'] / 'hyperopt_results',
config.get('hyperoptexportfilename'))
# Previous evaluations
epochs = Hyperopt.load_previous_results(results_file)
total_epochs = len(epochs)
epochs = _hyperopt_filter_epochs(epochs, filteroptions)
epochs = hyperopt_filter_epochs(epochs, filteroptions)
if print_colorized:
colorama_init(autoreset=True)
@@ -78,8 +83,10 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None:
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')
results_file = get_latest_hyperopt_file(
config['user_data_dir'] / 'hyperopt_results',
config.get('hyperoptexportfilename'))
n = config.get('hyperopt_show_index', -1)
filteroptions = {
@@ -92,14 +99,16 @@ def start_hyperopt_show(args: Dict[str, Any]) -> 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)
'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None),
'filter_min_objective': config.get('hyperopt_list_min_objective', None),
'filter_max_objective': config.get('hyperopt_list_max_objective', None)
}
# Previous evaluations
epochs = Hyperopt.load_previous_results(results_file)
total_epochs = len(epochs)
epochs = _hyperopt_filter_epochs(epochs, filteroptions)
epochs = hyperopt_filter_epochs(epochs, filteroptions)
filtered_epochs = len(epochs)
if n > filtered_epochs:
@@ -119,7 +128,7 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None:
header_str="Epoch details")
def _hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List:
def hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List:
"""
Filter our items from the list of hyperopt results
"""
@@ -127,6 +136,24 @@ def _hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List:
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]
epochs = _hyperopt_filter_epochs_trade_count(epochs, filteroptions)
epochs = _hyperopt_filter_epochs_duration(epochs, filteroptions)
epochs = _hyperopt_filter_epochs_profit(epochs, filteroptions)
epochs = _hyperopt_filter_epochs_objective(epochs, filteroptions)
logger.info(f"{len(epochs)} " +
("best " if filteroptions['only_best'] else "") +
("profitable " if filteroptions['only_profitable'] else "") +
"epochs found.")
return epochs
def _hyperopt_filter_epochs_trade_count(epochs: List, filteroptions: dict) -> List:
if filteroptions['filter_min_trades'] > 0:
epochs = [
x for x in epochs
@@ -137,6 +164,11 @@ def _hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List:
x for x in epochs
if x['results_metrics']['trade_count'] < filteroptions['filter_max_trades']
]
return epochs
def _hyperopt_filter_epochs_duration(epochs: List, filteroptions: dict) -> List:
if filteroptions['filter_min_avg_time'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
@@ -149,6 +181,12 @@ def _hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List:
x for x in epochs
if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time']
]
return epochs
def _hyperopt_filter_epochs_profit(epochs: List, filteroptions: dict) -> List:
if filteroptions['filter_min_avg_profit'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [
@@ -173,10 +211,18 @@ def _hyperopt_filter_epochs(epochs: List, filteroptions: dict) -> List:
x for x in epochs
if x['results_metrics']['profit'] < filteroptions['filter_max_total_profit']
]
return epochs
logger.info(f"{len(epochs)} " +
("best " if filteroptions['only_best'] else "") +
("profitable " if filteroptions['only_profitable'] else "") +
"epochs found.")
def _hyperopt_filter_epochs_objective(epochs: List, filteroptions: dict) -> List:
if filteroptions['filter_min_objective'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [x for x in epochs if x['loss'] < filteroptions['filter_min_objective']]
if filteroptions['filter_max_objective'] is not None:
epochs = [x for x in epochs if x['results_metrics']['trade_count'] > 0]
epochs = [x for x in epochs if x['loss'] > filteroptions['filter_max_objective']]
return epochs

View File

@@ -5,20 +5,20 @@ from collections import OrderedDict
from pathlib import Path
from typing import Any, Dict, List
from colorama import init as colorama_init
from colorama import Fore, Style
import rapidjson
from colorama import Fore, Style
from colorama import init as colorama_init
from tabulate import tabulate
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.exchange import available_exchanges, ccxt_exchanges, market_is_active
from freqtrade.misc import plural
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -163,7 +163,7 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None:
tabular_data.append({'Id': v['id'], 'Symbol': v['symbol'],
'Base': v['base'], 'Quote': v['quote'],
'Active': market_is_active(v),
**({'Is pair': symbol_is_pair(v['symbol'])}
**({'Is pair': exchange.market_is_tradable(v)}
if not pairs_only else {})})
if (args.get('print_one_column', False) or
@@ -203,15 +203,16 @@ def start_show_trades(args: Dict[str, Any]) -> None:
"""
Show trades
"""
from freqtrade.persistence import init, Trade
import json
from freqtrade.persistence import Trade, init_db
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)
init_db(config['db_url'], clean_open_orders=False)
tfilter = []
if config.get('trade_ids'):

View File

@@ -6,6 +6,7 @@ from freqtrade.configuration import setup_utils_configuration
from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -58,6 +59,7 @@ def start_hyperopt(args: Dict[str, Any]) -> 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(
@@ -98,6 +100,7 @@ def start_edge(args: Dict[str, Any]) -> None:
: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')

View File

@@ -7,6 +7,7 @@ from freqtrade.configuration import setup_utils_configuration
from freqtrade.resolvers import ExchangeResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)

View File

@@ -1,5 +1,4 @@
import logging
from typing import Any, Dict

View File

@@ -1,7 +1,7 @@
# 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_setup import setup_utils_configuration
from freqtrade.configuration.config_validation import validate_config_consistency
from freqtrade.configuration.configuration import Configuration
from freqtrade.configuration.timerange import TimeRange

View File

@@ -2,11 +2,11 @@ import logging
from typing import Any, Dict
from freqtrade.exceptions import OperationalException
from freqtrade.exchange import (available_exchanges, get_exchange_bad_reason,
is_exchange_bad, is_exchange_known_ccxt,
is_exchange_officially_supported)
from freqtrade.exchange import (available_exchanges, get_exchange_bad_reason, is_exchange_bad,
is_exchange_known_ccxt, is_exchange_officially_supported)
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)

View File

@@ -1,10 +1,12 @@
import logging
from typing import Any, Dict
from freqtrade.state import RunMode
from .check_exchange import remove_credentials
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__)

View File

@@ -9,6 +9,7 @@ from freqtrade import constants
from freqtrade.exceptions import OperationalException
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -136,6 +137,10 @@ def _validate_edge(conf: Dict[str, Any]) -> None:
"Edge and VolumePairList are incompatible, "
"Edge will override whatever pairs VolumePairlist selects."
)
if not conf.get('ask_strategy', {}).get('use_sell_signal', True):
raise OperationalException(
"Edge requires `use_sell_signal` to be True, otherwise no sells will happen."
)
def _validate_whitelist(conf: Dict[str, Any]) -> None:

View File

@@ -10,14 +10,14 @@ from typing import Any, Callable, Dict, List, Optional
from freqtrade import constants
from freqtrade.configuration.check_exchange import check_exchange
from freqtrade.configuration.deprecated_settings import process_temporary_deprecated_settings
from freqtrade.configuration.directory_operations import (create_datadir,
create_userdata_dir)
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 NON_UTIL_MODES, TRADING_MODES, RunMode
logger = logging.getLogger(__name__)
@@ -54,7 +54,7 @@ class Configuration:
:param files: List of file paths
:return: configuration dictionary
"""
c = Configuration({"config": files}, RunMode.OTHER)
c = Configuration({'config': files}, RunMode.OTHER)
return c.get_config()
def load_from_files(self, files: List[str]) -> Dict[str, Any]:
@@ -123,10 +123,10 @@ class Configuration:
the -v/--verbose, --logfile options
"""
# Log level
config.update({'verbosity': self.args.get("verbosity", 0)})
config.update({'verbosity': self.args.get('verbosity', 0)})
if 'logfile' in self.args and self.args["logfile"]:
config.update({'logfile': self.args["logfile"]})
if 'logfile' in self.args and self.args['logfile']:
config.update({'logfile': self.args['logfile']})
setup_logging(config)
@@ -149,22 +149,22 @@ class Configuration:
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")})
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"]})
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.')
# Support for sd_notify
if 'sd_notify' in self.args and self.args["sd_notify"]:
if 'sd_notify' in self.args and self.args['sd_notify']:
config['internals'].update({'sd_notify': True})
def _process_datadir_options(self, config: Dict[str, Any]) -> None:
@@ -173,24 +173,24 @@ class Configuration:
--user-data, --datadir
"""
# Check exchange parameter here - otherwise `datadir` might be wrong.
if "exchange" in self.args and self.args["exchange"]:
config['exchange']['name'] = self.args["exchange"]
if 'exchange' in self.args and self.args['exchange']:
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"]})
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:
# Default to cwd/user_data (legacy option ...)
config.update({'user_data_dir': str(Path.cwd() / "user_data")})
config.update({'user_data_dir': str(Path.cwd() / 'user_data')})
# reset to user_data_dir so this contains the absolute path.
config['user_data_dir'] = create_userdata_dir(config['user_data_dir'], create_dir=False)
logger.info('Using user-data directory: %s ...', config['user_data_dir'])
config.update({'datadir': create_datadir(config, self.args.get("datadir", None))})
config.update({'datadir': create_datadir(config, self.args.get('datadir', None))})
logger.info('Using data directory: %s ...', config.get('datadir'))
if self.args.get('exportfilename'):
@@ -199,7 +199,7 @@ class Configuration:
config['exportfilename'] = Path(config['exportfilename'])
else:
config['exportfilename'] = (config['user_data_dir']
/ 'backtest_results/backtest-result.json')
/ 'backtest_results')
def _process_optimize_options(self, config: Dict[str, Any]) -> None:
@@ -219,8 +219,8 @@ class Configuration:
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"]})
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, '
'overriding max_open_trades to: %s ...', config.get('max_open_trades'))
elif config['runmode'] in NON_UTIL_MODES:
@@ -263,6 +263,9 @@ class Configuration:
self._args_to_config(config, argname='hyperopt_path',
logstring='Using additional Hyperopt lookup path: {}')
self._args_to_config(config, argname='hyperoptexportfilename',
logstring='Using hyperopt file: {}')
self._args_to_config(config, argname='epochs',
logstring='Parameter --epochs detected ... '
'Will run Hyperopt with for {} epochs ...'
@@ -295,9 +298,6 @@ class Configuration:
self._args_to_config(config, argname='hyperopt_min_trades',
logstring='Parameter --min-trades detected: {}')
self._args_to_config(config, argname='hyperopt_continue',
logstring='Hyperopt continue: {}')
self._args_to_config(config, argname='hyperopt_loss',
logstring='Using Hyperopt loss class name: {}')
@@ -334,6 +334,12 @@ class Configuration:
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_min_objective',
logstring='Parameter --min-objective detected: {}')
self._args_to_config(config, argname='hyperopt_list_max_objective',
logstring='Parameter --max-objective detected: {}')
self._args_to_config(config, argname='hyperopt_list_no_details',
logstring='Parameter --no-details detected: {}')
@@ -441,12 +447,12 @@ class Configuration:
config['pairs'].sort()
return
if "config" in self.args and self.args["config"]:
if 'config' in self.args and self.args['config']:
logger.info("Using pairlist from configuration.")
config['pairs'] = config.get('exchange', {}).get('pair_whitelist')
else:
# Fall back to /dl_path/pairs.json
pairs_file = 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

@@ -3,8 +3,9 @@ import shutil
from pathlib import Path
from typing import Any, Dict, Optional
from freqtrade.exceptions import OperationalException
from freqtrade.constants import USER_DATA_FILES
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)

View File

@@ -11,6 +11,7 @@ import rapidjson
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)

View File

@@ -52,11 +52,11 @@ class TimeRange:
:return: None (Modifies the object in place)
"""
if (not self.starttype or (startup_candles
and min_date.timestamp >= self.startts)):
and min_date.int_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.startts = (min_date.int_timestamp + timeframe_secs * startup_candles)
self.starttype = 'date'
@staticmethod
@@ -89,7 +89,7 @@ class TimeRange:
if stype[0]:
starts = rvals[index]
if stype[0] == 'date' and len(starts) == 8:
start = arrow.get(starts, 'YYYYMMDD').timestamp
start = arrow.get(starts, 'YYYYMMDD').int_timestamp
elif len(starts) == 13:
start = int(starts) // 1000
else:
@@ -98,7 +98,7 @@ class TimeRange:
if stype[1]:
stops = rvals[index]
if stype[1] == 'date' and len(stops) == 8:
stop = arrow.get(stops, 'YYYYMMDD').timestamp
stop = arrow.get(stops, 'YYYYMMDD').int_timestamp
elif len(stops) == 13:
stop = int(stops) // 1000
else:

View File

@@ -11,7 +11,6 @@ DEFAULT_EXCHANGE = 'bittrex'
PROCESS_THROTTLE_SECS = 5 # sec
HYPEROPT_EPOCH = 100 # epochs
RETRY_TIMEOUT = 30 # sec
DEFAULT_HYPEROPT_LOSS = 'DefaultHyperOptLoss'
DEFAULT_DB_PROD_URL = 'sqlite:///tradesv3.sqlite'
DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite'
UNLIMITED_STAKE_AMOUNT = 'unlimited'
@@ -21,21 +20,29 @@ REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']
ORDERBOOK_SIDES = ['ask', 'bid']
ORDERTYPE_POSSIBILITIES = ['limit', 'market']
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
HYPEROPT_LOSS_BUILTIN = ['ShortTradeDurHyperOptLoss', 'OnlyProfitHyperOptLoss',
'SharpeHyperOptLoss', 'SharpeHyperOptLossDaily',
'SortinoHyperOptLoss', 'SortinoHyperOptLossDaily']
AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList',
'AgeFilter', 'PrecisionFilter', 'PriceFilter',
'ShuffleFilter', 'SpreadFilter']
AVAILABLE_DATAHANDLERS = ['json', 'jsongz']
'RangeStabilityFilter', 'ShuffleFilter', 'SpreadFilter']
AVAILABLE_DATAHANDLERS = ['json', 'jsongz', 'hdf5']
DRY_RUN_WALLET = 1000
DATETIME_PRINT_FORMAT = '%Y-%m-%d %H:%M:%S'
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']
LAST_BT_RESULT_FN = '.last_result.json'
USERPATH_HYPEROPTS = 'hyperopts'
USERPATH_STRATEGIES = 'strategies'
USERPATH_NOTEBOOKS = 'notebooks'
TELEGRAM_SETTING_OPTIONS = ['on', 'off', 'silent']
# Soure files with destination directories within user-directory
USER_DATA_FILES = {
'sample_strategy.py': USERPATH_STRATEGIES,
@@ -156,7 +163,9 @@ CONF_SCHEMA = {
'emergencysell': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
'stoploss': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
'stoploss_on_exchange': {'type': 'boolean'},
'stoploss_on_exchange_interval': {'type': 'number'}
'stoploss_on_exchange_interval': {'type': 'number'},
'stoploss_on_exchange_limit_ratio': {'type': 'number', 'minimum': 0.0,
'maximum': 1.0}
},
'required': ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']
},
@@ -196,6 +205,18 @@ CONF_SCHEMA = {
'enabled': {'type': 'boolean'},
'token': {'type': 'string'},
'chat_id': {'type': 'string'},
'notification_settings': {
'type': 'object',
'properties': {
'status': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'warning': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'startup': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'buy': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'sell': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'buy_cancel': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'sell_cancel': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS}
}
}
},
'required': ['enabled', 'token', 'chat_id']
},
@@ -333,10 +354,17 @@ SCHEMA_MINIMAL_REQUIRED = [
CANCEL_REASON = {
"TIMEOUT": "cancelled due to timeout",
"PARTIALLY_FILLED": "partially filled - keeping order open",
"PARTIALLY_FILLED_KEEP_OPEN": "partially filled - keeping order open",
"PARTIALLY_FILLED": "partially filled",
"FULLY_CANCELLED": "fully cancelled",
"ALL_CANCELLED": "cancelled (all unfilled and partially filled open orders cancelled)",
"CANCELLED_ON_EXCHANGE": "cancelled on exchange",
"FORCE_SELL": "forcesold",
}
# List of pairs with their timeframes
ListPairsWithTimeframes = List[Tuple[str, str]]
PairWithTimeframe = Tuple[str, str]
ListPairsWithTimeframes = List[PairWithTimeframe]
# Type for trades list
TradeList = List[List]

View File

@@ -2,53 +2,172 @@
Helpers when analyzing backtest data
"""
import logging
from datetime import timezone
from pathlib import Path
from typing import Dict, Union, Tuple
from typing import Any, Dict, Optional, Tuple, Union
import numpy as np
import pandas as pd
from datetime import timezone
from freqtrade import persistence
from freqtrade.constants import LAST_BT_RESULT_FN
from freqtrade.misc import json_load
from freqtrade.persistence import Trade
from freqtrade.persistence import Trade, init_db
logger = logging.getLogger(__name__)
# must align with columns in backtest.py
BT_DATA_COLUMNS = ["pair", "profit_percent", "open_time", "close_time", "index", "duration",
BT_DATA_COLUMNS = ["pair", "profit_percent", "open_date", "close_date", "index", "trade_duration",
"open_rate", "close_rate", "open_at_end", "sell_reason"]
def load_backtest_data(filename: Union[Path, str]) -> pd.DataFrame:
def get_latest_optimize_filename(directory: Union[Path, str], variant: str) -> str:
"""
Load backtest data file.
:param filename: pathlib.Path object, or string pointing to the file.
:return: a dataframe with the analysis results
Get latest backtest export based on '.last_result.json'.
:param directory: Directory to search for last result
:param variant: 'backtest' or 'hyperopt' - the method to return
:return: string containing the filename of the latest backtest result
:raises: ValueError in the following cases:
* Directory does not exist
* `directory/.last_result.json` does not exist
* `directory/.last_result.json` has the wrong content
"""
if isinstance(filename, str):
filename = Path(filename)
if isinstance(directory, str):
directory = Path(directory)
if not directory.is_dir():
raise ValueError(f"Directory '{directory}' does not exist.")
filename = directory / LAST_BT_RESULT_FN
if not filename.is_file():
raise ValueError(f"File {filename} does not exist.")
raise ValueError(
f"Directory '{directory}' does not seem to contain backtest statistics yet.")
with filename.open() as file:
data = json_load(file)
df = pd.DataFrame(data, columns=BT_DATA_COLUMNS)
if f'latest_{variant}' not in data:
raise ValueError(f"Invalid '{LAST_BT_RESULT_FN}' format.")
df['open_time'] = pd.to_datetime(df['open_time'],
unit='s',
utc=True,
infer_datetime_format=True
)
df['close_time'] = pd.to_datetime(df['close_time'],
unit='s',
utc=True,
infer_datetime_format=True
)
df['profit'] = df['close_rate'] - df['open_rate']
df = df.sort_values("open_time").reset_index(drop=True)
return data[f'latest_{variant}']
def get_latest_backtest_filename(directory: Union[Path, str]) -> str:
"""
Get latest backtest export based on '.last_result.json'.
:param directory: Directory to search for last result
:return: string containing the filename of the latest backtest result
:raises: ValueError in the following cases:
* Directory does not exist
* `directory/.last_result.json` does not exist
* `directory/.last_result.json` has the wrong content
"""
return get_latest_optimize_filename(directory, 'backtest')
def get_latest_hyperopt_filename(directory: Union[Path, str]) -> str:
"""
Get latest hyperopt export based on '.last_result.json'.
:param directory: Directory to search for last result
:return: string containing the filename of the latest hyperopt result
:raises: ValueError in the following cases:
* Directory does not exist
* `directory/.last_result.json` does not exist
* `directory/.last_result.json` has the wrong content
"""
try:
return get_latest_optimize_filename(directory, 'hyperopt')
except ValueError:
# Return default (legacy) pickle filename
return 'hyperopt_results.pickle'
def get_latest_hyperopt_file(directory: Union[Path, str], predef_filename: str = None) -> Path:
"""
Get latest hyperopt export based on '.last_result.json'.
:param directory: Directory to search for last result
:return: string containing the filename of the latest hyperopt result
:raises: ValueError in the following cases:
* Directory does not exist
* `directory/.last_result.json` does not exist
* `directory/.last_result.json` has the wrong content
"""
if isinstance(directory, str):
directory = Path(directory)
if predef_filename:
return directory / predef_filename
return directory / get_latest_hyperopt_filename(directory)
def load_backtest_stats(filename: Union[Path, str]) -> Dict[str, Any]:
"""
Load backtest statistics file.
:param filename: pathlib.Path object, or string pointing to the file.
:return: a dictionary containing the resulting file.
"""
if isinstance(filename, str):
filename = Path(filename)
if filename.is_dir():
filename = filename / get_latest_backtest_filename(filename)
if not filename.is_file():
raise ValueError(f"File {filename} does not exist.")
logger.info(f"Loading backtest result from {filename}")
with filename.open() as file:
data = json_load(file)
return data
def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = None) -> pd.DataFrame:
"""
Load backtest data file.
:param filename: pathlib.Path object, or string pointing to a file or directory
:param strategy: Strategy to load - mainly relevant for multi-strategy backtests
Can also serve as protection to load the correct result.
:return: a dataframe with the analysis results
:raise: ValueError if loading goes wrong.
"""
data = load_backtest_stats(filename)
if not isinstance(data, list):
# new, nested format
if 'strategy' not in data:
raise ValueError("Unknown dataformat.")
if not strategy:
if len(data['strategy']) == 1:
strategy = list(data['strategy'].keys())[0]
else:
raise ValueError("Detected backtest result with more than one strategy. "
"Please specify a strategy.")
if strategy not in data['strategy']:
raise ValueError(f"Strategy {strategy} not available in the backtest result.")
data = data['strategy'][strategy]['trades']
df = pd.DataFrame(data)
df['open_date'] = pd.to_datetime(df['open_date'],
utc=True,
infer_datetime_format=True
)
df['close_date'] = pd.to_datetime(df['close_date'],
utc=True,
infer_datetime_format=True
)
else:
# old format - only with lists.
df = pd.DataFrame(data, columns=BT_DATA_COLUMNS)
df['open_date'] = pd.to_datetime(df['open_date'],
unit='s',
utc=True,
infer_datetime_format=True
)
df['close_date'] = pd.to_datetime(df['close_date'],
unit='s',
utc=True,
infer_datetime_format=True
)
df['profit_abs'] = df['close_rate'] - df['open_rate']
df = df.sort_values("open_date").reset_index(drop=True)
return df
@@ -62,9 +181,9 @@ def analyze_trade_parallelism(results: pd.DataFrame, timeframe: str) -> pd.DataF
"""
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,
dates = [pd.Series(pd.date_range(row[1]['open_date'], row[1]['close_date'],
freq=f"{timeframe_min}min"))
for row in results[['open_time', 'close_time']].iterrows()]
for row in results[['open_date', 'close_date']].iterrows()]
deltas = [len(x) for x in dates]
dates = pd.Series(pd.concat(dates).values, name='date')
df2 = pd.DataFrame(np.repeat(results.values, deltas, axis=0), columns=results.columns)
@@ -90,21 +209,26 @@ def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
return df_final[df_final['open_trades'] > max_open_trades]
def load_trades_from_db(db_url: str) -> pd.DataFrame:
def load_trades_from_db(db_url: str, strategy: Optional[str] = None) -> pd.DataFrame:
"""
Load trades from a DB (using dburl)
:param db_url: Sqlite url (default format sqlite:///tradesv3.dry-run.sqlite)
:param strategy: Strategy to load - mainly relevant for multi-strategy backtests
Can also serve as protection to load the correct result.
:return: Dataframe containing Trades
"""
trades: pd.DataFrame = pd.DataFrame([], columns=BT_DATA_COLUMNS)
persistence.init(db_url, clean_open_orders=False)
init_db(db_url, clean_open_orders=False)
columns = ["pair", "open_time", "close_time", "profit", "profit_percent",
"open_rate", "close_rate", "amount", "duration", "sell_reason",
columns = ["pair", "open_date", "close_date", "profit", "profit_percent",
"open_rate", "close_rate", "amount", "trade_duration", "sell_reason",
"fee_open", "fee_close", "open_rate_requested", "close_rate_requested",
"stake_amount", "max_rate", "min_rate", "id", "exchange",
"stop_loss", "initial_stop_loss", "strategy", "timeframe"]
filters = []
if strategy:
filters.append(Trade.strategy == strategy)
trades = pd.DataFrame([(t.pair,
t.open_date.replace(tzinfo=timezone.utc),
t.close_date.replace(tzinfo=timezone.utc) if t.close_date else None,
@@ -123,16 +247,16 @@ def load_trades_from_db(db_url: str) -> pd.DataFrame:
t.stop_loss, t.initial_stop_loss,
t.strategy, t.timeframe
)
for t in Trade.get_trades().all()],
for t in Trade.get_trades(filters).all()],
columns=columns)
return trades
def load_trades(source: str, db_url: str, exportfilename: Path,
no_trades: bool = False) -> pd.DataFrame:
no_trades: bool = False, strategy: Optional[str] = None) -> pd.DataFrame:
"""
Based on configuration option "trade_source":
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
@@ -148,7 +272,7 @@ def load_trades(source: str, db_url: str, exportfilename: Path,
if source == "DB":
return load_trades_from_db(db_url)
elif source == "file":
return load_backtest_data(exportfilename)
return load_backtest_data(exportfilename, strategy)
def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame,
@@ -163,11 +287,31 @@ def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame,
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)]
trades = trades.loc[(trades['open_date'] >= trades_start) &
(trades['close_date'] <= trades_stop)]
return trades
def calculate_market_change(data: Dict[str, pd.DataFrame], column: str = "close") -> float:
"""
Calculate market change based on "column".
Calculation is done by taking the first non-null and the last non-null element of each column
and calculating the pctchange as "(last - first) / first".
Then the results per pair are combined as mean.
:param data: Dict of Dataframes, dict key should be pair.
:param column: Column in the original dataframes to use
:return:
"""
tmp_means = []
for pair, df in data.items():
start = df[column].dropna().iloc[0]
end = df[column].dropna().iloc[-1]
tmp_means.append((end - start) / start)
return np.mean(tmp_means)
def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame],
column: str = "close") -> pd.DataFrame:
"""
@@ -190,7 +334,7 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
"""
Adds a column `col_name` with the cumulative profit for the given trades array.
:param df: DataFrame with date index
:param trades: DataFrame containing trades (requires columns close_time and profit_percent)
:param trades: DataFrame containing trades (requires columns close_date and profit_percent)
: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.
@@ -201,7 +345,7 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
from freqtrade.exchange import timeframe_to_minutes
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'
_trades_sum = trades.resample(f'{timeframe_minutes}min', on='close_date'
)[['profit_percent']].sum()
df.loc[:, col_name] = _trades_sum.cumsum()
# Set first value to 0
@@ -211,13 +355,13 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
return df
def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_time',
def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_date',
value_col: str = 'profit_percent'
) -> Tuple[float, pd.Timestamp, pd.Timestamp]:
"""
Calculate max drawdown and the corresponding close dates
:param trades: DataFrame containing trades (requires columns close_time and profit_percent)
:param date_col: Column in DataFrame to use for dates (defaults to 'close_time')
:param trades: DataFrame containing trades (requires columns close_date and profit_percent)
:param date_col: Column in DataFrame to use for dates (defaults to 'close_date')
:param value_col: Column in DataFrame to use for values (defaults to 'profit_percent')
:return: Tuple (float, highdate, lowdate) with absolute max drawdown, high and low time
:raise: ValueError if trade-dataframe was found empty.

View File

@@ -10,8 +10,8 @@ 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)
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList
logger = logging.getLogger(__name__)
@@ -168,7 +168,7 @@ def trades_remove_duplicates(trades: List[List]) -> List[List]:
return [i for i, _ in itertools.groupby(sorted(trades, key=itemgetter(0)))]
def trades_dict_to_list(trades: List[Dict]) -> List[List]:
def trades_dict_to_list(trades: List[Dict]) -> TradeList:
"""
Convert fetch_trades result into a List (to be more memory efficient).
:param trades: List of trades, as returned by ccxt.fetch_trades.
@@ -177,16 +177,18 @@ def trades_dict_to_list(trades: List[Dict]) -> List[List]:
return [[t[col] for col in DEFAULT_TRADES_COLUMNS] for t in trades]
def trades_to_ohlcv(trades: List, timeframe: str) -> DataFrame:
def trades_to_ohlcv(trades: TradeList, 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.
:raises: ValueError if no trades are provided
"""
from freqtrade.exchange import timeframe_to_minutes
timeframe_minutes = timeframe_to_minutes(timeframe)
if not trades:
raise ValueError('Trade-list empty.')
df = pd.DataFrame(trades, columns=DEFAULT_TRADES_COLUMNS)
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms',
utc=True,)
@@ -255,7 +257,8 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to:
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)
if len(data) > 0:
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

@@ -5,15 +5,16 @@ including ticker and orderbook data, live and historical candle (OHLCV) data
Common Interface for bot and strategy to access data.
"""
import logging
from typing import Any, Dict, List, Optional
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional, Tuple
from pandas import DataFrame
from freqtrade.constants import ListPairsWithTimeframes, PairWithTimeframe
from freqtrade.data.history import load_pair_history
from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.exceptions import ExchangeError, OperationalException
from freqtrade.exchange import Exchange
from freqtrade.state import RunMode
from freqtrade.constants import ListPairsWithTimeframes
logger = logging.getLogger(__name__)
@@ -25,6 +26,24 @@ class DataProvider:
self._config = config
self._exchange = exchange
self._pairlists = pairlists
self.__cached_pairs: Dict[PairWithTimeframe, Tuple[DataFrame, datetime]] = {}
def _set_cached_df(self, pair: str, timeframe: str, dataframe: DataFrame) -> None:
"""
Store cached Dataframe.
Using private method as this should never be used by a user
(but the class is exposed via `self.dp` to the strategy)
:param pair: pair to get the data for
:param timeframe: Timeframe to get data for
:param dataframe: analyzed dataframe
"""
self.__cached_pairs[(pair, timeframe)] = (dataframe, datetime.now(timezone.utc))
def add_pairlisthandler(self, pairlists) -> None:
"""
Allow adding pairlisthandler after initialization
"""
self._pairlists = pairlists
def refresh(self,
pairlist: ListPairsWithTimeframes,
@@ -68,7 +87,8 @@ class DataProvider:
"""
return load_pair_history(pair=pair,
timeframe=timeframe or self._config['timeframe'],
datadir=self._config['datadir']
datadir=self._config['datadir'],
data_format=self._config.get('dataformat_ohlcv', 'json')
)
def get_pair_dataframe(self, pair: str, timeframe: str = None) -> DataFrame:
@@ -89,6 +109,20 @@ class DataProvider:
logger.warning(f"No data found for ({pair}, {timeframe}).")
return data
def get_analyzed_dataframe(self, pair: str, timeframe: str) -> Tuple[DataFrame, datetime]:
"""
:param pair: pair to get the data for
:param timeframe: timeframe to get data for
:return: Tuple of (Analyzed Dataframe, lastrefreshed) for the requested pair / timeframe
combination.
Returns empty dataframe and Epoch 0 (1970-01-01) if no dataframe was cached.
"""
if (pair, timeframe) in self.__cached_pairs:
return self.__cached_pairs[(pair, timeframe)]
else:
return (DataFrame(), datetime.fromtimestamp(0, tz=timezone.utc))
def market(self, pair: str) -> Optional[Dict[str, Any]]:
"""
Return market data for the pair
@@ -105,7 +139,7 @@ class DataProvider:
"""
try:
return self._exchange.fetch_ticker(pair)
except DependencyException:
except ExchangeError:
return {}
def orderbook(self, pair: str, maximum: int) -> Dict[str, List]:

View File

@@ -5,10 +5,8 @@ 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,
# flake8: noqa: F401
from .history_utils import (convert_trades_to_ohlcv, 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
from .idatahandler import get_datahandler

View File

@@ -0,0 +1,213 @@
import logging
import re
from pathlib import Path
from typing import List, Optional
import numpy as np
import pandas as pd
from freqtrade import misc
from freqtrade.configuration import TimeRange
from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS,
ListPairsWithTimeframes, TradeList)
from .idatahandler import IDataHandler
logger = logging.getLogger(__name__)
class HDF5DataHandler(IDataHandler):
_columns = DEFAULT_DATAFRAME_COLUMNS
@classmethod
def ohlcv_get_available_data(cls, datadir: Path) -> ListPairsWithTimeframes:
"""
Returns a list of all pairs with ohlcv data available in this datadir
:param datadir: Directory to search for ohlcv files
:return: List of Tuples of (pair, timeframe)
"""
_tmp = [re.search(r'^([a-zA-Z_]+)\-(\d+\S+)(?=.h5)', p.name)
for p in datadir.glob("*.h5")]
return [(match[1].replace('_', '/'), match[2]) for match in _tmp
if match and len(match.groups()) > 1]
@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 + '.h5)', p.name)
for p in datadir.glob(f"*{timeframe}.h5")]
# 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: pd.DataFrame) -> None:
"""
Store data in hdf5 file.
:param pair: Pair - used to generate filename
:timeframe: Timeframe - used to generate filename
:data: Dataframe containing OHLCV data
:return: None
"""
key = self._pair_ohlcv_key(pair, timeframe)
_data = data.copy()
filename = self._pair_data_filename(self._datadir, pair, timeframe)
ds = pd.HDFStore(filename, mode='a', complevel=9, complib='blosc')
ds.put(key, _data.loc[:, self._columns], format='table', data_columns=['date'])
ds.close()
def _ohlcv_load(self, pair: str, timeframe: str,
timerange: Optional[TimeRange] = None) -> pd.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
"""
key = self._pair_ohlcv_key(pair, timeframe)
filename = self._pair_data_filename(self._datadir, pair, timeframe)
if not filename.exists():
return pd.DataFrame(columns=self._columns)
where = []
if timerange:
if timerange.starttype == 'date':
where.append(f"date >= Timestamp({timerange.startts * 1e9})")
if timerange.stoptype == 'date':
where.append(f"date < Timestamp({timerange.stopts * 1e9})")
pairdata = pd.read_hdf(filename, key=key, mode="r", where=where)
if list(pairdata.columns) != self._columns:
raise ValueError("Wrong dataframe format")
pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float',
'low': 'float', 'close': 'float', 'volume': 'float'})
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: pd.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.h5)', p.name)
for p in datadir.glob("*trades.h5")]
# 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
"""
key = self._pair_trades_key(pair)
ds = pd.HDFStore(self._pair_trades_filename(self._datadir, pair),
mode='a', complevel=9, complib='blosc')
ds.put(key, pd.DataFrame(data, columns=DEFAULT_TRADES_COLUMNS),
format='table', data_columns=['timestamp'])
ds.close()
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 h5 file.
:param pair: Load trades for this pair
:param timerange: Timerange to load trades for - currently not implemented
:return: List of trades
"""
key = self._pair_trades_key(pair)
filename = self._pair_trades_filename(self._datadir, pair)
if not filename.exists():
return []
where = []
if timerange:
if timerange.starttype == 'date':
where.append(f"timestamp >= {timerange.startts * 1e3}")
if timerange.stoptype == 'date':
where.append(f"timestamp < {timerange.stopts * 1e3}")
trades: pd.DataFrame = pd.read_hdf(filename, key=key, mode="r", where=where)
trades[['id', 'type']] = trades[['id', 'type']].replace({np.nan: None})
return trades.values.tolist()
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_ohlcv_key(cls, pair: str, timeframe: str) -> str:
return f"{pair}/ohlcv/tf_{timeframe}"
@classmethod
def _pair_trades_key(cls, pair: str) -> str:
return f"{pair}/trades"
@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}.h5')
return filename
@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.h5')
return filename

View File

@@ -9,14 +9,14 @@ 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.converter import (clean_ohlcv_dataframe, 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__)
@@ -135,7 +135,6 @@ def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optiona
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.
@@ -202,7 +201,10 @@ def _download_pair_history(datadir: Path,
if data.empty:
data = new_dataframe
else:
data = data.append(new_dataframe)
# Run cleaning again to ensure there were no duplicate candles
# Especially between existing and new data.
data = clean_ohlcv_dataframe(data.append(new_dataframe), timeframe, pair,
fill_missing=False, drop_incomplete=False)
logger.debug("New Start: %s",
f"{data.iloc[0]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None')
@@ -212,10 +214,9 @@ def _download_pair_history(datadir: Path,
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}'
except Exception:
logger.exception(
f'Failed to download history data for pair: "{pair}", timeframe: {timeframe}.'
)
return False
@@ -302,10 +303,9 @@ def _download_trades_history(exchange: Exchange,
logger.info(f"New Amount of trades: {len(trades)}")
return True
except Exception as e:
logger.error(
except Exception:
logger.exception(
f'Failed to download historic trades for pair: "{pair}". '
f'Error: {e}'
)
return False
@@ -354,9 +354,12 @@ def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str],
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)
try:
ohlcv = trades_to_ohlcv(trades, timeframe)
# Store ohlcv
data_handler_ohlcv.ohlcv_store(pair, timeframe, data=ohlcv)
except ValueError:
logger.exception(f'Could not convert {pair} to OHLCV.')
def get_timerange(data: Dict[str, DataFrame]) -> Tuple[arrow.Arrow, arrow.Arrow]:

View File

@@ -13,14 +13,12 @@ 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.constants import ListPairsWithTimeframes, TradeList
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]
logger = logging.getLogger(__name__)
class IDataHandler(ABC):
@@ -28,6 +26,14 @@ class IDataHandler(ABC):
def __init__(self, datadir: Path) -> None:
self._datadir = datadir
@abstractclassmethod
def ohlcv_get_available_data(cls, datadir: Path) -> ListPairsWithTimeframes:
"""
Returns a list of all pairs with ohlcv data available in this datadir
:param datadir: Directory to search for ohlcv files
:return: List of Tuples of (pair, timeframe)
"""
@abstractclassmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]:
"""
@@ -41,9 +47,7 @@ class IDataHandler(ABC):
@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>]]
Store ohlcv data.
:param pair: Pair - used to generate filename
:timeframe: Timeframe - used to generate filename
:data: Dataframe containing OHLCV data
@@ -230,6 +234,9 @@ def get_datahandlerclass(datatype: str) -> Type[IDataHandler]:
elif datatype == 'jsongz':
from .jsondatahandler import JsonGzDataHandler
return JsonGzDataHandler
elif datatype == 'hdf5':
from .hdf5datahandler import HDF5DataHandler
return HDF5DataHandler
else:
raise ValueError(f"No datahandler for datatype {datatype} available.")

View File

@@ -8,10 +8,11 @@ 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.constants import DEFAULT_DATAFRAME_COLUMNS, ListPairsWithTimeframes, TradeList
from freqtrade.data.converter import trades_dict_to_list
from .idatahandler import IDataHandler, TradeList
from .idatahandler import IDataHandler
logger = logging.getLogger(__name__)
@@ -21,6 +22,18 @@ class JsonDataHandler(IDataHandler):
_use_zip = False
_columns = DEFAULT_DATAFRAME_COLUMNS
@classmethod
def ohlcv_get_available_data(cls, datadir: Path) -> ListPairsWithTimeframes:
"""
Returns a list of all pairs with ohlcv data available in this datadir
:param datadir: Directory to search for ohlcv files
:return: List of Tuples of (pair, timeframe)
"""
_tmp = [re.search(r'^([a-zA-Z_]+)\-(\d+\S+)(?=.json)', p.name)
for p in datadir.glob(f"*.{cls._get_file_extension()}")]
return [(match[1].replace('_', '/'), match[2]) for match in _tmp
if match and len(match.groups()) > 1]
@classmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]:
"""

View File

@@ -9,11 +9,12 @@ 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.constants import DATETIME_PRINT_FORMAT, UNLIMITED_STAKE_AMOUNT
from freqtrade.data.history import get_timerange, load_data, refresh_data
from freqtrade.exceptions import OperationalException
from freqtrade.strategy.interface import SellType
logger = logging.getLogger(__name__)
@@ -86,7 +87,7 @@ class Edge:
heartbeat = self.edge_config.get('process_throttle_secs')
if (self._last_updated > 0) and (
self._last_updated + heartbeat > arrow.utcnow().timestamp):
self._last_updated + heartbeat > arrow.utcnow().int_timestamp):
return False
data: Dict[str, Any] = {}
@@ -121,12 +122,9 @@ class Edge:
# 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
)
logger.info(f'Measuring data from {min_date.strftime(DATETIME_PRINT_FORMAT)} '
f'up to {max_date.strftime(DATETIME_PRINT_FORMAT)} '
f'({(max_date - min_date).days} days)..')
headers = ['date', 'buy', 'open', 'close', 'sell', 'high', 'low']
trades: list = []
@@ -148,7 +146,7 @@ class Edge:
# 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
self._last_updated = arrow.utcnow().int_timestamp
return True
@@ -240,7 +238,7 @@ class Edge:
# 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['close_date'] - result['open_date']
result['trade_duration'] = result['trade_duration'].map(
lambda x: int(x.total_seconds() / 60))
@@ -281,8 +279,8 @@ class Edge:
#
# 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()])
results = results[results['profit_abs'] < 2 * results['profit_abs'].std()
+ results['profit_abs'].mean()]
##########################################################################
# Removing trades having a duration more than X minutes (set in config)
@@ -312,8 +310,10 @@ class Edge:
# 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']
df['average_win'] = np.where(df['nb_win_trades'] == 0, 0.0,
df['profit_sum'] / df['nb_win_trades'])
df['average_loss'] = np.where(df['nb_loss_trades'] == 0, 0.0,
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']
@@ -430,10 +430,8 @@ class Edge:
'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,
'open_date': date_column[open_trade_index],
'close_date': date_column[exit_index],
'trade_duration': '',
'open_rate': round(open_price, 15),
'close_rate': round(exit_price, 15),

View File

@@ -29,7 +29,14 @@ class PricingError(DependencyException):
"""
class InvalidOrderException(FreqtradeException):
class ExchangeError(DependencyException):
"""
Error raised out of the exchange.
Has multiple Errors to determine the appropriate error.
"""
class InvalidOrderException(ExchangeError):
"""
This is returned when the order is not valid. Example:
If stoploss on exchange order is hit, then trying to cancel the order
@@ -37,7 +44,21 @@ class InvalidOrderException(FreqtradeException):
"""
class TemporaryError(FreqtradeException):
class RetryableOrderError(InvalidOrderException):
"""
This is returned when the order is not found.
This Error will be repeated with increasing backof (in line with DDosError).
"""
class InsufficientFundsError(InvalidOrderException):
"""
This error is used when there are not enough funds available on the exchange
to create an order.
"""
class TemporaryError(ExchangeError):
"""
Temporary network or exchange related error.
This could happen when an exchange is congested, unavailable, or the user
@@ -45,6 +66,13 @@ class TemporaryError(FreqtradeException):
"""
class DDosProtection(TemporaryError):
"""
Temporary error caused by DDOS protection.
Bot will wait for a second and then retry.
"""
class StrategyError(FreqtradeException):
"""
Errors with custom user-code deteced.

View File

@@ -1,20 +1,16 @@
# flake8: noqa: F401
# isort: off
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,
timeframe_to_minutes,
timeframe_to_msecs,
timeframe_to_next_date,
timeframe_to_prev_date)
from freqtrade.exchange.exchange import (market_is_active,
symbol_is_pair)
from freqtrade.exchange.kraken import Kraken
from freqtrade.exchange.binance import Binance
# isort: on
from freqtrade.exchange.bibox import Bibox
from freqtrade.exchange.binance import Binance
from freqtrade.exchange.bittrex import Bittrex
from freqtrade.exchange.exchange import (available_exchanges, ccxt_exchanges,
get_exchange_bad_reason, is_exchange_bad,
is_exchange_known_ccxt, is_exchange_officially_supported,
market_is_active, timeframe_to_minutes, timeframe_to_msecs,
timeframe_to_next_date, timeframe_to_prev_date,
timeframe_to_seconds)
from freqtrade.exchange.ftx import Ftx
from freqtrade.exchange.kraken import Kraken

View File

@@ -4,6 +4,7 @@ from typing import Dict
from freqtrade.exchange import Exchange
logger = logging.getLogger(__name__)

View File

@@ -4,9 +4,11 @@ from typing import Dict
import ccxt
from freqtrade.exceptions import (DependencyException, InvalidOrderException,
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange import Exchange
from freqtrade.exchange.common import retrier
logger = logging.getLogger(__name__)
@@ -18,20 +20,9 @@ class Binance(Exchange):
"order_time_in_force": ['gtc', 'fok', 'ioc'],
"trades_pagination": "id",
"trades_pagination_arg": "fromId",
"l2_limit_range": [5, 10, 20, 50, 100, 500, 1000],
}
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict:
"""
get order book level 2 from exchange
20180619: binance support limits but only on specific range
"""
limit_range = [5, 10, 20, 50, 100, 500, 1000]
# get next-higher step in the limit_range list
limit = min(list(filter(lambda x: limit <= x, limit_range)))
return super().fetch_l2_order_book(pair, limit)
def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool:
"""
Verify stop_loss against stoploss-order value (limit or price)
@@ -39,6 +30,7 @@ class Binance(Exchange):
"""
return order['type'] == 'stop_loss_limit' and stop_loss > float(order['info']['stopPrice'])
@retrier(retries=0)
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
"""
creates a stoploss limit order.
@@ -77,8 +69,8 @@ class Binance(Exchange):
'stop price: %s. limit: %s', pair, stop_price, rate)
return order
except ccxt.InsufficientFunds as e:
raise DependencyException(
f'Insufficient funds to create {ordertype} sell order on market {pair}.'
raise InsufficientFundsError(
f'Insufficient funds to create {ordertype} sell order on market {pair}. '
f'Tried to sell amount {amount} at rate {rate}. '
f'Message: {e}') from e
except ccxt.InvalidOrder as e:
@@ -88,6 +80,8 @@ class Binance(Exchange):
f'Could not create {ordertype} sell order on market {pair}. '
f'Tried to sell amount {amount} at rate {rate}. '
f'Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(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

View File

@@ -0,0 +1,23 @@
""" Bittrex exchange subclass """
import logging
from typing import Dict
from freqtrade.exchange import Exchange
logger = logging.getLogger(__name__)
class Bittrex(Exchange):
"""
Bittrex 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.
"""
_ft_has: Dict = {
"l2_limit_range": [1, 25, 500],
}

View File

@@ -1,17 +1,26 @@
import asyncio
import logging
import time
from functools import wraps
from freqtrade.exceptions import DDosProtection, RetryableOrderError, TemporaryError
from freqtrade.exceptions import TemporaryError
logger = logging.getLogger(__name__)
# Maximum default retry count.
# Functions are always called RETRY_COUNT + 1 times (for the original call)
API_RETRY_COUNT = 4
API_FETCH_ORDER_RETRY_COUNT = 5
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.",
"phemex": "Does not provide history. ",
**dict.fromkeys([
'adara',
'anxpro',
@@ -88,6 +97,13 @@ MAP_EXCHANGE_CHILDCLASS = {
}
def calculate_backoff(retrycount, max_retries):
"""
Calculate backoff
"""
return (max_retries - retrycount) ** 2 + 1
def retrier_async(f):
async def wrapper(*args, **kwargs):
count = kwargs.pop('count', API_RETRY_COUNT)
@@ -96,9 +112,13 @@ def retrier_async(f):
except TemporaryError as ex:
logger.warning('%s() returned exception: "%s"', f.__name__, ex)
if count > 0:
logger.warning('retrying %s() still for %s times', f.__name__, count)
count -= 1
kwargs.update({'count': count})
logger.warning('retrying %s() still for %s times', f.__name__, count)
if isinstance(ex, DDosProtection):
backoff_delay = calculate_backoff(count + 1, API_RETRY_COUNT)
logger.info(f"Applying DDosProtection backoff delay: {backoff_delay}")
await asyncio.sleep(backoff_delay)
return await wrapper(*args, **kwargs)
else:
logger.warning('Giving up retrying: %s()', f.__name__)
@@ -106,19 +126,31 @@ def retrier_async(f):
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
def retrier(_func=None, retries=API_RETRY_COUNT):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
count = kwargs.pop('count', retries)
try:
return f(*args, **kwargs)
except (TemporaryError, RetryableOrderError) as ex:
logger.warning('%s() returned exception: "%s"', f.__name__, ex)
if count > 0:
logger.warning('retrying %s() still for %s times', f.__name__, count)
count -= 1
kwargs.update({'count': count})
if isinstance(ex, DDosProtection) or isinstance(ex, RetryableOrderError):
# increasing backoff
backoff_delay = calculate_backoff(count + 1, retries)
logger.info(f"Applying DDosProtection backoff delay: {backoff_delay}")
time.sleep(backoff_delay)
return wrapper(*args, **kwargs)
else:
logger.warning('Giving up retrying: %s()', f.__name__)
raise ex
return wrapper
# Support both @retrier and @retrier(retries=2) syntax
if _func is None:
return decorator
else:
return decorator(_func)

View File

@@ -8,22 +8,24 @@ import logging
from copy import deepcopy
from datetime import datetime, timezone
from math import ceil
from random import randint
from typing import Any, Dict, List, Optional, Tuple
import arrow
import ccxt
import ccxt.async_support as ccxt_async
from ccxt.base.decimal_to_precision import (ROUND_DOWN, ROUND_UP, TICK_SIZE,
TRUNCATE, decimal_to_precision)
from ccxt.base.decimal_to_precision import (ROUND_DOWN, ROUND_UP, TICK_SIZE, TRUNCATE,
decimal_to_precision)
from pandas import DataFrame
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
from freqtrade.exceptions import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async
from freqtrade.misc import deep_merge_dicts, safe_value_fallback
from freqtrade.constants import ListPairsWithTimeframes
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError,
InvalidOrderException, OperationalException, RetryableOrderError,
TemporaryError)
from freqtrade.exchange.common import (API_FETCH_ORDER_RETRY_COUNT, BAD_EXCHANGES, retrier,
retrier_async)
from freqtrade.misc import deep_merge_dicts, safe_value_fallback2
CcxtModuleType = Any
@@ -51,7 +53,7 @@ class Exchange:
"ohlcv_partial_candle": True,
"trades_pagination": "time", # Possible are "time" or "id"
"trades_pagination_arg": "since",
"l2_limit_range": None,
}
_ft_has: Dict = {}
@@ -84,8 +86,8 @@ class Exchange:
# Deep merge ft_has with default ft_has options
self._ft_has = deep_merge_dicts(self._ft_has, deepcopy(self._ft_has_default))
if exchange_config.get("_ft_has_params"):
self._ft_has = deep_merge_dicts(exchange_config.get("_ft_has_params"),
if exchange_config.get('_ft_has_params'):
self._ft_has = deep_merge_dicts(exchange_config.get('_ft_has_params'),
self._ft_has)
logger.info("Overriding exchange._ft_has with config params, result: %s", self._ft_has)
@@ -122,7 +124,8 @@ class Exchange:
# Check if all pairs are available
self.validate_stakecurrency(config['stake_currency'])
self.validate_pairs(config['exchange']['pair_whitelist'])
if not exchange_config.get('skip_pair_validation'):
self.validate_pairs(config['exchange']['pair_whitelist'])
self.validate_ordertypes(config.get('order_types', {}))
self.validate_order_time_in_force(config.get('order_time_in_force', {}))
self.validate_required_startup_candles(config.get('startup_candle_count', 0))
@@ -186,6 +189,11 @@ class Exchange:
def timeframes(self) -> List[str]:
return list((self._api.timeframes or {}).keys())
@property
def ohlcv_candle_limit(self) -> int:
"""exchange ohlcv candle limit"""
return int(self._ohlcv_candle_limit)
@property
def markets(self) -> Dict:
"""exchange ccxt markets"""
@@ -216,7 +224,7 @@ class Exchange:
if quote_currencies:
markets = {k: v for k, v in markets.items() if v['quote'] in quote_currencies}
if pairs_only:
markets = {k: v for k, v in markets.items() if symbol_is_pair(v['symbol'])}
markets = {k: v for k, v in markets.items() if self.market_is_tradable(v)}
if active_only:
markets = {k: v for k, v in markets.items() if market_is_active(v)}
return markets
@@ -240,6 +248,19 @@ class Exchange:
"""
return self.markets.get(pair, {}).get('base', '')
def market_is_tradable(self, market: Dict[str, Any]) -> bool:
"""
Check if the market symbol is tradable by Freqtrade.
By default, checks if it's splittable by `/` and both sides correspond to base / quote
"""
symbol_parts = market['symbol'].split('/')
return (len(symbol_parts) == 2 and
len(symbol_parts[0]) > 0 and
len(symbol_parts[1]) > 0 and
symbol_parts[0] == market.get('base') and
symbol_parts[1] == market.get('quote')
)
def klines(self, pair_interval: Tuple[str, str], copy: bool = True) -> DataFrame:
if pair_interval in self._klines:
return self._klines[pair_interval].copy() if copy else self._klines[pair_interval]
@@ -252,8 +273,8 @@ class Exchange:
api.urls['api'] = api.urls['test']
logger.info("Enabled Sandbox API on %s", name)
else:
logger.warning(name, "No Sandbox URL in CCXT, exiting. "
"Please check your config.json")
logger.warning(
f"No Sandbox URL in CCXT for {name}, exiting. Please check your config.json")
raise OperationalException(f'Exchange {name} does not provide a sandbox api')
def _load_async_markets(self, reload: bool = False) -> None:
@@ -262,7 +283,7 @@ class Exchange:
asyncio.get_event_loop().run_until_complete(
self._api_async.load_markets(reload=reload))
except ccxt.BaseError as e:
except (asyncio.TimeoutError, ccxt.BaseError) as e:
logger.warning('Could not load async markets. Reason: %s', e)
return
@@ -271,7 +292,7 @@ class Exchange:
try:
self._api.load_markets()
self._load_async_markets()
self._last_markets_refresh = arrow.utcnow().timestamp
self._last_markets_refresh = arrow.utcnow().int_timestamp
except ccxt.BaseError as e:
logger.warning('Unable to initialize markets. Reason: %s', e)
@@ -280,14 +301,14 @@ class Exchange:
# Check whether markets have to be reloaded
if (self._last_markets_refresh > 0) and (
self._last_markets_refresh + self.markets_refresh_interval
> arrow.utcnow().timestamp):
> arrow.utcnow().int_timestamp):
return None
logger.debug("Performing scheduled market reload..")
try:
self._api.load_markets(reload=True)
# Also reload async markets to avoid issues with newly listed pairs
self._load_async_markets(reload=True)
self._last_markets_refresh = arrow.utcnow().timestamp
self._last_markets_refresh = arrow.utcnow().int_timestamp
except ccxt.BaseError:
logger.exception("Could not reload markets.")
@@ -351,7 +372,7 @@ class Exchange:
for pair in [f"{curr_1}/{curr_2}", f"{curr_2}/{curr_1}"]:
if pair in self.markets and self.markets[pair].get('active'):
return pair
raise DependencyException(f"Could not combine {curr_1} and {curr_2} to get a valid pair.")
raise ExchangeError(f"Could not combine {curr_1} and {curr_2} to get a valid pair.")
def validate_timeframes(self, timeframe: Optional[str]) -> None:
"""
@@ -468,18 +489,20 @@ class Exchange:
def dry_run_order(self, pair: str, ordertype: str, side: str, amount: float,
rate: float, params: Dict = {}) -> Dict[str, Any]:
order_id = f'dry_run_{side}_{randint(0, 10**6)}'
order_id = f'dry_run_{side}_{datetime.now().timestamp()}'
_amount = self.amount_to_precision(pair, amount)
dry_order = {
"id": order_id,
'pair': pair,
'id': order_id,
'symbol': pair,
'price': rate,
'average': rate,
'amount': _amount,
'cost': _amount * rate,
'type': ordertype,
'side': side,
'remaining': _amount,
'datetime': arrow.utcnow().isoformat(),
'timestamp': int(arrow.utcnow().int_timestamp * 1000),
'status': "closed" if ordertype == "market" else "open",
'fee': None,
'info': {}
@@ -501,7 +524,7 @@ class Exchange:
'rate': self.get_fee(pair)
}
})
if closed_order["type"] in ["stop_loss_limit"]:
if closed_order["type"] in ["stop_loss_limit", "stop-loss-limit"]:
closed_order["info"].update({"stopPrice": closed_order["price"]})
self._dry_run_open_orders[closed_order["id"]] = closed_order
@@ -518,15 +541,17 @@ class Exchange:
amount, rate_for_order, params)
except ccxt.InsufficientFunds as e:
raise DependencyException(
f'Insufficient funds to create {ordertype} {side} order on market {pair}.'
raise InsufficientFundsError(
f'Insufficient funds to create {ordertype} {side} order on market {pair}. '
f'Tried to {side} amount {amount} at rate {rate}.'
f'Message: {e}') from e
except ccxt.InvalidOrder as e:
raise DependencyException(
f'Could not create {ordertype} {side} order on market {pair}.'
f'Tried to {side} amount {amount} at rate {rate}.'
raise ExchangeError(
f'Could not create {ordertype} {side} order on market {pair}. '
f'Tried to {side} amount {amount} at rate {rate}. '
f'Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not place {side} order due to {e.__class__.__name__}. Message: {e}') from e
@@ -606,6 +631,8 @@ class Exchange:
balances.pop("used", None)
return balances
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not get balance due to {e.__class__.__name__}. Message: {e}') from e
@@ -620,6 +647,8 @@ class Exchange:
raise OperationalException(
f'Exchange {self._api.name} does not support fetching tickers in batch. '
f'Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not load tickers due to {e.__class__.__name__}. Message: {e}') from e
@@ -630,9 +659,11 @@ class Exchange:
def fetch_ticker(self, pair: str) -> dict:
try:
if pair not in self._api.markets or not self._api.markets[pair].get('active'):
raise DependencyException(f"Pair {pair} not available")
raise ExchangeError(f"Pair {pair} not available")
data = self._api.fetch_ticker(pair)
return data
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not load ticker due to {e.__class__.__name__}. Message: {e}') from e
@@ -648,15 +679,31 @@ class Exchange:
:param pair: Pair to download
:param timeframe: Timeframe to get data for
:param since_ms: Timestamp in milliseconds to get history from
:returns List with candle (OHLCV) data
:return: List with candle (OHLCV) data
"""
return asyncio.get_event_loop().run_until_complete(
self._async_get_historic_ohlcv(pair=pair, timeframe=timeframe,
since_ms=since_ms))
def get_historic_ohlcv_as_df(self, pair: str, timeframe: str,
since_ms: int) -> DataFrame:
"""
Minimal wrapper around get_historic_ohlcv - converting the result into a dataframe
:param pair: Pair to download
:param timeframe: Timeframe to get data for
:param since_ms: Timestamp in milliseconds to get history from
:return: OHLCV DataFrame
"""
ticks = self.get_historic_ohlcv(pair, timeframe, since_ms=since_ms)
return ohlcv_to_dataframe(ticks, timeframe, pair=pair, fill_missing=True,
drop_incomplete=self._ohlcv_partial_candle)
async def _async_get_historic_ohlcv(self, pair: str,
timeframe: str,
since_ms: int) -> List:
"""
Download historic ohlcv
"""
one_call = timeframe_to_msecs(timeframe) * self._ohlcv_candle_limit
logger.debug(
@@ -666,15 +713,20 @@ class Exchange:
)
input_coroutines = [self._async_get_candle_history(
pair, timeframe, since) for since in
range(since_ms, arrow.utcnow().timestamp * 1000, one_call)]
range(since_ms, arrow.utcnow().int_timestamp * 1000, one_call)]
results = await asyncio.gather(*input_coroutines, return_exceptions=True)
# Combine gathered results
data: List = []
for p, timeframe, res in results:
for res in results:
if isinstance(res, Exception):
logger.warning("Async code raised an exception: %s", res.__class__.__name__)
continue
# Deconstruct tuple if it's not an exception
p, _, new_data = res
if p == pair:
data.extend(res)
data.extend(new_data)
# Sort data again after extending the result - above calls return in "async order"
data = sorted(data, key=lambda x: x[0])
logger.info("Downloaded data for %s with length %s.", pair, len(data))
@@ -711,9 +763,8 @@ class Exchange:
if isinstance(res, Exception):
logger.warning("Async code raised an exception: %s", res.__class__.__name__)
continue
pair = res[0]
timeframe = res[1]
ticks = res[2]
# Deconstruct tuple (has 3 elements)
pair, timeframe, ticks = res
# keeping last candle time as last refreshed time of the pair
if ticks:
self._pairs_last_refresh_time[(pair, timeframe)] = ticks[-1][0] // 1000
@@ -729,7 +780,7 @@ class Exchange:
interval_in_sec = timeframe_to_seconds(timeframe)
return not ((self._pairs_last_refresh_time.get((pair, timeframe), 0)
+ interval_in_sec) >= arrow.utcnow().timestamp)
+ interval_in_sec) >= arrow.utcnow().int_timestamp)
@retrier_async
async def _async_get_candle_history(self, pair: str, timeframe: str,
@@ -766,6 +817,8 @@ class Exchange:
raise OperationalException(
f'Exchange {self._api.name} does not support fetching historical '
f'candle (OHLCV) data. Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(f'Could not fetch historical candle (OHLCV) data '
f'for pair {pair} due to {e.__class__.__name__}. '
@@ -802,6 +855,8 @@ class Exchange:
raise OperationalException(
f'Exchange {self._api.name} does not support fetching historical trade data.'
f'Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(f'Could not load trade history due to {e.__class__.__name__}. '
f'Message: {e}') from e
@@ -933,7 +988,7 @@ class Exchange:
def check_order_canceled_empty(self, order: Dict) -> bool:
"""
Verify if an order has been cancelled without being partially filled
:param order: Order dict as returned from get_order()
:param order: Order dict as returned from fetch_order()
:return: True if order has been cancelled without being filled, False otherwise.
"""
return order.get('status') in ('closed', 'canceled') and order.get('filled') == 0.0
@@ -941,20 +996,27 @@ class Exchange:
@retrier
def cancel_order(self, order_id: str, pair: str) -> Dict:
if self._config['dry_run']:
return {}
order = self._dry_run_open_orders.get(order_id)
if order:
order.update({'status': 'canceled', 'filled': 0.0, 'remaining': order['amount']})
return order
else:
return {}
try:
return self._api.cancel_order(order_id, pair)
except ccxt.InvalidOrder as e:
raise InvalidOrderException(
f'Could not cancel order. Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not cancel order due to {e.__class__.__name__}. Message: {e}') from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
# Assign method to get_stoploss_order to allow easy overriding in other classes
# Assign method to cancel_stoploss_order to allow easy overriding in other classes
cancel_stoploss_order = cancel_order
def is_cancel_order_result_suitable(self, corder) -> bool:
@@ -968,7 +1030,7 @@ class Exchange:
"""
Cancel order returning a result.
Creates a fake result if cancel order returns a non-usable result
and get_order does not work (certain exchanges don't return cancelled orders)
and fetch_order does not work (certain exchanges don't return cancelled orders)
:param order_id: Orderid to cancel
:param pair: Pair corresponding to order_id
:param amount: Amount to use for fake response
@@ -979,17 +1041,17 @@ class Exchange:
if self.is_cancel_order_result_suitable(corder):
return corder
except InvalidOrderException:
logger.warning(f"Could not cancel order {order_id}.")
logger.warning(f"Could not cancel order {order_id} for {pair}.")
try:
order = self.get_order(order_id, pair)
order = self.fetch_order(order_id, pair)
except InvalidOrderException:
logger.warning(f"Could not fetch cancelled order {order_id}.")
order = {'fee': {}, 'status': 'canceled', 'amount': amount, 'info': {}}
return order
@retrier
def get_order(self, order_id: str, pair: str) -> Dict:
@retrier(retries=API_FETCH_ORDER_RETRY_COUNT)
def fetch_order(self, order_id: str, pair: str) -> Dict:
if self._config['dry_run']:
try:
order = self._dry_run_open_orders[order_id]
@@ -1000,33 +1062,62 @@ class Exchange:
f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e
try:
return self._api.fetch_order(order_id, pair)
except ccxt.OrderNotFound as e:
raise RetryableOrderError(
f'Order not found (pair: {pair} id: {order_id}). Message: {e}') from e
except ccxt.InvalidOrder as e:
raise InvalidOrderException(
f'Tried to get an invalid order (id: {order_id}). Message: {e}') from e
f'Tried to get an invalid order (pair: {pair} id: {order_id}). Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not get order due to {e.__class__.__name__}. Message: {e}') from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
# Assign method to get_stoploss_order to allow easy overriding in other classes
get_stoploss_order = get_order
# Assign method to fetch_stoploss_order to allow easy overriding in other classes
fetch_stoploss_order = fetch_order
def fetch_order_or_stoploss_order(self, order_id: str, pair: str,
stoploss_order: bool = False) -> Dict:
"""
Simple wrapper calling either fetch_order or fetch_stoploss_order depending on
the stoploss_order parameter
:param stoploss_order: If true, uses fetch_stoploss_order, otherwise fetch_order.
"""
if stoploss_order:
return self.fetch_stoploss_order(order_id, pair)
return self.fetch_order(order_id, pair)
@staticmethod
def get_next_limit_in_list(limit: int, limit_range: Optional[List[int]]):
"""
Get next greater value in the list.
Used by fetch_l2_order_book if the api only supports a limited range
"""
if not limit_range:
return limit
return min([x for x in limit_range if limit <= x] + [max(limit_range)])
@retrier
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict:
"""
get order book level 2 from exchange
Notes:
20180619: bittrex doesnt support limits -.-
Get L2 order book from exchange.
Can be limited to a certain amount (if supported).
Returns a dict in the format
{'asks': [price, volume], 'bids': [price, volume]}
"""
limit1 = self.get_next_limit_in_list(limit, self._ft_has['l2_limit_range'])
try:
return self._api.fetch_l2_order_book(pair, limit)
return self._api.fetch_l2_order_book(pair, limit1)
except ccxt.NotSupported as e:
raise OperationalException(
f'Exchange {self._api.name} does not support fetching order book.'
f'Message: {e}') from e
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not get order book due to {e.__class__.__name__}. Message: {e}') from e
@@ -1063,7 +1154,8 @@ class Exchange:
matched_trades = [trade for trade in my_trades if trade['order'] == order_id]
return matched_trades
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not get trades due to {e.__class__.__name__}. Message: {e}') from e
@@ -1080,6 +1172,8 @@ class Exchange:
return self._api.calculate_fee(symbol=symbol, type=type, side=side, amount=amount,
price=price, takerOrMaker=taker_or_maker)['rate']
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') from e
@@ -1114,7 +1208,7 @@ class Exchange:
if fee_curr in self.get_pair_base_currency(order['symbol']):
# Base currency - divide by amount
return round(
order['fee']['cost'] / safe_value_fallback(order, order, 'filled', 'amount'), 8)
order['fee']['cost'] / safe_value_fallback2(order, order, 'filled', 'amount'), 8)
elif fee_curr in self.get_pair_quote_currency(order['symbol']):
# Quote currency - divide by cost
return round(order['fee']['cost'] / order['cost'], 8) if order['cost'] else None
@@ -1127,9 +1221,9 @@ class Exchange:
comb = self.get_valid_pair_combination(fee_curr, self._config['stake_currency'])
tick = self.fetch_ticker(comb)
fee_to_quote_rate = safe_value_fallback(tick, tick, 'last', 'ask')
fee_to_quote_rate = safe_value_fallback2(tick, tick, 'last', 'ask')
return round((order['fee']['cost'] * fee_to_quote_rate) / order['cost'], 8)
except DependencyException:
except ExchangeError:
return None
def extract_cost_curr_rate(self, order: Dict) -> Tuple[float, str, Optional[float]]:
@@ -1142,7 +1236,6 @@ class Exchange:
return (order['fee']['cost'],
order['fee']['currency'],
self.calculate_fee_rate(order))
# calculate rate ? (order['fee']['cost'] / (order['amount'] * order['price']))
def is_exchange_bad(exchange_name: str) -> bool:
@@ -1228,20 +1321,6 @@ def timeframe_to_next_date(timeframe: str, date: datetime = None) -> datetime:
return datetime.fromtimestamp(new_timestamp, tz=timezone.utc)
def symbol_is_pair(market_symbol: str, base_currency: str = None,
quote_currency: str = None) -> bool:
"""
Check if the market symbol is a pair, i.e. that its symbol consists of the base currency and the
quote currency separated by '/' character. If base_currency and/or quote_currency is passed,
it also checks that the symbol contains appropriate base and/or quote currency part before
and after the separating character correspondingly.
"""
symbol_parts = market_symbol.split('/')
return (len(symbol_parts) == 2 and
(symbol_parts[0] == base_currency if base_currency else len(symbol_parts[0]) > 0) and
(symbol_parts[1] == quote_currency if quote_currency else len(symbol_parts[1]) > 0))
def market_is_active(market: Dict) -> bool:
"""
Return True if the market is active.

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