Compare commits

...

1162 Commits

Author SHA1 Message Date
Matthias
38b96f071f Merge pull request #4434 from freqtrade/new_release
New release 2020.2
2021-02-24 19:27:43 +01:00
Matthias
834f00f580 Refresh slack link 2021-02-24 06:46:07 +01:00
Matthias
aea8f05d10 Version bump 2021.2 2021-02-24 06:39:59 +01:00
Matthias
cae67b02df Merge branch 'stable' into new_release 2021-02-24 06:39:51 +01:00
Matthias
d6d8678fd6 Fix missleading FAQ information 2021-02-24 06:34:10 +01:00
Matthias
133562ba06 Merge pull request #4428 from freqtrade/dependabot/pip/develop/ccxt-1.42.19
Bump ccxt from 1.41.90 to 1.42.19
2021-02-22 22:01:38 +01:00
Matthias
e8794e8b8c Merge pull request #4429 from freqtrade/dependabot/pip/develop/tabulate-0.8.9
Bump tabulate from 0.8.8 to 0.8.9
2021-02-22 21:59:44 +01:00
dependabot[bot]
3612c786b5 Bump tabulate from 0.8.8 to 0.8.9
Bumps [tabulate](https://github.com/astanin/python-tabulate) from 0.8.8 to 0.8.9.
- [Release notes](https://github.com/astanin/python-tabulate/releases)
- [Changelog](https://github.com/astanin/python-tabulate/blob/master/CHANGELOG)
- [Commits](https://github.com/astanin/python-tabulate/compare/v0.8.8...v0.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 19:06:39 +00:00
dependabot[bot]
a0fa1e84fc Bump ccxt from 1.41.90 to 1.42.19
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.41.90 to 1.42.19.
- [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.41.90...1.42.19)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 19:06:36 +00:00
Matthias
c71ecd3680 Fix wrong pair-content in strategy-analysis notebook and documentation
closes #4399
2021-02-22 20:04:36 +01:00
Matthias
2b5f1ff256 Merge pull request #4426 from freqtrade/fix/4405
Don't fail API calls when live price is not available
2021-02-22 14:09:20 +01:00
Matthias
228e51b60b Fix #4405 2021-02-22 13:34:52 +01:00
Matthias
5e4730b73b Add test confirming #4405 2021-02-22 11:44:39 +01:00
Matthias
62885166a9 Merge pull request #4424 from freqtrade/dependabot/docker/python-3.9.2-slim-buster
Bump python from 3.9.1-slim-buster to 3.9.2-slim-buster
2021-02-22 08:43:54 +01:00
Matthias
21933a55f7 Merge pull request #4423 from freqtrade/dependabot/pip/develop/cryptography-3.4.6
Bump cryptography from 3.4.5 to 3.4.6
2021-02-22 08:23:19 +01:00
Matthias
8a62bfa0e5 armhf image should not be updated to python3.9 2021-02-22 08:20:45 +01:00
Matthias
8ffeafd2c3 Merge pull request #4422 from freqtrade/dependabot/pip/develop/scipy-1.6.1
Bump scipy from 1.6.0 to 1.6.1
2021-02-22 08:19:12 +01:00
Matthias
e34d8cba0e Merge pull request #4421 from freqtrade/dependabot/pip/develop/uvicorn-0.13.4
Bump uvicorn from 0.13.3 to 0.13.4
2021-02-22 08:02:16 +01:00
dependabot[bot]
d8c7e5ce8d Bump python from 3.9.1-slim-buster to 3.9.2-slim-buster
Bumps python from 3.9.1-slim-buster to 3.9.2-slim-buster.

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 05:56:25 +00:00
Matthias
6feabd51a2 Merge pull request #4418 from freqtrade/dependabot/pip/develop/python-telegram-bot-13.3
Bump python-telegram-bot from 13.2 to 13.3
2021-02-22 06:48:25 +01:00
Matthias
d7cc86735b Merge pull request #4417 from freqtrade/dependabot/pip/develop/tabulate-0.8.8
Bump tabulate from 0.8.7 to 0.8.8
2021-02-22 06:47:57 +01:00
dependabot[bot]
85f12f8c28 Bump cryptography from 3.4.5 to 3.4.6
Bumps [cryptography](https://github.com/pyca/cryptography) from 3.4.5 to 3.4.6.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/3.4.5...3.4.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 05:27:57 +00:00
dependabot[bot]
dea04c6452 Bump scipy from 1.6.0 to 1.6.1
Bumps [scipy](https://github.com/scipy/scipy) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.6.0...v1.6.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 05:27:54 +00:00
dependabot[bot]
932aabd012 Bump uvicorn from 0.13.3 to 0.13.4
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.13.3 to 0.13.4.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.13.3...0.13.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 05:27:51 +00:00
dependabot[bot]
8c398acc09 Bump python-telegram-bot from 13.2 to 13.3
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 13.2 to 13.3.
- [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/v13.2...v13.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 05:27:42 +00:00
dependabot[bot]
ab74c6e771 Bump tabulate from 0.8.7 to 0.8.8
Bumps [tabulate](https://github.com/astanin/python-tabulate) from 0.8.7 to 0.8.8.
- [Release notes](https://github.com/astanin/python-tabulate/releases)
- [Changelog](https://github.com/astanin/python-tabulate/blob/master/CHANGELOG)
- [Commits](https://github.com/astanin/python-tabulate/compare/v0.8.7...v0.8.8)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-22 05:27:41 +00:00
Matthias
95fcb1eb27 Merge pull request #4415 from The-smooth-operator/develop
Fix example in storing-information docs
2021-02-21 19:34:11 +01:00
Alberto del Barrio
188d7aaf8c Fix example in storing-information docs 2021-02-21 18:50:11 +01:00
Matthias
3629892fc3 Stoploss-guard should use the trade_limit or more
fix #4404
2021-02-20 19:38:44 +01:00
Matthias
245e39e523 dry-run should be a bool, not a string 2021-02-20 19:17:26 +01:00
Matthias
4e5f8478b1 Merge pull request #4394 from JoeSchr/develop
fix(doc/plotting): misplaced comma in example code
2021-02-18 17:43:53 +01:00
JoeSchr
c9688f1c89 fix(doc/plotting): misplaced comma in example code 2021-02-18 17:30:29 +01:00
Matthias
2b0d2070d0 Avoid crash with /delete
When a trade is deleted between querying the database and actually
handling the trade.

closes #4326
2021-02-18 12:49:14 +01:00
Matthias
327c23618f Improve documentation for get_analyzed_dataframe 2021-02-18 09:30:35 +01:00
Matthias
b5a9ce2894 Download data in the right format as well ...
closes #4393
2021-02-18 09:26:35 +01:00
Matthias
87dc1d3955 Explicitly push tag and tag_plot images 2021-02-17 20:52:25 +01:00
Matthias
fedbb5c0c4 Remove last flask occurance from setup.py
fixes #4390
2021-02-17 20:47:11 +01:00
Matthias
11b20d6932 Add config to hyperopt_loss_function documentation 2021-02-17 07:04:29 +01:00
Matthias
eff0d46ea1 Merge pull request #4375 from flomerz/pass_processed_data
pass data and config to loss function
2021-02-16 20:06:50 +01:00
Matthias
009a447d8a Adjust documentation for new parameter in loss functions 2021-02-16 19:51:09 +01:00
Florian Merz
3e06cd8b3a pass data and config to loss function 2021-02-16 10:11:33 +01:00
Matthias
a97a5a7ca8 Merge pull request #4372 from freqtrade/dependabot/pip/develop/cryptography-3.4.5
Bump cryptography from 3.3.2 to 3.4.5
2021-02-15 14:24:37 +01:00
dependabot[bot]
bc188907b8 Bump cryptography from 3.3.2 to 3.4.5
Bumps [cryptography](https://github.com/pyca/cryptography) from 3.3.2 to 3.4.5.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/3.3.2...3.4.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-15 08:46:46 +00:00
Matthias
eab1d298bc Merge pull request #4374 from freqtrade/dependabot/pip/develop/ccxt-1.41.90
Bump ccxt from 1.41.70 to 1.41.90
2021-02-15 09:45:44 +01:00
dependabot[bot]
5f25139348 Bump ccxt from 1.41.70 to 1.41.90
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.41.70 to 1.41.90.
- [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.41.70...1.41.90)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-15 08:18:04 +00:00
Matthias
1a3e7191ed Merge pull request #4116 from squat0001/develop-squat
Develop squat
2021-02-15 07:15:11 +01:00
Matthias
833e2768e6 Merge pull request #4371 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.16
Bump prompt-toolkit from 3.0.14 to 3.0.16
2021-02-15 06:59:37 +01:00
Matthias
86fdc3016c Merge pull request #4369 from freqtrade/dependabot/pip/develop/joblib-1.0.1
Bump joblib from 1.0.0 to 1.0.1
2021-02-15 06:46:49 +01:00
Matthias
4503fd0790 Merge pull request #4370 from freqtrade/dependabot/pip/develop/pandas-1.2.2
Bump pandas from 1.2.1 to 1.2.2
2021-02-15 06:45:29 +01:00
dependabot[bot]
dbef5425c5 Bump prompt-toolkit from 3.0.14 to 3.0.16
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.14 to 3.0.16.
- [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.14...3.0.16)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-15 05:27:12 +00:00
dependabot[bot]
d08572ea0d Bump pandas from 1.2.1 to 1.2.2
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.2.1 to 1.2.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.2.1...v1.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-15 05:27:05 +00:00
dependabot[bot]
44cb206688 Bump joblib from 1.0.0 to 1.0.1
Bumps [joblib](https://github.com/joblib/joblib) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/joblib/joblib/releases)
- [Changelog](https://github.com/joblib/joblib/blob/master/CHANGES.rst)
- [Commits](https://github.com/joblib/joblib/compare/1.0.0...1.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-15 05:27:01 +00:00
Matthias
1a166f639d Add test for calcuate_csum 2021-02-14 19:44:13 +01:00
Florian Reitmeir
5c263c7ffd add backtesting results abs profit min/abs profit max, to get a better view if a strategy has a enough money to succeed 2021-02-14 19:41:12 +01:00
Matthias
f82dd55153 Merge pull request #4367 from freqtrade/fix/4181
ohlcv_candle_limit per timeframe
2021-02-14 19:32:05 +01:00
Matthias
ee74bc1f52 timeframe is mandatory, no need to use .get() 2021-02-14 11:01:12 +01:00
Matthias
ffca09bbcb Test ohlcv_candle_limit explicitly 2021-02-14 10:38:49 +01:00
Matthias
da89838b5c Set bittrex limits as returned by the exchange
closes #4181
2021-02-14 10:32:55 +01:00
Matthias
5622bb3247 Make candle_limit optionally timeframe dependent 2021-02-14 10:29:45 +01:00
Matthias
7ecf8f8b80 Cleanup candle_limit usage 2021-02-14 10:08:05 +01:00
Matthias
10a11bda34 Document bitvavo as community tested
closes #4360
2021-02-14 09:42:25 +01:00
Matthias
6f77ec063e Fix cookieError on python<3.8
Only occurs in combination with api-server enabled,
due to some hot-fixing starlette does.
Since we load starlette at a later point, we need to replicate
starlette's behaviour for now, so sameSite cookies don't create a
problem.

closes #4356
2021-02-14 07:22:08 +01:00
Matthias
73d91275c4 Reset sell_order_status if a new sell-order is placed
closes #4365
2021-02-14 07:11:07 +01:00
Matthias
4b5f4aa1c1 Merge pull request #4361 from freqtrade/format_currencies
Format currencies
2021-02-13 19:23:23 +01:00
Matthias
d4c8be915c Use fstring where possible 2021-02-13 16:11:49 +01:00
Matthias
e7acee7904 Improve coin value output by rounding coin specific 2021-02-13 16:05:56 +01:00
Matthias
072abde9b7 Introduce round_coin_value to simplify coin rounding 2021-02-13 16:05:35 +01:00
Matthias
dd23f6bcbc Fix type for getting pairs 2021-02-11 20:29:31 +01:00
Matthias
843fb204e9 Fix problem with inf values returned from dataframe for api methods 2021-02-11 20:21:31 +01:00
Matthias
aa79574c0c Position-size should NEVER be over available_capital
Part of #4353
2021-02-11 17:09:31 +01:00
Matthias
3110d2dbb1 Add small test cases 2021-02-09 20:09:10 +01:00
Matthias
86fa75b286 Pin version of cryptography 2021-02-09 06:55:36 +01:00
Matthias
7ee149da5d Improve plotting errorhandling
closes #4327
2021-02-08 20:08:32 +01:00
Matthias
427d762746 Improve tests for cancel_order to be more realistic 2021-02-08 19:37:24 +01:00
Matthias
c5ab3a80a5 Check if order is a dict before parsing
closes #4331
2021-02-08 19:35:22 +01:00
Matthias
de727645ab FIx random test failure if certain files exist 2021-02-08 19:21:33 +01:00
Matthias
afaac92685 Merge pull request #4337 from freqtrade/dependabot/pip/develop/python-telegram-bot-13.2
Bump python-telegram-bot from 13.1 to 13.2
2021-02-08 09:46:10 +01:00
Matthias
48e203f6a4 Merge pull request #4338 from freqtrade/dependabot/pip/develop/ccxt-1.41.70
Bump ccxt from 1.41.62 to 1.41.70
2021-02-08 09:45:49 +01:00
Matthias
f999366bf5 Merge pull request #4333 from freqtrade/dependabot/pip/develop/py-find-1st-1.1.5
Bump py-find-1st from 1.1.4 to 1.1.5
2021-02-08 09:45:20 +01:00
dependabot[bot]
c412f8df62 Bump python-telegram-bot from 13.1 to 13.2
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 13.1 to 13.2.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v13.1...v13.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-08 08:28:11 +00:00
dependabot[bot]
12168cbf01 Bump ccxt from 1.41.62 to 1.41.70
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.41.62 to 1.41.70.
- [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.41.62...1.41.70)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-08 08:26:18 +00:00
Matthias
0850145b3d Merge pull request #4334 from freqtrade/dependabot/pip/develop/numpy-1.20.1
Bump numpy from 1.20.0 to 1.20.1
2021-02-08 08:22:30 +01:00
Matthias
9821d3a554 Merge pull request #4335 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.23
Bump sqlalchemy from 1.3.22 to 1.3.23
2021-02-08 08:21:46 +01:00
Matthias
d681565756 Merge pull request #4336 from freqtrade/dependabot/pip/develop/mkdocs-material-6.2.8
Bump mkdocs-material from 6.2.7 to 6.2.8
2021-02-08 08:21:22 +01:00
dependabot[bot]
22d447b3f5 Bump mkdocs-material from 6.2.7 to 6.2.8
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.2.7 to 6.2.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/6.2.7...6.2.8)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-08 05:27:46 +00:00
dependabot[bot]
676cd7bb55 Bump sqlalchemy from 1.3.22 to 1.3.23
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.22 to 1.3.23.
- [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>
2021-02-08 05:27:45 +00:00
dependabot[bot]
dd7f9181c5 Bump numpy from 1.20.0 to 1.20.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.20.0 to 1.20.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.20.0...v1.20.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-08 05:27:44 +00:00
dependabot[bot]
d1bb46bed0 Bump py-find-1st from 1.1.4 to 1.1.5
Bumps [py-find-1st](https://github.com/roebel/py_find_1st) from 1.1.4 to 1.1.5.
- [Release notes](https://github.com/roebel/py_find_1st/releases)
- [Commits](https://github.com/roebel/py_find_1st/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-08 05:27:42 +00:00
Matthias
f6cdc6d9a2 Merge pull request #4325 from freqtrade/refresh_order_skip
Refresh order skip
2021-02-07 08:23:22 +01:00
Matthias
4cb67f140a Merge pull request #4323 from eselskas/patch-2
Fix sample strategy documentation link
2021-02-06 20:17:20 +01:00
Edvinas Selskas
694f55c0a5 Use suggested link 2021-02-06 14:43:50 +00:00
Matthias
d5cf837c0f Parse regular cancel_order call to update orders table 2021-02-06 09:23:10 +01:00
Matthias
729e773353 Merge pull request #4319 from JoeSchr/patch-2
Update data-download.md
2021-02-06 09:11:49 +01:00
Edvinas Selskas
bc8fda8d63 Update sample_strategy.py
Fix test
2021-02-06 03:13:53 +00:00
Edvinas Selskas
0a43988f3f Fix sample strategy documentation link
Noticed that the current link is dead. I think this would be the most appropriate link in this case.
2021-02-06 03:02:37 +00:00
Matthias
aec22c5c3d introduce skip_open_order_update parameter
skips startup-open-order-update
closes #4128
2021-02-05 20:17:53 +01:00
Matthias
86a97988c0 Improve wording 2021-02-05 20:09:13 +01:00
Matthias
0806202d47 ccxt version bump to 1.41.62 2021-02-05 20:02:55 +01:00
Matthias
2c71b3b118 Merge pull request #4309 from freqtrade/extract_stake_amount
Move get_trade_stake_amount to wallets
2021-02-05 19:47:30 +01:00
Matthias
545a94f360 Merge pull request #4321 from JoeSchr/fix/lint-binance-example-config
chore(lint): lint binance example config
2021-02-05 14:58:24 +01:00
Joe Schr
a816fb1245 chore(lint): lint binance example config 2021-02-05 12:43:19 +01:00
Matthias
1310a7b547 Fix bug with wrong conversion for BTCST/BTC
This can happen if a pair starts with the stake-currency

closes #4307
2021-02-04 19:58:44 +01:00
Matthias
17e1cfbd43 Merge pull request #4313 from raoulbuzziol/develop
setting resize_keyboard=True for slightly smaller Telegram buttons
2021-02-04 19:42:45 +01:00
JoeSchr
428d2af312 add sudo to chown
that was the whole point d'oh
2021-02-04 19:39:25 +01:00
JoeSchr
5165357f40 Update data-download.md
Fix wrong path
Add section about fixing wrong docker permission, if user_data is created by docker, it's permission are set to `root`
2021-02-04 19:36:04 +01:00
Matthias
19e43e2e9d Merge pull request #4314 from JoeSchr/patch-1
Update README.md
2021-02-04 17:34:23 +01:00
JoeSchr
5cd8745997 Update README.md
Typo playing -> paying
2021-02-04 16:26:03 +01:00
raoulus
99b2214d1f setting resize_keyboard=True for slightly smaller Telegram buttons 2021-02-04 15:27:18 +01:00
Matthias
e8e5acc2e2 Fix import in strategy template 2021-02-03 20:15:08 +01:00
Matthias
024849d844 Merge pull request #4285 from freqtrade/ui_deploy
Deploy FreqUI into webserver
2021-02-03 20:09:31 +01:00
Matthias
b8cb39462c Move get_trade_stake_amount to wallets
this way it can be easier used by other functions
2021-02-03 20:00:33 +01:00
Matthias
6c87c49871 Merge pull request #4306 from The-smooth-operator/docs
Fix documentation links pointing to pairlists
2021-02-03 19:30:20 +01:00
Alberto del Barrio
f36c61e32f Fix documentation links pointing to pairlists 2021-02-03 18:12:48 +01:00
Matthias
caa3e1a7fa Merge pull request #4301 from freqtrade/doc_reorg
Doc reorg
2021-02-03 12:02:05 +01:00
Matthias
de72734076 Merge pull request #4302 from mobrine1/patch-1
#4289 printing json output
2021-02-03 10:13:44 +01:00
mobrine1
06b56544a8 printing json by default now 2021-02-03 03:27:54 -05:00
mobrine1
56569690d9 Update rest_client.py 2021-02-02 15:59:48 -05:00
mobrine1
12bcbf4374 #4289 printing json output
Adding --json flag to print json output
2021-02-02 15:40:33 -05:00
Matthias
cd41d11b85 Merge pull request #4300 from freqtrade/extract_get_min_stake_amount
Extract min stake amount from bot to exchange class
2021-02-02 20:28:35 +01:00
Matthias
43986d3f73 Move Pricing to subpage 2021-02-02 20:26:01 +01:00
Matthias
b41078cc46 Don't include plugin documentation in Configuration page 2021-02-02 20:23:30 +01:00
Matthias
dabe456d65 Improve wording of configuration doc
remove unneeded sections
2021-02-02 20:20:34 +01:00
Matthias
3e3c9e99c7 Move command references to their respective subpages 2021-02-02 20:03:28 +01:00
Matthias
f0532f28cf Small doc-reorg adding "advanced topics" as main header 2021-02-02 20:03:01 +01:00
Matthias
cfd0bb8964 Extract min stake amount from bot to exchange class 2021-02-02 19:47:21 +01:00
Matthias
fa8156b321 Merge pull request #4282 from pan-long/patch-1
Fix a bug when compare sell_profit_offset
2021-02-02 08:22:38 +01:00
Matthias
3d9b4034e6 Use already calculated current_profit for sell_profit_offset comparison 2021-02-02 08:06:19 +01:00
Matthias
a69fde39e5 Merge pull request #4296 from freqtrade/fix/pairlistbug
Fix disappearing pairs pairlist bug
2021-02-01 20:02:50 +01:00
Matthias
a9f1c871dd Add path loading snippet to derived strategies
closes #4279
2021-02-01 19:48:29 +01:00
Matthias
52acf9aaf6 Fix "disappearing pairs" bug
closes #4277
2021-02-01 19:40:31 +01:00
Matthias
130a9b4db3 Add test to call verify_pairlist multiple times 2021-02-01 19:39:55 +01:00
Matthias
55c9489eb2 Downgrade RPI docker-image to 3.7
otherwise piwheels.org does not work at the moment
2021-02-01 15:11:04 +01:00
Matthias
cd5c58fd37 Properly patch exchange for plot_profit test 2021-02-01 12:58:18 +01:00
Matthias
b33534b8f5 Merge pull request #4290 from freqtrade/dependabot/pip/develop/urllib3-1.26.3
Bump urllib3 from 1.26.2 to 1.26.3
2021-02-01 11:01:45 +01:00
Matthias
4facf662de Fix random test-failure caused by un-clean hyperopt shutdown
pytest --random-order-seed=415781
2021-02-01 11:00:55 +01:00
Matthias
fd5468f9cc Merge pull request #4292 from freqtrade/dependabot/pip/develop/pymdown-extensions-8.1.1
Bump pymdown-extensions from 8.1 to 8.1.1
2021-02-01 10:52:47 +01:00
dependabot[bot]
ccdac3d4c3 Bump urllib3 from 1.26.2 to 1.26.3
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.2 to 1.26.3.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/1.26.3/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.2...1.26.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 08:50:24 +00:00
dependabot[bot]
7fcf0d5231 Bump pymdown-extensions from 8.1 to 8.1.1
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 8.1 to 8.1.1.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/8.1...8.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 08:45:31 +00:00
Matthias
dc55c79e41 Merge pull request #4286 from freqtrade/dataload_valueerror
Fix valueerror in case of empty array files
2021-02-01 07:52:05 +01:00
Matthias
ed2ae65ffb Merge pull request #4293 from freqtrade/dependabot/pip/develop/jinja2-2.11.3
Bump jinja2 from 2.11.2 to 2.11.3
2021-02-01 07:48:22 +01:00
Matthias
8e1f3a5196 Merge pull request #4291 from freqtrade/dependabot/pip/develop/pytest-6.2.2
Bump pytest from 6.2.1 to 6.2.2
2021-02-01 07:47:40 +01:00
Matthias
382cd9eaaf Merge pull request #4295 from freqtrade/dependabot/pip/develop/mkdocs-material-6.2.7
Bump mkdocs-material from 6.2.5 to 6.2.7
2021-02-01 07:47:23 +01:00
Matthias
8cf8ef98c4 Merge pull request #4294 from freqtrade/dependabot/pip/develop/ccxt-1.41.35
Bump ccxt from 1.40.99 to 1.41.35
2021-02-01 07:47:06 +01:00
dependabot[bot]
2a5e0920ec Bump mkdocs-material from 6.2.5 to 6.2.7
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.2.5 to 6.2.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/6.2.5...6.2.7)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:42:08 +00:00
dependabot[bot]
aa7120f27c Bump ccxt from 1.40.99 to 1.41.35
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.40.99 to 1.41.35.
- [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.40.99...1.41.35)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:42:06 +00:00
dependabot[bot]
ed1d4f0568 Bump jinja2 from 2.11.2 to 2.11.3
Bumps [jinja2](https://github.com/pallets/jinja) from 2.11.2 to 2.11.3.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/2.11.2...2.11.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:42:05 +00:00
dependabot[bot]
76312d722a Bump pytest from 6.2.1 to 6.2.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:41:53 +00:00
Matthias
2c80388b40 Fix valueerror in case of empty array files 2021-02-01 06:28:49 +01:00
Matthias
06e2bc94c3 Deploy to subdirectory 2021-01-31 16:01:00 +01:00
Matthias
e4a085027b Add test for UI methods 2021-01-31 15:27:00 +01:00
Matthias
28be71806f Install html file as well 2021-01-31 15:13:51 +01:00
Matthias
a87a885ccd Don't use Path object to return fileresponses 2021-01-31 14:54:58 +01:00
Matthias
7b3d99819f Fix bug with not cleaning UI folder 2021-01-31 14:50:54 +01:00
Matthias
944d674eeb Store freqUI version and read it again 2021-01-31 14:50:54 +01:00
Matthias
2af1d2d639 Extract last FreqUI version from api response 2021-01-31 14:50:54 +01:00
Matthias
1df0aa8751 Add ui installation to docker container builds 2021-01-31 14:50:54 +01:00
Matthias
35c2e2556e Document FreqUI usage 2021-01-31 14:50:54 +01:00
Matthias
e928d2991d Add fallback file 2021-01-31 14:50:54 +01:00
Matthias
f05f2c45e8 Allow deleting of UI only 2021-01-31 14:50:54 +01:00
Matthias
ddc99553bd Add test case for get_ui_download_url 2021-01-31 14:50:54 +01:00
Matthias
a1a35115ad Extract get_ui_download_url 2021-01-31 14:50:54 +01:00
Matthias
87ed2d7502 Write some tests for UI Downloading 2021-01-31 14:50:54 +01:00
Matthias
a47616eed4 Add UI installation subcommand 2021-01-31 14:50:54 +01:00
Matthias
27970b424d Add webUI serving to api-server 2021-01-31 14:50:54 +01:00
Matthias
79087ba166 Fix intermitted test failure 2021-01-31 14:50:39 +01:00
Matthias
f288ed1f36 Merge pull request #4284 from freqtrade/windows_ci_error
Version bump numpy 1.20.0
2021-01-31 13:59:36 +01:00
Matthias
5724371a4f Fix types for numpy 1.20.0 upgrade 2021-01-31 11:21:23 +01:00
Matthias
92721db583 Version bump numpy to 1.20.0 2021-01-31 10:51:21 +01:00
Matthias
bc586fe73b Try fix CI 2021-01-31 10:29:43 +01:00
Pan Long
4cc93151c5 Fix a bug when compare sell_profit_offset
It should be comparing the ratio instead of absolut profit.

Also updated the comment.
2021-01-31 12:14:09 +08:00
Matthias
16dad8b6d4 Allow custom_stoploss to cooperate with stoploss on exchange 2021-01-30 20:11:18 +01:00
Matthias
30e5c01cb1 Improve formatting of custom_stoploss docs 2021-01-30 19:59:14 +01:00
Matthias
afdb39d78f Merge pull request #4280 from andre-ac/develop
Fixed virtualenv link
2021-01-30 19:20:13 +01:00
andre-ac
6b63129eb0 Fixed virtualenv link 2021-01-30 15:36:59 +00:00
Matthias
406682c3bb Fix random api failure in slow cases 2021-01-30 10:20:40 +01:00
Matthias
b68ed458b8 Merge pull request #4067 from freqtrade/dependabot/docker/python-3.9.1-slim-buster
Bump python from 3.8.6-slim-buster to 3.9.1-slim-buster
2021-01-30 10:13:32 +01:00
Matthias
5d18289821 Fix name in issue template 2021-01-30 07:17:25 +01:00
Matthias
375f551e5d Merge pull request #4218 from sobeit2020/develop
Conda - installation process : adding and explaining
2021-01-29 20:01:07 +01:00
Matthias
1e6194fa30 Improve wording, fix hirerchial hierarchy 2021-01-29 19:46:45 +01:00
Matthias
d8353bc90e Merge branch 'develop' into pr/sobeit2020/4218 2021-01-29 19:11:19 +01:00
Matthias
ea0ffbae73 use profit_ratio in calculate_cum_profit 2021-01-29 19:06:57 +01:00
Matthias
ad9efd3ac5 Merge pull request #4275 from freqtrade/markets_ref
Cache markets in the exchange object
2021-01-29 16:57:57 +01:00
sobeit2020
b12d0b110e Update installation.md 2021-01-28 23:09:39 +00:00
Matthias
5cdd9dd445 Cache markets in the exchange object 2021-01-28 19:47:32 +01:00
dependabot[bot]
4bb2a00f03 Bump python from 3.8.6-slim-buster to 3.9.1-slim-buster
Bumps python from 3.8.6-slim-buster to 3.9.1-slim-buster.

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-27 18:12:56 +00:00
Matthias
65459086a3 Merge pull request #4268 from freqtrade/backtest_trade_object
Backtest trade object
2021-01-27 19:10:21 +01:00
Matthias
766c786d90 Merge pull request #4273 from freqtrade/new_release
New release 2021.1
2021-01-27 19:02:52 +01:00
sobeit2020
d1d77f56df Update installation.md 2021-01-27 13:38:59 +00:00
sobeit2020
a414d5d75a Update installation.md 2021-01-27 13:25:16 +00:00
sobeit2020
ec2cf7f979 Update installation.md 2021-01-27 13:23:53 +00:00
sobeit2020
5da8a3078b Update installation.md 2021-01-27 13:04:04 +00:00
Matthias
eac98dbbd6 Version bump to 2021.1 2021-01-27 07:29:40 +01:00
Matthias
a9b4d6de33 Check for existance of ask key in ticker
closes #4267
2021-01-26 17:18:55 +01:00
Matthias
4d7f3e570b Add test for spreadfilter division exception 2021-01-26 17:18:51 +01:00
Matthias
5ab8cc56a4 Update docs to also work for postgres 2021-01-26 08:13:43 +01:00
Matthias
9005cd25b8 Merge pull request #4256 from thopd88/patch-2
Fix operator does not exist: boolean = integer
2021-01-26 07:21:39 +01:00
Tho Pham (Alex)
8f529f48da Update freqtrade/freqtradebot.py use is_open.is_(True)
Co-authored-by: Matthias <xmatthias@outlook.com>
2021-01-26 07:38:25 +07:00
sobeit2020
188010329c Update installation.md 2021-01-25 21:22:43 +00:00
sobeit2020
bcc7adb186 Update installation.md 2021-01-25 21:18:38 +00:00
sobeit2020
d848242379 Update installation.md 2021-01-25 21:12:48 +00:00
sobeit2020
39cef2dbe0 Update environment.yml 2021-01-25 20:45:35 +00:00
sobeit2020
4a28fab8a1 Update installation.md 2021-01-25 20:41:55 +00:00
Matthias
91b6c02947 Update download-data --dl-trades sample command 2021-01-25 20:57:05 +01:00
sobeit2020
65e0ba60dc Update installation.md 2021-01-25 19:51:01 +00:00
Matthias
13ad6dd461 Fix documentation 2021-01-25 19:56:40 +01:00
Matthias
c659150d9f Also print trade_duration in seconds to json 2021-01-25 19:42:34 +01:00
Matthias
3a83492999 Merge pull request #4265 from freqtrade/dependabot/pip/develop/ccxt-1.40.99
Bump ccxt from 1.40.74 to 1.40.99
2021-01-25 10:11:56 +01:00
dependabot[bot]
f98bd40955 Bump ccxt from 1.40.74 to 1.40.99
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.40.74 to 1.40.99.
- [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.40.74...1.40.99)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 08:24:17 +00:00
Matthias
6fc165c133 Merge pull request #4264 from freqtrade/dependabot/pip/develop/scikit-learn-0.24.1
Bump scikit-learn from 0.24.0 to 0.24.1
2021-01-25 08:23:57 +01:00
Matthias
d10e00b61b Merge pull request #4262 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.14
Bump prompt-toolkit from 3.0.10 to 3.0.14
2021-01-25 08:23:30 +01:00
Matthias
c0df15af29 Merge pull request #4257 from freqtrade/dependabot/pip/develop/cachetools-4.2.1
Bump cachetools from 4.2.0 to 4.2.1
2021-01-25 08:22:46 +01:00
Matthias
9b8148356e Merge pull request #4261 from freqtrade/dependabot/pip/develop/pandas-1.2.1
Bump pandas from 1.2.0 to 1.2.1
2021-01-25 08:22:12 +01:00
Matthias
04058b1a33 Merge pull request #4258 from freqtrade/dependabot/pip/develop/blosc-1.10.2
Bump blosc from 1.10.1 to 1.10.2
2021-01-25 08:04:27 +01:00
Matthias
1314e75bc6 Merge pull request #4259 from freqtrade/dependabot/pip/develop/pytest-cov-2.11.1
Bump pytest-cov from 2.10.1 to 2.11.1
2021-01-25 08:03:24 +01:00
dependabot[bot]
cb749b578d Bump scikit-learn from 0.24.0 to 0.24.1
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.24.0 to 0.24.1.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.24.0...0.24.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:37:51 +00:00
dependabot[bot]
fb99cf1459 Bump prompt-toolkit from 3.0.10 to 3.0.14
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.10 to 3.0.14.
- [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.10...3.0.14)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:37:50 +00:00
dependabot[bot]
d4e9037e6e Bump pandas from 1.2.0 to 1.2.1
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.2.0 to 1.2.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.2.0...v1.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:37:49 +00:00
dependabot[bot]
afdcd2c0af Bump pytest-cov from 2.10.1 to 2.11.1
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 2.10.1 to 2.11.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.1...v2.11.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:37:42 +00:00
dependabot[bot]
9422062cbd Bump blosc from 1.10.1 to 1.10.2
Bumps [blosc](https://github.com/blosc/python-blosc) from 1.10.1 to 1.10.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.10.1...v1.10.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:37:25 +00:00
dependabot[bot]
b976baae3f Bump cachetools from 4.2.0 to 4.2.1
Bumps [cachetools](https://github.com/tkem/cachetools) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/tkem/cachetools/releases)
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v4.2.0...v4.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-25 05:37:16 +00:00
Tho Pham (Alex)
c22cccb55b Fix operator does not exist: boolean = integer 2021-01-25 12:24:47 +07:00
sobeit2020
2226f6781f Update installation.md 2021-01-24 21:31:36 +00:00
Matthias
62e43539c9 Limit max_open_trades to maximum available pairs
closes #4008
2021-01-24 19:59:54 +01:00
Matthias
789a980a30 Fix tests for new export format 2021-01-24 19:42:32 +01:00
sobeit2020
2c2a33b2e8 updated environemnt.ylm 2021-01-24 17:06:40 +00:00
sobeit2020
9af89786ba update installation.md
ma
2021-01-24 17:03:56 +00:00
Matthias
deb8432d33 Streamline trade to dataframe conversion 2021-01-24 08:58:41 +01:00
Matthias
8ee264bc59 Don't use profit_percent for backtesting results anymore 2021-01-24 08:58:41 +01:00
Matthias
48977493bb Backtesting does not need to convert to BacktestResult object 2021-01-24 08:58:41 +01:00
Matthias
3b51545d23 Add trade_duration to to_json 2021-01-24 08:58:41 +01:00
Matthias
9a3c425cf4 Update slack link 2021-01-24 08:53:05 +01:00
Matthias
16f9675356 Fix whitelist expansion problem 2021-01-23 20:40:27 +01:00
Matthias
37acaa685b Merge pull request #4249 from freqtrade/config_rename
Config rename
2021-01-23 09:20:42 +01:00
Matthias
31e0b09643 Rename config.json.example
it's really the config dedicated to bittrex,
so the name should reflect this in beeing config_bittrex.json.example
2021-01-22 19:18:34 +01:00
Matthias
371b374ea6 Remove unused config setup from setup.sh 2021-01-22 19:12:34 +01:00
Matthias
bec9b580b0 sell_profit_offset should be documented in the strategy override section 2021-01-22 17:38:55 +01:00
Matthias
e94e2dd383 Remove docker config without compose 2021-01-22 17:32:57 +01:00
Matthias
c42241986e further investigate random test failure 2021-01-21 19:20:38 +01:00
Matthias
c998577d4a Merge pull request #4244 from dannoso/patch-1
Fixed quickstart link in docs
2021-01-21 19:12:47 +01:00
Davide
fd379d36ac Fixed quickstart link in docs 2021-01-21 12:27:22 +01:00
Matthias
5c0f98b518 Blacklist Poloniex - as ccxt does not provide a fetch_order endpoint 2021-01-20 19:31:17 +01:00
Matthias
06cae1b60c Merge pull request #4241 from tijmenvandenbrink/develop
Small improvement to MaxDrawDown protection
2021-01-20 14:16:08 +01:00
Matthias
5f5f75e147 Improve wording in protections documentation 2021-01-20 13:57:53 +01:00
Tijmen van den Brink
992d6b8018 Small improvement to MaxDrawDown protection 2021-01-20 09:24:30 +01:00
Matthias
7c80eeea95 Add use_custom_stoploss to optimize_report 2021-01-19 22:51:12 +01:00
Matthias
86b3306a3b Small doc refactoring 2021-01-19 22:07:10 +01:00
Matthias
7c99e6f0e6 Avoid random test failure 2021-01-19 20:49:28 +01:00
Matthias
20591b539a Merge pull request #4228 from baartch/develop
Extending the Telegram Bot command /status with the possibility to query specific trade_ids
2021-01-19 20:08:49 +01:00
Matthias
cd8d4da466 Add test for /status <tradeids> functionality 2021-01-19 19:45:13 +01:00
Andreas Brunner
a68a546dd9 _rpc_trade_status argument datatype optimizations 2021-01-18 15:26:53 +01:00
Matthias
c785bce7e6 Merge pull request #4234 from freqtrade/dependabot/pip/develop/pyjwt-2.0.1
Bump pyjwt from 2.0.0 to 2.0.1
2021-01-18 09:20:16 +01:00
Matthias
d05cbe239a Merge pull request #4231 from freqtrade/dependabot/pip/develop/coveralls-3.0.0
Bump coveralls from 2.2.0 to 3.0.0
2021-01-18 08:59:05 +01:00
Matthias
792c8503f9 Merge pull request #4233 from freqtrade/dependabot/pip/develop/mkdocs-material-6.2.5
Bump mkdocs-material from 6.2.4 to 6.2.5
2021-01-18 08:48:44 +01:00
Matthias
10104927c9 Fix devcontainer
closes #4230
2021-01-18 07:46:19 +00:00
Matthias
611dbdc522 Merge pull request #4235 from freqtrade/dependabot/pip/develop/ccxt-1.40.74
Bump ccxt from 1.40.30 to 1.40.74
2021-01-18 07:31:34 +01:00
Matthias
3386ca9999 Merge pull request #4232 from freqtrade/dependabot/pip/develop/plotly-4.14.3
Bump plotly from 4.14.1 to 4.14.3
2021-01-18 07:29:41 +01:00
dependabot[bot]
994b4013ad Bump ccxt from 1.40.30 to 1.40.74
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.40.30 to 1.40.74.
- [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.40.30...1.40.74)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-18 05:38:06 +00:00
dependabot[bot]
8b5f8937cc Bump pyjwt from 2.0.0 to 2.0.1
Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/2.0.0...2.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-18 05:37:48 +00:00
dependabot[bot]
7f8dbce367 Bump mkdocs-material from 6.2.4 to 6.2.5
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.2.4 to 6.2.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.2.4...6.2.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-18 05:37:45 +00:00
dependabot[bot]
6a8e495102 Bump plotly from 4.14.1 to 4.14.3
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.14.1 to 4.14.3.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.14.1...v4.14.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-18 05:37:37 +00:00
dependabot[bot]
296a6bd43c Bump coveralls from 2.2.0 to 3.0.0
Bumps [coveralls](https://github.com/coveralls-clients/coveralls-python) from 2.2.0 to 3.0.0.
- [Release notes](https://github.com/coveralls-clients/coveralls-python/releases)
- [Changelog](https://github.com/TheKevJames/coveralls-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/coveralls-clients/coveralls-python/compare/2.2.0...3.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-18 05:37:29 +00:00
Andreas Brunner
eb95d970e9 flake8 beautify 2021-01-17 21:26:55 +01:00
Andreas Brunner
d21eff0d52 fix, if an non existing trade_id is provided 2021-01-17 21:21:31 +01:00
Andreas Brunner
3ea33d1737 updating doc and help with new /status argument 2021-01-17 21:15:17 +01:00
Andreas Brunner
6d40814dbf extend status bot command to query specific trades 2021-01-17 20:39:35 +01:00
Matthias
a8bae3a381 Don't update trade fees for dry-run orders 2021-01-17 20:31:27 +01:00
Matthias
389db2fe7d Enhance wording of docker quickstart 2021-01-17 19:11:00 +01:00
Matthias
3a2bac4ae3 Merge pull request #4223 from freqtrade/bot_name
Add bot_name setting
2021-01-17 15:23:41 +01:00
sobeit2020
172a629c58 Update installation.md 2021-01-16 22:41:37 +00:00
sobeit2020
f9dd74585e Update installation.md 2021-01-16 22:39:11 +00:00
sobeit2020
73206a9194 Update installation.md 2021-01-16 22:35:42 +00:00
sobeit2020
63be27f671 Update installation.md 2021-01-16 22:28:23 +00:00
sobeit2020
9ad0817105 Update installation.md 2021-01-16 22:27:25 +00:00
sobeit2020
a271c9e98e Update installation.md 2021-01-16 22:24:22 +00:00
Matthias
53c208197d Add bot_name setting
allows naming the bot to simply differentiate when running different
bots.
2021-01-16 16:19:49 +01:00
Matthias
572f5f9186 Fix fstring syntax error 2021-01-16 10:05:47 +01:00
Matthias
9f338ba6ed Debug random test failure in CI 2021-01-16 10:01:31 +01:00
Matthias
3fefb6f1c8 Merge pull request #4215 from freqtrade/refactor/backtest
Small backtest refactor, introduce calling `bot_loop_start` in backtesting
2021-01-16 09:32:19 +01:00
Matthias
d74376726a api-server should fully support max_open_trades=-1 2021-01-15 20:47:12 +01:00
Matthias
baef8b4f79 Merge pull request #4197 from nas-/develop
Added support for regex in whitelist
2021-01-15 07:34:49 +01:00
Matthias
bf5868c96d Add testcase for nonexisting pairs on whitelist 2021-01-15 07:10:17 +01:00
nas-
f72d53351c Added ability to keep invalid pairs while expanding expand_pairlist 2021-01-15 06:37:57 +01:00
sobeit2020
ce5ba1bb6e Adding Conda installation process 2021-01-15 00:14:11 +00:00
Matthias
0b65fe6afe Capture backtest start / end time 2021-01-14 19:09:25 +01:00
Matthias
9147106259 call bot_loop_start() in backtesting to allow setup-code to run 2021-01-14 19:09:25 +01:00
Matthias
baa1142afa Use preprocessed to get min/max date in hyperopt 2021-01-14 19:09:21 +01:00
Matthias
9d4cdcad10 Extract backtesting of one strategy 2021-01-14 19:04:42 +01:00
Matthias
6d1fba1409 Remove unnecessary log output tests 2021-01-14 19:04:42 +01:00
Matthias
f3de0dd3eb Fix support for protections in hyperopt
closes #4208
2021-01-14 06:53:40 +01:00
Matthias
d289fe44cb Merge pull request #4205 from tejeshreddy/docs-edge
fix: edge doc typos [done]
2021-01-13 16:43:43 +01:00
tejeshreddy
950c5c0113 fix: edge doc typos 2021-01-13 16:50:38 +05:30
Matthias
adb3fb123e Fix typo 2021-01-12 19:35:02 +01:00
Matthias
47a06c6213 Fix enable/reenable of swagger UI endpoint 2021-01-12 19:28:22 +01:00
Matthias
ac43591c44 Fix failing api when max_open_trades is unlimited 2021-01-12 19:24:37 +01:00
Matthias
60ea32e398 Improve wording 2021-01-12 19:05:25 +01:00
Matthias
6007d5182a Merge pull request #4147 from hoeckxer/ignore_expired_candle
Ignoring candles that have expired within timeframe
2021-01-12 19:04:16 +01:00
hoeckxer
1f6a71fdd9 Reformat code on new version 2021-01-12 08:24:11 +01:00
Matthias
951c6ac1d4 Merge pull request #4193 from freqtrade/sell_profit_offset
Sell profit offset
2021-01-12 07:58:07 +01:00
hoeckxer
71f45021b9 Removed redundant statement 2021-01-12 07:35:30 +01:00
hoeckxer
e328182bd7 Changed workings so it only needs to timing-parameter, instead of also requiring a boolean value 2021-01-12 07:30:39 +01:00
nas-
4d7ffa8c81 Added suppoort for regex in whitelist 2021-01-12 01:13:58 +01:00
Matthias
b062b836cc Add test for sell_profit_offset 2021-01-11 19:42:44 +01:00
Matthias
63a579dbab Add sell_profit_offset parameter
Allows defining positive offsets before enabling the sell signal
2021-01-11 19:30:25 +01:00
Matthias
dbc25f00ac Switch full config from bittrex to binance
bittrex no longer supports volumepairlist.

closes #4192
2021-01-11 19:12:03 +01:00
Matthias
0c6c5162e8 Merge pull request #4189 from freqtrade/fix/4183
Include stoploss_on_exchange in stoploss_guard
2021-01-11 08:14:59 +01:00
Matthias
689c19620c Merge pull request #4188 from freqtrade/dependabot/pip/develop/pytest-mock-3.5.1
Bump pytest-mock from 3.5.0 to 3.5.1
2021-01-11 07:57:19 +01:00
Matthias
f159c46438 Include stoploss_on_exchange in stoploss_guard
fix #4183
2021-01-11 07:55:01 +01:00
Matthias
bc0550358f Merge pull request #4186 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.10
Bump prompt-toolkit from 3.0.9 to 3.0.10
2021-01-11 07:36:29 +01:00
Matthias
d78fd3fa8f Merge pull request #4185 from freqtrade/dependabot/pip/develop/mkdocs-material-6.2.4
Bump mkdocs-material from 6.2.3 to 6.2.4
2021-01-11 07:34:48 +01:00
Matthias
6c29964bcc Merge pull request #4187 from freqtrade/dependabot/pip/develop/ccxt-1.40.30
Bump ccxt from 1.40.25 to 1.40.30
2021-01-11 07:33:55 +01:00
dependabot[bot]
59efc5f083 Bump pytest-mock from 3.5.0 to 3.5.1
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.5.0 to 3.5.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.5.0...v3.5.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-11 05:38:47 +00:00
dependabot[bot]
f1809286cf Bump ccxt from 1.40.25 to 1.40.30
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.40.25 to 1.40.30.
- [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.40.25...1.40.30)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-11 05:38:47 +00:00
dependabot[bot]
a34753fcb1 Bump prompt-toolkit from 3.0.9 to 3.0.10
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.9 to 3.0.10.
- [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.9...3.0.10)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-11 05:38:45 +00:00
dependabot[bot]
ddecf3ef98 Bump mkdocs-material from 6.2.3 to 6.2.4
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.2.3 to 6.2.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.2.3...6.2.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-11 05:38:34 +00:00
Matthias
5102dfd6df Merge pull request #4144 from freqtrade/improve_informativepair
Improve merge_informative_pairs to properly merge correct timeframes
2021-01-09 10:15:59 +01:00
Matthias
61d225a575 Merge pull request #4170 from freqtrade/dependabot/pip/develop/pyjwt-2.0.0
Bump pyjwt from 1.7.1 to 2.0.0
2021-01-08 19:48:04 +01:00
Matthias
8631a54514 Fix test due to pyjwt2.0 2021-01-08 19:34:01 +01:00
Matthias
5f17dd06a5 Merge pull request #4173 from freqtrade/fix/4161
Fix #4161 - by not using the problematic method for windows
2021-01-08 19:22:48 +01:00
Matthias
47f391e43e Merge pull request #4164 from freqtrade/ci_macos_39
Run CI for mac on 3.9
2021-01-08 19:22:15 +01:00
Matthias
378a252ad1 Fix #4161 - by not using the problematic method for windows 2021-01-08 13:46:43 +01:00
Matthias
cc428d7e36 Merge pull request #4171 from freqtrade/dependabot/pip/develop/numpy-1.19.5
Bump numpy from 1.19.4 to 1.19.5
2021-01-08 13:44:09 +01:00
dependabot[bot]
c8df3c4730 Bump pyjwt from 1.7.1 to 2.0.0
Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 1.7.1 to 2.0.0.
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jpadilla/pyjwt/compare/1.7.1...2.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-08 07:48:31 +00:00
Matthias
de26867ad2 Merge pull request #4166 from freqtrade/dependabot/pip/develop/pytest-mock-3.5.0
Bump pytest-mock from 3.4.0 to 3.5.0
2021-01-08 08:48:14 +01:00
dependabot[bot]
4d2c59b7ec Bump numpy from 1.19.4 to 1.19.5
Bumps [numpy](https://github.com/numpy/numpy) from 1.19.4 to 1.19.5.
- [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.4...v1.19.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-08 07:47:47 +00:00
Matthias
eb9d137d5b Merge pull request #4167 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.9
Bump prompt-toolkit from 3.0.8 to 3.0.9
2021-01-08 08:47:32 +01:00
Matthias
ee6d340aa7 Merge pull request #4169 from freqtrade/dependabot/pip/develop/ccxt-1.40.25
Bump ccxt from 1.40.14 to 1.40.25
2021-01-08 08:47:12 +01:00
Matthias
3bc59d427c Merge pull request #4168 from freqtrade/dependabot/pip/develop/uvicorn-0.13.3
Bump uvicorn from 0.13.2 to 0.13.3
2021-01-08 08:46:42 +01:00
dependabot[bot]
3cf506fa5d Bump ccxt from 1.40.14 to 1.40.25
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.40.14 to 1.40.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.40.14...1.40.25)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-08 07:16:49 +00:00
dependabot[bot]
784630e2f2 Bump uvicorn from 0.13.2 to 0.13.3
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.13.2 to 0.13.3.
- [Release notes](https://github.com/encode/uvicorn/releases)
- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/uvicorn/compare/0.13.2...0.13.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-08 07:16:49 +00:00
dependabot[bot]
f3319e1382 Bump prompt-toolkit from 3.0.8 to 3.0.9
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.8 to 3.0.9.
- [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/3.0.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-08 07:16:48 +00:00
dependabot[bot]
bd5f46e4c2 Bump pytest-mock from 3.4.0 to 3.5.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.4.0 to 3.5.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.4.0...v3.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-08 07:16:36 +00:00
Matthias
2e7faa782c Add documentation section for macOS installation error on 3.999999999 2021-01-08 06:51:37 +01:00
Matthias
3a9583403b Merge pull request #4165 from freqtrade/trades_dl
Trades dl fix faulty behaviour
2021-01-08 06:22:13 +01:00
Matthias
4f126bea35 Change trades-test2 to better test correct behaviour 2021-01-07 20:06:26 +01:00
Matthias
bf182dc01e Fix wrong key usage in trade_history_timebased 2021-01-07 20:03:34 +01:00
Matthias
124cb5c5bf Add cblosc brew dependency 2021-01-07 19:36:50 +01:00
Matthias
54ab61d18a Install hdf5 via brew 2021-01-07 19:27:35 +01:00
Matthias
9e66417e85 Run CI for mac on 3.9 2021-01-07 19:21:42 +01:00
Matthias
b43ef474ad Fix expired candle implementation
Improve and simplify test by passing the current time to the function
2021-01-07 07:51:49 +01:00
Matthias
7a628432a8 Merge pull request #4159 from freqtrade/protections/strategy
Allow protections to be set in the strategy
2021-01-07 06:39:34 +01:00
Matthias
c9e477214f Allow protections to be set in the strategy 2021-01-06 16:37:09 +01:00
Matthias
6ca2b2d52d Merge pull request #4158 from freqtrade/fix/rpc_history_bug
Fix bug in RPC history mode when no data is found
2021-01-06 16:03:03 +01:00
Matthias
e69dac2704 Fix bug in RPC history mode when no data is found 2021-01-06 15:38:46 +01:00
Matthias
a9ca72c1b8 Fix typo in documentation 2021-01-06 11:04:14 +01:00
Matthias
dfe9247c65 Merge pull request #4155 from freqtrade/fix_dry_open_order_update
Don't update open orders in dry-run mode
2021-01-06 10:52:39 +01:00
Matthias
91f8667881 DOn't update open orders in dry-run mode 2021-01-06 09:57:36 +01:00
Matthias
3d57a108d8 Merge pull request #4150 from hoeckxer/protection_documentation_clarification
Protections - clarification in documentation
2021-01-06 09:55:43 +01:00
Matthias
a906093153 FIx doc wording for all guards 2021-01-06 09:45:21 +01:00
hoeckxer
f7b055a58c Attempt to improve wording
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2021-01-06 09:26:03 +01:00
hoeckxer
95732e8991 Clarification in documentation
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2021-01-05 21:03:23 +01:00
hoeckxer
c0f170fdb9 Merge branch 'develop' into ignore_expired_candle 2021-01-05 21:00:08 +01:00
hoeckxer
5c34140a19 Adjusted documentation to reflect sub-key configuration 2021-01-05 20:59:31 +01:00
hoeckxer
65d91a3a58 isort fix 2021-01-05 15:36:34 +01:00
hoeckxer
573de1cf08 Fixed flake8 warnings 2021-01-05 15:30:29 +01:00
hoeckxer
67d84e7514 Merge branch 'ignore_expired_candle' of github.com:hoeckxer/freqtrade into ignore_expired_candle 2021-01-05 14:49:46 +01:00
hoeckxer
e3f3f36298 Changes based on review comments 2021-01-05 14:49:35 +01:00
Erwin Hoeckx
eaaaddac86 Update docs/configuration.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2021-01-05 11:10:00 +01:00
Matthias
c010cdf894 Merge pull request #4138 from freqtrade/fastapi
use Fastapi instead of flask for API operations
2021-01-05 10:07:19 +01:00
hoeckxer
c9ed2137bb Simplified return statements
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2021-01-05 09:07:46 +01:00
Erwin Hoeckx
67306d943a Update interface.py
Simplified return value, thereby including the situation where the time simply hasn't expired yet
2021-01-05 07:33:34 +01:00
Erwin Hoeckx
9a93a0876a Update interface.py
Adjusted comment
2021-01-05 07:32:07 +01:00
hoeckxer
844df96ec7 Making changes so the build checks are satisified (imports & flake8)
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2021-01-05 07:06:53 +01:00
hoeckxer
614a996597 First commit about ignoring expired candle
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2021-01-04 20:49:24 +01:00
Matthias
cce4d7e42c Merge pull request #4145 from hoeckxer/custom_stoploss_doc_addition
Added an example with a positive offset for a custom stoploss
2021-01-04 19:19:53 +01:00
hoeckxer
1cf6e2c957 Changed documentation based on review comments
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2021-01-04 14:37:22 +01:00
hoeckxer
0704cfb05b Added an example with a positive offset for a custom stoploss
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2021-01-04 14:14:52 +01:00
Matthias
07bc0c3fce Improve merge_informative_pairs to properly merge correct timeframes
explanation in #4073, closes #4073
2021-01-04 13:49:38 +01:00
Matthias
d1804dee6b Add note about python-dev dependency 2021-01-04 09:40:17 +01:00
Matthias
9e84dd9274 Merge pull request #4141 from freqtrade/dependabot/pip/develop/scipy-1.6.0
Bump scipy from 1.5.4 to 1.6.0
2021-01-04 09:30:57 +01:00
Matthias
a7e3f9ef70 Merge pull request #4142 from freqtrade/dependabot/pip/develop/isort-5.7.0
Bump isort from 5.6.4 to 5.7.0
2021-01-04 09:27:04 +01:00
Matthias
a33f4fd9ca Merge pull request #4143 from freqtrade/dependabot/pip/develop/ccxt-1.40.14
Bump ccxt from 1.39.79 to 1.40.14
2021-01-04 08:30:42 +01:00
dependabot[bot]
9e435fba0b Bump ccxt from 1.39.79 to 1.40.14
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.39.79 to 1.40.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.39.79...1.40.14)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-04 05:39:14 +00:00
dependabot[bot]
7d06e61461 Bump scipy from 1.5.4 to 1.6.0
Bumps [scipy](https://github.com/scipy/scipy) from 1.5.4 to 1.6.0.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.5.4...v1.6.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-04 05:38:57 +00:00
dependabot[bot]
66391b80ae Bump isort from 5.6.4 to 5.7.0
Bumps [isort](https://github.com/pycqa/isort) from 5.6.4 to 5.7.0.
- [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.4...5.7.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-04 05:38:57 +00:00
Matthias
5ca2cd3a1e Change defaults to log only errors 2021-01-03 07:18:41 +01:00
Matthias
634d6f3898 Change logging to stderr 2021-01-03 07:15:45 +01:00
Matthias
26c3463403 Stake-amount supports unlimited, too 2021-01-03 06:49:10 +01:00
Matthias
cff50f9f66 Add response-model for show_config 2021-01-03 06:49:10 +01:00
Matthias
ca0bb7bbb8 Don't require RPC for strategy 2021-01-03 06:49:07 +01:00
Matthias
e6176d43f3 Optional RPC dependency 2021-01-03 06:49:07 +01:00
Matthias
3dc37dd79d Add types for deps 2021-01-03 06:49:07 +01:00
Matthias
336dd1a29c Rename api_models to api_schemas 2021-01-03 06:49:07 +01:00
Matthias
84ced92002 Fix mock-tests missing some fields 2021-01-03 06:49:07 +01:00
Matthias
29f4dd1dcd Enhance some response models 2021-01-03 06:49:07 +01:00
Matthias
718f2b24d2 Don't use relative imports 2021-01-03 06:49:07 +01:00
Matthias
b2ab553a31 Rename api_server2 module to apiserver 2021-01-03 06:49:04 +01:00
Matthias
eb20f6e7d0 Align auth token to flask version to prevent user-logout 2021-01-03 06:49:04 +01:00
Matthias
346542e5cd Remove flask dependency 2021-01-03 06:49:04 +01:00
Matthias
68d148e72d Allow configuration of openAPI interface 2021-01-03 06:49:04 +01:00
Matthias
1717121f10 Properly use JWT secret key 2021-01-03 06:49:04 +01:00
Matthias
790f833653 Some more tests around api_auth 2021-01-03 06:49:04 +01:00
Matthias
29ce323649 Fix wrong hyperoptlosstest 2021-01-03 06:49:04 +01:00
Matthias
776ce57f55 Remove api_server 2021-01-03 06:49:04 +01:00
Matthias
54a50b1fb4 Fix some tests 2021-01-03 06:49:04 +01:00
Matthias
9f873305eb Improve response models 2021-01-03 06:49:04 +01:00
Matthias
9350f505bc Implement missing methods 2021-01-03 06:49:04 +01:00
Matthias
e23898d17b Improve some tests 2021-01-03 06:49:04 +01:00
Matthias
9ee1d88355 Implement more endpoints 2021-01-03 06:49:04 +01:00
Matthias
73a29e6d74 Improve tests, implement more fastapi methods 2021-01-03 06:49:04 +01:00
Matthias
a18d66e108 Add more endpoints to fastapi 2021-01-03 06:49:04 +01:00
Matthias
f37ea4ba24 Fix some initial tests towards fastAPI 2021-01-03 06:49:04 +01:00
Matthias
4b86700a0f Implement more endpoints 2021-01-03 06:48:56 +01:00
Matthias
5e4c4cae06 Fix auth providers 2021-01-03 06:48:53 +01:00
Matthias
86d0700884 Move models to apimodels 2021-01-03 06:46:25 +01:00
Matthias
6594278509 Reorder endpoints 2021-01-03 06:46:25 +01:00
Matthias
eac74a9dec Implement auth in fastapi 2021-01-03 06:46:25 +01:00
Matthias
619b855d5f Add version endpoint 2021-01-03 06:46:25 +01:00
Matthias
a862f19f82 Allow retrieval of rpc and config via dependencies 2021-01-03 06:46:25 +01:00
Matthias
1e38fec61b Initial fastapi implementation (Ping working) 2021-01-03 06:46:25 +01:00
Matthias
31829d5250 Merge pull request #4134 from hoeckxer/documentation_imports_custom_stoploss
Added imports to documentation for clarification when using custom st…
2021-01-02 09:23:43 +01:00
Matthias
11f36fbaee Fix all custom stoploss samples 2021-01-02 09:14:31 +01:00
Erwin Hoeckx
67ced6a53c Update docs/strategy-advanced.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2021-01-01 20:49:04 +01:00
hoeckxer
e5840abaf9 Added imports to documentation for clarification when using custom stoploss
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
2020-12-31 21:05:47 +01:00
Matthias
885da85fce Merge branch 'stable' into develop 2020-12-31 10:39:20 +01:00
Matthias
9e3224ccc0 Merge pull request #4089 from freqtrade/feat/stoploss_custom
introduce custom stoploss
2020-12-31 10:33:33 +01:00
Matthias
12de29dd3e Merge pull request #4133 from freqtrade/dynamic_pairlist
Wildcard based blacklist
2020-12-31 10:02:30 +01:00
Matthias
512e163355 change docstring to better reflect what the method is for 2020-12-31 09:48:49 +01:00
Matthias
bd7600ff06 Small visual changes 2020-12-31 09:43:24 +01:00
Matthias
04624aae40 Add documentation for wildcard-blacklist 2020-12-30 12:30:50 +01:00
Matthias
0affacd39a Support invalid regex blacklist from config 2020-12-30 10:14:22 +01:00
Matthias
9feabe707f Fix RPC methods to allow wildcards (and validate wildcards) 2020-12-30 09:57:31 +01:00
Matthias
704cf14383 Add expand_pairlist method 2020-12-30 09:55:44 +01:00
Matthias
2fdda8e448 plot-profit should fail gracefully if no trade is within the selected timerange
closes #4119
2020-12-30 08:30:41 +01:00
Matthias
b8899b39ec Show advanced plot-config section again
closes #4132
2020-12-30 06:29:59 +01:00
Matthias
9d7e0514ff Merge pull request #4131 from freqtrade/fix/krakenbalance
Fix/krakenbalance
2020-12-30 06:23:25 +01:00
Matthias
b607740dd1 Fix kraken balance bug if open buy orders exist 2020-12-29 20:06:37 +01:00
Matthias
238e9aabb1 Add test showing wrong behaviour 2020-12-29 20:05:07 +01:00
Matthias
f97e810429 Merge pull request #4127 from freqtrade/new_release
New release 2020.12
2020-12-29 07:07:54 +01:00
Matthias
0925a3cd19 Reinstate header partials 2020-12-28 14:12:39 +01:00
Matthias
a2fdb9d2f6 Move jquery to the bottom 2020-12-28 14:12:39 +01:00
Matthias
f6e56027b1 Reinstate jquery 2020-12-28 14:12:39 +01:00
Matthias
625da69fcb Remove custom header section from docs 2020-12-28 14:12:15 +01:00
Matthias
dcc7d559ee Reinstate header partials 2020-12-28 14:08:57 +01:00
Matthias
ecea6c9526 Move jquery to the bottom 2020-12-28 14:02:30 +01:00
Matthias
accc59aa1b Reinstate jquery 2020-12-28 13:49:08 +01:00
Matthias
8366e67fee Remove custom header section from docs 2020-12-28 10:19:50 +01:00
Matthias
003552d78c Remove custom header section from docs 2020-12-28 10:19:24 +01:00
Matthias
d4e42987e2 Merge pull request #4126 from freqtrade/dependabot/pip/develop/pandas-1.2.0
Bump pandas from 1.1.5 to 1.2.0
2020-12-28 10:09:05 +01:00
Matthias
f80ffe279b Version bump 2020.12 2020-12-28 09:54:58 +01:00
Matthias
ea22588649 Merge branch 'stable' into new_release 2020-12-28 09:54:46 +01:00
Matthias
fe8898c7f8 Merge pull request #4124 from freqtrade/dependabot/pip/develop/scikit-learn-0.24.0
Bump scikit-learn from 0.23.2 to 0.24.0
2020-12-28 09:54:29 +01:00
Matthias
0d4cf32086 Slightly adapt to pandas incompatibility 2020-12-28 09:50:48 +01:00
dependabot[bot]
30087697e0 Bump pandas from 1.1.5 to 1.2.0
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.1.5 to 1.2.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.1.5...v1.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 08:21:17 +00:00
Matthias
8dca3c84f8 Merge pull request #4122 from freqtrade/dependabot/pip/develop/ccxt-1.39.79
Bump ccxt from 1.39.52 to 1.39.79
2020-12-28 09:19:15 +01:00
Matthias
0fc504fc4e Merge pull request #4125 from freqtrade/dependabot/pip/develop/blosc-1.10.1
Bump blosc from 1.9.2 to 1.10.1
2020-12-28 09:18:14 +01:00
Matthias
25b872a9c8 Merge pull request #4123 from freqtrade/dependabot/pip/develop/pymdown-extensions-8.1
Bump pymdown-extensions from 8.0.1 to 8.1
2020-12-28 09:17:09 +01:00
Matthias
a328bf58f4 Merge pull request #4121 from freqtrade/dependabot/pip/develop/mkdocs-material-6.2.3
Bump mkdocs-material from 6.1.7 to 6.2.3
2020-12-28 09:16:46 +01:00
dependabot[bot]
f492609115 Bump blosc from 1.9.2 to 1.10.1
Bumps [blosc](https://github.com/blosc/python-blosc) from 1.9.2 to 1.10.1.
- [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.2...v1.10.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 05:37:17 +00:00
dependabot[bot]
092ebf845d Bump scikit-learn from 0.23.2 to 0.24.0
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 0.23.2 to 0.24.0.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/0.23.2...0.24.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 05:37:16 +00:00
dependabot[bot]
87b896879f Bump ccxt from 1.39.52 to 1.39.79
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.39.52 to 1.39.79.
- [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.39.52...1.39.79)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 05:37:13 +00:00
dependabot[bot]
10840ec170 Bump pymdown-extensions from 8.0.1 to 8.1
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 8.0.1 to 8.1.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/8.0.1...8.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 05:37:13 +00:00
dependabot[bot]
b3e929d14b Bump mkdocs-material from 6.1.7 to 6.2.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.7 to 6.2.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/6.1.7...6.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-28 05:37:11 +00:00
Matthias
8cf3dbb682 Merge pull request #4110 from freqtrade/test/exchange_ccxt
add tests to verify exchange compatibility with ccxt
2020-12-26 16:32:25 +01:00
Matthias
7d2b9447d0 Update slack link 2020-12-26 15:30:55 +01:00
Matthias
4b910426ff Merge pull request #4113 from freqtrade/ref/rpc
Refactor RPC dependency tree
2020-12-25 10:10:50 +01:00
Matthias
a87c273903 Refactor RPC modules so handlers don't inherit RPC directly 2020-12-24 09:09:23 +01:00
Matthias
1508e08ea5 Move fiatconvert init to RPC class 2020-12-24 08:39:00 +01:00
Matthias
48f7997a77 Merge pull request #4112 from freqtrade/tests/telegram
simplify telegram tests
2020-12-24 08:24:11 +01:00
Matthias
5bf739b917 Simplify more telegram tests 2020-12-24 07:39:46 +01:00
Matthias
be4a4be7a3 Further simplify test_telegram 2020-12-24 07:29:26 +01:00
Matthias
4cbbb80bc3 Refactor test_telegram to simplify tests 2020-12-24 07:10:01 +01:00
Matthias
516e56bfaa Move init of _config to apiserver parent 2020-12-23 20:50:32 +01:00
Matthias
0b98f19f2c Merge pull request #4111 from freqtrade/move_pairlist_plugins
Move pairlists to be a plugin submodule
2020-12-23 19:10:08 +01:00
Matthias
f11fd2fee1 Sort imports 2020-12-23 17:00:02 +01:00
Matthias
67193bca3d Move pairlists to be a plugin submodule 2020-12-23 16:54:35 +01:00
Matthias
7cef5ac217 Merge pull request #4092 from MrKrautee/telegram
Telegram: specify custom keyboard in config
2020-12-23 16:25:37 +01:00
Matthias
1713841d0b Initialize markets at startup for ccxt tests 2020-12-23 16:20:25 +01:00
Matthias
721d0fb2a8 Improve wording of developer docs 2020-12-23 16:00:26 +01:00
Christof
74bcd82c3d Exception msg 2020-12-23 16:00:01 +01:00
Matthias
65d91b7cbb Add note on adding new exchange with compat tests 2020-12-23 15:53:41 +01:00
Matthias
5599490aa2 Adjust ohlcv test after rebase 2020-12-23 15:50:24 +01:00
Matthias
b39de171c8 Don't run longrun regularily 2020-12-23 15:46:08 +01:00
Matthias
0981287c62 Improve test syntax for ccxt_compat tests 2020-12-23 15:41:59 +01:00
Matthias
2016eea212 Fix some test-errors in ccxt_compat 2020-12-23 15:41:59 +01:00
Matthias
a6e6ce16b1 Fix test failures 2020-12-23 15:41:59 +01:00
Matthias
b7d4ff9c21 Add test for fetch_ohlcv (against exchange) 2020-12-23 15:41:59 +01:00
Matthias
7833d9935c Add dummy test for fetch_ohlcv 2020-12-23 15:41:59 +01:00
Matthias
79ed89e487 Add test for fee calculation 2020-12-23 15:41:59 +01:00
Matthias
38af1b2a5d Improve compat tests 2020-12-23 15:41:59 +01:00
Matthias
36d60fa8a8 First small compat test 2020-12-23 15:41:59 +01:00
Christof
b1fe5940fa check for Exception and log msgs 2020-12-22 13:01:01 +01:00
Christof
cd1a8e2c42 better error msg 2020-12-22 12:39:27 +01:00
Christof
be28b42bfa Exception for invalid keyboard config 2020-12-22 12:34:21 +01:00
Matthias
4dadfd199d Documentation syntax 2020-12-22 07:36:53 +01:00
Matthias
39579b6e5d Merge pull request #4093 from freqtrade/ohlcv_limit
set ohlcv limit on ccxt calls
2020-12-21 19:34:50 +01:00
Matthias
9d37ac9955 Merge pull request #4094 from MrKrautee/plot_area
Plot area between traces
2020-12-21 19:30:07 +01:00
Matthias
9c0850ff50 Merge pull request #4103 from MrKrautee/tg_docs
added /locks to command list
2020-12-21 10:22:54 +01:00
Christof
78dff3d510 docs: Note syntax 2020-12-21 10:22:24 +01:00
Christof
2787ba0809 added /locks to command list 2020-12-21 10:03:27 +01:00
Christof
277f3ff47b tests: cleaup 2020-12-21 09:52:10 +01:00
Matthias
5bd14bcccf Merge pull request #4100 from freqtrade/dependabot/pip/develop/pytest-mock-3.4.0
Bump pytest-mock from 3.3.1 to 3.4.0
2020-12-21 09:31:44 +01:00
Matthias
bbc049c838 Merge pull request #4102 from freqtrade/dependabot/pip/develop/sqlalchemy-1.3.22
Bump sqlalchemy from 1.3.20 to 1.3.22
2020-12-21 09:31:35 +01:00
dependabot[bot]
d25fe58574 Bump sqlalchemy from 1.3.20 to 1.3.22
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.3.20 to 1.3.22.
- [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-12-21 08:19:10 +00:00
dependabot[bot]
8eb0130200 Bump pytest-mock from 3.3.1 to 3.4.0
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.3.1 to 3.4.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.3.1...v3.4.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 08:18:53 +00:00
Matthias
fae631c026 Merge pull request #4096 from freqtrade/dependabot/pip/develop/pytest-6.2.1
Bump pytest from 6.2.0 to 6.2.1
2020-12-21 07:41:05 +01:00
Matthias
08a1f74748 Merge pull request #4098 from freqtrade/dependabot/pip/develop/flake8-tidy-imports-4.2.1
Bump flake8-tidy-imports from 4.2.0 to 4.2.1
2020-12-21 07:40:46 +01:00
Matthias
537c20ed87 Merge pull request #4097 from freqtrade/dependabot/pip/develop/questionary-1.9.0
Bump questionary from 1.8.1 to 1.9.0
2020-12-21 07:40:20 +01:00
Matthias
3a46f02682 Merge pull request #4101 from freqtrade/dependabot/pip/develop/ccxt-1.39.52
Bump ccxt from 1.39.33 to 1.39.52
2020-12-21 07:39:34 +01:00
Matthias
e587c005de Merge pull request #4099 from freqtrade/dependabot/pip/develop/joblib-1.0.0
Bump joblib from 0.17.0 to 1.0.0
2020-12-21 07:35:09 +01:00
Matthias
bc110cfe8f Merge pull request #4095 from freqtrade/dependabot/pip/develop/requests-2.25.1
Bump requests from 2.25.0 to 2.25.1
2020-12-21 07:34:30 +01:00
dependabot[bot]
3b67863914 Bump ccxt from 1.39.33 to 1.39.52
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.39.33 to 1.39.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.39.33...1.39.52)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 05:36:27 +00:00
dependabot[bot]
a2873096c8 Bump flake8-tidy-imports from 4.2.0 to 4.2.1
Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases)
- [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/master/HISTORY.rst)
- [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/4.2.0...4.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 05:36:24 +00:00
dependabot[bot]
5716202e45 Bump joblib from 0.17.0 to 1.0.0
Bumps [joblib](https://github.com/joblib/joblib) from 0.17.0 to 1.0.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.17.0...1.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 05:36:24 +00:00
dependabot[bot]
fe27206926 Bump questionary from 1.8.1 to 1.9.0
Bumps [questionary](https://github.com/tmbo/questionary) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/tmbo/questionary/releases)
- [Commits](https://github.com/tmbo/questionary/compare/1.8.1...1.9.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 05:36:12 +00:00
dependabot[bot]
a1755364e1 Bump pytest from 6.2.0 to 6.2.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.0 to 6.2.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.2.0...6.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 05:36:09 +00:00
dependabot[bot]
e7e687c8ec Bump requests from 2.25.0 to 2.25.1
Bumps [requests](https://github.com/psf/requests) from 2.25.0 to 2.25.1.
- [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.25.0...v2.25.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 05:36:08 +00:00
Christof
5423c21be0 keyboard type 2020-12-20 22:51:40 +01:00
Christof
f39dde121a moved keyboard config validation to __inti__ 2020-12-20 22:36:56 +01:00
Christof
18a24d75ef cleanup 2020-12-20 21:31:01 +01:00
Christof
3cb559994e some more test 2020-12-20 21:31:01 +01:00
Christof
c1b8ad7232 renaming, comments, cleanups 2020-12-20 21:31:01 +01:00
Christof
fabb31e1bc imports order 2020-12-20 21:31:01 +01:00
Christof
f120c8d6c7 documentation 2020-12-20 21:31:01 +01:00
Christof
f24626e139 removed too many blank lines 2020-12-20 21:31:01 +01:00
Christof
43091a26ce simple tests 2020-12-20 21:28:57 +01:00
Christof
8b24878023 plot_config documentation for fill_to, fill_label, fill_color 2020-12-20 21:28:57 +01:00
Christof
5b2902fcbc cleanup 2020-12-20 21:28:57 +01:00
Christof
16baca5eeb fixed: too complex warning 2020-12-20 21:28:57 +01:00
Christof
d901a86165 typo 2020-12-20 21:28:57 +01:00
Christof
75e4758936 changed config params, added fill area in subplots 2020-12-20 21:28:57 +01:00
Christof
cc39cf97dd revert to former create_plotconfig behaviour 2020-12-20 21:28:57 +01:00
Christof
4531c924da PEP8 2020-12-20 21:28:57 +01:00
Christof
fb3d82ccb9 cleanup 2020-12-20 21:28:57 +01:00
Christof
fdd4b40c34 fixed subplots, empty create plot_config if its not given by strategie 2020-12-20 21:28:57 +01:00
Christof
daa1727e2b Exeption for fill_area.traces 2020-12-20 21:28:57 +01:00
Christof
3fdfc06a1e label for fill_area added and documentation updated 2020-12-20 21:28:57 +01:00
Christof
ecadfdd98e fixed:advanced config. added. feature: fill area between traces by advanced configuration. 2020-12-20 21:28:57 +01:00
Christof
6b44545d37 sort order imports 2020-12-20 21:06:45 +01:00
Christof
799e6be2eb fix tests 2020-12-20 21:06:45 +01:00
Christof
621105df9a renaming shortcut_btns to keyboard 2020-12-20 21:06:45 +01:00
Christof
bf92099486 test for custom keyboard 2020-12-20 21:06:45 +01:00
Christof
5b3ffd5141 better log msg, comments 2020-12-20 21:06:45 +01:00
Christof
5e6897b278 documentation for custom keyboard 2020-12-20 21:06:45 +01:00
Christof
e92bcb00f6 telegram: specify custom shortcut bottons (keyboard) in config.json 2020-12-20 21:06:45 +01:00
Matthias
8d3f096a97 AgeFilter does not require tickers 2020-12-20 20:08:54 +01:00
Matthias
d7daa86434 Add bybit subclass 2020-12-20 19:59:46 +01:00
Matthias
bd0af1b300 Fix test warning 2020-12-20 19:38:12 +01:00
Matthias
7d2395ddb7 Add limit parameter to fetch_ohlcv 2020-12-20 19:33:04 +01:00
Matthias
fc0d14c1b5 Improve documentation 2020-12-20 19:14:18 +01:00
Matthias
676dd0d664 Improve documentation 2020-12-20 11:22:15 +01:00
Matthias
9d5961e224 Rename method to custom_stoploss 2020-12-20 11:17:50 +01:00
Matthias
277342f167 Rename flag to "use_custom_stoposs" 2020-12-20 11:12:22 +01:00
Matthias
8574751a07 Add stoploss_value to strategy template 2020-12-20 10:49:22 +01:00
Matthias
f8639fe938 Add more tests for custom_loss 2020-12-19 20:36:19 +01:00
Matthias
5f8610b28f Add explicit test for stop_loss_reached 2020-12-19 20:08:03 +01:00
Matthias
22d64553c9 Rename test file 2020-12-19 18:00:44 +01:00
Matthias
ea4238e860 cleanup some tests 2020-12-19 17:59:49 +01:00
Matthias
11e2915621 Fix documentation problem 2020-12-19 17:44:39 +01:00
Matthias
6892c08e9b Improve docstring 2020-12-19 13:18:06 +01:00
Matthias
b2c1098316 more docs for dynamic stoploss method 2020-12-19 12:03:18 +01:00
Matthias
f7b54c2415 Allow and document time-based custom stoploss
closes #3206
2020-12-19 11:46:49 +01:00
Matthias
f235ab8cf4 Fix some typos in docs 2020-12-19 11:39:21 +01:00
Matthias
18795844d8 Add initial set of custom stoploss documentation 2020-12-19 11:37:20 +01:00
Matthias
a414b57d54 Experiment with custom stoploss interface 2020-12-18 06:56:56 +01:00
Matthias
8f6aefb591 Extract stoploss assignment 2020-12-18 06:56:56 +01:00
Matthias
768a24c375 Add stoplossvalue interface 2020-12-18 06:56:56 +01:00
Matthias
b9f3410d8b Merge pull request #4082 from bigchakalaka/patch-2
Update strategy-customization.md
2020-12-18 06:16:13 +01:00
bigchakalaka
ca9fd08991 Update strategy-customization.md 2020-12-17 21:40:54 +01:00
Matthias
4e7f914e92 Improve test for AgeFilter, fix bug in Agefilter 2020-12-17 13:34:53 +01:00
Matthias
266031a6be Disallow PerformanceFilter for backtesting
closes #4072
2020-12-16 19:24:47 +01:00
Matthias
8441d0f60f Merge pull request #4069 from freqtrade/refactor_ohlcv_download
Refactor pairlist ohlcv download to use async
2020-12-16 19:11:49 +01:00
Matthias
d1fda28d2e Fix typehints 2020-12-15 20:59:58 +01:00
Matthias
011ba1d9ae Adapt tests to use async methods 2020-12-15 20:49:46 +01:00
Matthias
3c85d5201f Use async to get candle data for pairlists 2020-12-15 20:38:26 +01:00
Matthias
f320cb0d7a Merge pull request #4068 from freqtrade/docker_stage_pi
Docker stage pi
2020-12-15 19:10:10 +01:00
Matthias
4c0edd0461 Move dependencies to base image for RPI 2020-12-15 09:28:56 +01:00
Matthias
c8dde63227 Allow test-pairlist to run with verbosity 2020-12-15 09:23:40 +01:00
Matthias
69901c1314 Provide pair to _validate_pairs in pairlists 2020-12-15 09:23:40 +01:00
Matthias
39fec25ae0 add optional Cache arguments to refresh_pairs method 2020-12-15 09:23:27 +01:00
Matthias
dc92808335 Change PI dockerfile to use staged build 2020-12-15 06:44:08 +01:00
Matthias
ca9036ee1d Merge pull request #3840 from freqtrade/dependabot/docker/python-3.9.0-slim-buster
Bump python from 3.8.6-slim-buster to 3.9.1-slim-buster (build actions using 3.9)
2020-12-14 20:44:29 +01:00
Matthias
e240f0b372 Merge branch 'develop' into dependabot/docker/python-3.9.0-slim-buster 2020-12-14 20:18:34 +01:00
Matthias
8366e2fd89 Merge pull request #4064 from freqtrade/dependabot/pip/develop/pytest-6.2.0
Bump pytest from 6.1.2 to 6.2.0
2020-12-14 19:46:13 +01:00
Matthias
9f5c4ead15 Remove support for 3.6 2020-12-14 19:18:54 +01:00
Matthias
66d5271ada Don't build for 3.6 any longer 2020-12-14 19:10:24 +01:00
Matthias
ba869a330f Build 3.6 on github actions too 2020-12-14 19:05:41 +01:00
dependabot[bot]
8965b8a18d Bump pytest from 6.1.2 to 6.2.0
Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.1.2 to 6.2.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.1.2...6.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 08:27:36 +00:00
Matthias
bf48df92c1 Merge pull request #4059 from freqtrade/dependabot/pip/develop/plotly-4.14.1
Bump plotly from 4.13.0 to 4.14.1
2020-12-14 07:42:24 +01:00
Matthias
e763aa04bd Merge pull request #4062 from freqtrade/dependabot/pip/develop/python-rapidjson-1.0
Bump python-rapidjson from 0.9.4 to 1.0
2020-12-14 07:40:49 +01:00
Matthias
36fba4826f Merge pull request #4058 from freqtrade/dependabot/pip/develop/cachetools-4.2.0
Bump cachetools from 4.1.1 to 4.2.0
2020-12-14 07:40:03 +01:00
Matthias
4813eec308 Merge pull request #4063 from freqtrade/dependabot/pip/develop/ccxt-1.39.33
Bump ccxt from 1.39.10 to 1.39.33
2020-12-14 07:39:30 +01:00
Matthias
aace993842 Merge pull request #4061 from freqtrade/dependabot/pip/develop/pandas-1.1.5
Bump pandas from 1.1.4 to 1.1.5
2020-12-14 07:38:45 +01:00
Matthias
834cf384f6 Merge pull request #4060 from freqtrade/dependabot/pip/develop/flake8-tidy-imports-4.2.0
Bump flake8-tidy-imports from 4.1.0 to 4.2.0
2020-12-14 07:37:00 +01:00
dependabot[bot]
a9b586d338 Bump ccxt from 1.39.10 to 1.39.33
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.39.10 to 1.39.33.
- [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.39.10...1.39.33)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 05:44:16 +00:00
dependabot[bot]
44f295110b Bump python-rapidjson from 0.9.4 to 1.0
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 0.9.4 to 1.0.
- [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.4...v1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 05:43:46 +00:00
dependabot[bot]
bdd895b8da Bump pandas from 1.1.4 to 1.1.5
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.1.4 to 1.1.5.
- [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.4...v1.1.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 05:43:42 +00:00
dependabot[bot]
a3139dd9d4 Bump flake8-tidy-imports from 4.1.0 to 4.2.0
Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases)
- [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/master/HISTORY.rst)
- [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/4.1.0...4.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 05:43:34 +00:00
dependabot[bot]
4cf16fa8d1 Bump plotly from 4.13.0 to 4.14.1
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.13.0 to 4.14.1.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.13.0...v4.14.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 05:43:33 +00:00
dependabot[bot]
3bea9255e7 Bump cachetools from 4.1.1 to 4.2.0
Bumps [cachetools](https://github.com/tkem/cachetools) from 4.1.1 to 4.2.0.
- [Release notes](https://github.com/tkem/cachetools/releases)
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v4.1.1...v4.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 05:43:33 +00:00
Matthias
dad427461d Downgrade dockerfile to 3.8.6 to avoid image bloat 2020-12-13 13:11:04 +01:00
Matthias
a4bfd0b0aa Split linux and OSX builds into 2 seperate, parallel jobs 2020-12-13 11:25:42 +01:00
Matthias
be555895b2 Merge branch 'develop' into dependabot/docker/python-3.9.0-slim-buster 2020-12-13 11:24:23 +01:00
Matthias
7c6357cc45 Merge pull request #4041 from freqtrade/plugins/protections_backtest
Introduce Protection Plugins
2020-12-13 11:08:24 +01:00
Matthias
657b002a81 Explicitly check for False in fetch_ticker 2020-12-13 10:59:29 +01:00
Matthias
9cd1be8f93 Update usage of open_trade_price to open_trade_value 2020-12-13 10:33:45 +01:00
Matthias
7eab33de08 Merge branch 'develop' into plugins/protections_backtest 2020-12-13 10:31:33 +01:00
Matthias
8a2fbf6592 Small cleanup of protection stuff 2020-12-13 10:16:09 +01:00
Matthias
1436dc58f5 Merge pull request #4057 from freqtrade/avoid_high_fee_wrong_reports
Avoid high fee wrong reports
2020-12-12 20:04:06 +01:00
Matthias
14647fb5f0 Add tests for update fee 2020-12-12 11:49:52 +01:00
Matthias
3ee7fe64ba Clean up some tests 2020-12-12 11:25:56 +01:00
Matthias
181b88dc75 Don't accept too high fees, assuming they are erroneous
Forces fallback to "detection from trades"
2020-12-12 10:52:27 +01:00
Matthias
aa4ac87fd4 Merge pull request #4052 from Samaoo/patch-4
Update backtesting.md
2020-12-12 10:48:23 +01:00
Samaoo
b45c2fb1d0 Update backtesting.md 2020-12-12 10:27:17 +01:00
Matthias
6107878f4e Bump ccxt to 1.39.10
closes #4051
2020-12-12 07:08:29 +01:00
Matthias
aab8e36e78 Merge pull request #4046 from dmmop/patch-1
Update dockerfile to multistage
2020-12-11 09:10:36 +01:00
Matthias
c784e5780e Merge pull request #4054 from freqtrade/models_open_price
Models open price
2020-12-11 06:31:02 +01:00
Matthias
95fd3824da Finish renamal of open_trade_price to open_value 2020-12-10 19:36:52 +01:00
Matthias
201cc67e05 Rename open_trade_price to "open_trade_value" 2020-12-10 19:21:20 +01:00
Matthias
76594d5dde Merge pull request #3799 from imxuwang/issue3783
Introduce Telegram /stats endpoint
2020-12-10 15:41:09 +01:00
Matthias
ca99d484fc Refactor to use list comprehension 2020-12-10 07:39:50 +01:00
Matthias
33f330256b Reorder commands on telegram init 2020-12-09 20:36:30 +01:00
Samaoo
af53dfbfab Update backtesting.md 2020-12-09 15:57:15 +01:00
Samaoo
f5817063b7 Update backtesting.md 2020-12-09 15:53:38 +01:00
David Martinez Martin
25f8e0cc57 Added git packages for future dependencies 2020-12-09 11:28:45 +01:00
David Martinez Martin
5708098256 Move ENV PATH to base image 2020-12-09 10:34:38 +01:00
Matthias
7126aa9514 Merge pull request #4047 from freqtrade/strategy_manatory
Ensure non-defined attributes fail correctly
2020-12-09 10:27:29 +01:00
Matthias
f1af2972e2 Ensure non-defined attributes fail correctly
Remove unnecessary check, as stoploss cannot be none (it's mandatory and
a number)
2020-12-09 07:55:08 +01:00
David Martinez Martin
e6b3e64534 Update dockerfile to multistage
This change reduce the image size from 727Mb to 469Mb.
2020-12-09 03:27:59 +01:00
Matthias
d9a86158f4 Add cmake to support raspberry 64bit installs 2020-12-08 19:46:54 +01:00
Matthias
ad7b29cc1d Merge pull request #4045 from Samaoo/patch-3
Update data-download.md
2020-12-08 19:14:17 +01:00
Samaoo
118a22d010 Update data-download.md 2020-12-08 18:04:26 +01:00
Matthias
9725b8e17c Update Dockerfile 2020-12-08 08:43:22 +01:00
Matthias
f897b683c7 Add seperate page describing plugins 2020-12-07 19:22:14 +01:00
Matthias
82bc6973fe Add last key to config_full 2020-12-07 16:16:33 +01:00
Matthias
c37bc307e2 Small finetunings to documentation 2020-12-07 16:12:03 +01:00
Matthias
b5289d5f0e Update full config with correct protection keys 2020-12-07 16:02:55 +01:00
Matthias
de2cc9708d Fix test leakage 2020-12-07 16:01:29 +01:00
Matthias
f047297995 Improve wording, fix bug 2020-12-07 15:48:06 +01:00
Matthias
3ab5514697 Add API endpoint for /stats 2020-12-07 15:07:08 +01:00
Matthias
81410fb404 Document /stats for telegram 2020-12-07 15:03:16 +01:00
Matthias
e873cafdc4 Beautify code a bit 2020-12-07 14:54:39 +01:00
Matthias
effc96e92b Improve tests for backtest protections 2020-12-07 11:39:01 +01:00
Matthias
5849d07497 Export locks as part of backtesting 2020-12-07 11:39:01 +01:00
Matthias
57a4044eb0 Enhance test verifying that locks are not replaced 2020-12-07 11:39:01 +01:00
Matthias
bb51da8297 Fix slow backtest due to protections 2020-12-07 11:39:01 +01:00
Matthias
75a5161650 Support multis-strategy backtests with protections 2020-12-07 11:39:01 +01:00
Matthias
a3f9cd2c26 Only load protections when necessary 2020-12-07 11:39:01 +01:00
Matthias
946fb09455 Update help command output 2020-12-07 11:39:01 +01:00
Matthias
e2d15f4082 Add parameter to enable protections for backtesting 2020-12-07 11:39:01 +01:00
Matthias
32189d27c8 Disable output from plugins in backtesting 2020-12-07 11:39:01 +01:00
Matthias
9f34aebdaa Allow closing trades without message 2020-12-07 11:39:01 +01:00
Matthias
b606936eb7 Make changes to backtesting to incorporate protections 2020-12-07 11:39:01 +01:00
Matthias
98c88fa58e Prepare protections for backtesting 2020-12-07 11:39:01 +01:00
Matthias
3426e99b8b Improve formatting of protection startup message 2020-12-07 11:37:57 +01:00
Matthias
64d6c7bb65 Update developer docs 2020-12-07 11:17:11 +01:00
Matthias
0e2a43ab4d Add duration_explanation functions 2020-12-07 11:12:09 +01:00
Matthias
c993831a04 Add protections to startup messages 2020-12-07 10:57:01 +01:00
Matthias
d4799e6aa3 Implement *candle definitions 2020-12-07 10:54:26 +01:00
Matthias
a93bb6853b Document *candles settings, implement validations 2020-12-07 10:47:13 +01:00
Matthias
eb952d77be Move lookback_period to parent __init__ 2020-12-07 08:27:14 +01:00
Matthias
f13e9ce5ed Improve docs 2020-12-07 08:23:10 +01:00
Matthias
b36f333b2f Add new protections to full sample, documentation 2020-12-07 08:23:10 +01:00
Matthias
f06b58dc91 Test MaxDrawdown desc 2020-12-07 08:23:10 +01:00
Matthias
089c463cfb Introduce max_drawdown protection 2020-12-07 08:23:10 +01:00
Matthias
9d6f3a89ef Improve docs and fix typos 2020-12-07 08:23:10 +01:00
Matthias
768d7fa196 Readd optional for get_pair_locks - it's necessary 2020-12-07 08:23:10 +01:00
Matthias
9947dcd1da Beta feature warning 2020-12-07 08:23:10 +01:00
Matthias
ad746627b3 Fix lock-loop 2020-12-07 08:23:10 +01:00
Matthias
397a15cb61 Improve protection documentation 2020-12-07 08:23:10 +01:00
Matthias
4351a26b4c Move stop_duration to parent class
avoids reimplementation and enhances standardization
2020-12-07 08:23:10 +01:00
Matthias
12e84bda1e Add developer docs for Protections 2020-12-07 08:23:10 +01:00
Matthias
6d0f16920f Get Longest lock logic 2020-12-07 08:23:10 +01:00
Matthias
dce2364672 Add stoploss per pair support 2020-12-07 08:23:10 +01:00
Matthias
dcdf4a0503 Improve tests 2020-12-07 08:23:10 +01:00
Matthias
32cde1cb7d Improve test for lowprofitpairs 2020-12-07 08:23:10 +01:00
Matthias
8f958ef723 Improve login-mixin structure 2020-12-07 08:23:10 +01:00
Matthias
8d9c66a638 Add LogginMixin to freqtradebot class to avoid over-logging 2020-12-07 08:23:10 +01:00
Matthias
be57ceb252 Remove confusing entry
(in this branch of the if statement, candle_date is empty
2020-12-07 08:23:10 +01:00
Matthias
5e3d2401f5 Only call stop methods when they actually support this method 2020-12-07 08:23:10 +01:00
Matthias
2cd54a5933 Allow disabling output from plugins 2020-12-07 08:23:10 +01:00
Matthias
8ebd6ad200 Rename login-mixin log method 2020-12-07 08:23:10 +01:00
Matthias
2e5b9fd4b2 format profit in low_profit_pairs 2020-12-07 08:23:10 +01:00
Matthias
e29d918ea5 Avoid double-locks also in per pair locks 2020-12-07 08:23:10 +01:00
Matthias
fc97266dd4 Add "now" to lock_pair method 2020-12-07 08:23:10 +01:00
Matthias
59091ef2b7 Add helper method to calculate protection until 2020-12-07 08:23:10 +01:00
Matthias
47cd856fea Include protection documentation 2020-12-07 08:23:10 +01:00
Matthias
5133675988 Apply all stops in the list, even if the first would apply already 2020-12-07 08:23:10 +01:00
Matthias
9484ee6690 Test for low_profit_pairs 2020-12-07 08:23:10 +01:00
Matthias
bb06365c50 Improve protection documentation 2020-12-07 08:23:10 +01:00
Matthias
1f703dc341 Improve protection documentation 2020-12-07 08:23:10 +01:00
Matthias
00d4820bc1 Add low_profit_pairs 2020-12-07 08:23:10 +01:00
Matthias
9f6c2a583f Better wording for config options 2020-12-07 08:23:10 +01:00
Matthias
8dbef6bbea Add test for cooldown period 2020-12-07 08:23:10 +01:00
Matthias
fe0afb9883 Implement calling of per-pair protection 2020-12-07 08:23:10 +01:00
Matthias
2a66c33a4e Add locks per pair 2020-12-07 08:23:10 +01:00
Matthias
ff7ba23477 Simplify enter_positions and add global pairlock check 2020-12-07 08:23:10 +01:00
Matthias
05be33ccd4 Simplify is_pair_locked 2020-12-07 08:23:10 +01:00
Matthias
56975db2ed Add more tests 2020-12-07 08:23:10 +01:00
Matthias
2b85e7eac3 Add initial tests for StoplossGuard protection 2020-12-07 08:23:10 +01:00
Matthias
816703b8e1 Improve protections work 2020-12-07 08:23:10 +01:00
Matthias
f39a534fc0 Implement global stop (First try) 2020-12-07 08:23:10 +01:00
Matthias
246b4a57a4 add small note to pairlist dev docs 2020-12-07 08:23:10 +01:00
Matthias
04878c3ce1 Rename test directory for pairlist 2020-12-07 08:23:10 +01:00
Matthias
3447f1ae53 Implement first stop method 2020-12-07 08:23:10 +01:00
Matthias
a0bd2ce837 Add first version of protection manager 2020-12-07 08:23:10 +01:00
Matthias
b6b9c8e5cc Move "slow-log" to it's own mixin 2020-12-07 08:23:10 +01:00
Matthias
f01d86060a Merge pull request #4040 from freqtrade/dependabot/pip/develop/ccxt-1.38.87
Bump ccxt from 1.38.55 to 1.38.87
2020-12-07 08:12:30 +01:00
Matthias
1fd652d3de Merge pull request #4039 from freqtrade/dependabot/pip/develop/mkdocs-material-6.1.7
Bump mkdocs-material from 6.1.6 to 6.1.7
2020-12-07 08:06:02 +01:00
dependabot[bot]
647e6509a4 Bump ccxt from 1.38.55 to 1.38.87
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.38.55 to 1.38.87.
- [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.38.55...1.38.87)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-07 05:48:43 +00:00
dependabot[bot]
0c0eb8236d Bump mkdocs-material from 6.1.6 to 6.1.7
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.6 to 6.1.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/6.1.6...6.1.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-07 05:48:23 +00:00
Matthias
51fbd0698c Move get_logs to be static method 2020-12-06 19:57:48 +01:00
Matthias
245c19f5e9 Add simple test for /stats call 2020-12-05 14:48:56 +01:00
Matthias
aa27c9ace2 Reorder methods in telegram
/stats is closely related to /profit
2020-12-05 14:39:50 +01:00
Matthias
143423145c Refactor most of the logic to rpc.py
this way /stats can be used by other RPC methods too
2020-12-05 14:38:42 +01:00
Matthias
c556d1b37e Make /stats working 2020-12-05 14:06:46 +01:00
Matthias
8f61b68b2a Merge branch 'develop' into pr/imxuwang/3799 2020-12-05 14:06:23 +01:00
Matthias
058d40a72c Fix telegram /daily command without arguments 2020-12-05 08:16:40 +01:00
Matthias
71e46794b4 Add updating documentation
closes #4036
2020-12-04 19:59:26 +01:00
Matthias
f37af9d98a Merge pull request #4033 from Samaoo/patch-2
Put dollar sign after amount in edge.md
2020-12-04 19:50:46 +01:00
Samaoo
7f453033a4 Update edge.md 2020-12-04 16:53:41 +01:00
Matthias
2fbbeb970b Gracefully handle cases where no buy price was found
closes #4030
2020-12-04 07:42:16 +01:00
Matthias
22595e6f92 Merge pull request #3929 from radwayne/roi_trailing_backtest
change backtesting behaviour if roi and trailing-stop happen at the same time
2020-12-03 19:40:46 +01:00
Matthias
01cb676f2c Merge pull request #4015 from freqtrade/dependabot/pip/develop/python-telegram-bot-13.1
Bump python-telegram-bot from 13.0 to 13.1
2020-12-02 19:02:10 +01:00
Matthias
9e063b9fc8 Merge pull request #4026 from Samaoo/patch-1
Update faq.md
2020-12-02 09:05:59 +01:00
Samaoo
9b4a81c0a4 Update faq.md 2020-12-02 08:40:49 +01:00
Matthias
c09c23eab1 Make sure non-int telegram values don't crash the bot 2020-12-02 07:51:59 +01:00
Matthias
d039ce1fb3 Update available columns for hyperopt
closes #4025
2020-12-02 06:46:18 +01:00
Matthias
4f8bc73d1a Merge pull request #4024 from Samaoo/patch-2
Update faq.md
2020-12-02 06:40:02 +01:00
Samaoo
3c4fe66d86 Update faq.md 2020-12-01 21:50:51 +01:00
Samaoo
4bc24ece41 Update faq.md 2020-12-01 21:49:50 +01:00
Samaoo
c1fffb9925 Update faq.md 2020-12-01 21:38:54 +01:00
Matthias
d6cc3d7374 Improve FAQ
related to question in #4023
2020-12-01 19:58:06 +01:00
Matthias
5dfa1807a3 Fix tests after small updates 2020-12-01 19:57:43 +01:00
Matthias
36b7edc342 Update typing errors 2020-12-01 19:57:09 +01:00
Matthias
de0c5f9133 Merge pull request #4022 from freqtrade/pi_setup
improve setup.sh script
2020-12-01 07:03:26 +01:00
Matthias
cec771b593 Ask for plotting dependency installation 2020-12-01 06:48:16 +01:00
Matthias
5f70d1f9a7 Ask for hyperopt installation during setup
closes #2871
2020-12-01 06:48:16 +01:00
Matthias
95b24ba8a9 Update setup.sh with some specifics 2020-12-01 06:48:12 +01:00
Matthias
202ca88e23 Changes to pi steup 2020-11-30 17:37:19 +01:00
dependabot[bot]
14d44b2cd6 Bump python-telegram-bot from 13.0 to 13.1
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 13.0 to 13.1.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v13.0...v13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-30 08:02:09 +00:00
Matthias
dda5bcbc8d Merge pull request #4009 from mrsegen/patch-4
[Pairlist] Add PerformanceFilter
2020-11-30 07:48:15 +01:00
Matthias
5da41160bf Merge pull request #4017 from freqtrade/dependabot/pip/develop/ccxt-1.38.55
Bump ccxt from 1.38.13 to 1.38.55
2020-11-30 07:29:14 +01:00
Matthias
a22fd7eb3b Merge pull request #4016 from freqtrade/dependabot/pip/develop/plotly-4.13.0
Bump plotly from 4.12.0 to 4.13.0
2020-11-30 07:29:01 +01:00
dependabot[bot]
275cfb3a9c Bump ccxt from 1.38.13 to 1.38.55
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.38.13 to 1.38.55.
- [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.38.13...1.38.55)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-30 05:42:12 +00:00
dependabot[bot]
f17c7f0609 Bump plotly from 4.12.0 to 4.13.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 4.12.0 to 4.13.0.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v4.12.0...v4.13.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-30 05:42:00 +00:00
Leif Segen
b7de18608d Trigger CI 2020-11-29 10:30:43 -06:00
Leif Segen
99abe52043 Trigger CI 2020-11-29 10:30:02 -06:00
Leif Segen
5f8e67d2b2 Update docs/includes/pairlists.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2020-11-29 05:05:54 -06:00
Matthias
18de9cc5e5 Merge pull request #4012 from freqtrade/best_worst_pair
Enhance backtesting summary report
2020-11-29 10:54:09 +01:00
Leif Segen
90070f0dc5 Force test rerun 2020-11-28 17:17:40 -06:00
Leif Segen
1791495475 Trigger another run of tests 2020-11-28 16:50:44 -06:00
Leif Segen
4b6f5b92b5 Remove non-pertinent test case 2020-11-28 12:47:36 -06:00
Leif Segen
e7a035eefe Lint 2020-11-28 12:29:31 -06:00
Leif Segen
d6c9391924 Restoring expectation 2020-11-28 12:18:23 -06:00
Leif Segen
323c0657f8 Sort by profit after sort by count/pair 2020-11-28 12:17:03 -06:00
Leif Segen
6a74c57c3d Pair name-based sorting.
Attempt at more rational string sorting. Change test to show not working as expected.
2020-11-28 11:33:25 -06:00
Matthias
e40d97e05e Small formatting improvements 2020-11-28 17:52:29 +01:00
Matthias
5d3f59df90 Add best / worst trade 2020-11-28 17:45:56 +01:00
Matthias
a00f852cf9 Add best / worst pair to summary statistics 2020-11-28 17:37:10 +01:00
Leif Segen
03c5714399 Use explicit merge without depending on library detail. Add no trades case. 2020-11-28 09:45:17 -06:00
Leif Segen
e1d42ba78c Alphabetize 2020-11-28 09:44:01 -06:00
Matthias
56529180eb Further improve hyperopt docs 2020-11-28 16:42:08 +01:00
Matthias
ff286bd80c Slightly clarify hyperopt docs 2020-11-28 16:32:44 +01:00
Matthias
a47d8dbe56 Small refactor, avoiding duplicate calculation of profits 2020-11-28 11:35:29 +01:00
Matthias
829a47b187 Merge pull request #4006 from freqtrade/remove_deprecated_experimentals
Remove deprecated experimental settings
2020-11-28 10:34:47 +01:00
Matthias
4cb331b5ad Remove non-needed parameters from tests 2020-11-28 10:24:44 +01:00
Matthias
b7703e6428 Merge pull request #4007 from mrsegen/patch-2
Fix link
2020-11-28 10:22:58 +01:00
Leif Segen
37d2e476df isort imports 2020-11-28 01:59:30 -06:00
Leif Segen
f448564073 Lint 2020-11-28 01:49:46 -06:00
Leif Segen
ecce5265f5 Linting 2020-11-28 01:43:19 -06:00
Leif Segen
fefa500963 More lint 2020-11-28 01:34:40 -06:00
Leif Segen
966c6b308f Satisfy linter. 2020-11-28 01:34:18 -06:00
Leif Segen
1f7d681ddb Merge branch 'patch-4' of https://github.com/mrsegen/freqtrade into patch-4 2020-11-28 01:22:15 -06:00
Leif Segen
dbd50fdff6 Document filter. 2020-11-28 01:22:03 -06:00
Leif Segen
cfbd1c4c43 Merge branch 'develop' into patch-4 2020-11-28 01:17:34 -06:00
Leif Segen
662ec32073 Add test cases 2020-11-28 01:15:36 -06:00
Leif Segen
26855800a3 Remove unused seed 2020-11-28 00:39:18 -06:00
Leif Segen
4600bb807c Existing tests pass. 2020-11-28 00:38:06 -06:00
Leif Segen
9538fa1d72 Tweak main parameterized block for PerformanceFilter
Remove randomized exception that was geared toward ShuffleFilter. Remove case involvoing seed, also geared toward ShuffleFilter. Mock get_overall_performance().
2020-11-28 00:24:48 -06:00
Leif Segen
91b4c80d35 Remove unused parameters 2020-11-27 22:18:49 -06:00
Leif Segen
afb795b6f5 Remove unnecessary test
PerforamnceFilter doesn't use seeds, so no need to provide different ones.
2020-11-27 22:08:23 -06:00
Leif Segen
380cca2252 Remove unused imports 2020-11-27 22:00:48 -06:00
Leif Segen
3357350628 Revert unintended change 2020-11-27 22:00:36 -06:00
Leif Segen
c34150552f Revert unrelated change 2020-11-27 21:36:55 -06:00
Leif Segen
05686998bb Add starter entry in documentation 2020-11-27 21:26:42 -06:00
Leif Segen
7cbd89657f Initial step towards implementing proposed code 2020-11-27 21:24:40 -06:00
Leif Segen
89573348b6 Fix link 2020-11-27 20:37:52 -06:00
Matthias
af1b3721fb remove duplicate settings check 2020-11-27 20:28:17 +01:00
Matthias
95c3c45ec9 Remove long deprecated settings that moved from experimental to
ask_strategy
2020-11-27 20:24:32 +01:00
Leif Segen
46ec6f498c Correct link
Fix prior redirection to a non-working link: https://www.freqtrade.io/en/latest/telegram-usage/configuration/#understand-forcebuy_enable
2020-11-27 12:51:44 -06:00
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
c69ce28b76 Update backtest assumption documentation 2020-11-27 09:26:58 +01:00
Matthias
fefb4b23d0 revise logic in should_sell 2020-11-27 09:24:53 +01:00
Matthias
4aa6ebee04 Add more tests for #2422 2020-11-27 09:17:25 +01:00
Matthias
57461a59f3 Update backtesting documentation with new logic 2020-11-27 08:30:17 +01:00
Matthias
81d08c4def Add detailed backtest test verifying the ROI / trailing stop collision 2020-11-27 08:24:56 +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
Leif Segen
d959eeb97d Merge pull request #2 from freqtrade/develop
catch up forked dev with original dev
2020-11-23 22:11:17 -06:00
Leif Segen
312533fded Match current dev file 2020-11-23 22:08:53 -06: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
7a8b274a44 Merge branch 'develop' into pr/imxuwang/3799 2020-11-19 13:18:03 +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
dd42d61d03 Run CI on 3.9 2020-11-17 19:44:39 +01:00
dependabot[bot]
181d3a3808 Bump python from 3.8.6-slim-buster to 3.9.0-slim-buster
Bumps python from 3.8.6-slim-buster to 3.9.0-slim-buster.

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-17 19:44:05 +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
radwayne
8e03fee868 Update interface.py
Changed The should_sell() method, to handle the case where both ROI and trailing stoploss are reached in backtest.
2020-11-06 13:56:46 +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
50e7418d24 Merge branch 'develop' into pr/imxuwang/3799 2020-10-22 08:05:09 +02:00
Matthias
9999017953 Fix small bug in case of duplicate locks 2020-10-22 08:04:48 +02:00
Matthias
2f91f87ad3 Merge branch 'develop' into pr/imxuwang/3799 2020-10-22 07:55: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
Xu Wang
1c27aaab72 Declare type of 'dur'. 2020-10-18 20:24:13 +01: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
Xu Wang
355afc082e Add command 'stats' in expected test output. 2020-10-05 10:05:15 +01: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
Xu Wang
7bce2cd29d Add trade duration by win/loss. 2020-09-28 20:30:20 +01: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
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
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
Xu Wang
627e221b65 Use tabulate to create sell reason message. 2020-09-27 20:23:13 +01: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
Xu Wang
44ad0f631c Summarize trade reason for telegram command /stats. 2020-09-26 22:40:54 +01:00
Xu Wang
28411da83e Add the telegram command function template. 2020-09-22 22:28:12 +01:00
Leif Segen
1b4b10f8cd Update docs/installation.md
Address that numpy is required before `python3 -m pip install -r requirements.txt` can run.
2019-07-23 23:45:27 -05:00
241 changed files with 11020 additions and 4963 deletions

View File

@@ -3,13 +3,15 @@ FROM freqtradeorg/freqtrade:develop
# Install dependencies
COPY requirements-dev.txt /freqtrade/
RUN apt-get update \
&& apt-get -y install git sudo vim \
&& apt-get -y install git mercurial 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 \
&& mv /root/.local /home/ftuser/.local/ \
&& chown ftuser:ftuser -R /home/ftuser/.local/ \
&& chown ftuser: -R /home/ftuser/
USER ftuser

View File

@@ -7,8 +7,8 @@ services:
dockerfile: ".devcontainer/Dockerfile"
volumes:
# Allow git usage within container
- "/home/${USER}/.ssh:/home/ftuser/.ssh:ro"
- "/home/${USER}/.gitconfig:/home/ftuser/.gitconfig:ro"
- "${HOME}/.ssh:/home/ftuser/.ssh:ro"
- "${HOME}/.gitconfig:/home/ftuser/.gitconfig:ro"
- ..:/freqtrade:cached
# Persist bash-history
- freqtrade-vscode-server:/home/ftuser/.vscode-server

View File

@@ -1,5 +1,5 @@
---
name: BQuestion
name: Question
about: Ask a question you could not find an answer in the docs
title: ''
labels: "Question"

View File

@@ -14,43 +14,36 @@ on:
- cron: '0 5 * * 4'
jobs:
build:
build_linux:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-18.04, macos-latest ]
python-version: [3.7, 3.8]
os: [ ubuntu-18.04, ubuntu-20.04 ]
python-version: [3.7, 3.8, 3.9]
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 }}
- name: Cache_dependencies
uses: actions/cache@v1
uses: actions/cache@v2
id: cache
with:
path: ~/dependencies/
key: ${{ runner.os }}-dependencies
- name: pip cache (linux)
uses: actions/cache@preview
uses: actions/cache@v2
if: startsWith(matrix.os, 'ubuntu')
with:
path: ~/.cache/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
- name: pip cache (macOS)
uses: actions/cache@preview
if: startsWith(matrix.os, 'macOS')
with:
path: ~/Library/Caches/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
- name: TA binary *nix
if: steps.cache.outputs.cache-hit != 'true'
run: |
@@ -68,9 +61,15 @@ jobs:
- name: Tests
run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc
if: matrix.python-version != '3.9'
- name: Tests incl. ccxt compatibility tests
run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc --longrun
if: matrix.python-version == '3.9'
- 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
@@ -80,20 +79,24 @@ jobs:
- name: Backtesting
run: |
cp config.json.example config.json
cp config_bittrex.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt
run: |
cp config.json.example config.json
cp config_bittrex.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt --print-all
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
@@ -109,6 +112,99 @@ jobs:
channel: '#notifications'
url: ${{ secrets.SLACK_WEBHOOK }}
build_macos:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ macos-latest ]
python-version: [3.7, 3.8, 3.9]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Cache_dependencies
uses: actions/cache@v2
id: cache
with:
path: ~/dependencies/
key: ${{ runner.os }}-dependencies
- name: pip cache (macOS)
uses: actions/cache@v2
if: startsWith(matrix.os, 'macOS')
with:
path: ~/Library/Caches/pip
key: test-${{ matrix.os }}-${{ matrix.python-version }}-pip
- name: TA binary *nix
if: steps.cache.outputs.cache-hit != 'true'
run: |
cd build_helpers && ./install_ta-lib.sh ${HOME}/dependencies/; cd ..
- name: Installation - macOS
run: |
brew install hdf5 c-blosc
python -m pip install --upgrade pip
export LD_LIBRARY_PATH=${HOME}/dependencies/lib:$LD_LIBRARY_PATH
export TA_LIBRARY_PATH=${HOME}/dependencies/lib
export TA_INCLUDE_PATH=${HOME}/dependencies/include
pip install -r requirements-dev.txt
pip install -e .
- name: Tests
run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc
- name: Coveralls
if: (startsWith(matrix.os, 'ubuntu-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
run: |
# Allow failure for coveralls
coveralls -v || true
- name: Backtesting
run: |
cp config_bittrex.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt
run: |
cp config_bittrex.json.example config.json
freqtrade create-userdir --userdir user_data
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
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
if: failure() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
with:
type: ${{ job.status }}
job_name: '*Freqtrade CI ${{ matrix.os }}*'
mention: 'here'
mention_if: 'failure'
channel: '#notifications'
url: ${{ secrets.SLACK_WEBHOOK }}
build_windows:
runs-on: ${{ matrix.os }}
@@ -121,7 +217,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 }}
@@ -142,15 +238,15 @@ jobs:
- name: Backtesting
run: |
cp config.json.example config.json
cp config_bittrex.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
- name: Hyperopt
run: |
cp config.json.example config.json
cp config_bittrex.json.example config.json
freqtrade create-userdir --userdir user_data
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt --print-all
freqtrade hyperopt --datadir tests/testdata -e 5 --strategy SampleStrategy --hyperopt SampleHyperOpt --hyperopt-loss SharpeHyperOptLossDaily --print-all
- name: Flake8
run: |
@@ -172,7 +268,7 @@ jobs:
url: ${{ secrets.SLACK_WEBHOOK }}
docs_check:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
@@ -180,6 +276,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,7 +297,7 @@ 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
@@ -200,8 +307,8 @@ jobs:
# 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
needs: [ build_linux, build_macos, build_windows, docs_check ]
runs-on: ubuntu-20.04
steps:
- name: Slack Notification
uses: homoluctus/slatify@v1.8.0
@@ -213,14 +320,15 @@ jobs:
url: ${{ secrets.SLACK_WEBHOOK }}
deploy:
needs: [ build, build_windows, docs_check ]
runs-on: ubuntu-18.04
needs: [ build_linux, build_macos, build_windows, docs_check ]
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

1
.gitignore vendored
View File

@@ -8,6 +8,7 @@ user_data/*
user_data/notebooks/*
freqtrade-plot.html
freqtrade-profit-plot.html
freqtrade/rpc/api_server/ui/*
# Byte-compiled / optimized / DLL files
__pycache__/

View File

@@ -4,5 +4,5 @@ build:
image: latest
python:
version: 3.6
setup_py_install: false
version: 3.8
setup_py_install: false

View File

@@ -1,9 +1,9 @@
os:
- linux
dist: xenial
dist: bionic
language: python
python:
- 3.6
- 3.8
services:
- docker
env:
@@ -26,14 +26,14 @@ jobs:
# - coveralls || true
name: pytest
- script:
- cp config.json.example config.json
- cp config_bittrex.json.example config.json
- freqtrade create-userdir --userdir user_data
- freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy
name: backtest
- script:
- cp config.json.example config.json
- cp config_bittrex.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

@@ -12,8 +12,7 @@ Few pointers for contributions:
- 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-mm786y93-Fxo37glxMY9g8OQC5AoOIw) or in a [issue](https://github.com/freqtrade/freqtrade/issues) before a PR.
## Getting started
@@ -65,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

View File

@@ -1,29 +1,48 @@
FROM python:3.8.6-slim-buster
FROM python:3.9.2-slim-buster as base
RUN apt-get update \
&& apt-get -y install curl build-essential libssl-dev sqlite3 \
&& apt-get clean \
&& pip install --upgrade pip
# Setup env
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONFAULTHANDLER 1
ENV PATH=/root/.local/bin:$PATH
# Prepare environment
RUN mkdir /freqtrade
WORKDIR /freqtrade
# Install dependencies
FROM base as python-deps
RUN apt-get update \
&& apt-get -y install curl build-essential libssl-dev git \
&& apt-get clean \
&& pip install --upgrade pip
# Install TA-lib
COPY build_helpers/* /tmp/
RUN cd /tmp && /tmp/install_ta-lib.sh && rm -r /tmp/*ta-lib*
ENV LD_LIBRARY_PATH /usr/local/lib
# Install dependencies
COPY requirements.txt requirements-hyperopt.txt /freqtrade/
RUN pip install numpy --no-cache-dir \
&& pip install -r requirements-hyperopt.txt --no-cache-dir
RUN pip install --user --no-cache-dir numpy \
&& pip install --user --no-cache-dir -r requirements-hyperopt.txt
# Copy dependencies to runtime-image
FROM base as runtime-image
COPY --from=python-deps /usr/local/lib /usr/local/lib
ENV LD_LIBRARY_PATH /usr/local/lib
COPY --from=python-deps /root/.local /root/.local
# Install and execute
COPY . /freqtrade/
RUN pip install -e . --no-cache-dir \
&& mkdir /freqtrade/user_data/
&& mkdir /freqtrade/user_data/ \
&& freqtrade install-ui
ENTRYPOINT ["freqtrade"]
# Default to trade mode
CMD [ "trade" ]

View File

@@ -1,29 +1,49 @@
FROM --platform=linux/arm/v7 python:3.7.7-slim-buster
FROM --platform=linux/arm/v7 python:3.7.9-slim-buster as base
RUN apt-get update \
&& 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
# Setup env
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONFAULTHANDLER 1
ENV PATH=/root/.local/bin:$PATH
# Prepare environment
RUN mkdir /freqtrade
WORKDIR /freqtrade
RUN apt-get update \
&& apt-get -y install libatlas3-base curl sqlite3 \
&& apt-get clean
# Install dependencies
FROM base as python-deps
RUN apt-get -y install build-essential libssl-dev libffi-dev libgfortran5 \
&& apt-get clean \
&& pip install --upgrade pip \
&& echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > /etc/pip.conf
# Install TA-lib
COPY build_helpers/* /tmp/
RUN cd /tmp && /tmp/install_ta-lib.sh && rm -r /tmp/*ta-lib*
ENV LD_LIBRARY_PATH /usr/local/lib
# Install dependencies
COPY requirements.txt /freqtrade/
RUN pip install numpy --no-cache-dir \
&& pip install -r requirements.txt --no-cache-dir
RUN pip install --user --no-cache-dir numpy \
&& pip install --user --no-cache-dir -r requirements.txt
# Copy dependencies to runtime-image
FROM base as runtime-image
COPY --from=python-deps /usr/local/lib /usr/local/lib
ENV LD_LIBRARY_PATH /usr/local/lib
COPY --from=python-deps /root/.local /root/.local
# Install and execute
COPY . /freqtrade/
RUN pip install -e . --no-cache-dir
RUN pip install -e . --no-cache-dir \
&& freqtrade install-ui
ENTRYPOINT ["freqtrade"]
# Default to trade mode
CMD [ "trade" ]

View File

@@ -1,5 +1,6 @@
include LICENSE
include README.md
include config.json.example
recursive-include freqtrade *.py
recursive-include freqtrade/templates/ *.j2 *.ipynb
include freqtrade/rpc/api_server/ui/fallback_file.html
include freqtrade/rpc/api_server/ui/favicon.ico

View File

@@ -22,12 +22,21 @@ expect.
We strongly recommend you to have coding and Python knowledge. Do not
hesitate to read the source code and understand the mechanism of this bot.
## Exchange marketplaces supported
## Supported Exchange marketplaces
Please read the [exchange specific notes](docs/exchanges.md) to learn about eventual, special configurations needed for each exchange.
- [X] [Bittrex](https://bittrex.com/)
- [X] [Binance](https://www.binance.com/) ([*Note for binance users](docs/exchanges.md#blacklists))
- [X] [Kraken](https://kraken.com/)
- [ ] [113 others to tests](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
- [X] [FTX](https://ftx.com)
- [ ] [potentially many others](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
### Community tested
Exchanges confirmed working by the community:
- [X] [Bitvavo](https://bitvavo.com/)
## Documentation
@@ -37,9 +46,9 @@ Please find the complete documentation on our [website](https://www.freqtrade.io
## Features
- [x] **Based on Python 3.6+**: For botting on any operating system - Windows, macOS and Linux.
- [x] **Based on Python 3.7+**: For botting on any operating system - Windows, macOS and Linux.
- [x] **Persistence**: Persistence is achieved through sqlite.
- [x] **Dry-run**: Run the bot without playing money.
- [x] **Dry-run**: Run the bot without paying money.
- [x] **Backtesting**: Run a simulation of your buy/sell strategy.
- [x] **Strategy Optimization by machine learning**: Use machine learning to optimize your buy/sell strategy parameters with real exchange data.
- [x] **Edge position sizing** Calculate your win rate, risk reward ratio, the best stoploss and adjust your position size before taking a position for each specific market. [Learn more](https://www.freqtrade.io/en/latest/edge/).
@@ -55,9 +64,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,17 +119,17 @@ 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 <trade_id>|[table]`: Lists all or specific 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
@@ -133,12 +141,13 @@ The project is currently setup in two main branches:
## 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-mm786y93-Fxo37glxMY9g8OQC5AoOIw).
### [Bugs / Issues](https://github.com/freqtrade/freqtrade/issues?q=is%3Aissue)
@@ -166,10 +175,10 @@ 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-mm786y93-Fxo37glxMY9g8OQC5AoOIw). 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 `stable`.
@@ -177,7 +186,7 @@ Issues labeled [good first issue](https://github.com/freqtrade/freqtrade/labels/
### 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
@@ -187,9 +196,9 @@ To run this bot we recommend you a cloud instance with a minimum of:
### Software requirements
- [Python 3.6.x](http://docs.python-guide.org/en/latest/starting/installation/)
- [Python 3.7.x](http://docs.python-guide.org/en/latest/starting/installation/)
- [pip](https://pip.pypa.io/en/stable/installing/)
- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
- [TA-Lib](https://mrjbq7.github.io/ta-lib/install.html)
- [virtualenv](https://virtualenv.pypa.io/en/stable/installation/) (Recommended)
- [virtualenv](https://virtualenv.pypa.io/en/stable/installation.html) (Recommended)
- [Docker](https://www.docker.com/products/docker) (Recommended)

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

@@ -30,7 +30,7 @@ if [ $? -ne 0 ]; then
fi
# Run backtest
docker run --rm -v $(pwd)/config.json.example:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy DefaultStrategy
docker run --rm -v $(pwd)/config_bittrex.json.example:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy DefaultStrategy
if [ $? -ne 0 ]; then
echo "failed running backtest"
@@ -51,6 +51,8 @@ fi
docker images
docker push ${IMAGE_NAME}
docker push ${IMAGE_NAME}:$TAG_PLOT
docker push ${IMAGE_NAME}:$TAG
if [ $? -ne 0 ]; then
echo "failed pushing repo"
return 1

View File

@@ -12,15 +12,15 @@
"sell": 30
},
"bid_strategy": {
"use_order_book": false,
"ask_last_balance": 0.0,
"use_order_book": false,
"order_book_top": 1,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"ask_strategy":{
"ask_strategy": {
"use_order_book": false,
"order_book_min": 1,
"order_book_max": 1,
@@ -84,12 +84,13 @@
"enabled": false,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"verbosity": "info",
"verbosity": "error",
"jwt_secret_key": "somethingrandom",
"CORS_origins": [],
"username": "",
"password": ""
"username": "freqtrader",
"password": "SuperSecurePassword"
},
"bot_name": "freqtrade",
"initial_state": "running",
"forcebuy_enable": false,
"internals": {

View File

@@ -5,15 +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,
"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,
@@ -79,12 +79,13 @@
"enabled": false,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"verbosity": "info",
"verbosity": "error",
"jwt_secret_key": "somethingrandom",
"CORS_origins": [],
"username": "",
"password": ""
"username": "freqtrader",
"password": "SuperSecurePassword"
},
"bot_name": "freqtrade",
"initial_state": "running",
"forcebuy_enable": false,
"internals": {

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,
@@ -42,6 +42,7 @@
"order_book_max": 1,
"use_sell_signal": true,
"sell_profit_only": false,
"sell_profit_offset": 0.0,
"ignore_roi_if_buy_signal": false
},
"order_types": {
@@ -67,10 +68,43 @@
{"method": "AgeFilter", "min_days_listed": 10},
{"method": "PrecisionFilter"},
{"method": "PriceFilter", "low_price_ratio": 0.01, "min_price": 0.00000010},
{"method": "SpreadFilter", "max_spread_ratio": 0.005}
{"method": "SpreadFilter", "max_spread_ratio": 0.005},
{
"method": "RangeStabilityFilter",
"lookback_days": 10,
"min_rate_of_change": 0.01,
"refresh_period": 1440
}
],
"protections": [
{
"method": "StoplossGuard",
"lookback_period_candles": 60,
"trade_limit": 4,
"stop_duration_candles": 60,
"only_per_pair": false
},
{
"method": "CooldownPeriod",
"stop_duration_candles": 20
},
{
"method": "MaxDrawdown",
"lookback_period_candles": 200,
"trade_limit": 20,
"stop_duration_candles": 10,
"max_allowed_drawdown": 0.2
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 360,
"trade_limit": 1,
"stop_duration_candles": 2,
"required_profit": 0.02
}
],
"exchange": {
"name": "bittrex",
"name": "binance",
"sandbox": false,
"key": "your_exchange_key",
"secret": "your_exchange_secret",
@@ -82,16 +116,21 @@
"aiohttp_trust_env": false
},
"pair_whitelist": [
"ALGO/BTC",
"ATOM/BTC",
"BAT/BTC",
"BCH/BTC",
"BRD/BTC",
"EOS/BTC",
"ETH/BTC",
"IOTA/BTC",
"LINK/BTC",
"LTC/BTC",
"ETC/BTC",
"DASH/BTC",
"ZEC/BTC",
"XLM/BTC",
"NXT/BTC",
"TRX/BTC",
"ADA/BTC",
"XMR/BTC"
"NEO/BTC",
"NXS/BTC",
"XMR/BTC",
"XRP/BTC",
"XTZ/BTC"
],
"pair_blacklist": [
"DOGE/BTC"
@@ -114,7 +153,7 @@
"remove_pumps": false
},
"telegram": {
"enabled": true,
"enabled": false,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id",
"notification_settings": {
@@ -131,12 +170,14 @@
"enabled": false,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"verbosity": "info",
"verbosity": "error",
"enable_openapi": false,
"jwt_secret_key": "somethingrandom",
"CORS_origins": [],
"username": "freqtrader",
"password": "SuperSecurePassword"
},
"bot_name": "freqtrade",
"db_url": "sqlite:///tradesv3.sqlite",
"initial_state": "running",
"forcebuy_enable": false,

View File

@@ -27,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,
@@ -90,12 +89,13 @@
"enabled": false,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"verbosity": "info",
"verbosity": "error",
"jwt_secret_key": "somethingrandom",
"CORS_origins": [],
"username": "",
"password": ""
"username": "freqtrader",
"password": "SuperSecurePassword"
},
"bot_name": "freqtrade",
"initial_state": "running",
"forcebuy_enable": false,
"internals": {

View File

@@ -9,11 +9,16 @@ services:
# Build step - only needed when additional dependencies are needed
# build:
# context: .
# dockerfile: "./Dockerfile.technical"
# dockerfile: "./docker/Dockerfile.technical"
restart: unless-stopped
container_name: freqtrade
volumes:
- "./user_data:/freqtrade/user_data"
# Expose api on port 8080 (localhost only)
# Please read the https://www.freqtrade.io/en/latest/rest-api/ documentation
# before enabling this.
# ports:
# - "127.0.0.1:8080:8080"
# Default command used when running `docker compose up`
command: >
trade

View File

@@ -5,6 +5,3 @@ FROM freqtradeorg/freqtrade:${sourceimage}
COPY requirements-plot.txt /freqtrade/
RUN pip install -r requirements-plot.txt --no-cache-dir
# Empty the ENTRYPOINT to allow all commands
ENTRYPOINT []

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
@@ -40,6 +40,11 @@ For the sample below, you then need to add the command line parameter `--hyperop
A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found in [userdata/hyperopts](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_loss.py).
``` python
from datetime import datetime
from typing import Dict
from pandas import DataFrame
from freqtrade.optimize.hyperopt import IHyperOptLoss
TARGET_TRADES = 600
@@ -54,6 +59,7 @@ class SuperDuperHyperOptLoss(IHyperOptLoss):
@staticmethod
def hyperopt_loss_function(results: DataFrame, trade_count: int,
min_date: datetime, max_date: datetime,
config: Dict, processed: Dict[str, DataFrame],
*args, **kwargs) -> float:
"""
Objective function, returns smaller number for better results
@@ -63,7 +69,7 @@ class SuperDuperHyperOptLoss(IHyperOptLoss):
* 0.25: Avoiding trade loss
* 1.0 to total profit, compared to the expected value (`EXPECTED_MAX_PROFIT`) defined above
"""
total_profit = results['profit_percent'].sum()
total_profit = results['profit_ratio'].sum()
trade_duration = results['trade_duration'].mean()
trade_loss = 1 - 0.25 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.8)
@@ -77,10 +83,12 @@ Currently, the arguments are:
* `results`: DataFrame containing the result
The following columns are available in results (corresponds to the output-file of backtesting when used with `--export trades`):
`pair, profit_percent, profit_abs, open_time, close_time, open_index, close_index, trade_duration, open_at_end, open_rate, close_rate, sell_reason`
`pair, profit_ratio, profit_abs, open_date, open_rate, fee_open, close_date, close_rate, fee_close, amount, trade_duration, is_open, sell_reason, stake_amount, min_rate, max_rate, stop_loss_ratio, stop_loss_abs`
* `trade_count`: Amount of trades (identical to `len(results)`)
* `min_date`: Start date of the hyperopting TimeFrame
* `min_date`: End date of the hyperopting TimeFrame
* `min_date`: Start date of the timerange used
* `min_date`: End date of the timerange used
* `config`: Config object used (Note: Not all strategy-related parameters will be updated here if they are part of a hyperopt space).
* `processed`: Dict of Dataframes with the pair as keys containing the data used for backtesting.
This function needs to return a floating point number (`float`). Smaller numbers will be interpreted as better results. The parameters and balancing for this is up to you.

View File

@@ -5,6 +5,89 @@ This page explains how to validate your strategy performance by using Backtestin
Backtesting requires historic data to be available.
To learn how to get data for the pairs and exchange you're interested in, head over to the [Data Downloading](data-download.md) section of the documentation.
## Backtesting command reference
```
usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-i TIMEFRAME]
[--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[--eps] [--dmmp] [--enable-protections]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
[--export EXPORT] [--export-filename PATH]
optional arguments:
-h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--data-format-ohlcv {json,jsongz,hdf5}
Storage format for downloaded candle (OHLCV) data.
(default: `None`).
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--eps, --enable-position-stacking
Allow buying the same pair multiple times (position
stacking).
--dmmp, --disable-max-market-positions
Disable applying `max_open_trades` during backtest
(same as setting `max_open_trades` to a very high
number).
--enable-protections, --enableprotections
Enable protections for backtesting.Will slow
backtesting down by a considerable amount, but will
include configured protections
--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]
Provide a space-separated list of strategies to
backtest. Please note that ticker-interval needs to be
set either in config or via command line. When using
this together with `--export trades`, the strategy-
name is injected into the filename (so `backtest-
data.json` becomes `backtest-data-
DefaultStrategy.json`
--export EXPORT Export backtest results, argument are: trades.
Example: `--export=trades`
--export-filename PATH
Save backtest results to the file with this filename.
Requires `--export` to be set as well. Example:
`--export-filename=user_data/backtest_results/backtest
_today.json`
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
## Test your strategy with Backtesting
Now you have good Buy and Sell strategies and some historic data, you want to test it against
@@ -20,7 +103,7 @@ The result of backtesting will confirm if your bot has better odds of making a p
!!! Warning "Using dynamic pairlists for backtesting"
Using dynamic pairlists is possible, however it relies on the current market conditions - which will not reflect the historic status of the pairlist.
Also, when using pairlists other than StaticPairlist, reproducability of backtesting-results cannot be guaranteed.
Please read the [pairlists documentation](configuration.md#pairlists) for more information.
Please read the [pairlists documentation](plugins.md#pairlists) for more information.
To achieve reproducible results, best generate a pairlist via the [`test-pairlist`](utils.md#test-pairlist) command and use that as static pairlist.
@@ -162,11 +245,16 @@ A backtesting result will look like that:
|-----------------------+---------------------|
| 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 Pair | LSK/BTC 26.26% |
| Worst Pair | ZEC/BTC -10.18% |
| Best Trade | LSK/BTC 4.25% |
| Worst Trade | ZEC/BTC -10.25% |
| Best day | 25.27% |
| Worst day | -30.67% |
| Avg. Duration Winners | 4:23:00 |
@@ -233,11 +321,16 @@ It contains some useful key metrics about performance of your strategy on backte
|-----------------------+---------------------|
| 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 Pair | LSK/BTC 26.26% |
| Worst Pair | ZEC/BTC -10.18% |
| Best Trade | LSK/BTC 4.25% |
| Worst Trade | ZEC/BTC -10.25% |
| Best day | 25.27% |
| Worst day | -30.67% |
| Avg. Duration Winners | 4:23:00 |
@@ -251,16 +344,17 @@ It contains some useful key metrics about performance of your strategy on backte
```
- `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.
- `Backtesting from` / `Backtesting to`: Backtesting range (usually defined with the `--timerange` option).
- `Total Profit %`: Total profit per stake amount. Aligned to the TOTAL column of the first table.
- `Max open trades`: Setting of `max_open_trades` (or `--max-open-trades`) - or number of pairs in the pairlist (whatever is lower).
- `Total trades`: Identical to the total trades of the backtest output table.
- `Total Profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from 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 Pair` / `Worst Pair`: Best and worst performing pair, and it's corresponding `Cum Profit %`.
- `Best Trade` / `Worst Trade`: Biggest winning trade and biggest losing trade
- `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 datetimes for this largest drawdown (can also be visualized via the `plot-dataframe` sub-command).
- `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
@@ -268,18 +362,24 @@ It contains some useful key metrics about performance of your strategy on backte
Since backtesting lacks some detailed information about what happens within a candle, it needs to take a few assumptions:
- Buys happen at open-price
- Sell signal sells happen at open-price of the following candle
- Low happens before high for stoploss, protecting capital first
- Sell-signal sells happen at open-price of the consecutive candle
- Sell-signal is favored over Stoploss, because sell-signals are assumed to trigger on candle's open
- ROI
- sells are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the sell will be at 2%)
- sells are never "below the candle", so a ROI of 2% may result in a sell at 2.4% if low was at 2.4% profit
- Forcesells caused by `<N>=-1` ROI entries use low as sell value, unless N falls on the candle open (e.g. `120: -1` for 1h candles)
- Stoploss sells happen exactly at stoploss price, even if low was lower
- Stoploss sells happen exactly at stoploss price, even if low was lower, but the loss will be `2 * fees` higher than the stoploss price
- Stoploss is evaluated before ROI within one candle. So you can often see more trades with the `stoploss` sell reason comparing to the results obtained with the same strategy in the Dry Run/Live Trade modes
- Low happens before high for stoploss, protecting capital first
- Trailing stoploss
- High happens first - adjusting stoploss
- Low uses the adjusted stoploss (so sells with large high-low difference are backtested correctly)
- ROI applies before trailing-stop, ensuring profits are "top-capped" at ROI if both ROI and trailing stop applies
- Sell-reason does not explain if a trade was positive or negative, just what triggered the sell (this can look odd if negative ROI values are used)
- Stoploss (and trailing stoploss) is evaluated before ROI within one candle. So you can often see more trades with the `stoploss` and/or `trailing_stop` sell reason comparing to the results obtained with the same strategy in the Dry Run/Live Trade modes.
- Evaluation sequence (if multiple signals happen on the same candle)
- ROI (if not stoploss)
- Sell-signal
- Stoploss
Taking these assumptions, backtesting tries to mirror real trading as closely as possible. However, backtesting will **never** replace running a strategy in dry-run mode.
Also, keep in mind that past results don't guarantee future success.

View File

@@ -4,6 +4,7 @@ This page provides you some basic concepts on how Freqtrade works and operates.
## Freqtrade terminology
* Strategy: Your trading strategy, telling the bot what to do.
* 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).
@@ -49,8 +50,9 @@ This loop will be repeated again and again until the bot is stopped.
[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()`
* Calls `bot_loop_start()` once.
* Calculate indicators (calls `populate_indicators()` once per pair).
* Calculate buy / sell signals (calls `populate_buy_trend()` and `populate_sell_trend()` once per pair)
* Loops per candle simulating entry and exit points.
* Generate backtest report output

View File

@@ -205,245 +205,6 @@ in production mode. Example command:
freqtrade trade -c config.json --db-url sqlite:///tradesv3.dry_run.sqlite
```
## Backtesting commands
Backtesting also uses the config specified via `-c/--config`.
```
usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-i TIMEFRAME]
[--timerange TIMERANGE] [--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[--eps] [--dmmp]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
[--export EXPORT] [--export-filename PATH]
optional arguments:
-h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--eps, --enable-position-stacking
Allow buying the same pair multiple times (position
stacking).
--dmmp, --disable-max-market-positions
Disable applying `max_open_trades` during backtest
(same as setting `max_open_trades` to a very high
number).
--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]
Provide a space-separated list of strategies to
backtest. Please note that ticker-interval needs to be
set either in config or via command line. When using
this together with `--export trades`, the strategy-
name is injected into the filename (so `backtest-
data.json` becomes `backtest-data-
DefaultStrategy.json`
--export EXPORT Export backtest results, argument are: trades.
Example: `--export=trades`
--export-filename PATH
Save backtest results to the file with this filename.
Requires `--export` to be set as well. Example:
`--export-filename=user_data/backtest_results/backtest
_today.json`
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
### Getting historic data for backtesting
The first time your run Backtesting, you will need to download some historic data first.
This can be accomplished by using `freqtrade download-data`.
Check the corresponding [Data Downloading](data-download.md) section for more details
## Hyperopt commands
To optimize your strategy, you can use hyperopt parameter hyperoptimization
to find optimal parameter values for your strategy.
```
usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[--hyperopt NAME] [--hyperopt-path PATH] [--eps]
[-e INT]
[--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]]
[--dmmp] [--print-all] [--no-color] [--print-json]
[-j JOBS] [--random-state INT] [--min-trades INT]
[--continue] [--hyperopt-loss NAME]
optional arguments:
-h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--hyperopt NAME Specify hyperopt class name which will be used by the
bot.
--hyperopt-path PATH Specify additional lookup path for Hyperopt and
Hyperopt Loss functions.
--eps, --enable-position-stacking
Allow buying the same pair multiple times (position
stacking).
-e INT, --epochs INT Specify number of epochs (default: 100).
--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]
Specify which parameters to hyperopt. Space-separated
list.
--dmmp, --disable-max-market-positions
Disable applying `max_open_trades` during backtest
(same as setting `max_open_trades` to a very high
number).
--print-all Print all results, not only the best ones.
--no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file.
--print-json Print output in JSON format.
-j JOBS, --job-workers JOBS
The number of concurrently running jobs for
hyperoptimization (hyperopt worker processes). If -1
(default), all CPUs are used, for -2, all CPUs but one
are used, etc. If 1 is given, no parallel computing
code is used at all.
--random-state INT Set random state to some positive integer for
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,
OnlyProfitHyperOptLoss, SharpeHyperOptLoss,
SharpeHyperOptLossDaily, SortinoHyperOptLoss,
SortinoHyperOptLossDaily.(default:
`DefaultHyperOptLoss`).
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
## Edge commands
To know your trade expectancy and winrate against historical data, you can use Edge.
```
usage: freqtrade edge [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--max-open-trades INT] [--stake-amount STAKE_AMOUNT]
[--fee FLOAT] [--stoplosses STOPLOSS_RANGE]
optional arguments:
-h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--stoplosses STOPLOSS_RANGE
Defines a range of stoploss values against which edge
will assess the strategy. The format is "min,max,step"
(without any space). Example:
`--stoplosses=-0.01,-0.1,-0.001`
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
To understand edge and how to read the results, please read the [edge documentation](edge.md).
## Next step
The optimal strategy of the bot will change with time depending of the market trends. The next step is to

View File

@@ -16,8 +16,7 @@ In some advanced use cases, multiple configuration files can be specified and us
If you used the [Quick start](installation.md/#quick-start) method for installing
the bot, the installation script should have already created the default configuration file (`config.json`) for you.
If default configuration file is not created we recommend you to copy and use the `config.json.example` as a template
for your bot configuration.
If default configuration file is not created we recommend you to use `freqtrade new-config --config config.json` to generate a basic configuration file.
The Freqtrade configuration file is to be written in the JSON format.
@@ -59,8 +58,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `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
@@ -72,8 +71,10 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `ask_strategy.order_book_min` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate. <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
| `ask_strategy.order_book_max` | Bot will scan from the top min to max Order Book Asks searching for a profitable rate. <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
| `ask_strategy.use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `ask_strategy.sell_profit_only` | Wait until the bot makes a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `ask_strategy.sell_profit_only` | Wait until the bot reaches `ask_strategy.sell_profit_offset` before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `ask_strategy.sell_profit_offset` | Sell-signal is only active above this value. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
| `ask_strategy.ignore_roi_if_buy_signal` | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `ask_strategy.ignore_buying_expired_candle_after` | Specifies the number of seconds until a buy signal is no longer used. <br> **Datatype:** Integer
| `order_types` | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Dict
| `order_time_in_force` | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
| `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename). <br> **Datatype:** String
@@ -81,15 +82,18 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `exchange.key` | API key to use for the exchange. Only required when you are in production mode.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.secret` | API secret to use for the exchange. Only required when you are in production mode.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.password` | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `exchange.pair_whitelist` | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Not used by VolumePairList (see [below](#pairlists-and-pairlist-handlers)). <br> **Datatype:** List
| `exchange.pair_blacklist` | List of pairs the bot must absolutely avoid for trading and backtesting (see [below](#pairlists-and-pairlist-handlers)). <br> **Datatype:** List
| `exchange.pair_whitelist` | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Supports regex pairs as `.*/BTC`. Not used by VolumePairList. [More information](plugins.md#pairlists-and-pairlist-handlers). <br> **Datatype:** List
| `exchange.pair_blacklist` | List of pairs the bot must absolutely avoid for trading and backtesting. [More information](plugins.md#pairlists-and-pairlist-handlers). <br> **Datatype:** List
| `exchange.ccxt_config` | Additional CCXT parameters passed to both ccxt instances (sync and async). This is usually the correct place for ccxt configurations. 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_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
| `exchange.skip_open_order_update` | Skips open order updates on startup should the exchange cause problems. Only relevant in live conditions.<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
| `pairlists` | Define one or more pairlists to be used. [More information](plugins.md#pairlists-and-pairlist-handlers). <br>*Defaults to `StaticPairList`.* <br> **Datatype:** List of Dicts
| `protections` | Define one or more protections to be used. [More information](plugins.md#protections). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** List of Dicts
| `telegram.enabled` | Enable the usage of Telegram. <br> **Datatype:** Boolean
| `telegram.token` | Your Telegram bot token. Only required if `telegram.enabled` is `true`. <br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
| `telegram.chat_id` | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. <br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String
@@ -106,13 +110,14 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `api_server.verbosity` | Logging verbosity. `info` will print all RPC Calls, while "error" will only display errors. <br>**Datatype:** Enum, either `info` or `error`. Defaults to `info`.
| `api_server.username` | Username for API server. See the [API Server documentation](rest-api.md) for more details. <br>**Keep it in secret, do not disclose publicly.**<br> **Datatype:** String
| `api_server.password` | Password for API server. See the [API Server documentation](rest-api.md) for more details. <br>**Keep it in secret, do not disclose publicly.**<br> **Datatype:** String
| `bot_name` | Name of the bot. Passed via API to a client - can be shown to distinguish / name bots.<br> *Defaults to `freqtrade`*<br> **Datatype:** String
| `db_url` | Declares database URL to use. NOTE: This defaults to `sqlite:///tradesv3.dryrun.sqlite` if `dry_run` is `true`, and to `sqlite:///tradesv3.sqlite` for production instances. <br> **Datatype:** String, SQLAlchemy connect string
| `initial_state` | Defines the initial application state. More information below. <br>*Defaults to `stopped`.* <br> **Datatype:** Enum, either `stopped` or `running`
| `initial_state` | Defines the initial application state. If set to stopped, then the bot has to be explicitly started via `/start` RPC command. <br>*Defaults to `stopped`.* <br> **Datatype:** Enum, either `stopped` or `running`
| `forcebuy_enable` | Enables the RPC Commands to force a buy. More information below. <br> **Datatype:** Boolean
| `disable_dataframe_checks` | Disable checking the OHLCV dataframe returned from the strategy methods for correctness. Only use when intentionally changing the dataframe and understand what you are doing. [Strategy Override](#parameters-in-the-strategy).<br> *Defaults to `False`*. <br> **Datatype:** Boolean
| `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`. <br> **Datatype:** ClassName
| `strategy_path` | Adds an additional strategy lookup path (must be a directory). <br> **Datatype:** String
| `internals.process_throttle_secs` | Set the process throttle. Value in second. <br>*Defaults to `5` seconds.* <br> **Datatype:** Positive Integer
| `internals.process_throttle_secs` | Set the process throttle, or minimum loop duration for one bot iteration loop. Value in second. <br>*Defaults to `5` seconds.* <br> **Datatype:** Positive Integer
| `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages. <br>*Defaults to `60` seconds.* <br> **Datatype:** Positive Integer or 0
| `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details. <br> **Datatype:** Boolean
| `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file. <br> **Datatype:** String
@@ -132,6 +137,7 @@ Values set in the configuration file always overwrite values set in the strategy
* `trailing_stop_positive`
* `trailing_stop_positive_offset`
* `trailing_only_offset_is_reached`
* `use_custom_stoploss`
* `process_only_new_candles`
* `order_types`
* `order_time_in_force`
@@ -139,9 +145,12 @@ Values set in the configuration file always overwrite values set in the strategy
* `stake_amount`
* `unfilledtimeout`
* `disable_dataframe_checks`
* `protections`
* `use_sell_signal` (ask_strategy)
* `sell_profit_only` (ask_strategy)
* `sell_profit_offset` (ask_strategy)
* `ignore_roi_if_buy_signal` (ask_strategy)
* `ignore_buying_expired_candle_after` (ask_strategy)
### Configuring amount per trade
@@ -176,7 +185,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
@@ -238,37 +247,31 @@ If it is not set in either Strategy or Configuration, a default of 1000% `{"0":
!!! Note "Special case to forcesell after a specific time"
A special case presents using `"<N>": -1` as ROI. This forces the bot to sell a trade after N Minutes, no matter if it's positive or negative, so represents a time-limited force-sell.
### Understand stoploss
Go to the [stoploss documentation](stoploss.md) for more details.
### Understand trailing stoploss
Go to the [trailing stoploss Documentation](stoploss.md#trailing-stop-loss) for details on trailing stoploss.
### Understand initial_state
The `initial_state` configuration parameter is an optional field that defines the initial application state.
Possible values are `running` or `stopped`. (default=`running`)
If the value is `stopped` the bot has to be started with `/start` first.
### Understand forcebuy_enable
The `forcebuy_enable` configuration parameter enables the usage of forcebuy commands via Telegram.
This is disabled for security reasons by default, and will show a warning message on startup if enabled.
For example, you can send `/forcebuy ETH/BTC` Telegram command when this feature if enabled to the bot,
who then buys the pair and holds it until a regular sell-signal (ROI, stoploss, /forcesell) appears.
The `forcebuy_enable` configuration parameter enables the usage of forcebuy commands via Telegram and REST API.
For security reasons, it's disabled by default, and freqtrade will show a warning message on startup if enabled.
For example, you can send `/forcebuy ETH/BTC` to the bot, which will result in freqtrade buying the pair and holds it until a regular sell-signal (ROI, stoploss, /forcesell) appears.
This can be dangerous with some strategies, so use with care.
See [the telegram documentation](telegram-usage.md) for details on usage.
### Understand process_throttle_secs
### Ignoring expired candles
The `process_throttle_secs` configuration parameter is an optional field that defines in seconds how long the bot should wait
before asking the strategy if we should buy or a sell an asset. After each wait period, the strategy is asked again for
every opened trade wether or not we should sell, and for all the remaining pairs (either the dynamic list of pairs or
the static list of pairs) if we should buy.
When working with larger timeframes (for example 1h or more) and using a low `max_open_trades` value, the last candle can be processed as soon as a trade slot becomes available. When processing the last candle, this can lead to a situation where it may not be desirable to use the buy signal on that candle. For example, when using a condition in your strategy where you use a cross-over, that point may have passed too long ago for you to start a trade on it.
In these situations, you can enable the functionality to ignore candles that are beyond a specified period by setting `ask_strategy.ignore_buying_expired_candle_after` to a positive number, indicating the number of seconds after which the buy signal becomes expired.
For example, if your strategy is using a 1h timeframe, and you only want to buy within the first 5 minutes when a new candle comes in, you can add the following configuration to your strategy:
``` json
"ask_strategy":{
"ignore_buying_expired_candle_after": 300,
"price_side": "bid",
// ...
},
```
### Understand order_types
@@ -313,22 +316,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.
@@ -447,273 +449,9 @@ The valid values are:
"BTC", "ETH", "XRP", "LTC", "BCH", "USDT"
```
## Prices used for orders
--8<-- "includes/pricing.md"
Prices for regular orders can be controlled via the parameter structures `bid_strategy` for buying and `ask_strategy` for selling.
Prices are always retrieved right before an order is placed, either by querying the exchange tickers or by using the orderbook data.
!!! Note
Orderbook data used by Freqtrade are the data retrieved from exchange by the ccxt's function `fetch_order_book()`, i.e. are usually data from the L2-aggregated orderbook, while the ticker data are the structures returned by the ccxt's `fetch_ticker()`/`fetch_tickers()` functions. Refer to the ccxt library [documentation](https://github.com/ccxt/ccxt/wiki/Manual#market-data) for more details.
!!! Warning "Using market orders"
Please read the section [Market order pricing](#market-order-pricing) section when using market orders.
### Buy price
#### Check depth of market
When check depth of market is enabled (`bid_strategy.check_depth_of_market.enabled=True`), the buy signals are filtered based on the orderbook depth (sum of all amounts) for each orderbook side.
Orderbook `bid` (buy) side depth is then divided by the orderbook `ask` (sell) side depth and the resulting delta is compared to the value of the `bid_strategy.check_depth_of_market.bids_to_ask_delta` parameter. The buy order is only executed if the orderbook delta is greater than or equal to the configured delta value.
!!! Note
A delta value below 1 means that `ask` (sell) orderbook side depth is greater than the depth of the `bid` (buy) orderbook side, while a value greater than 1 means opposite (depth of the buy side is higher than the depth of the sell side).
#### Buy price side
The configuration setting `bid_strategy.price_side` defines the side of the spread the bot looks for when buying.
The following displays an orderbook.
``` explanation
...
103
102
101 # ask
-------------Current spread
99 # bid
98
97
...
```
If `bid_strategy.price_side` is set to `"bid"`, then the bot will use 99 as buying price.
In line with that, if `bid_strategy.price_side` is set to `"ask"`, then the bot will use 101 as buying price.
Using `ask` price often guarantees quicker filled orders, but the bot can also end up paying more than what would have been necessary.
Taker fees instead of maker fees will most likely apply even when using limit buy orders.
Also, prices at the "ask" side of the spread are higher than prices at the "bid" side in the orderbook, so the order behaves similar to a market order (however with a maximum price).
#### Buy price with Orderbook enabled
When buying with the orderbook enabled (`bid_strategy.use_order_book=True`), Freqtrade fetches the `bid_strategy.order_book_top` entries from the orderbook and then uses the entry specified as `bid_strategy.order_book_top` on the configured side (`bid_strategy.price_side`) of the orderbook. 1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on.
#### Buy price without Orderbook enabled
The following section uses `side` as the configured `bid_strategy.price_side`.
When not using orderbook (`bid_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `side` price is above the `last` price), it calculates a rate between `side` and `last` price.
The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `side` price, while `1.0` will use the `last` price and values between those interpolate between ask and last price.
### Sell price
#### Sell price side
The configuration setting `ask_strategy.price_side` defines the side of the spread the bot looks for when selling.
The following displays an orderbook:
``` explanation
...
103
102
101 # ask
-------------Current spread
99 # bid
98
97
...
```
If `ask_strategy.price_side` is set to `"ask"`, then the bot will use 101 as selling price.
In line with that, if `ask_strategy.price_side` is set to `"bid"`, then the bot will use 99 as selling price.
#### Sell price with Orderbook enabled
When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the configured orderbook side are validated for a profitable sell-possibility based on the strategy configuration (`minimal_roi` conditions) and the sell order is placed at the first profitable spot.
!!! Note
Using `order_book_max` higher than `order_book_min` only makes sense when ask_strategy.price_side is set to `"ask"`.
The idea here is to place the sell order early, to be ahead in the queue.
A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number.
!!! Warning "Order_book_max > 1 - increased risks for stoplosses!"
Using `ask_strategy.order_book_max` higher than 1 will increase the risk the stoploss on exchange is cancelled too early, since an eventual [stoploss on exchange](#understand-order_types) will be cancelled as soon as the order is placed.
Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (with or without using stoploss on exchange).
!!! Warning "Order_book_max > 1 in dry-run"
Using `ask_strategy.order_book_max` higher than 1 will result in improper dry-run results (significantly better than real orders executed on exchange), since dry-run assumes orders to be filled almost instantly.
It is therefore advised to not use this setting for dry-runs.
#### Sell price without Orderbook enabled
When not using orderbook (`ask_strategy.use_order_book=False`), the price at the `ask_strategy.price_side` side (defaults to `"ask"`) from the ticker will be used as the sell price.
### Market order pricing
When using market orders, prices should be configured to use the "correct" side of the orderbook to allow realistic pricing detection.
Assuming both buy and sell are using market orders, a configuration similar to the following might be used
``` jsonc
"order_types": {
"buy": "market",
"sell": "market"
// ...
},
"bid_strategy": {
"price_side": "ask",
// ...
},
"ask_strategy":{
"price_side": "bid",
// ...
},
```
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 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.
### 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}
],
```
## Switch to Dry-run mode
## Using Dry-run mode
We recommend starting the bot in the Dry-run mode to see how your bot will
behave and what is the performance of your strategy. In the Dry-run mode the
@@ -746,9 +484,10 @@ Once you will be happy with your bot performance running in the Dry-run mode, yo
### Considerations for dry-run
* API-keys may or may not be provided. Only Read-Only operations (i.e. operations that do not alter account state) on the exchange are performed in the dry-run mode.
* Wallets (`/balance`) are simulated.
* API-keys may or may not be provided. Only Read-Only operations (i.e. operations that do not alter account state) on the exchange are performed in dry-run mode.
* Wallets (`/balance`) are simulated based on `dry_run_wallet`.
* Orders are simulated, and will not be posted to the exchange.
* Orders are assumed to fill immediately, and will never time out.
* In combination with `stoploss_on_exchange`, the stop_loss price is assumed to be filled.
* Open orders (not trades, which are stored in the database) are reset on bot restart.
@@ -806,32 +545,6 @@ export HTTPS_PROXY="http://addr:port"
freqtrade
```
## Embedding Strategies
Freqtrade provides you with with an easy way to embed the strategy into your configuration file.
This is done by utilizing BASE64 encoding and providing this string at the strategy configuration field,
in your chosen config file.
### Encoding a string as BASE64
This is a quick example, how to generate the BASE64 string in python
```python
from base64 import urlsafe_b64encode
with open(file, 'r') as f:
content = f.read()
content = urlsafe_b64encode(content.encode('utf-8'))
```
The variable 'content', will contain the strategy file in a BASE64 encoded form. Which can now be set in your configurations file as following
```json
"strategy": "NameOfStrategy:BASE64String"
```
Please ensure that 'NameOfStrategy' is identical to the strategy name!
## Next step
Now you have configured your config.json, the next step is to [start your bot](bot-usage.md).

View File

@@ -8,7 +8,7 @@ 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.
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.
@@ -264,7 +264,19 @@ If you are using Binance for example:
```bash
mkdir -p user_data/data/binance
cp freqtrade/tests/testdata/pairs.json user_data/data/binance
cp tests/testdata/pairs.json user_data/data/binance
```
If you your configuration directory `user_data` was made by docker, you may get the following error:
```
cp: cannot create regular file 'user_data/data/binance/pairs.json': Permission denied
```
You can fix the permissions of your user-data directory as follows:
```
sudo chown -R $UID:$GID user_data
```
The format of the `pairs.json` file is a simple json list.
@@ -308,10 +320,13 @@ Since this data is large by default, the files use gzip by default. They are sto
To use this mode, simply add `--dl-trades` to your call. This will swap the download method to download trades, and resamples the data locally.
!!! Warning "do not use"
You should not use this unless you're a kraken user. Most other exchanges provide OHLCV data with sufficient history.
Example call:
```bash
freqtrade download-data --exchange binance --pairs XRP/ETH ETH/BTC --days 20 --dl-trades
freqtrade download-data --exchange kraken --pairs XRP/EUR ETH/EUR --days 20 --dl-trades
```
!!! Note

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-mm786y93-Fxo37glxMY9g8OQC5AoOIw) where you can ask questions.
## Documentation
@@ -94,9 +94,11 @@ Below is an outline of exception inheritance hierarchy:
+---+ StrategyError
```
## Modules
---
### Dynamic Pairlist
## Plugins
### 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.
@@ -119,6 +121,9 @@ The base-class provides an instance of the exchange (`self._exchange`) the pairl
self._pairlist_pos = pairlist_pos
```
!!! Tip
Don't forget to register your pairlist in `constants.py` under the variable `AVAILABLE_PAIRLISTS` - otherwise it will not be selectable.
Now, let's step through the methods which require actions:
#### Pairlist configuration
@@ -170,6 +175,66 @@ In `VolumePairList`, this implements different methods of sorting, does early va
return pairs
```
### Protections
Best read the [Protection documentation](plugins.md#protections) to understand protections.
This Guide is directed towards Developers who want to develop a new protection.
No protection should use datetime directly, but use the provided `date_now` variable for date calculations. This preserves the ability to backtest protections.
!!! Tip "Writing a new Protection"
Best copy one of the existing Protections to have a good example.
Don't forget to register your protection in `constants.py` under the variable `AVAILABLE_PROTECTIONS` - otherwise it will not be selectable.
#### Implementation of a new protection
All Protection implementations must have `IProtection` as parent class.
For that reason, they must implement the following methods:
* `short_desc()`
* `global_stop()`
* `stop_per_pair()`.
`global_stop()` and `stop_per_pair()` must return a ProtectionReturn tuple, which consists of:
* lock pair - boolean
* lock until - datetime - until when should the pair be locked (will be rounded up to the next new candle)
* reason - string, used for logging and storage in the database
The `until` portion should be calculated using the provided `calculate_lock_end()` method.
All Protections should use `"stop_duration"` / `"stop_duration_candles"` to define how long a a pair (or all pairs) should be locked.
The content of this is made available as `self._stop_duration` to the each Protection.
If your protection requires a look-back period, please use `"lookback_period"` / `"lockback_period_candles"` to keep all protections aligned.
#### Global vs. local stops
Protections can have 2 different ways to stop trading for a limited :
* Per pair (local)
* For all Pairs (globally)
##### Protections - per pair
Protections that implement the per pair approach must set `has_local_stop=True`.
The method `stop_per_pair()` will be called whenever a trade closed (sell order completed).
##### Protections - global protection
These Protections should do their evaluation across all pairs, and consequently will also lock all pairs from trading (called a global PairLock).
Global protection must set `has_global_stop=True` to be evaluated for global stops.
The method `global_stop()` will be called whenever a trade closed (sell order completed).
##### Protections - calculating lock end time
Protections should calculate the lock end time based on the last trade it considers.
This avoids re-locking should the lookback-period be longer than the actual lock period.
The `IProtection` parent class provides a helper method for this in `calculate_lock_end()`.
---
## Implement a new Exchange (WIP)
!!! Note
@@ -177,6 +242,9 @@ In `VolumePairList`, this implements different methods of sorting, does early va
Most exchanges supported by CCXT should work out of the box.
To quickly test the public endpoints of an exchange, add a configuration for your exchange to `test_ccxt_compat.py` and run these tests with `pytest --longrun tests/exchange/test_ccxt_compat.py`.
Completing these tests successfully a good basis point (it's a requirement, actually), however these won't guarantee correct exchange functioning, as this only tests public endpoints, but no private endpoint (like generate order or similar).
### Stoploss On Exchange
Check if the new exchange supports Stoploss on Exchange orders through their API.

View File

@@ -1,201 +0,0 @@
## Freqtrade with docker without docker-compose
!!! Warning
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
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:stable
# Optionally tag the repository so the run-commands remain shorter
docker tag freqtradeorg/freqtrade:stable freqtrade
```
To update the image, simply run the above commands again and restart your running container.
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 `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
Even though you will use docker, you'll still need some files from the github repository.
#### Clone the git repository
Linux/Mac/Windows with WSL
```bash
git clone https://github.com/freqtrade/freqtrade.git
```
Windows with docker
```bash
git clone --config core.autocrlf=input https://github.com/freqtrade/freqtrade.git
```
#### Copy `config.json.example` to `config.json`
```bash
cd freqtrade
cp -n config.json.example config.json
```
> To understand the configuration options, please refer to the [Bot Configuration](configuration.md) page.
#### Create your database file
=== "Dry-Run"
``` bash
touch tradesv3.dryrun.sqlite
```
=== "Production"
``` bash
touch tradesv3.sqlite
```
!!! 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/docker/Dockerfile.technical) which adds the [technical](https://github.com/freqtrade/technical) module to the image.
```bash
docker build -t freqtrade -f docker/Dockerfile.technical .
```
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 docker/Dockerfile.develop -t freqtrade-dev .
```
!!! 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
After the build process you can verify that the image was created with:
```bash
docker images
```
The output should contain the freqtrade image.
### Run the Docker image
You can run a one-off container that is immediately deleted upon exiting with the following command (`config.json` must be in the current working directory):
```bash
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 refresh your image.
#### Adjust timezone
By default, the container will use UTC timezone.
If you would like to change the timezone use the following commands:
=== "Linux"
``` 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
```
=== "MacOS"
```bash
docker run --rm -e TZ=`ls -la /etc/localtime | cut -d/ -f8-9` -v `pwd`/config.json:/freqtrade/config.json -it freqtrade
```
!!! 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).
#### 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.
```bash
mkdir ~/.freqtrade
mv config.json ~/.freqtrade
mv tradesv3.sqlite ~/.freqtrade
```
#### 2. Run the docker image
```bash
docker run -d \
--name freqtrade \
-v ~/.freqtrade/config.json:/freqtrade/config.json \
-v ~/.freqtrade/user_data/:/freqtrade/user_data \
-v ~/.freqtrade/tradesv3.sqlite:/freqtrade/tradesv3.sqlite \
freqtrade trade --db-url sqlite:///tradesv3.sqlite --strategy MyAwesomeStrategy
```
!!! Note
When using docker, it's best to specify `--db-url` explicitly to ensure that the database URL and the mounted database file match.
!!! Note
All available bot command line parameters can be added to the end of the `docker run` command.
!!! Note
You can define a [restart policy](https://docs.docker.com/config/containers/start-containers-automatically/) in docker. It can be useful in some cases to use the `--restart unless-stopped` flag (crash of freqtrade or reboot of your system).
### Monitor your Docker instance
You can use the following commands to monitor and manage your container:
```bash
docker logs freqtrade
docker logs -f freqtrade
docker restart freqtrade
docker stop freqtrade
docker start freqtrade
```
For more information on how to operate Docker, please refer to the [official Docker documentation](https://docs.docker.com/).
!!! Note
You do not need to rebuild the image for configuration changes, it will suffice to edit `config.json` and restart the container.
### Backtest with docker
The following assumes that the download/setup of the docker image have been completed successfully.
Also, backtest-data should be available at `~/.freqtrade/user_data/`.
```bash
docker run -d \
--name freqtrade \
-v /etc/localtime:/etc/localtime:ro \
-v ~/.freqtrade/config.json:/freqtrade/config.json \
-v ~/.freqtrade/tradesv3.sqlite:/freqtrade/tradesv3.sqlite \
-v ~/.freqtrade/user_data/:/freqtrade/user_data/ \
freqtrade backtesting --strategy AwsomelyProfitableStrategy
```
Head over to the [Backtesting Documentation](backtesting.md) for more details.
!!! Note
Additional bot command line parameters can be appended after the image name (`freqtrade` in the above example).

View File

@@ -8,9 +8,7 @@ Start by downloading and installing Docker CE for your platform:
* [Windows](https://docs.docker.com/docker-for-windows/install/)
* [Linux](https://docs.docker.com/install/)
Optionally, [`docker-compose`](https://docs.docker.com/compose/install/) should be installed and available to follow the [docker quick start guide](#docker-quick-start).
Once you have Docker installed, simply prepare the config file (e.g. `config.json`) and run the image for `freqtrade` as explained below.
To simplify running freqtrade, please install [`docker-compose`](https://docs.docker.com/compose/install/) should be installed and available to follow the below [docker quick start guide](#docker-quick-start).
## Freqtrade with docker-compose
@@ -71,7 +69,7 @@ The last 2 steps in the snippet create the directory with `user_data`, as well a
!!! 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.
You can also change the both Strategy and commands by editing the command section of your `docker-compose.yml` file.
#### Adding a custom strategy
@@ -83,7 +81,8 @@ 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!
Please always backtest your strategy and use dry-run for some time before risking real money!
You will find more information about Strategy development in the [Strategy documentation](strategy-customization.md).
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).
@@ -91,18 +90,23 @@ Once this is done, you're ready to launch the bot in trading mode (Dry-run or Li
docker-compose up -d
```
#### Monitoring the bot
You can check for running instances with `docker-compose ps`.
This should list the service `freqtrade` as `running`. If that's not the case, best check the logs (see next point).
#### 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`.
Logs will be written to: `user_data/logs/freqtrade.log`.
You can also check the latest log with the command `docker-compose logs -f`.
#### Database
The database will be at: `user_data/tradesv3.sqlite`
The database will be located 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:
Updating freqtrade when using `docker-compose` is as simple as running the following 2 commands:
``` bash
# Download the latest image
@@ -120,10 +124,10 @@ This will first pull the latest image, and will then restart the container with
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>`.
All 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).
Including `--rm` will remove 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
@@ -172,19 +176,19 @@ docker-compose run --rm freqtrade plot-dataframe --strategy AwesomeStrategy -p B
The output will be stored in the `user_data/plot` directory, and can be opened with any modern browser.
## Data analayis using docker compose
## Data analysis 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
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`.
This will create a docker-container 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.
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) up-to-date.
``` bash
docker-compose -f docker/docker-compose-jupyter.yml build --no-cache

View File

@@ -1,6 +1,6 @@
# Edge positioning
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.
The `Edge Positioning` module uses probability to calculate your win rate and risk reward ratio. It will use these statistics to control your strategy trade entry points, position size and, stoploss.
!!! Warning
`Edge positioning` is not compatible with dynamic (volume-based) whitelist.
@@ -9,6 +9,7 @@ The `Edge Positioning` module uses probability to calculate your win rate and ri
`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 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.
@@ -23,8 +24,8 @@ The Edge Positioning module seeks to improve a strategy's winning probability an
We raise the following question[^1]:
!!! 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
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\$
???+ Info "Answer"
The expected value of *a)* is smaller than the expected value of *b)*.<br/>
@@ -34,8 +35,8 @@ We raise the following question[^1]:
Another way to look at it is to ask a similar question:
!!! 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
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\$
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.
@@ -55,7 +56,7 @@ 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>
In a section where a strategy made four transactions $O = \{3.5, -1, 15, 0\}$:<br>
$T_{win} = \{3.5, 15\}$<br>
$T_{lose} = \{-1, 0\}$<br>
@@ -82,20 +83,34 @@ Risk Reward Ratio ($R$) is a formula used to measure the expected gains of a giv
$$ R = \frac{\text{potential_profit}}{\text{potential_loss}} $$
???+ 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.<br>
Your potential profit is calculated as:<br>
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).
Your potential profit is calculated as:
$\begin{aligned}
\text{potential_profit} &= (\text{potential_price} - \text{cost_per_unit}) * \frac{\text{investment}}{\text{cost_per_unit}} \\
&= (15 - 10) * \frac{100}{15}\\
&= 33.33
\end{aligned}$<br>
Since the price might go to $0, the $100 dolars invested could turn into 0. We can compute the Risk Reward Ratio as follows:<br>
\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{33.33}{100}\\
&= 0.333...
&= \frac{50}{15}\\
&= 3.33
\end{aligned}$<br>
What it effectivelly means is that the strategy have the potential to make $0.33 for each $1 invested.
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:
@@ -127,7 +142,7 @@ $$E = R * W - L$$
$E = R * W - L = 5 * 0.28 - 0.72 = 0.68$
<br>
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.
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.
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.
@@ -192,7 +207,61 @@ Let's say the stake currency is **ETH** and there is $10$ **ETH** on the wallet.
- 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**.
- **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**.
## Edge command reference
```
usage: freqtrade edge [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--max-open-trades INT] [--stake-amount STAKE_AMOUNT]
[--fee FLOAT] [--stoplosses STOPLOSS_RANGE]
optional arguments:
-h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--stoplosses STOPLOSS_RANGE
Defines a range of stoploss values against which edge
will assess the strategy. The format is "min,max,step"
(without any space). Example:
`--stoplosses=-0.01,-0.1,-0.001`
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
## Configurations
@@ -208,7 +277,7 @@ Edge module has following configuration options:
| `stoploss_range_max` | Maximum stoploss. <br>*Defaults to `-0.10`.* <br> **Datatype:** Float
| `stoploss_range_step` | As an example if this is set to -0.01 then Edge will test the strategy for `[-0.01, -0,02, -0,03 ..., -0.09, -0.10]` ranges. <br> **Note** than having a smaller step means having a bigger range which could lead to slow calculation. <br> If you set this parameter to -0.001, you then slow down the Edge calculation by a factor of 10. <br>*Defaults to `-0.001`.* <br> **Datatype:** Float
| `minimum_winrate` | It filters out pairs which don't have at least minimum_winrate. <br>This comes handy if you want to be conservative and don't comprise win rate in favour of risk reward ratio. <br>*Defaults to `0.60`.* <br> **Datatype:** Float
| `minimum_expectancy` | It filters out pairs which have the expectancy lower than this number. <br>Having an expectancy of 0.20 means if you put 10$ on a trade you expect a 12$ return. <br>*Defaults to `0.20`.* <br> **Datatype:** Float
| `minimum_expectancy` | It filters out pairs which have the expectancy lower than this number. <br>Having an expectancy of 0.20 means if you put 10\$ on a trade you expect a 12\$ return. <br>*Defaults to `0.20`.* <br> **Datatype:** Float
| `min_trade_number` | When calculating *W*, *R* and *E* (expectancy) against historical data, you always want to have a minimum number of trades. The more this number is the more Edge is reliable. <br>Having a win rate of 100% on a single trade doesn't mean anything at all. But having a win rate of 70% over past 100 trades means clearly something. <br>*Defaults to `10` (it is highly recommended not to decrease this number).* <br> **Datatype:** Integer
| `max_trade_duration_minute` | Edge will filter out trades with long duration. If a trade is profitable after 1 month, it is hard to evaluate the strategy based on it. But if most of trades are profitable and they have maximum duration of 30 minutes, then it is clearly a good sign.<br>**NOTICE:** While configuring this value, you should take into consideration your timeframe. As an example filtering out trades having duration less than one day for a strategy which has 4h interval does not make sense. Default value is set assuming your strategy interval is relatively small (1m or 5m, etc.).<br>*Defaults to `1440` (one day).* <br> **Datatype:** Integer
| `remove_pumps` | Edge will remove sudden pumps in a given market while going through historical data. However, given that pumps happen very often in crypto markets, we recommend you keep this off.<br>*Defaults to `false`.* <br> **Datatype:** Boolean

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

@@ -2,30 +2,30 @@
## 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).
* 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
Running the bot with `freqtrade trade --config config.json` does show the output `freqtrade: command not found`.
Running the bot with `freqtrade trade --config config.json` shows the output `freqtrade: command not found`.
This could have the following reasons:
This could be caused by the following reasons:
* The virtual environment is not active
* run `source .env/bin/activate` to activate the virtual environment
* The virtual environment is not active.
* Run `source .env/bin/activate` to activate the virtual environment.
* The installation did not work correctly.
* Please check the [Installation documentation](installation.md).
### I have waited 5 minutes, why hasn't the bot made any trades yet?!
### 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
situation of the market etc, it can take up to hours to find good entry
situation of the market etc, it can take up to hours to find a 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).
* It may be because of a configuration error. It's best to check the logs, they usually tell 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 have made 12 trades already, why is my total profit negative?
I understand your disappointment but unfortunately 12 trades is just
not enough to say anything. If you run backtesting, you can see that our
@@ -36,20 +36,17 @@ of course constantly aim to improve the bot but it will _always_ be a
gamble, which should leave you with modest wins on monthly basis but
you can't say much from few trades.
### Id like to change the stake amount. Can I just stop the bot with /stop and then change the config.json and run it again?
### Id like to make changes to the config. Can I do that without having to kill the bot?
Not quite. Trades are persisted to a database but the configuration is
currently only read when the bot is killed and restarted. `/stop` more
like pauses. You can stop your bot, adjust settings and start it again.
Yes. You can edit your config and use the `/reload_config` command to reload the configuration. The bot will stop, reload the configuration and strategy and will restart with the new configuration and strategy.
### I want to improve the bot with a new strategy
That's great. We have a nice backtesting and hyperoptimization setup. See
the tutorial [here|Testing-new-strategies-with-Hyperopt](bot-usage.md#hyperopt-commands).
That's great. We have a nice backtesting and hyperoptimization setup. See the tutorial [here|Testing-new-strategies-with-Hyperopt](bot-usage.md#hyperopt-commands).
### Is there a setting to only SELL the coins being held and not perform anymore BUYS?
You can use the `/forcesell all` command from Telegram.
You can use the `/stopbuy` command in Telegram to prevent future buys, followed by `/forcesell all` (sell all open trades).
### I want to run multiple bots on the same machine
@@ -59,7 +56,7 @@ Please look at the [advanced setup documentation Page](advanced-setup.md#running
This message is just a warning that the latest candles had missing candles in them.
Depending on the exchange, this can indicate that the pair didn't have a trade for the timeframe you are using - and the exchange does only return candles with volume.
On low volume pairs, this is a rather common occurance.
On low volume pairs, this is a rather common occurrence.
If this happens for all pairs in the pairlist, this might indicate a recent exchange downtime. Please check your exchange's public channels for details.
@@ -73,7 +70,7 @@ Read [the Bittrex section about restricted markets](exchanges.md#restricted-mark
### I'm getting the "Exchange Bittrex does not support market orders." message and cannot run my strategy
As the message says, Bittrex does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Probably your strategy was written with other exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of the exchanges supporting market orders (but not for Bittrex).
As the message says, Bittrex does not support market orders and you have one of the [order types](configuration.md/#understand-order_types) set to "market". Your strategy was probably written with other exchanges in mind and sets "market" orders for "stoploss" orders, which is correct and preferable for most of the exchanges supporting market orders (but not for Bittrex).
To fix it for Bittrex, redefine order types in the strategy to use "limit" instead of "market":
@@ -85,7 +82,7 @@ To fix it for Bittrex, redefine order types in the strategy to use "limit" inste
}
```
Same fix should be done in the configuration file, if order types are defined in your custom config rather than in the strategy.
The same fix should be applied in the configuration file, if order types are defined in your custom config rather than in the strategy.
### How do I search the bot logs for something?
@@ -127,10 +124,10 @@ On Windows, the `--logfile` option is also supported by Freqtrade and you can us
## Hyperopt module
### How many epoch do I need to get a good Hyperopt result?
### How many epochs do I need to get a good Hyperopt result?
Per default Hyperopt called without the `-e`/`--epochs` command line option will only
run 100 epochs, means 100 evals of your triggers, guards, ... Too few
run 100 epochs, means 100 evaluations of your triggers, guards, ... Too few
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.
@@ -140,38 +137,32 @@ Since hyperopt uses Bayesian search, running for too many epochs may not produce
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 1000
```
or if you want intermediate result to see
```bash
for i in {1..100}; do freqtrade hyperopt -e 1000; done
freqtrade hyperopt --hyperopt SampleHyperopt --hyperopt-loss SharpeHyperOptLossDaily --strategy SampleStrategy -e 1000
```
### Why does it take a long time to run hyperopt?
* 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/enQtNjU5ODcwNjI1MDU3LTU1MTgxMjkzNmYxNWE1MDEzYzQ3YmU4N2MwZjUyNjJjODRkMDVkNjg4YTAyZGYzYzlhOTZiMTE4ZjQ4YzM0OGE) - 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.
* 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-mm786y93-Fxo37glxMY9g8OQC5AoOIw) - 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.
* If you wonder why it can take from 20 minutes to days to do 1000 epochs here are some answers:
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
- 1 stoploss calculation: let's say we want 10 values from that too to be evaluated
* 8 triggers
* 9 guards: let's say we evaluate even 10 values from each
* 1 stoploss calculation: let's say we want 10 values from that too to be evaluated
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
already 8\*10^9\*10 evaluations. A roughly total of 80 billion evaluations.
Did you run 100 000 evaluations? Congrats, you've done roughly 1 / 100 000 th
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:
Example:
`freqtrade --config config.json --strategy SampleStrategy --hyperopt SampleHyperopt -e 1000 --timerange 20190601-20200601`
## Edge module

View File

@@ -32,17 +32,126 @@ source .env/bin/activate
pip install -r requirements-hyperopt.txt
```
## Hyperopt command reference
```
usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[--hyperopt NAME] [--hyperopt-path PATH] [--eps]
[--dmmp] [--enable-protections] [-e INT]
[--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]]
[--print-all] [--no-color] [--print-json] [-j JOBS]
[--random-state INT] [--min-trades INT]
[--hyperopt-loss NAME]
optional arguments:
-h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME
Specify ticker interval (`1m`, `5m`, `30m`, `1h`,
`1d`).
--timerange TIMERANGE
Specify what timerange of data to use.
--data-format-ohlcv {json,jsongz,hdf5}
Storage format for downloaded candle (OHLCV) data.
(default: `None`).
--max-open-trades INT
Override the value of the `max_open_trades`
configuration setting.
--stake-amount STAKE_AMOUNT
Override the value of the `stake_amount` configuration
setting.
--fee FLOAT Specify fee ratio. Will be applied twice (on trade
entry and exit).
--hyperopt NAME Specify hyperopt class name which will be used by the
bot.
--hyperopt-path PATH Specify additional lookup path for Hyperopt and
Hyperopt Loss functions.
--eps, --enable-position-stacking
Allow buying the same pair multiple times (position
stacking).
--dmmp, --disable-max-market-positions
Disable applying `max_open_trades` during backtest
(same as setting `max_open_trades` to a very high
number).
--enable-protections, --enableprotections
Enable protections for backtesting.Will slow
backtesting down by a considerable amount, but will
include configured protections
-e INT, --epochs INT Specify number of epochs (default: 100).
--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]
Specify which parameters to hyperopt. Space-separated
list.
--print-all Print all results, not only the best ones.
--no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file.
--print-json Print output in JSON format.
-j JOBS, --job-workers JOBS
The number of concurrently running jobs for
hyperoptimization (hyperopt worker processes). If -1
(default), all CPUs are used, for -2, all CPUs but one
are used, etc. If 1 is given, no parallel computing
code is used at all.
--random-state INT Set random state to some positive integer for
reproducible hyperopt results.
--min-trades INT Set minimal desired number of trades for evaluations
in the hyperopt optimization path (default: 1).
--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:
ShortTradeDurHyperOptLoss, OnlyProfitHyperOptLoss,
SharpeHyperOptLoss, SharpeHyperOptLossDaily,
SortinoHyperOptLoss, SortinoHyperOptLossDaily
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default:
`userdir/config.json` or `config.json` whichever
exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
Strategy arguments:
-s NAME, --strategy NAME
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
```
## Prepare Hyperopting
Before we start digging into Hyperopt, we recommend you to take a look at
the sample hyperopt file located in [user_data/hyperopts/](https://github.com/freqtrade/freqtrade/blob/develop/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 +163,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.
* `populate_indicators` - fallback to create indicators
* `populate_buy_trend` - fallback if not optimizing for buy space. should come from strategy
* `populate_sell_trend` - fallback if not optimizing for sell space. should come from strategy
!!! 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,36 +187,41 @@ 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:
* Inside `indicator_space()` - the parameters hyperopt shall be optimizing.
* Inside `populate_buy_trend()` - applying the parameters.
* Within `buy_strategy_generator()` - populate the nested `populate_buy_trend()` to apply the parameters.
There you have two different types of indicators: 1. `guards` and 2. `triggers`.
1. Guards are conditions like "never buy if ADX < 10", or never buy if current price is over EMA10.
2. Triggers are ones that actually trigger buy in specific moment, like "buy when EMA5 crosses over EMA10" or "buy when close price touches lower Bollinger band".
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
@@ -117,7 +229,7 @@ Similar to the buy-signal above, sell-signals can also be optimized.
Place the corresponding settings into the following methods
* Inside `sell_indicator_space()` - the parameters hyperopt shall be optimizing.
* Inside `populate_sell_trend()` - applying the parameters.
* Within `sell_strategy_generator()` - populate the nested method `populate_sell_trend()` to apply the parameters.
The configuration and rules are the same than for buy signals.
To avoid naming collisions in the search-space, please prefix all sell-spaces with `sell-`.
@@ -126,7 +238,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
@@ -154,7 +266,7 @@ We will start by defining a search space:
Above definition says: I have five parameters I want you to randomly combine
to find the best combination. Two of them are integer values (`adx-value`
and `rsi-value`) and I want you test in the range of values 20 to 40.
and `rsi-value`) and I want you test in the range of values 20 to 40.
Then we have three category variables. First two are either `True` or `False`.
We use these to either enable or disable the ADX and RSI guards. The last
one we call `trigger` and use it to decide which buy trigger we want to use.
@@ -162,6 +274,11 @@ one we call `trigger` and use it to decide which buy trigger we want to use.
So let's write the buy strategy using these values:
```python
@staticmethod
def buy_strategy_generator(params: Dict[str, Any]) -> Callable:
"""
Define the buy strategy parameters to be used by Hyperopt.
"""
def populate_buy_trend(dataframe: DataFrame) -> DataFrame:
conditions = []
# GUARDS AND TRENDS
@@ -192,27 +309,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 +344,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 500 --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 +365,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 +379,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 +431,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
@@ -371,7 +484,7 @@ 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 nativly, therefore it is automatically disabled. To have color-output for hyperopt running under windows, please consider using WSL.
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
@@ -419,7 +532,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
@@ -441,7 +556,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
@@ -475,7 +590,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
@@ -494,10 +609,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.
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`).

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

@@ -0,0 +1,194 @@
## 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.
### Pair blacklist
The pair blacklist (configured via `exchange.pair_blacklist` in the configuration) disallows certain pairs from trading.
This can be as simple as excluding `DOGE/BTC` - which will remove exactly this pair.
The pair-blacklist does also support wildcards (in regex-style) - so `BNB/.*` will exclude ALL pairs that start with BNB.
You may also use something like `.*DOWN/BTC` or `.*UP/BTC` to exclude leveraged tokens (check Pair naming conventions for your exchange!)
### Available Pairlist Handlers
* [`StaticPairList`](#static-pair-list) (default, if not configured differently)
* [`VolumePairList`](#volume-pair-list)
* [`AgeFilter`](#agefilter)
* [`PerformanceFilter`](#performancefilter)
* [`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. The pairlist also supports wildcards (in regex-style) - so `.*/BTC` will include all pairs with BTC as a stake.
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
}],
```
!!! Note
`VolumePairList` does not support backtesting mode.
#### 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.
#### PerformanceFilter
Sorts pairs by past trade performance, as follows:
1. Positive performance.
2. No closed trades yet.
3. Negative performance.
Trade count is used as a tie breaker.
!!! Note
`PerformanceFilter` does not support backtesting mode.
#### 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}
],
```

127
docs/includes/pricing.md Normal file
View File

@@ -0,0 +1,127 @@
## Prices used for orders
Prices for regular orders can be controlled via the parameter structures `bid_strategy` for buying and `ask_strategy` for selling.
Prices are always retrieved right before an order is placed, either by querying the exchange tickers or by using the orderbook data.
!!! Note
Orderbook data used by Freqtrade are the data retrieved from exchange by the ccxt's function `fetch_order_book()`, i.e. are usually data from the L2-aggregated orderbook, while the ticker data are the structures returned by the ccxt's `fetch_ticker()`/`fetch_tickers()` functions. Refer to the ccxt library [documentation](https://github.com/ccxt/ccxt/wiki/Manual#market-data) for more details.
!!! Warning "Using market orders"
Please read the section [Market order pricing](#market-order-pricing) section when using market orders.
### Buy price
#### Check depth of market
When check depth of market is enabled (`bid_strategy.check_depth_of_market.enabled=True`), the buy signals are filtered based on the orderbook depth (sum of all amounts) for each orderbook side.
Orderbook `bid` (buy) side depth is then divided by the orderbook `ask` (sell) side depth and the resulting delta is compared to the value of the `bid_strategy.check_depth_of_market.bids_to_ask_delta` parameter. The buy order is only executed if the orderbook delta is greater than or equal to the configured delta value.
!!! Note
A delta value below 1 means that `ask` (sell) orderbook side depth is greater than the depth of the `bid` (buy) orderbook side, while a value greater than 1 means opposite (depth of the buy side is higher than the depth of the sell side).
#### Buy price side
The configuration setting `bid_strategy.price_side` defines the side of the spread the bot looks for when buying.
The following displays an orderbook.
``` explanation
...
103
102
101 # ask
-------------Current spread
99 # bid
98
97
...
```
If `bid_strategy.price_side` is set to `"bid"`, then the bot will use 99 as buying price.
In line with that, if `bid_strategy.price_side` is set to `"ask"`, then the bot will use 101 as buying price.
Using `ask` price often guarantees quicker filled orders, but the bot can also end up paying more than what would have been necessary.
Taker fees instead of maker fees will most likely apply even when using limit buy orders.
Also, prices at the "ask" side of the spread are higher than prices at the "bid" side in the orderbook, so the order behaves similar to a market order (however with a maximum price).
#### Buy price with Orderbook enabled
When buying with the orderbook enabled (`bid_strategy.use_order_book=True`), Freqtrade fetches the `bid_strategy.order_book_top` entries from the orderbook and then uses the entry specified as `bid_strategy.order_book_top` on the configured side (`bid_strategy.price_side`) of the orderbook. 1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on.
#### Buy price without Orderbook enabled
The following section uses `side` as the configured `bid_strategy.price_side`.
When not using orderbook (`bid_strategy.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's below the `last` traded price from the ticker. Otherwise (when the `side` price is above the `last` price), it calculates a rate between `side` and `last` price.
The `bid_strategy.ask_last_balance` configuration parameter controls this. A value of `0.0` will use `side` price, while `1.0` will use the `last` price and values between those interpolate between ask and last price.
### Sell price
#### Sell price side
The configuration setting `ask_strategy.price_side` defines the side of the spread the bot looks for when selling.
The following displays an orderbook:
``` explanation
...
103
102
101 # ask
-------------Current spread
99 # bid
98
97
...
```
If `ask_strategy.price_side` is set to `"ask"`, then the bot will use 101 as selling price.
In line with that, if `ask_strategy.price_side` is set to `"bid"`, then the bot will use 99 as selling price.
#### Sell price with Orderbook enabled
When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_max` entries in the orderbook. Then each of the orderbook steps between `ask_strategy.order_book_min` and `ask_strategy.order_book_max` on the configured orderbook side are validated for a profitable sell-possibility based on the strategy configuration (`minimal_roi` conditions) and the sell order is placed at the first profitable spot.
!!! Note
Using `order_book_max` higher than `order_book_min` only makes sense when ask_strategy.price_side is set to `"ask"`.
The idea here is to place the sell order early, to be ahead in the queue.
A fixed slot (mirroring `bid_strategy.order_book_top`) can be defined by setting `ask_strategy.order_book_min` and `ask_strategy.order_book_max` to the same number.
!!! Warning "Order_book_max > 1 - increased risks for stoplosses!"
Using `ask_strategy.order_book_max` higher than 1 will increase the risk the stoploss on exchange is cancelled too early, since an eventual [stoploss on exchange](#understand-order_types) will be cancelled as soon as the order is placed.
Also, the sell order will remain on the exchange for `unfilledtimeout.sell` (or until it's filled) - which can lead to missed stoplosses (with or without using stoploss on exchange).
!!! Warning "Order_book_max > 1 in dry-run"
Using `ask_strategy.order_book_max` higher than 1 will result in improper dry-run results (significantly better than real orders executed on exchange), since dry-run assumes orders to be filled almost instantly.
It is therefore advised to not use this setting for dry-runs.
#### Sell price without Orderbook enabled
When not using orderbook (`ask_strategy.use_order_book=False`), the price at the `ask_strategy.price_side` side (defaults to `"ask"`) from the ticker will be used as the sell price.
### Market order pricing
When using market orders, prices should be configured to use the "correct" side of the orderbook to allow realistic pricing detection.
Assuming both buy and sell are using market orders, a configuration similar to the following might be used
``` jsonc
"order_types": {
"buy": "market",
"sell": "market"
// ...
},
"bid_strategy": {
"price_side": "ask",
// ...
},
"ask_strategy":{
"price_side": "bid",
// ...
},
```
Obviously, if only one side is using limit orders, different pricing combinations can be used.

View File

@@ -0,0 +1,215 @@
## Protections
!!! Warning "Beta feature"
This feature is still in it's testing phase. Should you notice something you think is wrong please let us know via Discord, Slack or via Github Issue.
Protections will protect your strategy from unexpected events and market conditions by temporarily stop trading for either one pair, or for all pairs.
All protection end times are rounded up to the next candle to avoid sudden, unexpected intra-candle buys.
!!! Note
Not all Protections will work for all strategies, and parameters will need to be tuned for your strategy to improve performance.
To align your protection with your strategy, you can define protections in the strategy.
!!! Tip
Each Protection can be configured multiple times with different parameters, to allow different levels of protection (short-term / long-term).
!!! Note "Backtesting"
Protections are supported by backtesting and hyperopt, but must be explicitly enabled by using the `--enable-protections` flag.
### Available Protections
* [`StoplossGuard`](#stoploss-guard) Stop trading if a certain amount of stoploss occurred within a certain time window.
* [`MaxDrawdown`](#maxdrawdown) Stop trading if max-drawdown is reached.
* [`LowProfitPairs`](#low-profit-pairs) Lock pairs with low profits
* [`CooldownPeriod`](#cooldown-period) Don't enter a trade right after selling a trade.
### Common settings to all Protections
| Parameter| Description |
|------------|-------------|
| `method` | Protection name to use. <br> **Datatype:** String, selected from [available Protections](#available-protections)
| `stop_duration_candles` | For how many candles should the lock be set? <br> **Datatype:** Positive integer (in candles)
| `stop_duration` | how many minutes should protections be locked. <br>Cannot be used together with `stop_duration_candles`. <br> **Datatype:** Float (in minutes)
| `lookback_period_candles` | Only trades that completed within the last `lookback_period_candles` candles will be considered. This setting may be ignored by some Protections. <br> **Datatype:** Positive integer (in candles).
| `lookback_period` | Only trades that completed after `current_time - lookback_period` will be considered. <br>Cannot be used together with `lookback_period_candles`. <br>This setting may be ignored by some Protections. <br> **Datatype:** Float (in minutes)
| `trade_limit` | Number of trades required at minimum (not used by all Protections). <br> **Datatype:** Positive integer
!!! Note "Durations"
Durations (`stop_duration*` and `lookback_period*` can be defined in either minutes or candles).
For more flexibility when testing different timeframes, all below examples will use the "candle" definition.
#### Stoploss Guard
`StoplossGuard` selects all trades within `lookback_period` in minutes (or in candles when using `lookback_period_candles`).
If `trade_limit` or more trades resulted in stoploss, trading will stop for `stop_duration` in minutes (or in candles when using `stop_duration_candles`).
This applies across all pairs, unless `only_per_pair` is set to true, which will then only look at one pair at a time.
The below example stops trading for all pairs for 4 candles after the last trade if the bot hit stoploss 4 times within the last 24 candles.
```json
"protections": [
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 4,
"only_per_pair": false
}
],
```
!!! Note
`StoplossGuard` considers all trades with the results `"stop_loss"`, `"stoploss_on_exchange"` and `"trailing_stop_loss"` if the resulting profit was negative.
`trade_limit` and `lookback_period` will need to be tuned for your strategy.
#### MaxDrawdown
`MaxDrawdown` uses all trades within `lookback_period` in minutes (or in candles when using `lookback_period_candles`) to determine the maximum drawdown. If the drawdown is below `max_allowed_drawdown`, trading will stop for `stop_duration` in minutes (or in candles when using `stop_duration_candles`) after the last trade - assuming that the bot needs some time to let markets recover.
The below sample stops trading for 12 candles if max-drawdown is > 20% considering all pairs - with a minimum of `trade_limit` trades - within the last 48 candles. If desired, `lookback_period` and/or `stop_duration` can be used.
```json
"protections": [
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 12,
"max_allowed_drawdown": 0.2
},
],
```
#### Low Profit Pairs
`LowProfitPairs` uses all trades for a pair within `lookback_period` in minutes (or in candles when using `lookback_period_candles`) to determine the overall profit ratio.
If that ratio is below `required_profit`, that pair will be locked for `stop_duration` in minutes (or in candles when using `stop_duration_candles`).
The below example will stop trading a pair for 60 minutes if the pair does not have a required profit of 2% (and a minimum of 2 trades) within the last 6 candles.
```json
"protections": [
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration": 60,
"required_profit": 0.02
}
],
```
#### Cooldown Period
`CooldownPeriod` locks a pair for `stop_duration` in minutes (or in candles when using `stop_duration_candles`) after selling, avoiding a re-entry for this pair for `stop_duration` minutes.
The below example will stop trading a pair for 2 candles after closing a trade, allowing this pair to "cool down".
```json
"protections": [
{
"method": "CooldownPeriod",
"stop_duration_candles": 2
}
],
```
!!! Note
This Protection applies only at pair-level, and will never lock all pairs globally.
This Protection does not consider `lookback_period` as it only looks at the latest trade.
### Full example of Protections
All protections can be combined at will, also with different parameters, creating a increasing wall for under-performing pairs.
All protections are evaluated in the sequence they are defined.
The below example assumes a timeframe of 1 hour:
* Locks each pair after selling for an additional 5 candles (`CooldownPeriod`), giving other pairs a chance to get filled.
* Stops trading for 4 hours (`4 * 1h candles`) if the last 2 days (`48 * 1h candles`) had 20 trades, which caused a max-drawdown of more than 20%. (`MaxDrawdown`).
* Stops trading if more than 4 stoploss occur for all pairs within a 1 day (`24 * 1h candles`) limit (`StoplossGuard`).
* Locks all pairs that had 4 Trades within the last 6 hours (`6 * 1h candles`) with a combined profit ratio of below 0.02 (<2%) (`LowProfitPairs`).
* Locks all pairs for 2 candles that had a profit of below 0.01 (<1%) within the last 24h (`24 * 1h candles`), a minimum of 4 trades.
```json
"timeframe": "1h",
"protections": [
{
"method": "CooldownPeriod",
"stop_duration_candles": 5
},
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 4,
"max_allowed_drawdown": 0.2
},
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"only_per_pair": false
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration_candles": 60,
"required_profit": 0.02
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"required_profit": 0.01
}
],
```
You can use the same in your strategy, the syntax is only slightly different:
``` python
from freqtrade.strategy import IStrategy
class AwesomeStrategy(IStrategy)
timeframe = '1h'
protections = [
{
"method": "CooldownPeriod",
"stop_duration_candles": 5
},
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 4,
"max_allowed_drawdown": 0.2
},
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"only_per_pair": False
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration_candles": 60,
"required_profit": 0.02
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"required_profit": 0.01
}
]
# ...
```

View File

@@ -14,7 +14,7 @@
## Introduction
Freqtrade is a crypto-currency algorithmic trading software developed in python (3.6+) and supported on Windows, macOS and Linux.
Freqtrade is a crypto-currency algorithmic trading software developed in python (3.7+) and supported on Windows, macOS and Linux.
!!! Danger "DISCLAIMER"
This software is for educational purposes only. Do not risk money which you are afraid to lose. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
@@ -35,6 +35,22 @@ Freqtrade is a crypto-currency algorithmic trading software developed in python
- Control/Monitor: Use Telegram or a REST API (start/stop the bot, show profit/loss, daily summary, current open trades results, etc.).
- Analyse: Further analysis can be performed on either Backtesting data or Freqtrade trading history (SQL database), including automated standard plots, and methods to load the data into [interactive environments](data-analysis.md).
## Supported exchange marketplaces
Please read the [exchange specific notes](exchanges.md) to learn about eventual, special configurations needed for each exchange.
- [X] [Binance](https://www.binance.com/) ([*Note for binance users](exchanges.md#blacklists))
- [X] [Bittrex](https://bittrex.com/)
- [X] [FTX](https://ftx.com)
- [X] [Kraken](https://kraken.com/)
- [ ] [potentially many others](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
### Community tested
Exchanges confirmed working by the community:
- [X] [Bitvavo](https://bitvavo.com/)
## Requirements
### Hardware requirements
@@ -51,7 +67,7 @@ To run this bot we recommend you a linux cloud instance with a minimum of:
Alternatively
- Python 3.6.x
- Python 3.7+
- pip (pip3)
- git
- TA-Lib
@@ -59,11 +75,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-mm786y93-Fxo37glxMY9g8OQC5AoOIw).
## 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

@@ -2,116 +2,79 @@
This page explains how to prepare your environment for running the bot.
Please consider using the prebuilt [docker images](docker.md) to get started quickly while trying out freqtrade evaluating how it operates.
The freqtrade documentation describes various ways to install freqtrade
## Prerequisite
* [Docker images](docker_quickstart.md) (separate page)
* [Script Installation](#script-installation)
* [Manual Installation](#manual-installation)
* [Installation with Conda](#installation-with-conda)
### Requirements
Please consider using the prebuilt [docker images](docker_quickstart.md) to get started quickly while evaluating how freqtrade works.
Click each one for install guide:
------
* [Python >= 3.6.x](http://docs.python-guide.org/en/latest/starting/installation/)
* [pip](https://pip.pypa.io/en/stable/installing/)
* [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [virtualenv](https://virtualenv.pypa.io/en/stable/installation.html) (Recommended)
* [TA-Lib](https://mrjbq7.github.io/ta-lib/install.html) (install instructions below)
## Information
We also recommend a [Telegram bot](telegram-usage.md#setup-your-telegram-bot), which is optional but recommended.
For Windows installation, please use the [windows installation guide](windows_installation.md).
The easiest way to install and run Freqtrade is to clone the bot Github repository and then run the `./setup.sh` script, if it's available for your platform.
!!! 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 `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.7 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.
Also, python headers (`python<yourversion>-dev` / `python<yourversion>-devel`) must be available for the installation to complete successfully.
!!! 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.
!!! Note
Windows installation is explained [here](#windows).
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 `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.
This can be achieved with the following commands:
```bash
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
# git checkout stable # Optional, see (1)
./setup.sh --install
```
(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)
If you are on Debian, Ubuntu or MacOS Freqtrade provides the script to install, update, configure and reset the codebase of your bot.
```bash
$ ./setup.sh
usage:
-i,--install Install freqtrade from scratch
-u,--update Command git pull to update.
-r,--reset Hard reset your develop/stable branch.
-c,--config Easy config generator (Will override your existing file).
```
** --install **
With this option, the script will install the bot and most dependencies:
You will need to have git and python3.6+ installed beforehand for this to work.
* Mandatory software as: `ta-lib`
* Setup your virtualenv under `.env/`
This option is a combination of installation tasks, `--reset` and `--config`.
** --update **
This option will pull the last version of your current branch and update your virtualenv. Run the script with this option periodically to update your bot.
** --reset **
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
## Requirements
We've included/collected install instructions for Ubuntu 16.04, MacOS, and Windows. These are guidelines and your success may vary with other distros.
These requirements apply to both [Script Installation](#script-installation) and [Manual Installation](#manual-installation).
### Install guide
* [Python >= 3.7.x](http://docs.python-guide.org/en/latest/starting/installation/)
* [pip](https://pip.pypa.io/en/stable/installing/)
* [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [virtualenv](https://virtualenv.pypa.io/en/stable/installation.html) (Recommended)
* [TA-Lib](https://mrjbq7.github.io/ta-lib/install.html) (install instructions [below](#install-ta-lib))
### Install code
We've included/collected install instructions for Ubuntu, MacOS, and Windows. These are guidelines and your success may vary with other distros.
OS Specific steps are listed first, the [Common](#common) section below is necessary for all systems.
!!! Note
Python3.6 or higher and the corresponding pip are assumed to be available.
Python3.7 or higher and the corresponding pip are assumed to be available.
=== "Ubuntu 16.04"
=== "Debian/Ubuntu"
#### Install necessary dependencies
```bash
# update repository
sudo apt-get update
sudo apt-get install build-essential git
# install packages
sudo apt install -y python3-pip python3-venv python3-pandas python3-pip git
```
=== "RaspberryPi/Raspbian"
The following assumes the latest [Raspbian Buster lite image](https://www.raspberrypi.org/downloads/raspbian/) from at least September 2019.
The following assumes the latest [Raspbian Buster lite image](https://www.raspberrypi.org/downloads/raspbian/).
This image comes with python3.7 preinstalled, making it easy to get freqtrade up and running.
Tested using a Raspberry Pi 3 with the Raspbian Buster lite image, all updates applied.
``` bash
sudo apt-get install python3-venv libatlas-base-dev
```bash
sudo apt-get install python3-venv libatlas-base-dev cmake
# Use pywheels.org to speed up installation
sudo echo "[global]\nextra-index-url=https://www.piwheels.org/simple" > tee /etc/pip.conf
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
@@ -120,16 +83,106 @@ OS Specific steps are listed first, the [Common](#common) section below is neces
!!! Note "Installation duration"
Depending on your internet speed and the Raspberry Pi version, installation can take multiple hours to complete.
Due to this, we recommend to use the pre-build docker-image for Raspberry, by following the [Docker quickstart documentation](docker_quickstart.md)
!!! 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
------
#### 1. Install TA-Lib
## Freqtrade repository
Use the provided ta-lib installation script
Freqtrade is an open source crypto-currency trading bot, whose code is hosted on `github.com`
```bash
# Download `develop` branch of freqtrade repository
git clone https://github.com/freqtrade/freqtrade.git
# Enter downloaded directory
cd freqtrade
# your choice (1): novice user
git checkout stable
# your choice (2): advanced user
git checkout develop
```
(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 (2) `develop` branch.
You may later switch between branches at any time with the `git checkout stable`/`git checkout develop` commands.
------
## Script Installation
First of the ways to install Freqtrade, is to use provided the Linux/MacOS `./setup.sh` script, which install all dependencies and help you configure the bot.
Make sure you fulfill the [Requirements](#requirements) and have downloaded the [Freqtrade repository](#freqtrade-repository).
### Use /setup.sh -install (Linux/MacOS)
If you are on Debian, Ubuntu or MacOS, freqtrade provides the script to install freqtrade.
```bash
# --install, Install freqtrade from scratch
./setup.sh -i
```
### Activate your virtual environment
Each time you open a new terminal, you must run `source .env/bin/activate` to activate your virtual environment.
```bash
# then activate your .env
source ./.env/bin/activate
```
### Congratulations
[You are ready](#you-are-ready), and run the bot
### Other options of /setup.sh script
You can as well update, configure and reset the codebase of your bot with `./script.sh`
```bash
# --update, Command git pull to update.
./setup.sh -u
# --reset, Hard reset your develop/stable branch.
./setup.sh -r
```
```
** --install **
With this option, the script will install the bot and most dependencies:
You will need to have git and python3.7+ installed beforehand for this to work.
* Mandatory software as: `ta-lib`
* Setup your virtualenv under `.env/`
This option is a combination of installation tasks and `--reset`
** --update **
This option will pull the last version of your current branch and update your virtualenv. Run the script with this option periodically to update your bot.
** --reset **
This option will hard reset your branch (only if you are on either `stable` or `develop`) and recreate your virtualenv.
```
-----
## Manual Installation
Make sure you fulfill the [Requirements](#requirements) and have downloaded the [Freqtrade repository](#freqtrade-repository).
### Install TA-Lib
#### TA-Lib script installation
```bash
sudo ./build_helpers/install_ta-lib.sh
@@ -154,77 +207,193 @@ cd ..
rm -rf ./ta-lib*
```
!!! Note
An already downloaded version of ta-lib is included in the repository, as the sourceforge.net source seems to have problems frequently.
#### Setup Python virtual environment (virtualenv)
#### 2. Setup your Python virtual environment (virtualenv)
!!! Note
This step is optional but strongly recommended to keep your system organized
You will run freqtrade in separated `virtual environment`
```bash
# create virtualenv in directory /freqtrade/.env
python3 -m venv .env
# run virtualenv
source .env/bin/activate
```
#### 3. Install Freqtrade
Clone the git repository:
#### Install python dependencies
```bash
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
git checkout stable
```
#### 4. Install python dependencies
``` bash
python3 -m pip install --upgrade pip
python3 -m pip install -e .
```
#### 5. Initialize the configuration
### Congratulations
```bash
# Initialize the user_directory
freqtrade create-userdir --userdir user_data/
[You are ready](#you-are-ready), and run the bot
# Create a new configuration file
freqtrade new-config --config config.json
```
#### (Optional) Post-installation Tasks
> *To edit the config please refer to [Bot Configuration](configuration.md).*
!!! Note
If you run the bot on a server, you should consider using [Docker](docker_quickstart.md) or a terminal multiplexer like `screen` or [`tmux`](https://en.wikipedia.org/wiki/Tmux) to avoid that the bot is stopped on logout.
#### 6. Run the Bot
If this is the first time you run the bot, ensure you are running it in Dry-run `"dry_run": true,` otherwise it will start to buy and sell coins.
```bash
freqtrade trade -c config.json
```
*Note*: If you run the bot on a server, you should consider using [Docker](docker.md) or a terminal multiplexer like `screen` or [`tmux`](https://en.wikipedia.org/wiki/Tmux) to avoid that the bot is stopped on logout.
#### 7. (Optional) Post-installation Tasks
On Linux, as an optional post-installation task, you may wish to setup the bot to run as a `systemd` service or configure it to send the log messages to the `syslog`/`rsyslog` or `journald` daemons. See [Advanced Logging](advanced-setup.md#advanced-logging) for details.
On Linux with software suite `systemd`, as an optional post-installation task, you may wish to setup the bot to run as a `systemd service` or configure it to send the log messages to the `syslog`/`rsyslog` or `journald` daemons. See [Advanced Logging](advanced-setup.md#advanced-logging) for details.
------
### Anaconda
## Installation with Conda
Freqtrade can also be installed using Anaconda (or Miniconda).
Freqtrade can also be installed with Miniconda or Anaconda. We recommend using Miniconda as it's installation footprint is smaller. Conda will automatically prepare and manage the extensive library-dependencies of the Freqtrade program.
!!! Note
This requires the [ta-lib](#1-install-ta-lib) C-library to be installed first. See below.
### What is Conda?
``` bash
conda env create -f environment.yml
Conda is a package, dependency and environment manager for multiple programming languages: [conda docs](https://docs.conda.io/projects/conda/en/latest/index.html)
### Installation with conda
#### Install Conda
[Installing on linux](https://conda.io/projects/conda/en/latest/user-guide/install/linux.html#install-linux-silent)
[Installing on windows](https://conda.io/projects/conda/en/latest/user-guide/install/windows.html)
Answer all questions. After installation, it is mandatory to turn your terminal OFF and ON again.
#### Freqtrade download
Download and install freqtrade.
```bash
# download freqtrade
git clone https://github.com/freqtrade/freqtrade.git
# enter downloaded directory 'freqtrade'
cd freqtrade
```
#### Freqtrade instal: Conda Environment
Prepare conda-freqtrade environment, using file `environment.yml`, which exist in main freqtrade directory
```bash
conda env create -n freqtrade-conda -f environment.yml
```
!!! Note "Creating Conda Environment"
The conda command `create -n` automatically installs all nested dependencies for the selected libraries, general structure of installation command is:
```bash
# choose your own packages
conda env create -n [name of the environment] [python version] [packages]
# point to file with packages
conda env create -n [name of the environment] -f [file]
```
#### Enter/exit freqtrade-conda environment
To check available environments, type
```bash
conda env list
```
Enter installed environment
```bash
# enter conda environment
conda activate freqtrade-conda
# exit conda environment - don't do it now
conda deactivate
```
Install last python dependencies with pip
```bash
python3 -m pip install --upgrade pip
python3 -m pip install -e .
```
### Congratulations
[You are ready](#you-are-ready), and run the bot
### Important shortcuts
```bash
# list installed conda environments
conda env list
# activate base environment
conda activate
# activate freqtrade-conda environment
conda activate freqtrade-conda
#deactivate any conda environments
conda deactivate
```
### Further info on anaconda
!!! Info "New heavy packages"
It may happen that creating a new Conda environment, populated with selected packages at the moment of creation takes less time than installing a large, heavy library or application, into previously set environment.
!!! Warning "pip install within conda"
The documentation of conda says that pip should NOT be used within conda, because internal problems can occur.
However, they are rare. [Anaconda Blogpost](https://www.anaconda.com/blog/using-pip-in-a-conda-environment)
Nevertheless, that is why, the `conda-forge` channel is preferred:
* more libraries are available (less need for `pip`)
* `conda-forge` works better with `pip`
* the libraries are newer
Happy trading!
-----
## Troubleshooting
## You are ready
You've made it this far, so you have successfully installed freqtrade.
### Initialize the configuration
```bash
# Step 1 - Initialize user folder
freqtrade create-userdir --userdir user_data
# Step 2 - Create a new configuration file
freqtrade new-config --config config.json
```
You are ready to run, read [Bot Configuration](configuration.md), remember to start with `dry_run: True` and verify that everything is working.
To learn how to setup your configuration, please refer to the [Bot Configuration](configuration.md) documentation page.
### Start the Bot
```bash
freqtrade trade --config config.json --strategy SampleStrategy
```
!!! Warning
You should read through the rest of the documentation, backtest the strategy you're going to use, and use dry-run before enabling trading with real money.
-----
## Troubleshooting
### Common problem: "command not found"
If you used (1)`Script` or (2)`Manual` installation, you need to run the bot in virtual environment. If you get error as below, make sure venv is active.
```bash
# if:
bash: freqtrade: command not found
# then activate your .env
source ./.env/bin/activate
```
### MacOS installation error
@@ -233,13 +402,21 @@ Newer versions of MacOS may have installation failed with errors like `error: co
This error will require explicit installation of the SDK Headers, which are not installed by default in this version of MacOS.
For MacOS 10.14, this can be accomplished with the below command.
``` bash
```bash
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```
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.
-----
### MacOS installation error with python 3.9
Now you have an environment ready, the next step is
[Bot Configuration](configuration.md).
When using python 3.9 on macOS, it's currently necessary to install some os-level modules to allow dependencies to compile.
The errors you'll see happen during installation and are related to the installation of `tables` or `blosc`.
You can install the necessary libraries with the following command:
```bash
brew install hdf5 c-blosc
```
After this, please run the installation (script) again.

View File

@@ -1,54 +1,51 @@
{#-
This file was automatically generated - do not edit
-#}
{% set site_url = config.site_url | d(nav.homepage.url, true) | url %}
{% if not config.use_directory_urls and site_url[0] == site_url[-1] == "." %}
{% set site_url = site_url ~ "/index.html" %}
{% endif %}
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="{{ config.site_url | default(nav.homepage.url, true) | url }}" title="{{ config.site_name }}"
class="md-header-nav__button md-logo">
{% if config.theme.logo.icon %}
<i class="md-icon">{{ config.theme.logo.icon }}</i>
{% else %}
<img src="{{ config.theme.logo | url }}" width="24" height="24">
{% endif %}
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
{% block site_name %}
{% if config.site_name == page.title %}
{{ config.site_name }}
{% else %}
<span class="md-header-nav__topic">
{{ config.site_name }}
</span>
<span class="md-header-nav__topic">
{{ page.title }}
</span>
{% endif %}
{% endblock %}
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
{% block search_box %}
{% if "search" in config["plugins"] %}
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
{% include "partials/search.html" %}
{% endif %}
{% endblock %}
</div>
{% if config.repo_url %}
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
{% include "partials/source.html" %}
</div>
</div>
{% endif %}
<nav class="md-header-nav md-grid" aria-label="{{ lang.t('header.title') }}">
<a href="{{ site_url }}" title="{{ config.site_name | e }}" class="md-header-nav__button md-logo"
aria-label="{{ config.site_name }}">
{% include "partials/logo.html" %}
</a>
<label class="md-header-nav__button md-icon" for="__drawer">
{% include ".icons/material/menu" ~ ".svg" %}
</label>
<div class="md-header-nav__title" data-md-component="header-title">
<div class="md-header-nav__ellipsis">
<div class="md-header-nav__topic">
<span class="md-ellipsis">
{{ config.site_name }}
</span>
</div>
</nav>
<!-- Place this tag in your head or just before your close body tag. -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<div class="md-header-nav__topic">
<span class="md-ellipsis">
{% if page and page.meta and page.meta.title %}
{{ page.meta.title }}
{% else %}
{{ page.title }}
{% endif %}
</span>
</div>
</div>
</div>
{% if "search" in config["plugins"] %}
<label class="md-header-nav__button md-icon" for="__search">
{% include ".icons/material/magnify.svg" %}
</label>
{% include "partials/search.html" %}
{% endif %}
{% if config.repo_url %}
<div class="md-header-nav__source">
{% include "partials/source.html" %}
</div>
{% endif %}
</nav>
<!-- Place this tag in your head or just before your close body tag. -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
</header>

View File

@@ -168,6 +168,7 @@ Additional features when using plot_config include:
* Specify colors per indicator
* Specify additional subplots
* Specify indicator pairs to fill area in between
The sample plot configuration below specifies fixed colors for the indicators. Otherwise consecutive plots may produce different colorschemes each time, making comparisons difficult.
It also allows multiple subplots to display both MACD and RSI at the same time.
@@ -183,23 +184,34 @@ Sample configuration with inline comments explaining the process:
'ema50': {'color': '#CCCCCC'},
# By omitting color, a random color is selected.
'sar': {},
# fill area between senkou_a and senkou_b
'senkou_a': {
'color': 'green', #optional
'fill_to': 'senkou_b',
'fill_label': 'Ichimoku Cloud', #optional
'fill_color': 'rgba(255,76,46,0.2)', #optional
},
# plot senkou_b, too. Not only the area to it.
'senkou_b': {}
},
'subplots': {
# Create subplot MACD
"MACD": {
'macd': {'color': 'blue'},
'macdsignal': {'color': 'orange'},
'macd': {'color': 'blue', 'fill_to': 'macdhist'},
'macdsignal': {'color': 'orange'}
},
# Additional subplot RSI
"RSI": {
'rsi': {'color': 'red'},
'rsi': {'color': 'red'}
}
}
}
```
!!! Note
The above configuration assumes that `ema10`, `ema50`, `macd`, `macdsignal` and `rsi` are columns in the DataFrame created by the strategy.
The above configuration assumes that `ema10`, `ema50`, `senkou_a`, `senkou_b`,
`macd`, `macdsignal`, `macdhist` and `rsi` are columns in the DataFrame created by the strategy.
## Plot profit

3
docs/plugins.md Normal file
View File

@@ -0,0 +1,3 @@
# Plugins
--8<-- "includes/pairlists.md"
--8<-- "includes/protections.md"

View File

@@ -1,2 +1,3 @@
mkdocs-material==5.5.13
mkdocs-material==6.2.8
mdx_truly_sane_lists==1.2
pymdown-extensions==8.1.1

View File

@@ -1,4 +1,19 @@
# REST API Usage
# REST API & FreqUI
## FreqUI
Freqtrade provides a builtin webserver, which can serve [FreqUI](https://github.com/freqtrade/frequi), the freqtrade UI.
By default, the UI is not included in the installation (except for docker images), and must be installed explicitly with `freqtrade install-ui`.
This same command can also be used to update freqUI, should there be a new release.
Once the bot is started in trade / dry-run mode (with `freqtrade trade`) - the UI will be available under the configured port below (usually `http://127.0.0.1:8080`).
!!! info "Alpha release"
FreqUI is still considered an alpha release - if you encounter bugs or inconsistencies please open a [FreqUI issue](https://github.com/freqtrade/frequi/issues/new/choose).
!!! Note "developers"
Developers should not use this method, but instead use the method described in the [freqUI repository](https://github.com/freqtrade/frequi) to get the source-code of freqUI.
## Configuration
@@ -11,7 +26,8 @@ Sample configuration:
"enabled": true,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"verbosity": "info",
"verbosity": "error",
"enable_openapi": false,
"jwt_secret_key": "somethingrandom",
"CORS_origins": [],
"username": "Freqtrader",
@@ -22,9 +38,6 @@ Sample configuration:
!!! Danger "Security warning"
By default, the configuration listens on localhost only (so it's not reachable from other systems). We strongly recommend to not expose this API to the internet and choose a strong, unique password, since others will potentially be able to control your bot.
!!! Danger "Password selection"
Please make sure to select a very strong, unique password to protect your bot from unauthorized access.
You can then access the API by going to `http://127.0.0.1:8080/api/v1/ping` in a browser to check if the API is running correctly.
This should return the response:
@@ -34,16 +47,22 @@ This should return the response:
All other endpoints return sensitive info and require authentication and are therefore not available through a web browser.
To generate a secure password, either use a password manager, or use the below code snipped.
### Security
To generate a secure password, best use a password manager, or use the below code.
``` python
import secrets
secrets.token_hex()
```
!!! Hint
!!! Hint "JWT token"
Use the same method to also generate a JWT secret key (`jwt_secret_key`).
!!! Danger "Password selection"
Please make sure to select a very strong, unique password to protect your bot from unauthorized access.
Also change `jwt_secret_key` to something random (no need to remember this, but it'll be used to encrypt your session, so it better be something unique!).
### Configuration with 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.
@@ -56,28 +75,20 @@ If you run your bot using docker, you'll need to have the bot listen to incoming
},
```
Add the following to your docker command:
Uncomment the following from your docker-compose file:
``` bash
-p 127.0.0.1:8080:8080
```
A complete sample-command may then look as follows:
```bash
docker run -d \
--name freqtrade \
-v ~/.freqtrade/config.json:/freqtrade/config.json \
-v ~/.freqtrade/user_data/:/freqtrade/user_data \
-v ~/.freqtrade/tradesv3.sqlite:/freqtrade/tradesv3.sqlite \
-p 127.0.0.1:8080:8080 \
freqtrade trade --db-url sqlite:///tradesv3.sqlite --strategy MyAwesomeStrategy
```yml
ports:
- "127.0.0.1:8080:8080"
```
!!! Danger "Security warning"
By using `-p 8080:8080` the API is available to everyone connecting to the server under the correct port, so others may be able to control your bot.
By using `8080:8080` in the docker port mapping, the API will be available to everyone connecting to the server under the correct port, so others may be able to control your bot.
## Consuming the API
## Rest API
### Consuming the API
You can consume the API by using the script `scripts/rest_client.py`.
The client script only requires the `requests` module, so Freqtrade does not need to be installed on the system.
@@ -88,7 +99,7 @@ python3 scripts/rest_client.py <command> [optional parameters]
By default, the script assumes `127.0.0.1` (localhost) and port `8080` to be used, however you can specify a configuration file to override this behaviour.
### Minimalistic client config
#### Minimalistic client config
``` json
{
@@ -104,32 +115,43 @@ 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 | Description |
|----------|-------------|
| `ping` | Simple command testing the API Readiness - requires no authentication.
| `start` | Starts the trader
| `stop` | Stops the trader
| `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
| `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
| `profit` | Display a summary of your profit/loss from close trades and some stats about your performance
| `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
| `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).
| `stats` | Display a summary of profit / loss reasons as well as average holding times.
| `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
| `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.
@@ -140,6 +162,12 @@ 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.
@@ -179,9 +207,27 @@ 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
Return the performance of the different coins.
plot_config
Return plot configuration if the strategy defines one.
profit
Return the profit summary.
@@ -195,6 +241,9 @@ show_config
start
Start the bot if it's in the stopped state.
stats
Return the stats report (durations, sell-reasons).
status
Get the status of open trades.
@@ -204,6 +253,14 @@ stop
stopbuy
Stop buying (but handle sells gracefully). Use `reload_config` to reset.
strategies
Lists available strategies
strategy
Get strategy details
:param strategy: Strategy class name
trades
Return trades history.
@@ -215,10 +272,14 @@ version
whitelist
Show the current whitelist.
```
## Advanced API usage using JWT tokens
### OpenAPI interface
To enable the builtin openAPI interface (Swagger UI), specify `"enable_openapi": true` in the api_server configuration.
This will enable the Swagger UI at the `/docs` endpoint. By default, that's running at http://localhost:8080/docs/ - but it'll depend on your settings.
### Advanced API usage using JWT tokens
!!! Note
The below should be done in an application (a Freqtrade REST API client, which fetches info via API), and is not intended to be used on a regular basis.
@@ -243,9 +304,9 @@ Since the access token has a short timeout (15 min) - the `token/refresh` reques
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODkxMTk5NzQsIm5iZiI6MTU4OTExOTk3NCwianRpIjoiMDBjNTlhMWUtMjBmYS00ZTk0LTliZjAtNWQwNTg2MTdiZDIyIiwiZXhwIjoxNTg5MTIwODc0LCJpZGVudGl0eSI6eyJ1IjoiRnJlcXRyYWRlciJ9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MifQ.1seHlII3WprjjclY6DpRhen0rqdF4j6jbvxIhUFaSbs"}
```
## CORS
### CORS
All web-based frontends are subject to [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) - Cross-Origin Resource Sharing.
All web-based front-ends are subject to [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) - Cross-Origin Resource Sharing.
Since most of the requests to the Freqtrade API must be authenticated, a proper CORS policy is key to avoid security problems.
Also, the standard disallows `*` CORS policies for requests with credentials, so this setting must be set appropriately.

View File

@@ -43,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
@@ -98,11 +52,11 @@ 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
@@ -128,23 +82,12 @@ SET is_open=0,
WHERE id=31;
```
## Manually insert a new trade
```sql
INSERT INTO trades (exchange, pair, is_open, fee_open, fee_close, open_rate, stake_amount, amount, open_date)
VALUES ('binance', 'ETH/BTC', 1, 0.0025, 0.0025, <open_rate>, <stake_amount>, <amount>, '<datetime>')
```
### Insert trade example
```sql
INSERT INTO trades (exchange, pair, is_open, fee_open, fee_close, open_rate, stake_amount, amount, open_date)
VALUES ('binance', 'ETH/BTC', 1, 0.0025, 0.0025, 0.00258580, 0.002, 0.7715262081, '2020-06-28 12:44:24.000000')
```
## Remove trade from the database
Maybe you'd like to remove a trade from the database, because something went wrong.
!!! 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
DELETE FROM trades WHERE id = <tradeid>;

View File

@@ -23,11 +23,12 @@ These modes can be configured with these values:
```
!!! 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.
<ins>Do not set too low 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 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.
@@ -35,18 +36,23 @@ If `stoploss_on_exchange` uses limit orders, the exchange needs 2 prices, the st
`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$.
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.
@@ -72,6 +78,7 @@ At this stage the bot contains the following stoploss support modes:
2. Trailing stop loss.
3. Trailing stop loss, custom positive loss.
4. Trailing stop loss only once the trade has reached a certain offset.
5. [Custom stoploss function](strategy-advanced.md#custom-stoploss)
### Static Stop Loss
@@ -84,6 +91,7 @@ Example of stop loss:
```
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$
@@ -107,7 +115,7 @@ For example, simplified math:
* 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 -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$.
* 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 -10% of the highest observed price.
@@ -133,8 +141,8 @@ For example, simplified math:
* 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 increasements 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 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.
@@ -151,7 +159,7 @@ This option can be used with or without `trailing_stop_positive`, but uses `trai
trailing_only_offset_is_reached = True
```
Configuration (offset is buyprice + 3%):
Configuration (offset is buy-price + 3%):
``` python
stoploss = -0.10
@@ -169,7 +177,7 @@ For example, simplified math:
* 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$
* 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.

View File

@@ -8,11 +8,185 @@ If you're just getting started, please be familiar with the methods described in
!!! Note
All callback methods described below should only be implemented in a strategy if they are actually used.
!!! Tip
You can get a strategy template containing all below methods by running `freqtrade new-strategy --strategy MyAwesomeStrategy --template advanced`
## Custom stoploss
A stoploss can only ever move upwards - so if you set it to an absolute profit of 2%, you can never move it below this price.
Also, the traditional `stoploss` value serves as an absolute lower level and will be instated as the initial stoploss.
The usage of the custom stoploss method must be enabled by setting `use_custom_stoploss=True` on the strategy object.
The method must return a stoploss value (float / number) with a relative ratio below the current price.
E.g. `current_profit = 0.05` (5% profit) - stoploss returns `0.02` - then you "locked in" a profit of 3% (`0.05 - 0.02 = 0.03`).
To simulate a regular trailing stoploss of 4% (trailing 4% behind the maximum reached price) you would use the following very simple method:
``` python
# additional imports required
from datetime import datetime
from freqtrade.persistence import Trade
class AwesomeStrategy(IStrategy):
# ... populate_* methods
use_custom_stoploss = True
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
"""
Custom stoploss logic, returning the new distance relative to current_rate (as ratio).
e.g. returning -0.05 would create a stoploss 5% below current_rate.
The custom stoploss can never be below self.stoploss, which serves as a hard maximum loss.
For full documentation please go to https://www.freqtrade.io/en/latest/strategy-advanced/
When not implemented by a strategy, returns the initial stoploss value
Only called when use_custom_stoploss is set to True.
:param pair: Pair that's currently analyzed
:param trade: trade object.
:param current_time: datetime object, containing the current datetime
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
:param current_profit: Current profit (as ratio), calculated based on current_rate.
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return float: New stoploss value, relative to the currentrate
"""
return -0.04
```
Stoploss on exchange works similar to `trailing_stop`, and the stoploss on exchange is updated as configured in `stoploss_on_exchange_interval` ([More details about stoploss on exchange](stoploss.md#stop-loss-on-exchange-freqtrade)).
!!! Note "Use of dates"
All time-based calculations should be done based on `current_time` - using `datetime.now()` or `datetime.utcnow()` is discouraged, as this will break backtesting support.
!!! Tip "Trailing stoploss"
It's recommended to disable `trailing_stop` when using custom stoploss values. Both can work in tandem, but you might encounter the trailing stop to move the price higher while your custom function would not want this, causing conflicting behavior.
### Custom stoploss examples
The next section will show some examples on what's possible with the custom stoploss function.
Of course, many more things are possible, and all examples can be combined at will.
#### Time based trailing stop
Use the initial stoploss for the first 60 minutes, after this change to 10% trailing stoploss, and after 2 hours (120 minutes) we use a 5% trailing stoploss.
``` python
from datetime import datetime, timedelta
from freqtrade.persistence import Trade
class AwesomeStrategy(IStrategy):
# ... populate_* methods
use_custom_stoploss = True
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Make sure you have the longest interval first - these conditions are evaluated from top to bottom.
if current_time - timedelta(minutes=120) > trade.open_date:
return -0.05
elif current_time - timedelta(minutes=60) > trade.open_date:
return -0.10
return 1
```
#### Different stoploss per pair
Use a different stoploss depending on the pair.
In this example, we'll trail the highest price with 10% trailing stoploss for `ETH/BTC` and `XRP/BTC`, with 5% trailing stoploss for `LTC/BTC` and with 15% for all other pairs.
``` python
from datetime import datetime
from freqtrade.persistence import Trade
class AwesomeStrategy(IStrategy):
# ... populate_* methods
use_custom_stoploss = True
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
if pair in ('ETH/BTC', 'XRP/BTC'):
return -0.10
elif pair in ('LTC/BTC'):
return -0.05
return -0.15
```
#### Trailing stoploss with positive offset
Use the initial stoploss until the profit is above 4%, then use a trailing stoploss of 50% of the current profit with a minimum of 2.5% and a maximum of 5%.
Please note that the stoploss can only increase, values lower than the current stoploss are ignored.
``` python
from datetime import datetime, timedelta
from freqtrade.persistence import Trade
class AwesomeStrategy(IStrategy):
# ... populate_* methods
use_custom_stoploss = True
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
if current_profit < 0.04:
return -1 # return a value bigger than the inital stoploss to keep using the inital stoploss
# After reaching the desired offset, allow the stoploss to trail by half the profit
desired_stoploss = current_profit / 2
# Use a minimum of 2.5% and a maximum of 5%
return max(min(desired_stoploss, 0.05), 0.025)
```
#### Absolute stoploss
The below example sets absolute profit levels based on the current profit.
* Use the regular stoploss until 20% profit is reached
* Once profit is > 40%, stoploss will be at 25%, locking in at least 25% of the profit.
* Once profit is > 25% - stoploss will be 15%.
* Once profit is > 20% - stoploss will be set to 7%.
``` python
from datetime import datetime
from freqtrade.persistence import Trade
class AwesomeStrategy(IStrategy):
# ... populate_* methods
use_custom_stoploss = True
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# Calculate as `-desired_stop_from_open + current_profit` to get the distance between current_profit and initial price
if current_profit > 0.40:
return (-0.25 + current_profit)
if current_profit > 0.25:
return (-0.15 + current_profit)
if current_profit > 0.20:
return (-0.7 + current_profit)
return 1
```
---
## Custom order timeout rules
Simple, timebased order-timeouts can be configured either via strategy or in the configuration in the `unfilledtimeout` section.
Simple, time-based order-timeouts can be configured either via strategy or in the configuration in the `unfilledtimeout` section.
However, freqtrade also offers a custom callback for both ordertypes, which allows you to decide based on custom criteria if a order did time out or not.
However, freqtrade also offers a custom callback for both order types, which allows you to decide based on custom criteria if a order did time out or not.
!!! Note
Unfilled order timeouts are not relevant during backtesting or hyperopt, and are only relevant during real (live) trading. Therefore these methods are only called in these circumstances.
@@ -28,7 +202,7 @@ The function must return either `True` (cancel order) or `False` (keep order ali
from datetime import datetime, timedelta
from freqtrade.persistence import Trade
class Awesomestrategy(IStrategy):
class AwesomeStrategy(IStrategy):
# ... populate_* methods
@@ -67,7 +241,7 @@ class Awesomestrategy(IStrategy):
from datetime import datetime
from freqtrade.persistence import Trade
class Awesomestrategy(IStrategy):
class AwesomeStrategy(IStrategy):
# ... populate_* methods
@@ -95,6 +269,8 @@ class Awesomestrategy(IStrategy):
return False
```
---
## Bot loop start callback
A simple callback which is called once at the start of every bot throttling iteration.
@@ -103,7 +279,7 @@ This can be used to perform calculations which are pair independent (apply to al
``` python
import requests
class Awesomestrategy(IStrategy):
class AwesomeStrategy(IStrategy):
# ... populate_* methods
@@ -128,7 +304,7 @@ class Awesomestrategy(IStrategy):
`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):
class AwesomeStrategy(IStrategy):
# ... populate_* methods
@@ -164,7 +340,7 @@ class Awesomestrategy(IStrategy):
from freqtrade.persistence import Trade
class Awesomestrategy(IStrategy):
class AwesomeStrategy(IStrategy):
# ... populate_* methods
@@ -200,6 +376,8 @@ class Awesomestrategy(IStrategy):
```
---
## 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:
@@ -219,4 +397,41 @@ class MyAwesomeStrategy2(MyAwesomeStrategy):
trailing_stop = True
```
Both attributes and methods may be overriden, altering behavior of the original strategy in a way you need.
Both attributes and methods may be overridden, altering behavior of the original strategy in a way you need.
!!! Note "Parent-strategy in different files"
If you have the parent-strategy in a different file, you'll need to add the following to the top of your "child"-file to ensure proper loading, otherwise freqtrade may not be able to load the parent strategy correctly.
``` python
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).parent))
from myawesomestrategy import MyAwesomeStrategy
```
## Embedding Strategies
Freqtrade provides you with with an easy way to embed the strategy into your configuration file.
This is done by utilizing BASE64 encoding and providing this string at the strategy configuration field,
in your chosen config file.
### Encoding a string as BASE64
This is a quick example, how to generate the BASE64 string in python
```python
from base64 import urlsafe_b64encode
with open(file, 'r') as f:
content = f.read()
content = urlsafe_b64encode(content.encode('utf-8'))
```
The variable 'content', will contain the strategy file in a BASE64 encoded form. Which can now be set in your configurations file as following
```json
"strategy": "NameOfStrategy:BASE64String"
```
Please ensure that 'NameOfStrategy' is identical to the strategy name!

View File

@@ -147,7 +147,7 @@ Let's try to backtest 1 month (January 2019) of 5m candles using an example stra
freqtrade backtesting --timerange 20190101-20190201 --timeframe 5m
```
Assuming `startup_candle_count` is set to 100, backtesting knows it needs 100 candles to generate valid buy signals. It will load data from `20190101 - (100 * 5m)` - which is ~2019-12-31 15:30:00.
Assuming `startup_candle_count` is set to 100, backtesting knows it needs 100 candles to generate valid buy signals. It will load data from `20190101 - (100 * 5m)` - which is ~2018-12-31 15:30:00.
If this data is available, indicators will be calculated with this extended timerange. The instable startup period (up to 2019-01-01 00:00:00) will then be removed before starting backtesting.
!!! Note
@@ -309,15 +309,20 @@ Storing information can be accomplished by creating a new dictionary within the
The name of the variable can be chosen at will, but should be prefixed with `cust_` to avoid naming collisions with predefined strategy variables.
```python
class Awesomestrategy(IStrategy):
class AwesomeStrategy(IStrategy):
# Create custom dictionary
cust_info = {}
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Check if the entry already exists
if "crosstime" in self.cust_info[metadata["pair"]:
self.cust_info[metadata["pair"]["crosstime"] += 1
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
else:
self.cust_info[metadata["pair"]["crosstime"] = 1
self.cust_info[metadata["pair"]]["crosstime"] = 1
```
!!! Warning
@@ -439,14 +444,19 @@ It can also be used in specific callbacks to get the signal that caused the acti
``` python
# fetch current dataframe
if self.dp:
dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=metadata['pair'],
timeframe=self.timeframe)
if self.dp.runmode.value in ('live', 'dry_run'):
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.
!!! Warning "Warning about backtesting"
This method will return an empty dataframe during backtesting.
### *orderbook(pair, maximum)*
``` python
@@ -457,8 +467,8 @@ if self.dp:
dataframe['best_ask'] = ob['asks'][0][0]
```
!!! Warning
The order book is not part of the historic data which means backtesting and hyperopt will not work correctly if this method is used.
!!! Warning "Warning about backtesting"
The order book is not part of the historic data which means backtesting and hyperopt will not work correctly if this method is used, as the method will return uptodate values.
### *ticker(pair)*
@@ -648,7 +658,7 @@ The following example queries for the current pair and trades from today, howeve
if self.config['runmode'].value in ('live', 'dry_run'):
trades = Trade.get_trades([Trade.pair == metadata['pair'],
Trade.open_date > datetime.utcnow() - timedelta(days=1),
Trade.is_open == False,
Trade.is_open.is_(False),
]).order_by(Trade.close_date).all()
# Summarize profit for this pair.
curdayprofit = sum(trade.close_profit for trade in trades)
@@ -688,18 +698,18 @@ Locked pairs will show the message `Pair <pair> is currently locked.`.
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
@@ -714,7 +724,7 @@ if self.config['runmode'].value in ('live', 'dry_run'):
# fetch closed trades for the last 2 days
trades = Trade.get_trades([Trade.pair == metadata['pair'],
Trade.open_date > datetime.utcnow() - timedelta(days=2),
Trade.is_open == False,
Trade.is_open.is_(False),
]).all()
# Analyze the conditions you'd like to lock the pair .... will probably be different for every strategy
sumprofit = sum(trade.close_profit for trade in trades)
@@ -765,8 +775,6 @@ To get additional Ideas for strategies, head over to our [strategy repository](h
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

@@ -24,7 +24,7 @@ config["strategy"] = "SampleStrategy"
# Location of the data
data_location = Path(config['user_data_dir'], 'data', 'binance')
# Pair to analyze - Only use one pair here
pair = "BTC_USDT"
pair = "BTC/USDT"
```
@@ -34,7 +34,9 @@ from freqtrade.data.history import load_pair_history
candles = load_pair_history(datadir=data_location,
timeframe=config["timeframe"],
pair=pair)
pair=pair,
data_format = "hdf5",
)
# Confirm success
print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {data_location}")

View File

@@ -35,12 +35,30 @@ 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.
@@ -69,6 +87,41 @@ Example configuration showing the different settings:
},
```
## Create a custom keyboard (command shortcut buttons)
Telegram allows us to create a custom keyboard with buttons for commands.
The default custom keyboard looks like this.
```python
[
["/daily", "/profit", "/balance"], # row 1, 3 commands
["/status", "/status table", "/performance"], # row 2, 3 commands
["/count", "/start", "/stop", "/help"] # row 3, 4 commands
]
```
### Usage
You can create your own keyboard in `config.json`:
``` json
"telegram": {
"enabled": true,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id",
"keyboard": [
["/daily", "/stats", "/balance", "/profit"],
["/status table", "/performance"],
["/reload_config", "/count", "/logs"]
]
},
```
!!! Note "Supported Commands"
Only the following commands are allowed. Command arguments are not supported!
`/start`, `/stop`, `/status`, `/status table`, `/trades`, `/profit`, `/performance`, `/daily`, `/stats`, `/count`, `/locks`, `/balance`, `/stopbuy`, `/reload_config`, `/show_config`, `/logs`, `/whitelist`, `/blacklist`, `/edge`, `/help`, `/version`
## Telegram commands
Per default, the Telegram bot shows predefined commands. Some commands
@@ -84,10 +137,12 @@ official commands. You can ask at any moment for help with `/help`.
| `/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 <trade_id>` | Lists one or more specific trade. Separate multiple <trade_id> with a blank space.
| `/status table` | List all open trades in a table format. Pending buy orders are marked with an asterisk (*) Pending sell orders are marked with a double asterisk (**)
| `/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
| `/locks` | Show 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`).
@@ -95,6 +150,7 @@ official commands. You can ask at any moment for help with `/help`.
| `/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)
| `/stats` | Shows Wins / losses by Sell reason as well as Avg. holding durations for buys and sells
| `/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.
@@ -189,7 +245,7 @@ Return a summary of your profit/loss and performance.
Note that for this to work, `forcebuy_enable` needs to be set to true.
[More details](configuration.md/#understand-forcebuy_enable)
[More details](configuration.md#understand-forcebuy_enable)
### /performance

31
docs/updating.md Normal file
View File

@@ -0,0 +1,31 @@
# How to update
To update your freqtrade installation, please use one of the below methods, corresponding to your installation method.
## docker-compose
!!! Note "Legacy installations using the `master` image"
We're switching from master to stable for the release Images - please adjust your docker-file and replace `freqtradeorg/freqtrade:master` with `freqtradeorg/freqtrade:stable`
``` bash
docker-compose pull
docker-compose up -d
```
## Installation via setup script
``` bash
./setup.sh --update
```
!!! Note
Make sure to run this command with your virtual environment disabled!
## Plain native installation
Please ensure that you're also updating dependencies - otherwise things might break without you noticing.
``` bash
git pull
pip install -U -r requirements.txt
```

View File

@@ -391,7 +391,7 @@ $ freqtrade list-markets --exchange kraken --all
## Test pairlist
Use the `test-pairlist` subcommand to test the configuration of [dynamic pairlists](configuration.md#pairlists).
Use the `test-pairlist` subcommand to test the configuration of [dynamic pairlists](plugins.md#pairlists).
Requires a configuration with specified `pairlists` attribute.
Can be used to generate static pairlists to be used during backtesting / hyperopt.
@@ -415,7 +415,7 @@ optional arguments:
### Examples
Show whitelist when using a [dynamic pairlist](configuration.md#pairlists).
Show whitelist when using a [dynamic pairlist](plugins.md#pairlists).
```
freqtrade test-pairlist --config config.json --quote USDT BTC
@@ -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]
@@ -432,10 +432,11 @@ usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[--max-trades INT] [--min-avg-time FLOAT]
[--max-avg-time FLOAT] [--min-avg-profit FLOAT]
[--max-avg-profit FLOAT]
[--min-total-profit FLOAT] [--max-total-profit FLOAT]
[--min-total-profit FLOAT]
[--max-total-profit FLOAT]
[--min-objective FLOAT] [--max-objective FLOAT]
[--no-color] [--print-json] [--no-details]
[--export-csv FILE]
[--hyperopt-filename PATH] [--export-csv FILE]
optional arguments:
-h, --help show this help message and exit
@@ -443,24 +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 on above objective (- is added by default).
Select epochs above objective.
--max-objective FLOAT
Select epochs on below objective (- is added by default).
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
@@ -480,7 +484,11 @@ Common arguments:
--userdir PATH, --user-data-dir PATH
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:
@@ -501,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

@@ -1,4 +1,4 @@
We **strongly** recommend that Windows users use [Docker](docker.md) as this will work much easier and smoother (also more secure).
We **strongly** recommend that Windows users use [Docker](docker_quickstart.md) as this will work much easier and smoother (also more secure).
If that is not possible, try using the Windows Linux subsystem (WSL) - for which the Ubuntu instructions should work.
Otherwise, try the instructions below.
@@ -21,7 +21,7 @@ git clone https://github.com/freqtrade/freqtrade.git
Install ta-lib according to the [ta-lib documentation](https://github.com/mrjbq7/ta-lib#windows).
As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial precompiled windows Wheels [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib), which needs to be downloaded and installed using `pip install TA_Lib0.4.18cp38cp38win_amd64.whl` (make sure to use the version matching your python version)
As compiling from source on windows has heavy dependencies (requires a partial visual studio installation), there is also a repository of unofficial 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.
@@ -32,7 +32,7 @@ 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_helpes/TA_Lib0.4.18cp38cp38win_amd64.whl
pip install build_helpers/TA_Lib-0.4.19-cp38-cp38-win_amd64.whl
pip install -r requirements.txt
pip install -e .
freqtrade
@@ -50,8 +50,8 @@ freqtrade
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.
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.
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 compose](docker_quickstart.md) first.
---

View File

@@ -1,60 +1,71 @@
name: freqtrade
channels:
- defaults
- conda-forge
# - defaults
dependencies:
# Required for app
- python>=3.6
- pip
- wheel
- numpy
- pandas
- SQLAlchemy
- arrow
- requests
- urllib3
- wrapt
- jsonschema
- tabulate
- python-rapidjson
- flask
- python-dotenv
- cachetools
- python-telegram-bot
# Optional for plotting
- plotly
# Optional for hyperopt
- scipy
- scikit-optimize
- scikit-learn
- filelock
- joblib
# Optional for development
- flake8
- pytest
- pytest-mock
- pytest-asyncio
- pytest-cov
- coveralls
- mypy
# Useful for jupyter
- jupyter
- ipykernel
- isort
- yapf
- pip:
# Required for app
- cython
- pycoingecko
- ccxt
# 1/4 req main
- python>=3.7
- numpy
- pandas
- pip
- aiohttp
- SQLAlchemy
- python-telegram-bot
- arrow
- cachetools
- requests
- urllib3
- wrapt
- jsonschema
- TA-Lib
- py_find_1st
- tabulate
- jinja2
- blosc
- sdnotify
# Optional for develpment
- flake8-tidy-imports
- flake8-type-annotations
- pytest-random-order
- -e .
- fastapi
- uvicorn
- pyjwt
- colorama
- questionary
- prompt-toolkit
# ============================
# 2/4 req dev
- coveralls
- flake8
- mypy
- pytest
- pytest-asyncio
- pytest-cov
- pytest-mock
- isort
- nbconvert
# ============================
# 3/4 req hyperopt
- scipy
- scikit-learn
- filelock
- scikit-optimize
- joblib
- progressbar2
# ============================
# 4/4 req plot
- plotly
- jupyter
- pip:
- pycoingecko
- py_find_1st
- tables
- pytest-random-order
- flake8-type-annotations
- ccxt
- flake8-tidy-imports
- -e .
# - python-rapidjso

View File

@@ -1,5 +1,5 @@
""" Freqtrade bot """
__version__ = '2020.9.1'
__version__ = '2021.2'
if __version__ == 'develop':

View File

@@ -3,10 +3,11 @@
__main__.py for Freqtrade
To launch Freqtrade as a module
> python -m freqtrade (with Python >= 3.6)
> python -m freqtrade (with Python >= 3.7)
"""
from freqtrade import main
if __name__ == '__main__':
main.main()

View File

@@ -8,23 +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.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.deploy_commands import (start_create_userdir, start_install_ui,
start_new_hyperopt, start_new_strategy)
from freqtrade.commands.hyperopt_commands import start_hyperopt_list, start_hyperopt_show
from freqtrade.commands.list_commands import (start_list_exchanges, start_list_hyperopts,
start_list_markets, start_list_strategies,
start_list_timeframes, start_show_trades)
from freqtrade.commands.optimize_commands import start_backtesting, start_edge, start_hyperopt
from freqtrade.commands.pairlist_commands import start_test_pairlist
from freqtrade.commands.plot_commands import (start_plot_dataframe,
start_plot_profit)
from freqtrade.commands.plot_commands import start_plot_dataframe, start_plot_profit
from freqtrade.commands.trade_commands import start_trading

View File

@@ -9,6 +9,7 @@ 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"]
@@ -19,14 +20,16 @@ ARGS_COMMON_OPTIMIZE = ["timeframe", "timerange", "dataformat_ohlcv",
"max_open_trades", "stake_amount", "fee"]
ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_positions",
"enable_protections",
"strategy_list", "export", "exportfilename"]
ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
"position_stacking", "epochs", "spaces",
"use_max_market_positions", "print_all",
"position_stacking", "use_max_market_positions",
"enable_protections",
"epochs", "spaces", "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"]
@@ -41,7 +44,8 @@ ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
ARGS_LIST_PAIRS = ["exchange", "print_list", "list_pairs_print_json", "print_one_column",
"print_csv", "base_currencies", "quote_currencies", "list_pairs_all"]
ARGS_TEST_PAIRLIST = ["config", "quote_currencies", "print_one_column", "list_pairs_print_json"]
ARGS_TEST_PAIRLIST = ["verbosity", "config", "quote_currencies", "print_one_column",
"list_pairs_print_json"]
ARGS_CREATE_USERDIR = ["user_data_dir", "reset"]
@@ -66,6 +70,8 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit",
ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url",
"trade_source", "timeframe"]
ARGS_INSTALL_UI = ["erase_ui_only"]
ARGS_SHOW_TRADES = ["db_url", "trade_ids", "print_json"]
ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable",
@@ -75,10 +81,10 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable",
"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-data",
@@ -161,16 +167,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_list_data,
start_hyperopt_list, start_hyperopt_show,
start_list_exchanges, start_list_hyperopts,
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_install_ui,
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
@@ -353,6 +357,14 @@ class Arguments:
test_pairlist_cmd.set_defaults(func=start_test_pairlist)
self._build_args(optionlist=ARGS_TEST_PAIRLIST, parser=test_pairlist_cmd)
# Add install-ui subcommand
install_ui_cmd = subparsers.add_parser(
'install-ui',
help='Install FreqUI',
)
install_ui_cmd.set_defaults(func=start_install_ui)
self._build_args(optionlist=ARGS_INSTALL_UI, parser=install_ui_cmd)
# Add Plotting subcommand
plot_dataframe_cmd = subparsers.add_parser(
'plot-dataframe',

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:
@@ -143,6 +144,14 @@ AVAILABLE_CLI_OPTIONS = {
action='store_false',
default=True,
),
"enable_protections": Arg(
'--enable-protections', '--enableprotections',
help='Enable protections for backtesting.'
'Will slow backtesting down by a considerable amount, but will include '
'configured protections',
action='store_true',
default=False,
),
"strategy_list": Arg(
'--strategy-list',
help='Provide a space-separated list of strategies to backtest. '
@@ -252,23 +261,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 +362,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',
@@ -384,6 +387,12 @@ AVAILABLE_CLI_OPTIONS = {
help='Clean all existing data for the selected exchange/pairs/timeframes.',
action='store_true',
),
"erase_ui_only": Arg(
'--erase',
help="Clean UI folder, don't download new version.",
action='store_true',
default=False,
),
# Templating options
"template": Arg(
'--template',

View File

@@ -1,21 +1,20 @@
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.plugins.pairlist.pairlist_helpers import expand_pairlist
from freqtrade.resolvers import ExchangeResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -30,26 +29,31 @@ def start_download_data(args: Dict[str, Any]) -> None:
"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']}")
pairs_not_available: List[str] = []
# Init exchange
exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False)
# Manual validations of relevant settings
exchange.validate_pairs(config['pairs'])
expanded_pairs = expand_pairlist(config['pairs'], list(exchange.markets))
logger.info(f"About to download pairs: {expanded_pairs}, "
f"intervals: {config['timeframes']} to {config['datadir']}")
for timeframe in config['timeframes']:
exchange.validate_timeframes(timeframe)
@@ -57,20 +61,20 @@ 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'],
exchange, pairs=expanded_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'],
pairs=expanded_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'],
exchange, pairs=expanded_pairs, timeframes=config['timeframes'],
datadir=config['datadir'], timerange=timerange, erase=bool(config.get('erase')),
data_format=config['dataformat_ohlcv'])
@@ -105,8 +109,9 @@ def start_list_data(args: Dict[str, Any]) -> None:
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
from freqtrade.data.history.idatahandler import get_datahandler
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'])

View File

@@ -1,16 +1,18 @@
import logging
import sys
from pathlib import Path
from typing import Any, Dict
from typing import Any, Dict, Optional, Tuple
import requests
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__)
@@ -133,7 +135,91 @@ def start_new_hyperopt(args: Dict[str, Any]) -> None:
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.")
def clean_ui_subdir(directory: Path):
if directory.is_dir():
logger.info("Removing UI directory content.")
for p in reversed(list(directory.glob('**/*'))): # iterate contents from leaves to root
if p.name in ('.gitkeep', 'fallback_file.html'):
continue
if p.is_file():
p.unlink()
elif p.is_dir():
p.rmdir()
def read_ui_version(dest_folder: Path) -> Optional[str]:
file = dest_folder / '.uiversion'
if not file.is_file():
return None
with file.open('r') as f:
return f.read()
def download_and_install_ui(dest_folder: Path, dl_url: str, version: str):
from io import BytesIO
from zipfile import ZipFile
logger.info(f"Downloading {dl_url}")
resp = requests.get(dl_url).content
dest_folder.mkdir(parents=True, exist_ok=True)
with ZipFile(BytesIO(resp)) as zf:
for fn in zf.filelist:
with zf.open(fn) as x:
destfile = dest_folder / fn.filename
if fn.is_dir():
destfile.mkdir(exist_ok=True)
else:
destfile.write_bytes(x.read())
with (dest_folder / '.uiversion').open('w') as f:
f.write(version)
def get_ui_download_url() -> Tuple[str, str]:
base_url = 'https://api.github.com/repos/freqtrade/frequi/'
# Get base UI Repo path
resp = requests.get(f"{base_url}releases")
resp.raise_for_status()
r = resp.json()
latest_version = r[0]['name']
assets = r[0].get('assets', [])
dl_url = ''
if assets and len(assets) > 0:
dl_url = assets[0]['browser_download_url']
# URL not found - try assets url
if not dl_url:
assets = r[0]['assets_url']
resp = requests.get(assets)
r = resp.json()
dl_url = r[0]['browser_download_url']
return dl_url, latest_version
def start_install_ui(args: Dict[str, Any]) -> None:
dest_folder = Path(__file__).parents[1] / 'rpc/api_server/ui/installed/'
# First make sure the assets are removed.
dl_url, latest_version = get_ui_download_url()
curr_version = read_ui_version(dest_folder)
if curr_version == latest_version and not args.get('erase_ui_only'):
logger.info(f"UI already up-to-date, FreqUI Version {curr_version}.")
return
clean_ui_subdir(dest_folder)
if args.get('erase_ui_only'):
logger.info("Erased UI directory content. Not downloading new version.")
else:
# Download a new version
download_and_install_ui(dest_folder, dl_url, latest_version)

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__)
@@ -40,8 +42,9 @@ def start_hyperopt_list(args: Dict[str, Any]) -> 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)
@@ -80,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 = {

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)
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__)
@@ -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__)
@@ -14,7 +15,7 @@ def start_test_pairlist(args: Dict[str, Any]) -> None:
"""
Test Pairlist configuration
"""
from freqtrade.pairlist.pairlistmanager import PairListManager
from freqtrade.plugins.pairlistmanager import PairListManager
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False)

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__)
@@ -53,7 +54,7 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]:
return conf
except ValidationError as e:
logger.critical(
f"Invalid configuration. See config.json.example. Reason: {e}"
f"Invalid configuration. Reason: {e}"
)
raise ValidationError(
best_match(Draft4Validator(conf_schema).iter_errors(conf)).message
@@ -73,6 +74,7 @@ def validate_config_consistency(conf: Dict[str, Any]) -> None:
_validate_trailing_stoploss(conf)
_validate_edge(conf)
_validate_whitelist(conf)
_validate_protections(conf)
_validate_unlimited_amount(conf)
# validate configuration before returning
@@ -136,6 +138,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:
@@ -150,3 +156,22 @@ def _validate_whitelist(conf: Dict[str, Any]) -> None:
if (pl.get('method') == 'StaticPairList'
and not conf.get('exchange', {}).get('pair_whitelist')):
raise OperationalException("StaticPairList requires pair_whitelist to be set.")
def _validate_protections(conf: Dict[str, Any]) -> None:
"""
Validate protection configuration validity
"""
for prot in conf.get('protections', []):
if ('stop_duration' in prot and 'stop_duration_candles' in prot):
raise OperationalException(
"Protections must specify either `stop_duration` or `stop_duration_candles`.\n"
f"Please fix the protection {prot.get('method')}"
)
if ('lookback_period' in prot and 'lookback_period_candles' in prot):
raise OperationalException(
"Protections must specify either `lookback_period` or `lookback_period_candles`.\n"
f"Please fix the protection {prot.get('method')}"
)

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__)
@@ -211,6 +211,9 @@ class Configuration:
self._args_to_config(config, argname='position_stacking',
logstring='Parameter --enable-position-stacking detected ...')
self._args_to_config(
config, argname='enable_protections',
logstring='Parameter --enable-protections detected, enabling Protections. ...')
# Setting max_open_trades to infinite if -1
if config.get('max_open_trades') == -1:
config['max_open_trades'] = float('inf')
@@ -263,6 +266,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 +301,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: {}')

View File

@@ -26,6 +26,24 @@ def check_conflicting_settings(config: Dict[str, Any],
)
def process_removed_setting(config: Dict[str, Any],
section1: str, name1: str,
section2: str, name2: str) -> None:
"""
:param section1: Removed section
:param name1: Removed setting name
:param section2: new section for this key
:param name2: new setting name
"""
section1_config = config.get(section1, {})
if name1 in section1_config:
raise OperationalException(
f"Setting `{section1}.{name1}` has been moved to `{section2}.{name2}. "
f"Please delete it from your configuration and use the `{section2}.{name2}` "
"setting instead."
)
def process_deprecated_setting(config: Dict[str, Any],
section1: str, name1: str,
section2: str, name2: str) -> None:
@@ -44,19 +62,18 @@ def process_deprecated_setting(config: Dict[str, Any],
def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
check_conflicting_settings(config, 'ask_strategy', 'use_sell_signal',
'experimental', 'use_sell_signal')
check_conflicting_settings(config, 'ask_strategy', 'sell_profit_only',
'experimental', 'sell_profit_only')
check_conflicting_settings(config, 'ask_strategy', 'ignore_roi_if_buy_signal',
'experimental', 'ignore_roi_if_buy_signal')
# Kept for future deprecated / moved settings
# check_conflicting_settings(config, 'ask_strategy', 'use_sell_signal',
# 'experimental', 'use_sell_signal')
# process_deprecated_setting(config, 'ask_strategy', 'use_sell_signal',
# 'experimental', 'use_sell_signal')
process_deprecated_setting(config, 'ask_strategy', 'use_sell_signal',
'experimental', 'use_sell_signal')
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_only',
'experimental', 'sell_profit_only')
process_deprecated_setting(config, 'ask_strategy', 'ignore_roi_if_buy_signal',
'experimental', 'ignore_roi_if_buy_signal')
process_removed_setting(config, 'experimental', 'use_sell_signal',
'ask_strategy', 'use_sell_signal')
process_removed_setting(config, 'experimental', 'sell_profit_only',
'ask_strategy', 'sell_profit_only')
process_removed_setting(config, 'experimental', 'ignore_roi_if_buy_signal',
'ask_strategy', 'ignore_roi_if_buy_signal')
if (config.get('edge', {}).get('enabled', False)
and 'capital_available_percentage' in config.get('edge', {})):

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,9 +20,14 @@ 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']
'AgeFilter', 'PerformanceFilter', 'PrecisionFilter',
'PriceFilter', 'RangeStabilityFilter', 'ShuffleFilter',
'SpreadFilter']
AVAILABLE_PROTECTIONS = ['CooldownPeriod', 'LowProfitPairs', 'MaxDrawdown', 'StoplossGuard']
AVAILABLE_DATAHANDLERS = ['json', 'jsongz', 'hdf5']
DRY_RUN_WALLET = 1000
DATETIME_PRINT_FORMAT = '%Y-%m-%d %H:%M:%S'
@@ -41,6 +45,16 @@ USERPATH_NOTEBOOKS = 'notebooks'
TELEGRAM_SETTING_OPTIONS = ['on', 'off', 'silent']
# Define decimals per coin for outputs
# Only used for outputs.
DECIMAL_PER_COIN_FALLBACK = 3 # Should be low to avoid listing all possible FIAT's
DECIMALS_PER_COIN = {
'BTC': 8,
'ETH': 5,
}
# Soure files with destination directories within user-directory
USER_DATA_FILES = {
'sample_strategy.py': USERPATH_STRATEGIES,
@@ -112,6 +126,7 @@ CONF_SCHEMA = {
'trailing_stop_positive': {'type': 'number', 'minimum': 0, 'maximum': 1},
'trailing_stop_positive_offset': {'type': 'number', 'minimum': 0, 'maximum': 1},
'trailing_only_offset_is_reached': {'type': 'boolean'},
'bot_name': {'type': 'string'},
'unfilledtimeout': {
'type': 'object',
'properties': {
@@ -150,6 +165,7 @@ CONF_SCHEMA = {
'order_book_max': {'type': 'integer', 'minimum': 1, 'maximum': 50},
'use_sell_signal': {'type': 'boolean'},
'sell_profit_only': {'type': 'boolean'},
'sell_profit_offset': {'type': 'number', 'minimum': 0.0},
'ignore_roi_if_buy_signal': {'type': 'boolean'}
}
},
@@ -180,9 +196,6 @@ CONF_SCHEMA = {
'experimental': {
'type': 'object',
'properties': {
'use_sell_signal': {'type': 'boolean'},
'sell_profit_only': {'type': 'boolean'},
'ignore_roi_if_buy_signal': {'type': 'boolean'},
'block_bad_exchanges': {'type': 'boolean'}
}
},
@@ -192,7 +205,21 @@ CONF_SCHEMA = {
'type': 'object',
'properties': {
'method': {'type': 'string', 'enum': AVAILABLE_PAIRLISTS},
'config': {'type': 'object'}
},
'required': ['method'],
}
},
'protections': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'method': {'type': 'string', 'enum': AVAILABLE_PROTECTIONS},
'stop_duration': {'type': 'number', 'minimum': 0.0},
'stop_duration_candles': {'type': 'number', 'minimum': 0},
'trade_limit': {'type': 'number', 'minimum': 1},
'lookback_period': {'type': 'number', 'minimum': 1},
'lookback_period_candles': {'type': 'number', 'minimum': 1},
},
'required': ['method'],
}
@@ -363,3 +390,6 @@ CANCEL_REASON = {
# List of pairs with their timeframes
PairWithTimeframe = Tuple[str, str]
ListPairsWithTimeframes = List[PairWithTimeframe]
# Type for trades list
TradeList = List[List]

View File

@@ -3,28 +3,41 @@ Helpers when analyzing backtest data
"""
import logging
from pathlib import Path
from typing import Dict, Union, Tuple, Any, Optional
from typing import Any, Dict, List, 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_date", "close_date", "index", "trade_duration",
"open_rate", "close_rate", "open_at_end", "sell_reason"]
# Old format - maybe remove?
BT_DATA_COLUMNS_OLD = ["pair", "profit_percent", "open_date", "close_date", "index",
"trade_duration", "open_rate", "close_rate", "open_at_end", "sell_reason"]
# Mid-term format, crated by BacktestResult Named Tuple
BT_DATA_COLUMNS_MID = ['pair', 'profit_percent', 'open_date', 'close_date', 'trade_duration',
'open_rate', 'close_rate', 'open_at_end', 'sell_reason', 'fee_open',
'fee_close', 'amount', 'profit_abs', 'profit_ratio']
# Newest format
BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date',
'open_rate', 'close_rate',
'fee_open', 'fee_close', 'trade_duration',
'profit_ratio', 'profit_abs', 'sell_reason',
'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs',
'stop_loss_ratio', 'min_rate', 'max_rate', 'is_open', ]
def get_latest_backtest_filename(directory: Union[Path, str]) -> str:
def get_latest_optimize_filename(directory: Union[Path, str], variant: str) -> str:
"""
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
@@ -44,10 +57,57 @@ def get_latest_backtest_filename(directory: Union[Path, str]) -> str:
with filename.open() as file:
data = json_load(file)
if 'latest_backtest' not in data:
if f'latest_{variant}' not in data:
raise ValueError(f"Invalid '{LAST_BT_RESULT_FN}' format.")
return data['latest_backtest']
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]:
@@ -106,7 +166,7 @@ def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = Non
)
else:
# old format - only with lists.
df = pd.DataFrame(data, columns=BT_DATA_COLUMNS)
df = pd.DataFrame(data, columns=BT_DATA_COLUMNS_OLD)
df['open_date'] = pd.to_datetime(df['open_date'],
unit='s',
@@ -118,7 +178,10 @@ def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = Non
utc=True,
infer_datetime_format=True
)
# Create compatibility with new format
df['profit_abs'] = df['close_rate'] - df['open_rate']
if 'profit_ratio' not in df.columns:
df['profit_ratio'] = df['profit_percent']
df = df.sort_values("open_date").reset_index(drop=True)
return df
@@ -161,6 +224,20 @@ def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
return df_final[df_final['open_trades'] > max_open_trades]
def trade_list_to_dataframe(trades: List[Trade]) -> pd.DataFrame:
"""
Convert list of Trade objects to pandas Dataframe
:param trades: List of trade objects
:return: Dataframe with BT_DATA_COLUMNS
"""
df = pd.DataFrame.from_records([t.to_json() for t in trades], columns=BT_DATA_COLUMNS)
if len(df) > 0:
df.loc[:, 'close_date'] = pd.to_datetime(df['close_date'], utc=True)
df.loc[:, 'open_date'] = pd.to_datetime(df['open_date'], utc=True)
df.loc[:, 'close_rate'] = df['close_rate'].astype('float64')
return df
def load_trades_from_db(db_url: str, strategy: Optional[str] = None) -> pd.DataFrame:
"""
Load trades from a DB (using dburl)
@@ -169,38 +246,12 @@ def load_trades_from_db(db_url: str, strategy: Optional[str] = None) -> pd.DataF
Can also serve as protection to load the correct result.
:return: Dataframe containing Trades
"""
persistence.init(db_url, clean_open_orders=False)
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"]
init_db(db_url, clean_open_orders=False)
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,
t.calc_profit(), t.calc_profit_ratio(),
t.open_rate, t.close_rate, t.amount,
(round((t.close_date.timestamp() - t.open_date.timestamp()) / 60, 2)
if t.close_date else None),
t.sell_reason,
t.fee_open, t.fee_close,
t.open_rate_requested,
t.close_rate_requested,
t.stake_amount,
t.max_rate,
t.min_rate,
t.id, t.exchange,
t.stop_loss, t.initial_stop_loss,
t.strategy, t.timeframe
)
for t in Trade.get_trades(filters).all()],
columns=columns)
trades = trade_list_to_dataframe(Trade.get_trades(filters).all())
return trades
@@ -261,7 +312,7 @@ def calculate_market_change(data: Dict[str, pd.DataFrame], column: str = "close"
end = df[column].dropna().iloc[-1]
tmp_means.append((end - start) / start)
return np.mean(tmp_means)
return float(np.mean(tmp_means))
def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame],
@@ -286,7 +337,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_date and profit_percent)
:param trades: DataFrame containing trades (requires columns close_date and profit_ratio)
: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.
@@ -298,8 +349,8 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
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_date'
)[['profit_percent']].sum()
df.loc[:, col_name] = _trades_sum.cumsum()
)[['profit_ratio']].sum()
df.loc[:, col_name] = _trades_sum['profit_ratio'].cumsum()
# Set first value to 0
df.loc[df.iloc[0].name, col_name] = 0
# FFill to get continuous
@@ -308,13 +359,13 @@ def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_date',
value_col: str = 'profit_percent'
value_col: str = 'profit_ratio'
) -> Tuple[float, pd.Timestamp, pd.Timestamp]:
"""
Calculate max drawdown and the corresponding close dates
:param trades: DataFrame containing trades (requires columns close_date and profit_percent)
:param trades: DataFrame containing trades (requires columns close_date and profit_ratio)
: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')
:param value_col: Column in DataFrame to use for values (defaults to 'profit_ratio')
:return: Tuple (float, highdate, lowdate) with absolute max drawdown, high and low time
:raise: ValueError if trade-dataframe was found empty.
"""
@@ -332,3 +383,21 @@ def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_date'
high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col]
low_date = profit_results.loc[idxmin, date_col]
return abs(min(max_drawdown_df['drawdown'])), high_date, low_date
def calculate_csum(trades: pd.DataFrame) -> Tuple[float, float]:
"""
Calculate min/max cumsum of trades, to show if the wallet/stake amount ratio is sane
:param trades: DataFrame containing trades (requires columns close_date and profit_percent)
:return: Tuple (float, float) with cumsum of profit_abs
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
csum_df = pd.DataFrame()
csum_df['sum'] = trades['profit_abs'].cumsum()
csum_min = csum_df['sum'].min()
csum_max = csum_df['sum'].max()
return csum_min, csum_max

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,)

View File

@@ -8,7 +8,6 @@ import logging
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional, Tuple
from arrow import Arrow
from pandas import DataFrame
from freqtrade.constants import ListPairsWithTimeframes, PairWithTimeframe
@@ -17,6 +16,7 @@ from freqtrade.exceptions import ExchangeError, OperationalException
from freqtrade.exchange import Exchange
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
@@ -37,7 +37,7 @@ class DataProvider:
:param timeframe: Timeframe to get data for
:param dataframe: analyzed dataframe
"""
self.__cached_pairs[(pair, timeframe)] = (dataframe, Arrow.utcnow().datetime)
self.__cached_pairs[(pair, timeframe)] = (dataframe, datetime.now(timezone.utc))
def add_pairlisthandler(self, pairlists) -> None:
"""
@@ -87,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:

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

@@ -3,15 +3,16 @@ 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)
from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS,
ListPairsWithTimeframes, TradeList)
from .idatahandler import IDataHandler
from .idatahandler import IDataHandler, TradeList
logger = logging.getLogger(__name__)
@@ -175,7 +176,8 @@ class HDF5DataHandler(IDataHandler):
if timerange.stoptype == 'date':
where.append(f"timestamp < {timerange.stopts * 1e3}")
trades = pd.read_hdf(filename, key=key, mode="r", where=where)
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:

View File

@@ -9,15 +9,14 @@ from pandas import DataFrame
from freqtrade.configuration import TimeRange
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
from freqtrade.data.converter import (clean_ohlcv_dataframe,
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__)
@@ -215,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
@@ -305,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
@@ -357,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,15 +13,12 @@ from typing import List, Optional, Type
from pandas import DataFrame
from freqtrade.configuration import TimeRange
from freqtrade.constants import ListPairsWithTimeframes
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):

View File

@@ -8,11 +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,
ListPairsWithTimeframes)
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__)
@@ -86,8 +86,12 @@ class JsonDataHandler(IDataHandler):
filename = self._pair_data_filename(self._datadir, pair, timeframe)
if not filename.exists():
return DataFrame(columns=self._columns)
pairdata = read_json(filename, orient='values')
pairdata.columns = self._columns
try:
pairdata = read_json(filename, orient='values')
pairdata.columns = self._columns
except ValueError:
logger.error(f"Could not load data for {pair}.")
return DataFrame(columns=self._columns)
pairdata = pairdata.astype(dtype={'open': 'float', 'high': 'float',
'low': 'float', 'close': 'float', 'volume': 'float'})
pairdata['date'] = to_datetime(pairdata['date'],

View File

@@ -9,11 +9,13 @@ import utils_find_1st as utf1st
from pandas import DataFrame
from freqtrade.configuration import TimeRange
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT, DATETIME_PRINT_FORMAT
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.plugins.pairlist.pairlist_helpers import expand_pairlist
from freqtrade.strategy.interface import SellType
logger = logging.getLogger(__name__)
@@ -79,14 +81,16 @@ class Edge:
if config.get('fee'):
self.fee = config['fee']
else:
self.fee = self.exchange.get_fee(symbol=self.config['exchange']['pair_whitelist'][0])
self.fee = self.exchange.get_fee(symbol=expand_pairlist(
self.config['exchange']['pair_whitelist'], list(self.exchange.markets))[0])
def calculate(self) -> bool:
pairs = self.config['exchange']['pair_whitelist']
pairs = expand_pairlist(self.config['exchange']['pair_whitelist'],
list(self.exchange.markets))
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] = {}
@@ -100,6 +104,7 @@ class Edge:
exchange=self.exchange,
timeframe=self.strategy.timeframe,
timerange=self._timerange,
data_format=self.config.get('dataformat_ohlcv', 'json'),
)
data = load_data(
@@ -145,7 +150,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
@@ -155,7 +160,8 @@ class Edge:
available_capital = (total_capital + capital_in_trade) * self._capital_ratio
allowed_capital_at_risk = available_capital * self._allowed_risk
max_position_size = abs(allowed_capital_at_risk / stoploss)
position_size = min(max_position_size, free_capital)
# Position size must be below available capital.
position_size = min(min(max_position_size, free_capital), available_capital)
if pair in self._cached_pairs:
logger.info(
'winrate: %s, expectancy: %s, position size: %s, pair: %s,'
@@ -309,8 +315,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']

View File

@@ -1,19 +1,17 @@
# 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)
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.bybit import Bybit
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,12 +4,12 @@ from typing import Dict
import ccxt
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError,
InvalidOrderException, OperationalException,
TemporaryError)
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,22 +18,12 @@ class Binance(Exchange):
_ft_has: Dict = {
"stoploss_on_exchange": True,
"order_time_in_force": ['gtc', 'fok', 'ioc'],
"ohlcv_candle_limit": 1000,
"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)

View File

@@ -0,0 +1,29 @@
""" 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 = {
"ohlcv_candle_limit_per_timeframe": {
'1m': 1440,
'5m': 288,
'1h': 744,
'1d': 365,
},
"l2_limit_range": [1, 25, 500],
}

View File

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

View File

@@ -3,8 +3,8 @@ import logging
import time
from functools import wraps
from freqtrade.exceptions import (DDosProtection, RetryableOrderError,
TemporaryError)
from freqtrade.exceptions import DDosProtection, RetryableOrderError, TemporaryError
logger = logging.getLogger(__name__)
@@ -21,6 +21,7 @@ BAD_EXCHANGES = {
"hitbtc": "This API cannot be used with Freqtrade. "
"Use `hitbtc2` exchange id to access this exchange.",
"phemex": "Does not provide history. ",
"poloniex": "Does not provide fetch_order endpoint to fetch both open and closed orders.",
**dict.fromkeys([
'adara',
'anxpro',

View File

@@ -3,6 +3,7 @@
Cryptocurrency Exchanges support
"""
import asyncio
import http
import inspect
import logging
from copy import deepcopy
@@ -13,19 +14,20 @@ 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.constants import ListPairsWithTimeframes
from freqtrade.constants import DEFAULT_AMOUNT_RESERVE_PERCENT, 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.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
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
CcxtModuleType = Any
@@ -33,6 +35,12 @@ CcxtModuleType = Any
logger = logging.getLogger(__name__)
# Workaround for adding samesite support to pre 3.8 python
# Only applies to python3.7, and only on certain exchanges (kraken)
# Replicates the fix from starlette (which is actually causing this problem)
http.cookies.Morsel._reserved["samesite"] = "SameSite" # type: ignore
class Exchange:
_config: Dict = {}
@@ -53,7 +61,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 = {}
@@ -65,6 +73,7 @@ class Exchange:
"""
self._api: ccxt.Exchange = None
self._api_async: ccxt_async.Exchange = None
self._markets: Dict = {}
self._config.update(config)
@@ -92,7 +101,6 @@ class Exchange:
logger.info("Overriding exchange._ft_has with config params, result: %s", self._ft_has)
# Assign this directly for easy access
self._ohlcv_candle_limit = self._ft_has['ohlcv_candle_limit']
self._ohlcv_partial_candle = self._ft_has['ohlcv_partial_candle']
self._trades_pagination = self._ft_has['trades_pagination']
@@ -124,10 +132,12 @@ 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))
self.validate_required_startup_candles(config.get('startup_candle_count', 0),
config.get('timeframe', ''))
# Converts the interval provided in minutes in config to seconds
self.markets_refresh_interval: int = exchange_config.get(
@@ -188,26 +198,32 @@ 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"""
if not self._api.markets:
if not self._markets:
logger.info("Markets were not loaded. Loading them now..")
self._load_markets()
return self._api.markets
return self._markets
@property
def precisionMode(self) -> str:
"""exchange ccxt precisionMode"""
return self._api.precisionMode
def ohlcv_candle_limit(self, timeframe: str) -> int:
"""
Exchange ohlcv candle limit
Uses ohlcv_candle_limit_per_timeframe if the exchange has different limts
per timeframe (e.g. bittrex), otherwise falls back to ohlcv_candle_limit
:param timeframe: Timeframe to check
:return: Candle limit as integer
"""
return int(self._ft_has.get('ohlcv_candle_limit_per_timeframe', {}).get(
timeframe, self._ft_has.get('ohlcv_candle_limit')))
def get_markets(self, base_currencies: List[str] = None, quote_currencies: List[str] = None,
pairs_only: bool = False, active_only: bool = False) -> Dict:
pairs_only: bool = False, active_only: bool = False) -> Dict[str, Any]:
"""
Return exchange ccxt markets, filtered out by base currency and quote currency
if this was requested in parameters.
@@ -282,16 +298,16 @@ 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
def _load_markets(self) -> None:
""" Initialize markets both sync and async """
try:
self._api.load_markets()
self._markets = 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)
@@ -300,14 +316,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)
self._markets = 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.")
@@ -334,8 +350,9 @@ class Exchange:
if not self.markets:
logger.warning('Unable to validate pairs (assuming they are correct).')
return
extended_pairs = expand_pairlist(pairs, list(self.markets), keep_invalid=True)
invalid_pairs = []
for pair in pairs:
for pair in extended_pairs:
# Note: ccxt has BaseCurrency/QuoteCurrency format for pairs
# TODO: add a support for having coins in BTC/USDT format
if self.markets and pair not in self.markets:
@@ -417,15 +434,16 @@ class Exchange:
raise OperationalException(
f'Time in force policies are not supported for {self.name} yet.')
def validate_required_startup_candles(self, startup_candles: int) -> None:
def validate_required_startup_candles(self, startup_candles: int, timeframe: str) -> None:
"""
Checks if required startup_candles is more than ohlcv_candle_limit.
Checks if required startup_candles is more than ohlcv_candle_limit().
Requires a grace-period of 5 candles - so a startup-period up to 494 is allowed by default.
"""
if startup_candles + 5 > self._ft_has['ohlcv_candle_limit']:
candle_limit = self.ohlcv_candle_limit(timeframe)
if startup_candles + 5 > candle_limit:
raise OperationalException(
f"This strategy requires {startup_candles} candles to start. "
f"{self.name} only provides {self._ft_has['ohlcv_candle_limit']}.")
f"{self.name} only provides {candle_limit} for {timeframe}.")
def exchange_has(self, endpoint: str) -> bool:
"""
@@ -486,6 +504,41 @@ class Exchange:
else:
return 1 / pow(10, precision)
def get_min_pair_stake_amount(self, pair: str, price: float,
stoploss: float) -> Optional[float]:
try:
market = self.markets[pair]
except KeyError:
raise ValueError(f"Can't get market information for symbol {pair}")
if 'limits' not in market:
return None
min_stake_amounts = []
limits = market['limits']
if ('cost' in limits and 'min' in limits['cost']
and limits['cost']['min'] is not None):
min_stake_amounts.append(limits['cost']['min'])
if ('amount' in limits and 'min' in limits['amount']
and limits['amount']['min'] is not None):
min_stake_amounts.append(limits['amount']['min'] * price)
if not min_stake_amounts:
return None
# reserve some percent defined in config (5% default) + stoploss
amount_reserve_percent = 1.0 - self._config.get('amount_reserve_percent',
DEFAULT_AMOUNT_RESERVE_PERCENT)
amount_reserve_percent += stoploss
# it should not be more than 50%
amount_reserve_percent = max(amount_reserve_percent, 0.5)
# The value returned should satisfy both limits: for amount (base currency) and
# for cost (quote, stake currency), so max() is used here.
# See also #2575 at github.
return max(min_stake_amounts) / amount_reserve_percent
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}_{datetime.now().timestamp()}'
@@ -501,7 +554,7 @@ class Exchange:
'side': side,
'remaining': _amount,
'datetime': arrow.utcnow().isoformat(),
'timestamp': int(arrow.utcnow().timestamp * 1000),
'timestamp': int(arrow.utcnow().int_timestamp * 1000),
'status': "closed" if ordertype == "market" else "open",
'fee': None,
'info': {}
@@ -523,7 +576,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
@@ -657,7 +710,8 @@ class Exchange:
@retrier
def fetch_ticker(self, pair: str) -> dict:
try:
if pair not in self._api.markets or not self._api.markets[pair].get('active'):
if (pair not in self.markets or
self.markets[pair].get('active', False) is False):
raise ExchangeError(f"Pair {pair} not available")
data = self._api.fetch_ticker(pair)
return data
@@ -674,21 +728,37 @@ class Exchange:
"""
Get candle history using asyncio and returns the list of candles.
Handles all async work for this.
Async over one pair, assuming we get `self._ohlcv_candle_limit` candles per call.
Async over one pair, assuming we get `self.ohlcv_candle_limit()` candles per call.
: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
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
logger.debug(
"one_call: %s msecs (%s)",
one_call,
@@ -696,27 +766,36 @@ 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))
return data
def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes) -> List[Tuple[str, List]]:
def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes, *,
since_ms: Optional[int] = None, cache: bool = True
) -> Dict[Tuple[str, str], DataFrame]:
"""
Refresh in-memory OHLCV asynchronously and set `_klines` with the result
Loops asynchronously over pair_list and downloads all pairs async (semi-parallel).
Only used in the dataprovider.refresh() method.
:param pair_list: List of 2 element tuples containing pair, interval to refresh
:return: TODO: return value is only used in the tests, get rid of it
:param since_ms: time since when to download, in milliseconds
:param cache: Assign result to _klines. Usefull for one-off downloads like for pairlists
:return: Dict of [{(pair, timeframe): Dataframe}]
"""
logger.debug("Refreshing candle (OHLCV) data for %d pairs", len(pair_list))
@@ -726,7 +805,8 @@ class Exchange:
for pair, timeframe in set(pair_list):
if (not ((pair, timeframe) in self._klines)
or self._now_is_time_to_refresh(pair, timeframe)):
input_coroutines.append(self._async_get_candle_history(pair, timeframe))
input_coroutines.append(self._async_get_candle_history(pair, timeframe,
since_ms=since_ms))
else:
logger.debug(
"Using cached candle (OHLCV) data for pair %s, timeframe %s ...",
@@ -736,30 +816,32 @@ class Exchange:
results = asyncio.get_event_loop().run_until_complete(
asyncio.gather(*input_coroutines, return_exceptions=True))
results_df = {}
# handle caching
for res in results:
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
# keeping parsed dataframe in cache
self._klines[(pair, timeframe)] = ohlcv_to_dataframe(
ticks, timeframe, pair=pair, fill_missing=True,
drop_incomplete=self._ohlcv_partial_candle)
return results
ohlcv_df = ohlcv_to_dataframe(
ticks, timeframe, pair=pair, fill_missing=True,
drop_incomplete=self._ohlcv_partial_candle)
results_df[(pair, timeframe)] = ohlcv_df
if cache:
self._klines[(pair, timeframe)] = ohlcv_df
return results_df
def _now_is_time_to_refresh(self, pair: str, timeframe: str) -> bool:
# Timeframe in seconds
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,
@@ -777,7 +859,8 @@ class Exchange:
)
data = await self._api_async.fetch_ohlcv(pair, timeframe=timeframe,
since=since_ms)
since=since_ms,
limit=self.ohlcv_candle_limit(timeframe))
# Some exchanges sort OHLCV in ASC order and others in DESC.
# Ex: Bittrex returns the list of OHLCV in ASC order (oldest first, newest last)
@@ -905,7 +988,7 @@ class Exchange:
while True:
t = await self._async_fetch_trades(pair, since=since)
if len(t):
since = t[-1][1]
since = t[-1][0]
trades.extend(t)
# Reached the end of the defined-download period
if until and t[-1][0] > until:
@@ -950,7 +1033,7 @@ class Exchange:
"""
Get trade history data using asyncio.
Handles all async work and returns the list of candles.
Async over one pair, assuming we get `self._ohlcv_candle_limit` candles per call.
Async over one pair, assuming we get `self.ohlcv_candle_limit()` candles per call.
:param pair: Pair to download
:param since: Timestamp in milliseconds to get history from
:param until: Timestamp in milliseconds. Defaults to current timestamp if not defined.
@@ -1069,6 +1152,16 @@ class Exchange:
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:
"""
@@ -1077,9 +1170,10 @@ class Exchange:
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.'

View File

@@ -4,12 +4,12 @@ from typing import Any, Dict
import ccxt
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError,
InvalidOrderException, OperationalException,
TemporaryError)
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange import Exchange
from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT, retrier
logger = logging.getLogger(__name__)

View File

@@ -4,12 +4,12 @@ from typing import Any, Dict
import ccxt
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError,
InvalidOrderException, OperationalException,
TemporaryError)
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,6 +18,7 @@ class Kraken(Exchange):
_params: Dict = {"trading_agreement": "agree"}
_ft_has: Dict = {
"stoploss_on_exchange": True,
"ohlcv_candle_limit": 720,
"trades_pagination": "id",
"trades_pagination_arg": "since",
}
@@ -47,7 +48,7 @@ class Kraken(Exchange):
orders = self._api.fetch_open_orders()
order_list = [(x["symbol"].split("/")[0 if x["side"] == "sell" else 1],
x["remaining"],
x["remaining"] if x["side"] == "sell" else x["remaining"] * x["price"],
# Don't remove the below comment, this can be important for debuggung
# x["side"], x["amount"],
) for x in orders]
@@ -69,7 +70,8 @@ class Kraken(Exchange):
Verify stop_loss against stoploss-order value (limit or price)
Returns True if adjustment is necessary.
"""
return order['type'] == 'stop-loss' and stop_loss > float(order['price'])
return (order['type'] in ('stop-loss', 'stop-loss-limit')
and stop_loss > float(order['price']))
@retrier(retries=0)
def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict:
@@ -77,8 +79,15 @@ class Kraken(Exchange):
Creates a stoploss market order.
Stoploss market orders is the only stoploss type supported by kraken.
"""
params = self._params.copy()
ordertype = "stop-loss"
if order_types.get('stoploss', 'market') == 'limit':
ordertype = "stop-loss-limit"
limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99)
limit_rate = stop_price * limit_price_pct
params['price2'] = self.price_to_precision(pair, limit_rate)
else:
ordertype = "stop-loss"
stop_price = self.price_to_precision(pair, stop_price)
@@ -88,8 +97,6 @@ class Kraken(Exchange):
return dry_order
try:
params = self._params.copy()
amount = self.amount_to_precision(pair, amount)
order = self._api.create_order(symbol=pair, type=ordertype, side='sell',

View File

@@ -4,7 +4,7 @@ Freqtrade is the main module of this bot. It contains the class Freqtrade()
import copy
import logging
import traceback
from datetime import datetime
from datetime import datetime, timezone
from math import isclose
from threading import Lock
from typing import Any, Dict, List, Optional
@@ -12,17 +12,19 @@ from typing import Any, Dict, List, Optional
import arrow
from cachetools import TTLCache
from freqtrade import __version__, constants, persistence
from freqtrade import __version__, constants
from freqtrade.configuration import validate_config_consistency
from freqtrade.data.converter import order_book_to_dataframe
from freqtrade.data.dataprovider import DataProvider
from freqtrade.edge import Edge
from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError,
InvalidOrderException, PricingError)
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
from freqtrade.misc import safe_value_fallback, safe_value_fallback2
from freqtrade.pairlist.pairlistmanager import PairListManager
from freqtrade.persistence import Order, Trade
from freqtrade.mixins import LoggingMixin
from freqtrade.persistence import Order, PairLocks, Trade, cleanup_db, init_db
from freqtrade.plugins.pairlistmanager import PairListManager
from freqtrade.plugins.protectionmanager import ProtectionManager
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.rpc import RPCManager, RPCMessageType
from freqtrade.state import State
@@ -30,10 +32,11 @@ from freqtrade.strategy.interface import IStrategy, SellType
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
from freqtrade.wallets import Wallets
logger = logging.getLogger(__name__)
class FreqtradeBot:
class FreqtradeBot(LoggingMixin):
"""
Freqtrade is the main class of the bot.
This is from here the bot start its logic.
@@ -57,8 +60,8 @@ class FreqtradeBot:
# Cache values for 1800 to avoid frequent polling of the exchange for prices
# Caching only applies to RPC methods, so prices for open trades are still
# refreshed once every iteration.
self._sell_rate_cache = TTLCache(maxsize=100, ttl=1800)
self._buy_rate_cache = TTLCache(maxsize=100, ttl=1800)
self._sell_rate_cache: TTLCache = TTLCache(maxsize=100, ttl=1800)
self._buy_rate_cache: TTLCache = TTLCache(maxsize=100, ttl=1800)
self.strategy: IStrategy = StrategyResolver.load_strategy(self.config)
@@ -67,14 +70,18 @@ class FreqtradeBot:
self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config)
persistence.init(self.config.get('db_url', None), clean_open_orders=self.config['dry_run'])
init_db(self.config.get('db_url', None), clean_open_orders=self.config['dry_run'])
self.wallets = Wallets(self.config, self.exchange)
PairLocks.timeframe = self.config['timeframe']
self.pairlists = PairListManager(self.exchange, self.config)
self.dataprovider = DataProvider(self.config, self.exchange, self.pairlists)
self.protections = ProtectionManager(self.config)
# Attach Dataprovider to Strategy baseclass
IStrategy.dp = self.dataprovider
# Attach Wallets to Strategy baseclass
@@ -98,6 +105,7 @@ class FreqtradeBot:
self.rpc: RPCManager = RPCManager(self)
# Protect sell-logic from forcesell and viceversa
self._sell_lock = Lock()
LoggingMixin.__init__(self, logger, timeframe_to_seconds(self.strategy.timeframe))
def notify_status(self, msg: str) -> None:
"""
@@ -122,14 +130,14 @@ class FreqtradeBot:
self.check_for_open_trades()
self.rpc.cleanup()
persistence.cleanup()
cleanup_db()
def startup(self) -> None:
"""
Called on startup and after reloading the bot - triggers notifications and
performs startup tasks
"""
self.rpc.startup_messages(self.config, self.pairlists)
self.rpc.startup_messages(self.config, self.pairlists, self.protections)
if not self.edge:
# Adjust stoploss if it was changed
Trade.stoploss_reinitialization(self.strategy.stoploss)
@@ -171,6 +179,7 @@ class FreqtradeBot:
# Without this, freqtrade my try to recreate stoploss_on_exchange orders
# while selling is in process, since telegram messages arrive in an different thread.
with self._sell_lock:
trades = Trade.get_open_trades()
# First process current opened trades (positions)
self.exit_positions(trades)
@@ -192,7 +201,7 @@ class FreqtradeBot:
Notify the user when the bot is stopped
and there are still open trades active.
"""
open_trades = Trade.get_trades([Trade.is_open == 1]).all()
open_trades = Trade.get_trades([Trade.is_open.is_(True)]).all()
if len(open_trades) != 0:
msg = {
@@ -225,7 +234,7 @@ class FreqtradeBot:
_whitelist.extend([trade.pair for trade in trades if trade.pair not in _whitelist])
return _whitelist
def get_free_open_trades(self):
def get_free_open_trades(self) -> int:
"""
Return the number of free open trades slots or 0 if
max number of open trades reached
@@ -238,6 +247,10 @@ class FreqtradeBot:
Updates open orders based on order list kept in the database.
Mainly updates the state of orders - but may also close trades
"""
if self.config['dry_run'] or self.config['exchange'].get('skip_open_order_update', False):
# Updating open orders in dry-run does not make sense and will fail.
return
orders = Order.get_open_orders()
logger.info(f"Updating {len(orders)} open orders.")
for order in orders:
@@ -248,6 +261,7 @@ class FreqtradeBot:
self.update_trade_state(order.trade, order.order_id, fo)
except ExchangeError as e:
logger.warning(f"Error updating Order {order.order_id} due to {e}")
def update_closed_trades_without_assigned_fees(self):
@@ -255,6 +269,10 @@ class FreqtradeBot:
Update closed trades without close fees assigned.
Only acts when Orders are in the database, otherwise the last orderid is unknown.
"""
if self.config['dry_run']:
# Updating open orders in dry-run does not make sense and will fail.
return
trades: List[Trade] = Trade.get_sold_trades_without_assigned_fees()
for trade in trades:
@@ -344,27 +362,35 @@ class FreqtradeBot:
whitelist = copy.deepcopy(self.active_pair_whitelist)
if not whitelist:
logger.info("Active pair whitelist is empty.")
else:
# Remove pairs for currently opened trades from the whitelist
for trade in Trade.get_open_trades():
if trade.pair in whitelist:
whitelist.remove(trade.pair)
logger.debug('Ignoring %s in pair whitelist', trade.pair)
return trades_created
# Remove pairs for currently opened trades from the whitelist
for trade in Trade.get_open_trades():
if trade.pair in whitelist:
whitelist.remove(trade.pair)
logger.debug('Ignoring %s in pair whitelist', trade.pair)
if not whitelist:
logger.info("No currency pair in active pair whitelist, "
"but checking to sell open trades.")
if not whitelist:
logger.info("No currency pair in active pair whitelist, "
"but checking to sell open trades.")
return trades_created
if PairLocks.is_global_lock():
lock = PairLocks.get_pair_longest_lock('*')
if lock:
self.log_once(f"Global pairlock active until "
f"{lock.lock_end_time.strftime(constants.DATETIME_PRINT_FORMAT)}. "
"Not creating new trades.", logger.info)
else:
# Create entity and execute trade for each pair from whitelist
for pair in whitelist:
try:
trades_created += self.create_trade(pair)
except DependencyException as exception:
logger.warning('Unable to create trade for %s: %s', pair, exception)
self.log_once("Global pairlock active. Not creating new trades.", logger.info)
return trades_created
# Create entity and execute trade for each pair from whitelist
for pair in whitelist:
try:
trades_created += self.create_trade(pair)
except DependencyException as exception:
logger.warning('Unable to create trade for %s: %s', pair, exception)
if not trades_created:
logger.debug("Found no buy signals for whitelisted currencies. "
"Trying again...")
if not trades_created:
logger.debug("Found no buy signals for whitelisted currencies. Trying again...")
return trades_created
@@ -414,118 +440,6 @@ class FreqtradeBot:
return used_rate
def get_trade_stake_amount(self, pair: str) -> float:
"""
Calculate stake amount for the trade
:return: float: Stake amount
:raise: DependencyException if the available stake amount is too low
"""
stake_amount: float
# Ensure wallets are uptodate.
self.wallets.update()
if self.edge:
stake_amount = self.edge.stake_amount(
pair,
self.wallets.get_free(self.config['stake_currency']),
self.wallets.get_total(self.config['stake_currency']),
Trade.total_open_trades_stakes()
)
else:
stake_amount = self.config['stake_amount']
if stake_amount == constants.UNLIMITED_STAKE_AMOUNT:
stake_amount = self._calculate_unlimited_stake_amount()
return self._check_available_stake_amount(stake_amount)
def _get_available_stake_amount(self) -> float:
"""
Return the total currently available balance in stake currency,
respecting tradable_balance_ratio.
Calculated as
<open_trade stakes> + free amount ) * tradable_balance_ratio - <open_trade stakes>
"""
val_tied_up = Trade.total_open_trades_stakes()
# Ensure <tradable_balance_ratio>% is used from the overall balance
# Otherwise we'd risk lowering stakes with each open trade.
# (tied up + current free) * ratio) - tied up
available_amount = ((val_tied_up + self.wallets.get_free(self.config['stake_currency'])) *
self.config['tradable_balance_ratio']) - val_tied_up
return available_amount
def _calculate_unlimited_stake_amount(self) -> float:
"""
Calculate stake amount for "unlimited" stake amount
:return: 0 if max number of trades reached, else stake_amount to use.
"""
free_open_trades = self.get_free_open_trades()
if not free_open_trades:
return 0
available_amount = self._get_available_stake_amount()
return available_amount / free_open_trades
def _check_available_stake_amount(self, stake_amount: float) -> float:
"""
Check if stake amount can be fulfilled with the available balance
for the stake currency
:return: float: Stake amount
"""
available_amount = self._get_available_stake_amount()
if self.config['amend_last_stake_amount']:
# Remaining amount needs to be at least stake_amount * last_stake_amount_min_ratio
# Otherwise the remaining amount is too low to trade.
if available_amount > (stake_amount * self.config['last_stake_amount_min_ratio']):
stake_amount = min(stake_amount, available_amount)
else:
stake_amount = 0
if available_amount < stake_amount:
raise DependencyException(
f"Available balance ({available_amount} {self.config['stake_currency']}) is "
f"lower than stake amount ({stake_amount} {self.config['stake_currency']})"
)
return stake_amount
def _get_min_pair_stake_amount(self, pair: str, price: float) -> Optional[float]:
try:
market = self.exchange.markets[pair]
except KeyError:
raise ValueError(f"Can't get market information for symbol {pair}")
if 'limits' not in market:
return None
min_stake_amounts = []
limits = market['limits']
if ('cost' in limits and 'min' in limits['cost']
and limits['cost']['min'] is not None):
min_stake_amounts.append(limits['cost']['min'])
if ('amount' in limits and 'min' in limits['amount']
and limits['amount']['min'] is not None):
min_stake_amounts.append(limits['amount']['min'] * price)
if not min_stake_amounts:
return None
# reserve some percent defined in config (5% default) + stoploss
amount_reserve_percent = 1.0 - self.config.get('amount_reserve_percent',
constants.DEFAULT_AMOUNT_RESERVE_PERCENT)
if self.strategy.stoploss is not None:
amount_reserve_percent += self.strategy.stoploss
# it should not be more than 50%
amount_reserve_percent = max(amount_reserve_percent, 0.5)
# The value returned should satisfy both limits: for amount (base currency) and
# for cost (quote, stake currency), so max() is used here.
# See also #2575 at github.
return max(min_stake_amounts) / amount_reserve_percent
def create_trade(self, pair: str) -> bool:
"""
Check the implemented trading strategy for buy signals.
@@ -538,9 +452,15 @@ class FreqtradeBot:
logger.debug(f"create_trade for pair {pair}")
analyzed_df, _ = self.dataprovider.get_analyzed_dataframe(pair, self.strategy.timeframe)
if self.strategy.is_pair_locked(
pair, analyzed_df.iloc[-1]['date'] if len(analyzed_df) > 0 else None):
logger.info(f"Pair {pair} is currently locked.")
nowtime = analyzed_df.iloc[-1]['date'] if len(analyzed_df) > 0 else None
if self.strategy.is_pair_locked(pair, nowtime):
lock = PairLocks.get_pair_longest_lock(pair, nowtime)
if lock:
self.log_once(f"Pair {pair} is still locked until "
f"{lock.lock_end_time.strftime(constants.DATETIME_PRINT_FORMAT)}.",
logger.info)
else:
self.log_once(f"Pair {pair} is still locked.", logger.info)
return False
# get_free_open_trades is checked before create_trade is called
@@ -553,7 +473,8 @@ class FreqtradeBot:
(buy, sell) = self.strategy.get_signal(pair, self.strategy.timeframe, analyzed_df)
if buy and not sell:
stake_amount = self.get_trade_stake_amount(pair)
stake_amount = self.wallets.get_trade_stake_amount(pair, self.get_free_open_trades(),
self.edge)
if not stake_amount:
logger.debug(f"Stake amount is 0, ignoring possible trade for {pair}.")
return False
@@ -613,7 +534,11 @@ class FreqtradeBot:
# Calculate price
buy_limit_requested = self.get_buy_rate(pair, True)
min_stake_amount = self._get_min_pair_stake_amount(pair, buy_limit_requested)
if not buy_limit_requested:
raise PricingError('Could not determine buy price.')
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, buy_limit_requested,
self.strategy.stoploss)
if min_stake_amount is not None and min_stake_amount > stake_amount:
logger.warning(
f"Can't open a new trade for {pair}: stake amount "
@@ -936,8 +861,8 @@ class FreqtradeBot:
self.update_trade_state(trade, trade.stoploss_order_id, stoploss_order,
stoploss_order=True)
# Lock pair for one candle to prevent immediate rebuys
self.strategy.lock_pair(trade.pair,
timeframe_to_next_date(self.config['timeframe']))
self.strategy.lock_pair(trade.pair, datetime.now(timezone.utc),
reason='Auto lock')
self._notify_sell(trade, "stoploss")
return True
@@ -965,7 +890,8 @@ class FreqtradeBot:
logger.warning('Stoploss order was cancelled, but unable to recreate one.')
# Finally we check if stoploss on exchange should be moved up because of trailing.
if stoploss_order and self.config.get('trailing_stop', False):
if stoploss_order and (self.config.get('trailing_stop', False)
or self.config.get('use_custom_stoploss', False)):
# if trailing stoploss is enabled we check if stoploss value has changed
# in which case we cancel stoploss order and put another one with new
# value immediately
@@ -1145,7 +1071,9 @@ class FreqtradeBot:
if not self.exchange.check_order_canceled_empty(order):
try:
# if trade is not partially completed, just delete the order
self.exchange.cancel_order(trade.open_order_id, trade.pair)
co = self.exchange.cancel_order_with_result(trade.open_order_id, trade.pair,
trade.amount)
trade.update_order(co)
except InvalidOrderException:
logger.exception(f"Could not cancel sell order {trade.open_order_id}")
return 'error cancelling order'
@@ -1153,6 +1081,7 @@ class FreqtradeBot:
else:
reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE']
logger.info('Sell order %s for %s.', reason, trade)
trade.update_order(order)
trade.close_rate = None
trade.close_rate_requested = None
@@ -1255,6 +1184,7 @@ class FreqtradeBot:
trade.orders.append(order_obj)
trade.open_order_id = order['id']
trade.sell_order_status = ''
trade.close_rate_requested = limit
trade.sell_reason = sell_reason.value
# In case of market sell orders the order can be closed immediately
@@ -1263,7 +1193,8 @@ class FreqtradeBot:
Trade.session.flush()
# Lock pair for one candle to prevent immediate rebuys
self.strategy.lock_pair(trade.pair, timeframe_to_next_date(self.config['timeframe']))
self.strategy.lock_pair(trade.pair, datetime.now(timezone.utc),
reason='Auto lock')
self._notify_sell(trade, order_type)
@@ -1389,7 +1320,7 @@ class FreqtradeBot:
abs_tol=constants.MATH_CLOSE_PREC):
order['amount'] = new_amount
order.pop('filled', None)
trade.recalc_open_trade_price()
trade.recalc_open_trade_value()
except DependencyException as exception:
logger.warning("Could not update trade amount: %s", exception)
@@ -1401,6 +1332,8 @@ class FreqtradeBot:
# Updating wallets when order is closed
if not trade.is_open:
self.protections.stop_per_pair(trade.pair)
self.protections.global_stop()
self.wallets.update()
return False
@@ -1442,13 +1375,16 @@ class FreqtradeBot:
fee_cost, fee_currency, fee_rate = self.exchange.extract_cost_curr_rate(order)
logger.info(f"Fee for Trade {trade} [{order.get('side')}]: "
f"{fee_cost:.8g} {fee_currency} - rate: {fee_rate}")
trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side', ''))
if trade_base_currency == fee_currency:
# Apply fee to amount
return self.apply_fee_conditional(trade, trade_base_currency,
amount=order_amount, fee_abs=fee_cost)
return order_amount
if fee_rate is None or fee_rate < 0.02:
# Reject all fees that report as > 2%.
# These are most likely caused by a parsing bug in ccxt
# due to multiple trades (https://github.com/ccxt/ccxt/issues/8025)
trade.update_fee(fee_cost, fee_currency, fee_rate, order.get('side', ''))
if trade_base_currency == fee_currency:
# Apply fee to amount
return self.apply_fee_conditional(trade, trade_base_currency,
amount=order_amount, fee_abs=fee_cost)
return order_amount
return self.fee_detection_from_trades(trade, order, order_amount)
def fee_detection_from_trades(self, trade: Trade, order: Dict, order_amount: float) -> float:

View File

@@ -1,12 +1,12 @@
import logging
import sys
from logging import Formatter
from logging.handlers import (BufferingHandler, RotatingFileHandler,
SysLogHandler)
from logging.handlers import BufferingHandler, RotatingFileHandler, SysLogHandler
from typing import Any, Dict
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
LOGFORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
@@ -37,6 +37,13 @@ def _set_loggers(verbosity: int = 0, api_verbosity: str = 'info') -> None:
)
def get_existing_handlers(handlertype):
"""
Returns Existing handler or None (if the handler has not yet been added to the root handlers).
"""
return next((h for h in logging.root.handlers if isinstance(h, handlertype)), None)
def setup_logging_pre() -> None:
"""
Early setup for logging.
@@ -71,18 +78,24 @@ def setup_logging(config: Dict[str, Any]) -> None:
# config['logfilename']), which defaults to '/dev/log', applicable for most
# of the systems.
address = (s[1], int(s[2])) if len(s) > 2 else s[1] if len(s) > 1 else '/dev/log'
handler = SysLogHandler(address=address)
handler_sl = get_existing_handlers(SysLogHandler)
if handler_sl:
logging.root.removeHandler(handler_sl)
handler_sl = SysLogHandler(address=address)
# No datetime field for logging into syslog, to allow syslog
# to perform reduction of repeating messages if this is set in the
# syslog config. The messages should be equal for this.
handler.setFormatter(Formatter('%(name)s - %(levelname)s - %(message)s'))
logging.root.addHandler(handler)
handler_sl.setFormatter(Formatter('%(name)s - %(levelname)s - %(message)s'))
logging.root.addHandler(handler_sl)
elif s[0] == 'journald':
try:
from systemd.journal import JournaldLogHandler
except ImportError:
raise OperationalException("You need the systemd python package be installed in "
"order to use logging to journald.")
handler_jd = get_existing_handlers(JournaldLogHandler)
if handler_jd:
logging.root.removeHandler(handler_jd)
handler_jd = JournaldLogHandler()
# No datetime field for logging into journald, to allow syslog
# to perform reduction of repeating messages if this is set in the
@@ -90,6 +103,9 @@ def setup_logging(config: Dict[str, Any]) -> None:
handler_jd.setFormatter(Formatter('%(name)s - %(levelname)s - %(message)s'))
logging.root.addHandler(handler_jd)
else:
handler_rf = get_existing_handlers(RotatingFileHandler)
if handler_rf:
logging.root.removeHandler(handler_rf)
handler_rf = RotatingFileHandler(logfile,
maxBytes=1024 * 1024 * 10, # 10Mb
backupCount=10)

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