Compare commits

..

3151 Commits

Author SHA1 Message Date
robcaulk
755041c134 add noise feature, improve docstrings 2022-08-19 18:35:24 +02:00
robcaulk
98c62dad91 integrate inlier metric function 2022-08-19 15:22:54 +02:00
th0rntwig
52ee7fc981 Add inlier metric computation 2022-08-19 15:22:54 +02:00
Matthias
16af10a5bc Update notebook sample with simplified datadir configuration
closes #7252
2022-08-19 14:05:27 +02:00
Matthias
7d84ef2e2c Remove unused imports 2022-08-19 13:45:10 +02:00
Matthias
b420614d65 Reduce code duplication in datahandlers 2022-08-19 09:33:07 +02:00
Matthias
975bf8fe88 Update Docstring to match actual return values 2022-08-19 09:23:53 +02:00
Matthias
47b3143534 Simplify and fix some tests 2022-08-19 09:10:54 +02:00
Matthias
42eb508515 Attempt fix of #7184 2022-08-19 07:09:46 +02:00
Matthias
76a3e97e05 Add migrations end message
closes #7251
2022-08-19 06:39:51 +02:00
Matthias
70a77ba3d9 Check for "last" availability in PrecisionFilter
closes #7250
2022-08-18 20:07:50 +02:00
Matthias
85b43ec1a1 Remove double-check for "isolated margin" 2022-08-18 15:23:58 +02:00
Matthias
fde469a253 Remove unnecessary check 2022-08-18 14:53:44 +02:00
Matthias
075e9b8526 Log Exchange responses for set_leverage 2022-08-18 09:52:03 +02:00
Matthias
46e8d9a5e4 Reduce verbosity when whitelist is empty 2022-08-18 09:09:37 +02:00
Matthias
18fab86431 Add dock segment about webserver mode for docker 2022-08-18 08:32:15 +02:00
Matthias
0461a89348 Fix test failures 2022-08-18 07:20:49 +02:00
Matthias
66910bfe63 Don't fail if mark candles are missing
closes #7239
2022-08-17 20:01:57 +02:00
Matthias
3983368228 gateio futures is showing base currency in volume! 2022-08-17 14:51:48 +02:00
Matthias
83ca168bb8 Merge pull request #7216 from freqtrade/precise_calcs
Precise calcs
2022-08-17 14:32:02 +02:00
Matthias
c615e1bc62 Avoid loop error during ccxt tests 2022-08-17 14:31:40 +02:00
Matthias
b9667f50cf Fix random test failure 2022-08-17 14:05:12 +02:00
Matthias
e7902bffa0 Remove checks for dataprovider existance - it's available in all modes. 2022-08-17 10:57:25 +02:00
Matthias
e0883a4ea0 Improve doc wording 2022-08-17 10:55:59 +02:00
Matthias
819bc71941 Update docs for freqai docker container 2022-08-17 10:35:56 +02:00
Matthias
463cf66881 Fix bad image name 2022-08-17 10:32:29 +02:00
Matthias
c8d7c2caac Update CI to build and push freqAI images 2022-08-17 10:32:29 +02:00
Matthias
8d182768f9 stoploss should also use trimmed prices 2022-08-17 09:57:11 +02:00
Matthias
0b0e7eaf96 Mutex TTL Cache accesses which can be accessed by multiple threads
Apparently, cachetools is (intentionally) not threadsafe
when using the Caches directly.
It's therefore recommended to wrap these with an explicit lock to avoid
problems.

source: https://github.com/tkem/cachetools/issues/245

closes #7215
2022-08-16 19:48:21 +02:00
Matthias
24690c1918 Don't convert open_rate to precision
this may cause more problems than it solves.
2022-08-16 18:32:00 +02:00
Matthias
3b44dc52e1 Minor corrections 2022-08-16 18:10:48 +02:00
Matthias
ea6bc47d7a gateio default configs should specify unknown_fee_rate 2022-08-16 17:26:53 +02:00
Matthias
5dde011b31 Add unknown_fee_rate to full sample config 2022-08-16 17:23:49 +02:00
Matthias
a1e4fbf313 Run price_to_precision for dry-run orders 2022-08-16 17:23:49 +02:00
Matthias
1ac81aa316 Show message if fee update failed due to missing
closes #7234
2022-08-16 17:09:23 +02:00
Matthias
c865814a8e Merge pull request #7236 from freqtrade/fix-lgbm-warning
Fix input shape for LighGBMClassifier
2022-08-16 13:49:25 +02:00
robcaulk
4c0fda400f fix input shape warning for LGBMClassifier, add sample_weights/eval_weights 2022-08-16 11:41:53 +02:00
Matthias
fa89368c02 Add test for precision backpopulation 2022-08-16 11:11:52 +02:00
Matthias
96d2f61812 Properly round timestamps to avoid constant log messages 2022-08-16 10:22:59 +02:00
Matthias
b8c1cf0107 Fix test leakage if config is available 2022-08-16 10:19:19 +02:00
Matthias
15a1c59a91 Backtesting should cache precisionMode 2022-08-16 10:15:19 +02:00
Matthias
a73e4f8e41 Truncate amount before comparing for closure 2022-08-16 09:49:53 +02:00
Matthias
2fb7a3091d Improve backfill of precisions 2022-08-16 09:32:31 +02:00
Matthias
711b6b1a1a Merge branch 'develop' into precise_calcs 2022-08-16 09:29:39 +02:00
Matthias
a5b438e41e Run price_to_precision for dry-run orders 2022-08-16 09:28:23 +02:00
Matthias
1dd56e35d5 Ensure comparisions align when closing a trade 2022-08-16 08:21:02 +02:00
Matthias
e4b7bcaeab Fix some tests 2022-08-16 08:01:07 +02:00
Matthias
e818797427 Minor fix in amount_to_precision logic 2022-08-15 20:29:05 +02:00
Matthias
c0bdb71810 Update docstring 2022-08-15 20:06:29 +02:00
Matthias
f2b6ff910f Accept wrong pair in get_precision_amount 2022-08-15 20:05:22 +02:00
Matthias
09ee9089fb Merge pull request #6832 from freqtrade/feat/freqai
Freqai: an interface for users to build/train/backtest predictive models and run them live
2022-08-15 20:03:08 +02:00
Matthias
e6af9a6903 Allow empty precisionMode on conversions 2022-08-15 20:00:15 +02:00
Matthias
c3f159bd57 Add precision fields to database 2022-08-15 19:58:40 +02:00
Matthias
22241c55d5 Add methods to get precision_amount from markets 2022-08-15 19:56:25 +02:00
Matthias
15e85797c2 Simplify to_precision tests and imports 2022-08-15 08:51:15 +02:00
Matthias
6c32331740 Move precision calculations to standalone functions 2022-08-15 08:43:58 +02:00
Matthias
053ab12ba6 Merge pull request #7227 from freqtrade/dependabot/pip/develop/plotly-5.10.0
Bump plotly from 5.9.0 to 5.10.0
2022-08-15 08:11:38 +02:00
Matthias
c7e1719215 Fix interface import sorting 2022-08-15 06:53:02 +02:00
Matthias
686b72a82d Merge pull request #7229 from freqtrade/dependabot/pip/develop/ccxt-1.92.20
Bump ccxt from 1.91.93 to 1.92.20
2022-08-15 06:49:54 +02:00
Matthias
398b2946b5 Update test formatting 2022-08-15 06:49:28 +02:00
Matthias
490c3a30ed Merge pull request #7225 from freqtrade/dependabot/pip/develop/nbconvert-6.5.3
Bump nbconvert from 6.5.0 to 6.5.3
2022-08-15 06:32:54 +02:00
Matthias
3caf0f9df3 Merge pull request #7231 from freqtrade/dependabot/pip/develop/orjson-3.7.12
Bump orjson from 3.7.11 to 3.7.12
2022-08-15 06:32:31 +02:00
Matthias
b7b74a430c Merge pull request #7230 from freqtrade/dependabot/pip/develop/mkdocs-material-8.4.0
Bump mkdocs-material from 8.3.9 to 8.4.0
2022-08-15 06:31:40 +02:00
Matthias
4ae9b48d89 Merge pull request #7228 from freqtrade/dependabot/pip/develop/filelock-3.8.0
Bump filelock from 3.7.1 to 3.8.0
2022-08-15 06:31:19 +02:00
dependabot[bot]
dba7d7fd65 Bump ccxt from 1.91.93 to 1.92.20
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.91.93 to 1.92.20.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.91.93...1.92.20)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 04:29:20 +00:00
Matthias
a0c348cf97 Merge pull request #7226 from freqtrade/dependabot/pip/develop/numpy-1.23.2
Bump numpy from 1.23.1 to 1.23.2
2022-08-15 06:28:53 +02:00
Matthias
ce892d4cde Merge pull request #7224 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.40
Bump sqlalchemy from 1.4.39 to 1.4.40
2022-08-15 06:28:17 +02:00
dependabot[bot]
6fb5fbdd30 Bump orjson from 3.7.11 to 3.7.12
Bumps [orjson](https://github.com/ijl/orjson) from 3.7.11 to 3.7.12.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.7.11...3.7.12)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 03:01:56 +00:00
dependabot[bot]
bc79027cf4 Bump mkdocs-material from 8.3.9 to 8.4.0
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.3.9 to 8.4.0.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.3.9...8.4.0)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 03:01:51 +00:00
dependabot[bot]
2581acd75e Bump filelock from 3.7.1 to 3.8.0
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.7.1 to 3.8.0.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.7.1...3.8.0)

---
updated-dependencies:
- dependency-name: filelock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 03:01:36 +00:00
dependabot[bot]
baa0af68b2 Bump plotly from 5.9.0 to 5.10.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v5.9.0...v5.10.0)

---
updated-dependencies:
- dependency-name: plotly
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 03:01:33 +00:00
dependabot[bot]
025ff27dd2 Bump numpy from 1.23.1 to 1.23.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.23.1 to 1.23.2.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.23.1...v1.23.2)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 03:01:29 +00:00
dependabot[bot]
96c279f86c Bump nbconvert from 6.5.0 to 6.5.3
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.5.0 to 6.5.3.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/6.5...6.5.3)

---
updated-dependencies:
- dependency-name: nbconvert
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 03:01:22 +00:00
dependabot[bot]
4b708caa6a Bump sqlalchemy from 1.4.39 to 1.4.40
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.39 to 1.4.40.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 03:01:19 +00:00
robcaulk
3f6d427084 add a check for number of training features in tests 2022-08-14 21:46:37 +02:00
robcaulk
006b11e5d5 fix leftover bug in indicator population 2022-08-14 21:42:55 +02:00
robcaulk
8961b8d560 merge in inference timer and historic predictions handling improvements. 2022-08-14 20:31:15 +02:00
robcaulk
ad846cdb76 fix lock bug, update docstring 2022-08-14 20:24:29 +02:00
Matthias
464d99808f Update doc table formatting 2022-08-14 18:22:01 +02:00
Matthias
d442383a15 Fix ta-lib install script 2022-08-14 18:17:17 +02:00
Matthias
a29402ddde Rename and move analysis_lock to data_kitchen 2022-08-14 17:23:14 +02:00
Matthias
3a9ec76c91 Move "freqai.lock" to backend to simplify user interface 2022-08-14 17:19:50 +02:00
Matthias
a5e96881f4 slightly update doc wording 2022-08-14 17:08:29 +02:00
Matthias
c08a89378d Merge pull request #7192 from AchmadFathoni/patch_conda_ta-lib
Add script for patching conda libta-lib
2022-08-14 09:46:33 +02:00
Matthias
e7513c96b3 install py-find-1st from conda forge
closes #7193
2022-08-14 09:36:38 +02:00
Matthias
24f1dc4ecc Update patched ta-lib install for conda 2022-08-14 09:06:04 +02:00
Matthias
044cf8bb2e Allow new whitelist combination in "button" commands 2022-08-14 08:41:25 +02:00
Matthias
22ac291c3a Merge pull request #7211 from ecoppen/rpc/whitelist_options
Optional /whitelist args - sorted, nobase
2022-08-14 08:26:21 +02:00
Robert Caulk
c9c128f781 finalize logo, improve doc, improve algo overview, fix base tensorflowmodel for mypy 2022-08-14 02:49:01 +02:00
Matthias
8d9284a524 Fix docs edit button 2022-08-13 20:20:09 +02:00
Matthias
7a2b4dbb99 Fix docs edit button 2022-08-13 20:16:36 +02:00
robcaulk
58de20af0f make BaseClassifierModel. Add predict_proba to lightgbm 2022-08-13 20:07:31 +02:00
robcaulk
31be707cc8 clean up code, add docstrings 2022-08-13 19:40:24 +02:00
robcaulk
3e38c1b0bd take dynamic sized tail off historic_predictions as return dataframe to strategy. 2022-08-13 19:40:24 +02:00
robcaulk
7d448fd4ac allow fit_live_predictions access to current pair 2022-08-13 19:40:24 +02:00
robcaulk
1f192be43b avoid denormalizing labels twice 2022-08-13 19:40:24 +02:00
robcaulk
b1b76a2dbe debug classifier with predict proba 2022-08-13 19:40:24 +02:00
robcaulk
23cc21ce59 add predict_proba to base classifier, improve historic predictions handling 2022-08-13 19:40:24 +02:00
Matthias
61acbf21d0 Fix broken telegram tests 2022-08-13 15:46:06 +02:00
Matthias
7075b00e20 Remove odd dry run stoploss behavior
closes #7208
2022-08-13 11:37:23 +02:00
Matthias
7c18ec4053 Add missing key to "full" config sample 2022-08-13 11:24:55 +02:00
Matthias
e09fbe9e53 Improve test resiliance 2022-08-13 11:17:22 +02:00
Matthias
d36da95941 Fix bad import 2022-08-13 11:07:58 +02:00
Matthias
82ac8cb41f Add freqai backtesting_load test 2022-08-13 10:48:57 +02:00
Matthias
0b92c30abd Fix typo in test file 2022-08-13 10:19:46 +02:00
Matthias
5aaab75d1c Add test for dynamic_pairlist_expand 2022-08-13 10:18:57 +02:00
Matthias
1ac6ec1446 Fix failing test... 2022-08-13 09:56:21 +02:00
Matthias
b682fc446e Graciously fail if strategy has freqAI code, but freqAI is not enabled. 2022-08-13 09:53:18 +02:00
Matthias
c190d57f1a Test populate_any_indicator interface 2022-08-13 09:48:59 +02:00
Matthias
3918f4abbd Simplify strategy interface by removing explicit self.freqai_info assignment 2022-08-13 09:27:56 +02:00
Matthias
3b827ee60a Add "freqai.enabled" flag to disable freqAI via config flag
aligns with how other optional modules work in freqtrade.
2022-08-13 09:24:04 +02:00
Matthias
49989012ab Bump catboost requirement to latest 2022-08-13 09:20:58 +02:00
Matthias
f6545ebdb8 Disallow backtesting with --strategy-list for now. 2022-08-13 09:10:03 +02:00
Matthias
e3a5b97b45 Update recalc_from_trades to use FtPrecise 2022-08-13 08:43:56 +02:00
Matthias
9513c39a17 Fix migration rounding test 2022-08-13 08:43:56 +02:00
Matthias
3bcb47d75d Remove usage of Decimal 2022-08-13 08:43:56 +02:00
Matthias
902afc2f02 Use FtPrecise in interest calculation 2022-08-13 08:43:56 +02:00
Matthias
da253f12fe Bump CCXT to required version 2022-08-13 08:43:56 +02:00
Matthias
0e61c2d057 Replace Decimal with FtPrecise in trade_model 2022-08-13 08:43:56 +02:00
Matthias
df701b5862 Merge branch 'develop' into feat/freqai 2022-08-13 08:43:24 +02:00
ecoppen
2312b86a66 Update telegram-usage.md
Add the optional arguments to the documentation.
2022-08-12 19:59:08 +01:00
ecoppen
ccc0ad6f64 fix - reload whitelist
Should fix the issue, if not I'll move development to a different computer and get local testing running properly.
2022-08-12 19:58:41 +01:00
ecoppen
923f73a516 nobase -> baseonly 2022-08-12 19:56:46 +01:00
robcaulk
fb4b73ce89 ensure dates are saved 2022-08-12 12:03:44 +02:00
Matthias
b427c7ff13 Use diff. close time to avoid buggy behavior 2022-08-12 07:28:19 +00:00
Matthias
d93bb82193 Add more Commits to failing test 2022-08-12 08:19:40 +02:00
Matthias
aa1bf2adbd Try fix windows testfailure 2022-08-12 06:43:34 +02:00
Matthias
cc885e25ac Improve NAN Handling in RPC 2022-08-11 20:16:07 +02:00
Matthias
de690b0a69 Use PEP440 compatible versioning 2022-08-11 20:08:40 +02:00
Matthias
dd4e44931e Improve NAN handling in RPC module 2022-08-11 15:02:52 +00:00
Matthias
f7502bcc92 slightly update dca_short test 2022-08-11 11:35:24 +00:00
robcaulk
2cae3c42e6 remove trade database analyzer, clean up a bit 2022-08-10 17:43:06 +02:00
ecoppen
ace9626483 Update tests for sorted and nobase
Tests for PR #7211
2022-08-10 15:04:24 +01:00
ecoppen
c0d60c63ab Optional /whitelist args - sorted, nobase
Added two optional arguments for whitelist - `sorted` for alphabetical order and `nobase` for displaying the whitelist without base currency e.g. /USDT.

Updated help with optional commands.

Added a space in an unrelated help message.
2022-08-10 14:56:38 +01:00
Matthias
ed004236ce Add float initializer to FtPrecise 2022-08-10 11:54:07 +00:00
Matthias
e7cb1b7375 Wrap Precise into FtPecise 2022-08-10 11:26:06 +00:00
robcaulk
91d0c91287 improve docs 2022-08-10 11:56:42 +02:00
Matthias
adc8ee88e2 Move periodicCache to Utils package 2022-08-10 08:57:19 +00:00
Matthias
573964b19f Dry Market orders should update "remaining" 2022-08-10 07:12:56 +02:00
Matthias
53251e7140 Merge pull request #7194 from freqtrade/rpc/partial_forceexit
Partial forceExit
2022-08-10 07:12:40 +02:00
Matthias
ce2c9bf26d Slight renaming of variable 2022-08-10 06:44:41 +02:00
Matthias
736884c5a9 Orders should be allowed to have empty fill/remaining values 2022-08-09 20:43:58 +02:00
Matthias
b5c5a95b64 FTX: Use conditionalOrders endpoint to get proper stop-market order id
closes #7165
2022-08-09 20:09:35 +02:00
robcaulk
4289c5c684 update freqai logo 2022-08-09 16:51:57 +02:00
robcaulk
5a16d5a512 Deactivate database analyzer if user does not use sqlite 2022-08-09 16:36:22 +02:00
robcaulk
e7de812948 Allow user to user pair_dict for persistent storage of custom data 2022-08-09 16:03:10 +02:00
robcaulk
aef086b02e Improved dict typing, timeframe parser, collect dates associated with training data points 2022-08-09 15:30:25 +02:00
Matthias
02646a4a08 Update scikit-learn in freqai deps 2022-08-09 06:23:16 +02:00
Matthias
9a82898d6b Merge branch 'develop' into feat/freqai 2022-08-09 06:22:57 +02:00
Matthias
77b3b8a134 Use main exchange instead of creating a separate instance. 2022-08-08 18:34:11 +00:00
Matthias
20b4134787 Properly exclude catboost in ARM 2022-08-08 18:15:18 +00:00
Matthias
8a18609be4 Merge pull request #7201 from freqtrade/dependabot/pip/develop/types-requests-2.28.8
Bump types-requests from 2.28.6 to 2.28.8
2022-08-08 07:18:27 +02:00
Matthias
0c7d862aae types-requests bump pre-commit 2022-08-08 06:54:00 +02:00
Matthias
05fb4de68b Merge pull request #7198 from freqtrade/dependabot/pip/develop/flake8-5.0.4
Bump flake8 from 5.0.1 to 5.0.4
2022-08-08 06:53:09 +02:00
Matthias
21649712a9 Merge pull request #7202 from freqtrade/dependabot/pip/develop/ccxt-1.91.93
Bump ccxt from 1.91.55 to 1.91.93
2022-08-08 06:52:14 +02:00
Matthias
001b6c087a Merge pull request #7199 from freqtrade/dependabot/pip/develop/scikit-learn-1.1.2
Bump scikit-learn from 1.1.1 to 1.1.2
2022-08-08 06:50:09 +02:00
Matthias
77b6025f12 Merge pull request #7200 from freqtrade/dependabot/pip/develop/jsonschema-4.9.1
Bump jsonschema from 4.9.0 to 4.9.1
2022-08-08 06:49:49 +02:00
dependabot[bot]
71c88244fe Bump ccxt from 1.91.55 to 1.91.93
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.91.55 to 1.91.93.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.91.55...1.91.93)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 03:01:38 +00:00
dependabot[bot]
97c077171a Bump types-requests from 2.28.6 to 2.28.8
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.6 to 2.28.8.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 03:01:28 +00:00
dependabot[bot]
a45a35f38c Bump jsonschema from 4.9.0 to 4.9.1
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.9.0 to 4.9.1.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.9.0...v4.9.1)

---
updated-dependencies:
- dependency-name: jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 03:01:25 +00:00
dependabot[bot]
7fd3f98ae8 Bump scikit-learn from 1.1.1 to 1.1.2
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/1.1.1...1.1.2)

---
updated-dependencies:
- dependency-name: scikit-learn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 03:01:20 +00:00
dependabot[bot]
11a2eb6cc5 Bump flake8 from 5.0.1 to 5.0.4
Bumps [flake8](https://github.com/pycqa/flake8) from 5.0.1 to 5.0.4.
- [Release notes](https://github.com/pycqa/flake8/releases)
- [Commits](https://github.com/pycqa/flake8/compare/5.0.1...5.0.4)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 03:01:16 +00:00
robcaulk
ea64f43e52 bring back auto DF resizing for okx 2022-08-08 01:13:13 +02:00
robcaulk
67c722c9c8 fix asyncio bug 2022-08-07 14:48:39 +02:00
Matthias
e48e82232d Force response API to js to fix faulty system configs
closes #7147
2022-08-07 10:42:56 +02:00
Matthias
0b2104fc7a Properly increment the api version 2022-08-07 10:13:36 +02:00
Matthias
5182f755f1 Add debug setup documentation
closes #7167
2022-08-07 10:08:48 +02:00
Matthias
6ded2d5b7c Improve forceexit API test 2022-08-07 09:47:11 +02:00
Matthias
d3780b931c Add test passing leverage to execute_entry 2022-08-07 09:47:11 +02:00
Matthias
d1998f7ed0 Fix forceexit calling 2022-08-07 09:47:11 +02:00
Matthias
eff8cd7ecb Add leverage to force_entry 2022-08-07 09:47:11 +02:00
Matthias
daf015d007 extract nested force_exit function to private instance function 2022-08-07 09:47:11 +02:00
Matthias
82aecc81f3 Accept parameters to forceexit 2022-08-07 09:47:11 +02:00
Achmad Fathoni
aaa5349003 Add script for patching conda libta-lib 2022-08-07 13:44:09 +07:00
Matthias
78e129034e Update docs to specify trading limit behaviour
closes #7183
2022-08-06 17:59:08 +02:00
robcaulk
eb8bde37c1 Add lightgbm classifier, add classifier check test, fix classifier bug. 2022-08-06 17:51:21 +02:00
Matthias
bfa859e618 Remove unnecessary method (simplify) 2022-08-06 17:46:58 +02:00
Matthias
5250189f77 Add Rollback function to Trade
simplifies Session work
2022-08-06 17:03:49 +02:00
Matthias
47a30047eb Fix typo 2022-08-06 15:03:10 +02:00
Matthias
b16f57cb0d Minor stylistic fixes 2022-08-06 14:55:46 +02:00
Robert Caulk
c172ce1011 improve flexibility of user defined prediction dataframe 2022-08-06 13:51:19 +02:00
Matthias
45d68222a1 Reduce verbosity of Fiat Converter 2022-08-06 13:18:40 +02:00
Robert Caulk
fdc82f8302 add doc section for classifier 2022-08-06 09:45:26 +02:00
Matthias
f8f1ade163 Reduce function complexity by extracting message sending 2022-08-06 09:21:11 +02:00
Matthias
2687633941 Test iterative sending of /status 2022-08-06 09:16:04 +02:00
Matthias
b12dd15f4f Send multiple messages in /status if required 2022-08-06 09:10:12 +02:00
Robert Caulk
07763d0d4f add classifier, improve model naming scheme 2022-08-06 08:33:55 +02:00
Robert Caulk
ce8fbbf743 ensure loading historical df matches frequi indices 2022-08-06 07:25:59 +02:00
robcaulk
60d782e5c5 remove unnecessary function 2022-08-05 21:31:32 +02:00
robcaulk
a42a060ab5 fix DB once and for all. Make DBSCAN more efficient and robust. 2022-08-05 21:29:03 +02:00
Robert Caulk
a3799c4d5d start frequi with historical data if available 2022-08-05 18:27:47 +02:00
robcaulk
29b7b014e5 fix bug in DB path initialization 2022-08-05 18:19:26 +02:00
robcaulk
db1d367941 fix bug associated to fit_live_predictions_candles 2022-08-05 13:46:20 +02:00
robcaulk
26de992d20 ensure user sets startup candles in backtesting mode 2022-08-05 12:23:14 +02:00
robcaulk
05ec5c5e54 generalize database url path for any db type 2022-08-05 12:19:29 +02:00
Matthias
9545402452 Improve defaults for config builder 2022-08-05 11:58:09 +02:00
Matthias
29e41cc817 Update docs to reflect correct result
closes #7181
2022-08-05 11:15:44 +02:00
Matthias
7675187c37 Use telegram message length to avoid constants 2022-08-05 07:31:19 +02:00
Matthias
cffc769549 Fix /profit endpoint calculations for partial sells
* don't recalculate for closed trades
* include realized_profit in the calculation

part of #7178
2022-08-05 07:26:41 +02:00
Matthias
c6e121ffb4 Update tests with correct usdt mock trades 2022-08-05 07:21:46 +02:00
OGSK
a8541d86fb Edit index of custom_stake_amount 2022-08-05 06:25:21 +02:00
OGSK
debc73b654 Edit Typo Custom-stake-amount
Edit Custom-stake-amount to `custom_stake_amount`
2022-08-05 06:25:08 +02:00
Matthias
c2a3e2776e Merge pull request #7180 from freqtrade/dependabot/docker/python-3.10.6-slim-bullseye
Bump python from 3.10.5-slim-bullseye to 3.10.6-slim-bullseye
2022-08-05 06:24:00 +02:00
dependabot[bot]
df4a5a7573 Bump python from 3.10.5-slim-bullseye to 3.10.6-slim-bullseye
Bumps python from 3.10.5-slim-bullseye to 3.10.6-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-05 03:02:12 +00:00
Robert Caulk
51a6b4289f improve DBSCAN performance for subsequent trainings 2022-08-04 17:41:58 +02:00
Robert Caulk
fe1b8515a8 fix bug in DBSCAN, update doc 2022-08-04 17:00:59 +02:00
Matthias
55360b4c08 Merge pull request #7174 from stash86/patch-3
Fix typo
2022-08-04 16:27:22 +02:00
Stefano Ariestasia
febd809119 Fix typo
adjust_trade_position should return stake_amount, not amount
2022-08-04 20:55:52 +09:00
robcaulk
29225e4baf add DBSCAN outlier detection feature, add supporting documentation 2022-08-04 12:15:16 +02:00
Matthias
778833f90e Modify comment in new test-strategies to point out their purpose 2022-08-04 07:17:26 +02:00
Matthias
95327750dc Final abs. profit should not be doubled in rpc messages 2022-08-04 07:07:54 +02:00
robcaulk
eae82d0222 fix bug with database url during backtesting. comment out example trade db analysis. 2022-08-03 16:17:57 +02:00
robcaulk
95d3009a95 give user ability to analyze live trade dataframe inside custom prediction model. Add documentation to explain new functionality 2022-08-02 20:14:02 +02:00
Matthias
9df10c6b5b Merge pull request #7155 from freqtrade/dependabot/pip/develop/scipy-1.9.0
Bump scipy from 1.8.1 to 1.9.0
2022-08-01 19:54:20 +02:00
Matthias
ae0d6f63fa Version bump ccxt to 1.91.55
closes #7151
2022-08-01 19:43:13 +02:00
Matthias
87e5460aed Merge pull request #7157 from freqtrade/dependabot/pip/develop/types-requests-2.28.6
Bump types-requests from 2.28.3 to 2.28.6
2022-08-01 09:46:34 +02:00
Matthias
895ebbfd18 Exclude aarch64 from catboost requirements 2022-08-01 07:34:27 +00:00
Matthias
694bea133b Merge pull request #7156 from freqtrade/dependabot/pip/develop/flake8-5.0.1
Bump flake8 from 4.0.1 to 5.0.1
2022-08-01 08:39:06 +02:00
Matthias
3b90bdf980 Merge pull request #7160 from freqtrade/dependabot/pip/develop/jsonschema-4.9.0
Bump jsonschema from 4.7.2 to 4.9.0
2022-08-01 07:02:30 +02:00
Matthias
d75e0a9820 Fix Flake8 errors after flake update 2022-08-01 06:43:59 +02:00
Matthias
707a4e7c9e types-requests bump pre-commit 2022-08-01 06:41:08 +02:00
dependabot[bot]
f3154a4313 Bump jsonschema from 4.7.2 to 4.9.0
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.7.2 to 4.9.0.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.7.2...v4.9.0)

---
updated-dependencies:
- dependency-name: jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 04:35:30 +00:00
Matthias
e9b7e1e600 Merge pull request #7161 from freqtrade/dependabot/pip/develop/urllib3-1.26.11
Bump urllib3 from 1.26.10 to 1.26.11
2022-08-01 06:34:37 +02:00
Matthias
70dcff3b23 Merge pull request #7154 from freqtrade/dependabot/pip/develop/ccxt-1.91.52
Bump ccxt from 1.91.29 to 1.91.52
2022-08-01 06:34:16 +02:00
Matthias
dce16909b4 Merge pull request #7162 from freqtrade/dependabot/github_actions/develop/pypa/gh-action-pypi-publish-1.5.1
Bump pypa/gh-action-pypi-publish from 1.5.0 to 1.5.1
2022-08-01 06:33:52 +02:00
Matthias
f82724bbc1 Merge pull request #7158 from freqtrade/dependabot/pip/develop/orjson-3.7.11
Bump orjson from 3.7.8 to 3.7.11
2022-08-01 06:33:34 +02:00
robcaulk
3013282dbf remove non-catboost stuff from schema 2022-08-01 05:39:38 +02:00
dependabot[bot]
97064a9ce3 Bump pypa/gh-action-pypi-publish from 1.5.0 to 1.5.1
Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.5.0...v1.5.1)

---
updated-dependencies:
- dependency-name: pypa/gh-action-pypi-publish
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:13:38 +00:00
dependabot[bot]
79b650258e Bump urllib3 from 1.26.10 to 1.26.11
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.10 to 1.26.11.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/1.26.11/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.10...1.26.11)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:02:02 +00:00
dependabot[bot]
ed230dd750 Bump orjson from 3.7.8 to 3.7.11
Bumps [orjson](https://github.com/ijl/orjson) from 3.7.8 to 3.7.11.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.7.8...3.7.11)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:01:52 +00:00
dependabot[bot]
372be54252 Bump types-requests from 2.28.3 to 2.28.6
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.3 to 2.28.6.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:01:46 +00:00
dependabot[bot]
b4ded59c63 Bump flake8 from 4.0.1 to 5.0.1
Bumps [flake8](https://github.com/pycqa/flake8) from 4.0.1 to 5.0.1.
- [Release notes](https://github.com/pycqa/flake8/releases)
- [Commits](https://github.com/pycqa/flake8/compare/4.0.1...5.0.1)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:01:43 +00:00
dependabot[bot]
a75fa26caf Bump scipy from 1.8.1 to 1.9.0
Bumps [scipy](https://github.com/scipy/scipy) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.8.1...v1.9.0)

---
updated-dependencies:
- dependency-name: scipy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:01:38 +00:00
dependabot[bot]
7a696f58f9 Bump ccxt from 1.91.29 to 1.91.52
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.91.29 to 1.91.52.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.91.29...1.91.52)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-01 03:01:30 +00:00
robcaulk
946d4c7cfc fix trailing whitespace for flake8 2022-07-31 18:39:46 +02:00
robcaulk
4e68626bcb ensure convolutional window is prepended for frequi consistency 2022-07-31 17:51:19 +02:00
robcaulk
d830105605 *BREAKING CHANGE* remove unnecessary arguments from populate_any_indicators(), accommodate tests 2022-07-31 17:05:29 +02:00
robcaulk
153336d424 move corr_pairlist expansion to after expand_pairlist() 2022-07-31 15:45:28 +02:00
Matthias
659870312d Use JSON Schema validation for freaAI schema validation 2022-07-31 15:23:27 +02:00
Matthias
cbb05354a8 Add install variant for freqai 2022-07-31 15:10:01 +02:00
Kavinkumar
a4bada3ebe Partial exit using average price (#6545)
Introduce Partial exits
2022-07-31 14:19:04 +02:00
robcaulk
61693f6c8b fix tests after changing config_example file 2022-07-31 13:20:11 +02:00
robcaulk
e6ebc0443e make single generalized config for freqai. update docs to reflect that. 2022-07-31 13:08:43 +02:00
Matthias
369c6da5d8 Merge pull request #7146 from freqtrade/fix/liquidation
Update liquidation price handling
2022-07-31 08:09:54 +02:00
Matthias
15424169ad Merge pull request #7108 from rzrymiak/develop
Added description heading to README.md
2022-07-31 07:10:37 +02:00
rzrymiak
09e5fb2f55 Removed description header 2022-07-30 22:37:46 +00:00
Robert Caulk
c2eaa3d2cd add image of algorithmic overview to doc 2022-07-30 18:51:00 +02:00
Matthias
bad15f077c Simplify fetch_positions by using already existing method 2022-07-30 17:49:06 +02:00
Matthias
dc82675f00 Add Test for liquidation in stop-loss-reached 2022-07-30 17:28:19 +02:00
Matthias
fc31c890e3 Merge pull request #7135 from freqtrade/rpc/sendmsg
Strategy allow rpc messages
2022-07-30 16:15:00 +02:00
Matthias
d046f0cc5e Improve method wording for liquidation price setter 2022-07-30 16:11:31 +02:00
Matthias
dba7a7257d Use stop_or_liquidation instead of stop_loss 2022-07-30 16:10:16 +02:00
Matthias
845cecd38f Add stoploss or liquidation property 2022-07-30 16:10:16 +02:00
Matthias
4da96bc511 Update docs 2022-07-30 16:10:16 +02:00
Matthias
15752ce3c2 Rename set_stoploss method to be fully private 2022-07-30 16:10:16 +02:00
Matthias
ff4cc5d316 Revamp liquidation test to actually make sense 2022-07-30 16:10:16 +02:00
Matthias
9852733ef7 Improve tests to align with modified logic 2022-07-30 16:10:16 +02:00
Matthias
f57ecb1861 Simplify adjust_stop test 2022-07-30 16:10:16 +02:00
Matthias
8711b7d99f Liquidations cannot be rejected. 2022-07-30 16:10:16 +02:00
Matthias
995be90f91 Liquidation should be a separate exit type 2022-07-30 16:10:16 +02:00
robcaulk
dd8288c090 expose full parameter set for SVM outlier detection. Set default shuffle to false to improve reproducibility 2022-07-30 13:40:05 +02:00
Matthias
d70650b074 Add note for plot-dataframe and current-whitelist
closes #7142
2022-07-30 08:20:22 +02:00
robcaulk
f22b140782 fix backtesting bug, undo move of label stat calc, fix example strat exit logic 2022-07-29 17:27:35 +02:00
robcaulk
08d3ac7ef8 add keras and conv_width to schema and documentation 2022-07-29 08:49:35 +02:00
robcaulk
59624181bd isort BaseRegressionModel imports 2022-07-29 08:23:44 +02:00
robcaulk
c84d54b35e Fix typing issue, avoid using .get() when unnecessary, convert to fstrings 2022-07-29 08:12:50 +02:00
Matthias
efbd83c56d Small type and typo fixes in freqai_interface 2022-07-28 07:24:30 +02:00
Matthias
a2a0d35a24 Update missing typehints 2022-07-28 07:07:40 +02:00
Matthias
3273881282 Merge branch 'develop' into feat/freqai 2022-07-28 06:36:38 +02:00
Matthias
cc3ead9d7b Set required_profit for stoploss guard, allowing to ignore small stoplosses.
closes #7076
2022-07-27 19:52:39 +02:00
Matthias
f31106dc61 Minor comment fixes 2022-07-27 07:27:24 +02:00
Matthias
31ddec8348 Add missing test to confirm backtesting won't send messages 2022-07-27 06:51:56 +02:00
Matthias
2595e40e47 Remove unused test-strategy 2022-07-27 06:47:16 +02:00
Matthias
0adfa4d9ef Add tests for dataprovider send-message methods 2022-07-27 06:34:15 +02:00
Matthias
7bac054668 Add documentation and clarity for send_msg 2022-07-26 20:24:52 +02:00
Matthias
229e8864bb Add send_msg capability to dataprovider 2022-07-26 20:15:49 +02:00
Matthias
bc760b7eb2 Simplify small segment in datadrawer 2022-07-26 19:41:49 +02:00
Matthias
a0b9388757 Bump ccxt to 1.91.29
closes #7132
2022-07-26 17:57:25 +02:00
robcaulk
324e54c015 fix possible memory leak associated with Catboost Pool object 2022-07-26 17:29:29 +02:00
robcaulk
3f149c4067 fix return type in BaseTensorFlowModel 2022-07-26 16:01:54 +02:00
robcaulk
ad25a4cb56 reduce number of pair_dict lookups, remove coin_first 2022-07-26 15:58:40 +02:00
robcaulk
fb4e8430cd isort auto import sorting 2022-07-26 10:51:39 +02:00
robcaulk
e213d0ad55 isolate data_drawer functions from data_kitchen, accommodate tests, add new test 2022-07-26 10:24:14 +02:00
robcaulk
56b17e6f3c allow user to pass test_size = 0 and avoid using eval sets in prediction models 2022-07-25 19:40:13 +02:00
Matthias
4c68bec171 Fix problem in is_cancel_order_result_suitable
fixes #7119
2022-07-25 17:47:52 +02:00
Matthias
ea112fb583 Add test for empty order (cancelled order) 2022-07-25 17:47:28 +02:00
robcaulk
55cf378ec2 remove leftover breakpoint from test file 2022-07-25 17:13:24 +02:00
Robert Caulk
897f18a8c8 ensure proper integer type casting for timestamps. Add check test for backtesting subdaily time periods 2022-07-25 15:07:09 +02:00
Robert Caulk
7b105532d1 fix mypy error and add test for principal component analysis 2022-07-25 11:46:59 +02:00
Robert Caulk
4abc26b582 add test for follow_mode 2022-07-25 10:48:04 +02:00
Robert Caulk
c9d46a5237 finish bringing follow_mode up to date 2022-07-25 09:24:40 +02:00
Matthias
0806f253b1 Merge pull request #7125 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.19
Bump types-python-dateutil from 2.8.18 to 2.8.19
2022-07-25 08:43:58 +02:00
Matthias
4b8132f3c6 Merge pull request #7128 from freqtrade/dependabot/pip/develop/mypy-0.971
Bump mypy from 0.961 to 0.971
2022-07-25 08:42:16 +02:00
Matthias
47b52d4bab Bump types-dateutil in pre-commit 2022-07-25 07:58:16 +02:00
dependabot[bot]
40969f20bf Bump types-python-dateutil from 2.8.18 to 2.8.19
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.18 to 2.8.19.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 05:53:15 +00:00
dependabot[bot]
93340f546b Bump mypy from 0.961 to 0.971
Bumps [mypy](https://github.com/python/mypy) from 0.961 to 0.971.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.961...v0.971)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 05:53:10 +00:00
Matthias
b7f5beea40 Merge pull request #7124 from freqtrade/dependabot/pip/develop/mkdocs-1.3.1
Bump mkdocs from 1.3.0 to 1.3.1
2022-07-25 07:52:38 +02:00
Matthias
c0080f2241 Merge pull request #7126 from freqtrade/dependabot/pip/develop/types-requests-2.28.3
Bump types-requests from 2.28.1 to 2.28.3
2022-07-25 07:52:16 +02:00
Matthias
43343d0e55 Revert markdown to 3.3.7 2022-07-25 07:21:12 +02:00
Matthias
3ce46ff09e Bump types-requests in pre-commit 2022-07-25 07:19:21 +02:00
Matthias
fba3c3c649 Merge pull request #7127 from freqtrade/dependabot/pip/develop/ccxt-1.91.22
Bump ccxt from 1.90.89 to 1.91.22
2022-07-25 07:17:14 +02:00
Matthias
bc87171243 Merge pull request #7123 from freqtrade/dependabot/pip/develop/orjson-3.7.8
Bump orjson from 3.7.7 to 3.7.8
2022-07-25 07:17:00 +02:00
dependabot[bot]
f93a3a5fca Bump ccxt from 1.90.89 to 1.91.22
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.90.89 to 1.91.22.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.90.89...1.91.22)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 03:01:52 +00:00
dependabot[bot]
98d0ad76bf Bump types-requests from 2.28.1 to 2.28.3
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.1 to 2.28.3.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 03:01:44 +00:00
dependabot[bot]
d5933fb2af Bump mkdocs from 1.3.0 to 1.3.1
Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/mkdocs/mkdocs/releases)
- [Commits](https://github.com/mkdocs/mkdocs/compare/1.3.0...1.3.1)

---
updated-dependencies:
- dependency-name: mkdocs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 03:01:37 +00:00
dependabot[bot]
1b49e45222 Bump orjson from 3.7.7 to 3.7.8
Bumps [orjson](https://github.com/ijl/orjson) from 3.7.7 to 3.7.8.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.7.7...3.7.8)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-25 03:01:32 +00:00
Robert Caulk
ab587747fb first fix for follower path bug 2022-07-24 23:32:24 +02:00
Matthias
520ee3f7a1 Convert freqAI into packages 2022-07-24 17:07:45 +02:00
Matthias
1885deb632 More docstring changes 2022-07-24 16:54:39 +02:00
Matthias
70b7a254af Update some areas to use default docstring formatting 2022-07-24 16:51:48 +02:00
Matthias
61c41fd919 Merge branch 'develop' into feat/freqai 2022-07-24 16:18:58 +02:00
Matthias
83cac7bee2 Improve some more tests by adding proper orders 2022-07-24 10:51:13 +02:00
Matthias
6e691a016d Use leverage-tiers loading in tests 2022-07-24 10:24:59 +02:00
Robert Caulk
88e10f7306 add exception for not passing timerange. Remove hard coded arguments for CatboostPredictionModels. Update docs 2022-07-24 09:01:23 +02:00
Robert Caulk
fff39eff9e fix multitarget bug 2022-07-24 08:42:50 +02:00
Matthias
95f5218ceb Reenable Catboost test (#7118)
* Reenable Catboost test

* Simplify freqAI tests, ensure they use a tempdir for modelstorage
2022-07-24 07:32:13 +02:00
Matthias
2eb1d18c2a Don't load leverage tiers when not necessary 2022-07-23 19:56:38 +02:00
robcaulk
f3d46613ee move prediction denormalization into datakitchen. remove duplicate associated code. avoid normalization/denormalization for string dtypes. 2022-07-23 17:14:33 +02:00
Matthias
81c1aa3c13 Update imports in freqAI sample strategies 2022-07-23 17:08:05 +02:00
Matthias
8a3cffcd1b Remove remaining CustomModel references 2022-07-23 17:08:05 +02:00
Matthias
62f7606d2c Update tests to new variant 2022-07-23 17:08:05 +02:00
Matthias
8fa6e8b4ba Remove freqAI model bridge in favor of self.freqai 2022-07-23 17:08:05 +02:00
robcaulk
c91e23dc50 let user avoid normalizing labels 2022-07-23 16:14:13 +02:00
Matthias
7682c9ace7 Update trade_close test to include orders 2022-07-23 15:27:52 +02:00
Matthias
24a786bedd Update rpc test to contain sell order 2022-07-23 15:23:24 +02:00
Matthias
80845807e1 Improve some test resiliance 2022-07-23 15:14:38 +02:00
Matthias
a02d02ac12 Enhance protections tests to have orders in mock trade 2022-07-23 14:43:52 +02:00
robcaulk
50d630a155 remove unnecessary comments from data_drawer.py 2022-07-23 13:35:44 +02:00
robcaulk
a1cff377ec add record of contribution to data_kitchen.py 2022-07-23 13:32:04 +02:00
robcaulk
c2d6a0e891 add record of contribution to doc and source 2022-07-23 13:04:06 +02:00
robcaulk
3acc869570 improve the dataframe key description, update outdated parts of doc 2022-07-23 12:42:24 +02:00
Matthias
5c4f60f376 Improve configuration table formatting and ordering 2022-07-23 09:11:22 +02:00
Matthias
e97468964a Add support for --timeframe-detail in hyperopt
fix #7070
2022-07-23 08:52:03 +02:00
Matthias
36dc9be7aa Update some docs wording 2022-07-22 20:27:25 +02:00
Matthias
32c3f62934 Fix documentation typo
closes #7115
2022-07-22 19:45:50 +02:00
robcaulk
5559e605b8 small PR conversation resolutions 2022-07-22 17:46:14 +02:00
robcaulk
40f00196eb use cloudpickle in place of pickle. define Paths once in data_drawer. 2022-07-22 17:37:51 +02:00
robcaulk
accc629e32 set separate table sections in doc 2022-07-22 12:44:43 +02:00
robcaulk
98c8a447b2 add LightGBMPredictionMultiModel 2022-07-22 12:40:51 +02:00
robcaulk
afcb0bec00 clean up obsolete comments, move remove_features_from_df to datakitchen 2022-07-22 12:29:20 +02:00
Matthias
0b21750e76 Reorder advanced topics 2022-07-22 07:22:06 +02:00
robcaulk
ac0f484918 add freqai logo to top of doc 2022-07-22 00:02:07 +02:00
robcaulk
3205788bce extend doc to include descriptions of the return values from FreqAI to the strategy 2022-07-21 22:11:46 +02:00
robcaulk
8033e0bf23 add counter to backtesting log so users know how many more pairs and how many more models will need to be trained 2022-07-21 13:22:12 +02:00
robcaulk
183dec866a remove ability to backtest open ended timeranges (safer) 2022-07-21 13:02:52 +02:00
robcaulk
e694ea1cfd make sure backtesting gets the populated indicators with slimmed down user strat 2022-07-21 12:48:09 +02:00
robcaulk
ca4dd58642 remove superceded function from datakitchen 2022-07-21 12:40:54 +02:00
robcaulk
8f86b0deaa *breaking change* simplify user strat by consolidating feature loops into backend 2022-07-21 12:24:22 +02:00
robcaulk
e7337728bf add separator in folder name just incase an asset ends in an integer 2022-07-21 11:25:28 +02:00
robcaulk
c9a6dc88a1 add parameter list/discriptions to doc 2022-07-21 11:11:36 +02:00
Matthias
6c5e48dd4f dev-dependencies should include freqAI 2022-07-21 07:26:44 +02:00
robcaulk
a99c126266 help windows builds pass freqai tests. Add freqai to README.md 2022-07-20 16:14:19 +02:00
robcaulk
4e5d60fdc9 match scikit-learn version to hyperopt required version 2022-07-20 15:54:22 +02:00
robcaulk
921a7ef216 add requirements-freqai.txt to builds 2022-07-20 15:51:25 +02:00
robcaulk
286bd0c40b follow string for adding a strat to tests/strategy/strats 2022-07-20 15:00:02 +02:00
robcaulk
c43935e82a create dedicated minimal freqai test strat 2022-07-20 14:39:28 +02:00
robcaulk
88d769d801 comment out problematic catboost test 2022-07-20 14:18:06 +02:00
robcaulk
d43c146676 add more tests for datakitchen functionalities, add regression tests for freqai_interface train/backtest 2022-07-20 12:56:46 +02:00
Matthias
78f77f6d35 Merge pull request #7101 from freqtrade/dependabot/pip/develop/markdown-3.4.1
Bump markdown from 3.3.7 to 3.4.1
2022-07-20 06:48:28 +02:00
rzrymiak
ac2e8d760e Added description heading to README.md 2022-07-19 14:24:44 -07:00
Matthias
b609dbcd86 Update mdx_truly_sane_lists to be compatible with markdown again 2022-07-19 19:51:03 +02:00
lolong
9c051958a6 Feat/freqai (#7105)
Vectorize weight setting, log training dates

Co-authored-by: robcaulk <rob.caulk@gmail.com>
2022-07-19 17:49:18 +02:00
robcaulk
714d9534b6 start adding tests 2022-07-19 16:16:44 +02:00
Matthias
75e190ff1d Update sell-test without filled buy order 2022-07-19 07:20:36 +02:00
lolong
ed0f8b1189 Improve FreqAI documentation (#7072)
Improve doc + some other small fixes

Co-authored-by: robcaulk <rob.caulk@gmail.com>
2022-07-18 11:57:52 +02:00
Matthias
99d5fbc9c0 Merge pull request #7102 from freqtrade/dependabot/pip/develop/types-requests-2.28.1
Bump types-requests from 2.28.0 to 2.28.1
2022-07-18 08:38:35 +02:00
Matthias
0daa9d3e57 Bump types-requests in pre-commit 2022-07-18 07:56:41 +02:00
Matthias
7365d23db8 Merge pull request #7099 from freqtrade/dependabot/pip/develop/fastapi-0.79.0
Bump fastapi from 0.78.0 to 0.79.0
2022-07-18 07:55:29 +02:00
Matthias
df538f9cd6 Merge pull request #7097 from freqtrade/dependabot/pip/develop/jsonschema-4.7.2
Bump jsonschema from 4.6.2 to 4.7.2
2022-07-18 07:54:55 +02:00
Matthias
9d261c88e6 Merge pull request #7098 from freqtrade/dependabot/pip/develop/pytest-asyncio-0.19.0
Bump pytest-asyncio from 0.18.3 to 0.19.0
2022-07-18 07:54:31 +02:00
Matthias
8a1c95247d Merge pull request #7100 from freqtrade/dependabot/pip/develop/ccxt-1.90.89
Bump ccxt from 1.90.88 to 1.90.89
2022-07-18 07:53:52 +02:00
dependabot[bot]
ea523136fc Bump types-requests from 2.28.0 to 2.28.1
Bumps [types-requests](https://github.com/python/typeshed) from 2.28.0 to 2.28.1.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 03:01:49 +00:00
dependabot[bot]
d2ef248781 Bump markdown from 3.3.7 to 3.4.1
Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.3.7 to 3.4.1.
- [Release notes](https://github.com/Python-Markdown/markdown/releases)
- [Commits](https://github.com/Python-Markdown/markdown/compare/3.3.7...3.4.1)

---
updated-dependencies:
- dependency-name: markdown
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 03:01:43 +00:00
dependabot[bot]
f07ad7aa87 Bump ccxt from 1.90.88 to 1.90.89
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.90.88 to 1.90.89.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.90.88...1.90.89)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 03:01:40 +00:00
dependabot[bot]
cb63d5e3df Bump fastapi from 0.78.0 to 0.79.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.78.0 to 0.79.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.78.0...0.79.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 03:01:31 +00:00
dependabot[bot]
5f820ab0a6 Bump pytest-asyncio from 0.18.3 to 0.19.0
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.18.3 to 0.19.0.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Changelog](https://github.com/pytest-dev/pytest-asyncio/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.18.3...v0.19.0)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 03:01:26 +00:00
dependabot[bot]
2c6fb617a6 Bump jsonschema from 4.6.2 to 4.7.2
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.6.2 to 4.7.2.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.6.2...v4.7.2)

---
updated-dependencies:
- dependency-name: jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-18 03:01:23 +00:00
Robert Caulk
921f3899f0 revert pickle reading for historic predictions 2022-07-17 16:06:36 +02:00
Robert Caulk
41eeb99177 load pickle file for writing 2022-07-17 10:05:21 +02:00
Matthias
46be1b8778 Version bump ccxt to 1.90.88 2022-07-17 07:21:42 +02:00
Matthias
05a5ae4fcf Update plotting to use entry/exit terminology 2022-07-16 22:28:46 +02:00
Robert Caulk
9d184586f1 fix bug in historic prediction saving 2022-07-16 21:16:59 +02:00
Matthias
9347677c60 Uppdate pricecontours test to not recreate backtesting every loop
in hopes to fix random failure
2022-07-16 19:33:26 +02:00
Matthias
3bb4f2c7c2 Merge pull request #6780 from samgermain/dry-taker-or-maker
Dry run taker or maker fees
2022-07-16 18:15:02 +02:00
Matthias
f6bfd89cef Merge branch 'develop' into feat/freqai 2022-07-16 18:14:34 +02:00
Matthias
423af371c0 Simplify calculation by calling "get_fee" only once 2022-07-16 17:59:05 +02:00
Matthias
4172f92bfc simplify dry-run taker/maker selection 2022-07-16 17:25:13 +02:00
Matthias
8b2535a8da Update Typing for fees 2022-07-16 15:42:17 +02:00
Matthias
8d2e22f009 Merge branch 'develop' into pr/samgermain/6780 2022-07-16 15:35:00 +02:00
Matthias
004bf31142 Merge pull request #7093 from freqtrade/fix/gate_futures_stoposs
gateio futures - several fixes
2022-07-16 15:18:32 +02:00
Matthias
3eb2131d0b Merge pull request #7092 from freqtrade/fix/hyperopt_inherit
hyperopt inherit fix
2022-07-16 15:17:14 +02:00
Matthias
bf07d8fe87 Update test to properly patch/mock exchange 2022-07-16 13:57:12 +02:00
Matthias
357000c478 Extract exchange validation to separate method 2022-07-16 13:45:26 +02:00
Matthias
d03dfb3934 Oder cost is real cost (including leverage) 2022-07-16 13:14:21 +02:00
Matthias
ed64e4299b Stoploss orders should also be eligible to update closed fees 2022-07-16 13:14:21 +02:00
Matthias
415780a4fe gateio order cost is not in contracts
closes #7081
2022-07-16 13:14:21 +02:00
Matthias
7b8a5585dd Fetch 2ndary stoploss order once the order triggered. 2022-07-16 13:14:21 +02:00
Matthias
7c4dd4c48c Support fee cost as string
closes #7056
2022-07-16 13:14:21 +02:00
Matthias
40e2da10f3 Add hypeorpt cloudpickle magic
closes #7078
2022-07-16 11:49:33 +02:00
Matthias
e53e530874 Add test showing broken inheritance hyperopt 2022-07-16 11:49:33 +02:00
Matthias
2e642593e5 Update formatting of hyperopt_conf fixture 2022-07-16 11:47:32 +02:00
Matthias
29efe75a6f Update hyperoptable strategy to use V3 interface 2022-07-16 11:47:32 +02:00
Matthias
1c7f60103d Don't use master for publish CI action 2022-07-15 20:26:24 +02:00
Robert Caulk
4ef2ed2f1b Merge pull request #7085 from wagnercosta/feat/freqai
freqai: fix issue when bot restarts with same identifier, does not load predi…
2022-07-15 20:00:53 +02:00
Matthias
fada432f49 Pin markdown docs dependency 2022-07-15 19:48:12 +02:00
Matthias
b657a4df23 Improve hyperopt docs
part of #7088
2022-07-15 19:02:23 +02:00
Wagner Costa Santos
ca2029a46b fix issue when bot restarts with same identifier, does not load prediction history 2022-07-14 18:55:24 -03:00
Matthias
cdc58058d7 Add candletype to notebook example
closes #7084, closes #7073
2022-07-14 19:40:26 +02:00
robcaulk
4141d165ff add BaseTensorFlowModel class 2022-07-12 19:10:09 +02:00
robcaulk
ef409dd345 Add ground work for TensorFlow models, add protections from common mistakes 2022-07-12 18:09:17 +02:00
Robert Caulk
fea63fba12 Fix saving/loading historic predictions 2022-07-12 10:12:50 +02:00
Robert Caulk
8ce6b18318 start collecting indefinite history of predictions. Allow user to generate statistics on these predictions. Direct FreqAI to save these to disk and reload them if available. 2022-07-11 22:01:48 +02:00
Matthias
0669d93f56 Merge pull request #7068 from freqtrade/ccxt_ordertype_validations
Ccxt ordertype validations
2022-07-11 19:41:05 +02:00
Matthias
5c164efdb6 Also check for createLimitOrder as optionals 2022-07-11 16:09:12 +02:00
Matthias
b9ba94d644 Bump ccxt to 1.90.47 2022-07-11 16:07:58 +02:00
Matthias
bf992fd9df Add test for newly added functionality 2022-07-11 14:09:44 +02:00
Matthias
f9d3775d4c Move "candle" logic for message to telegram
this avoids calling this method unless necessary
2022-07-11 14:09:39 +02:00
Matthias
9a3a2f9013 Simplify adding candle to message 2022-07-11 13:55:32 +02:00
Matthias
8e8f026ea7 Telegram candle message should be configurable 2022-07-11 12:14:19 +02:00
Matthias
ed03ef47ef Merge branch 'develop' into pr/SurferAdmin/6916 2022-07-11 11:49:22 +02:00
Matthias
ec3179156c Revert unwanted changes. 2022-07-11 11:48:24 +02:00
Matthias
3fc92b1b21 Create BaseRegression model - designed to reduce code duplication across currently available models. 2022-07-11 11:33:59 +02:00
Matthias
64f89af69e Add Explicit test for "has" checks 2022-07-11 10:43:21 +02:00
Matthias
6ac1aa15f5 Reenable ccxt order checks 2022-07-11 10:36:19 +02:00
Matthias
f8e35d8760 Add TODO to disabled test 2022-07-11 10:30:05 +02:00
Matthias
523d8a84a8 skip "supports market order" for now until CCXT fixes their assignemnt bugs. 2022-07-11 10:22:51 +02:00
Matthias
7d6b3d0e02 Update hyperopt param docs to be clear that non-conclusive parameters will be ignored 2022-07-11 08:17:16 +02:00
Matthias
0600c4d70e Merge pull request #7064 from freqtrade/dependabot/pip/develop/urllib3-1.26.10
Bump urllib3 from 1.26.9 to 1.26.10
2022-07-11 08:16:58 +02:00
Matthias
2bba071b6a Merge pull request #7063 from freqtrade/dependabot/pip/develop/numpy-1.23.1
Bump numpy from 1.23.0 to 1.23.1
2022-07-11 08:16:39 +02:00
Matthias
a4901ae9a7 Merge pull request #7059 from freqtrade/dependabot/pip/develop/pre-commit-2.20.0
Bump pre-commit from 2.19.0 to 2.20.0
2022-07-11 08:16:01 +02:00
Matthias
04ec44edc3 Merge pull request #7065 from freqtrade/dependabot/pip/develop/python-rapidjson-1.8
Bump python-rapidjson from 1.6 to 1.8
2022-07-11 08:15:44 +02:00
Matthias
50d368f3ec Merge pull request #7060 from freqtrade/dependabot/pip/develop/cryptography-37.0.4
Bump cryptography from 37.0.2 to 37.0.4
2022-07-11 08:15:22 +02:00
dependabot[bot]
0bb8c8feba Bump python-rapidjson from 1.6 to 1.8
Bumps [python-rapidjson](https://github.com/python-rapidjson/python-rapidjson) from 1.6 to 1.8.
- [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/v1.6...v1.8)

---
updated-dependencies:
- dependency-name: python-rapidjson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 05:23:01 +00:00
Matthias
9b3032390c Merge pull request #7066 from freqtrade/dependabot/pip/develop/orjson-3.7.7
Bump orjson from 3.7.6 to 3.7.7
2022-07-11 07:22:01 +02:00
dependabot[bot]
c06b524b4e Bump urllib3 from 1.26.9 to 1.26.10
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.9 to 1.26.10.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/1.26.10/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.9...1.26.10)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 05:16:14 +00:00
dependabot[bot]
7c6c2c4d6e Bump cryptography from 37.0.2 to 37.0.4
Bumps [cryptography](https://github.com/pyca/cryptography) from 37.0.2 to 37.0.4.
- [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/37.0.2...37.0.4)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 05:15:38 +00:00
dependabot[bot]
7b998378ce Bump numpy from 1.23.0 to 1.23.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.23.0 to 1.23.1.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.23.0...v1.23.1)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 05:15:37 +00:00
Matthias
2bc78fd045 Merge pull request #7062 from freqtrade/dependabot/pip/develop/jsonschema-4.6.2
Bump jsonschema from 4.6.1 to 4.6.2
2022-07-11 07:15:07 +02:00
dependabot[bot]
fa158ba8de Bump pre-commit from 2.19.0 to 2.20.0
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.19.0 to 2.20.0.
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v2.19.0...v2.20.0)

---
updated-dependencies:
- dependency-name: pre-commit
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 05:14:41 +00:00
Matthias
9d453ffa08 Merge pull request #7061 from freqtrade/dependabot/pip/develop/ccxt-1.90.41
Bump ccxt from 1.90.40 to 1.90.41
2022-07-11 07:14:39 +02:00
Matthias
6aac4f9990 Merge pull request #7058 from freqtrade/dependabot/pip/develop/mkdocs-material-8.3.9
Bump mkdocs-material from 8.3.8 to 8.3.9
2022-07-11 07:13:52 +02:00
Matthias
d5e45d9c43 Merge pull request #7057 from freqtrade/dependabot/pip/develop/pytest-mock-3.8.2
Bump pytest-mock from 3.8.1 to 3.8.2
2022-07-11 07:13:29 +02:00
dependabot[bot]
719fa6f8e1 Bump orjson from 3.7.6 to 3.7.7
Bumps [orjson](https://github.com/ijl/orjson) from 3.7.6 to 3.7.7.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.7.6...3.7.7)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 03:02:39 +00:00
dependabot[bot]
c98786a4f6 Bump jsonschema from 4.6.1 to 4.6.2
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.6.1...v4.6.2)

---
updated-dependencies:
- dependency-name: jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 03:02:17 +00:00
dependabot[bot]
b1d34dba94 Bump ccxt from 1.90.40 to 1.90.41
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.90.40 to 1.90.41.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.90.40...1.90.41)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 03:02:12 +00:00
dependabot[bot]
5070a04a82 Bump mkdocs-material from 8.3.8 to 8.3.9
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.3.8 to 8.3.9.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.3.8...8.3.9)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 03:01:50 +00:00
dependabot[bot]
9086176f73 Bump pytest-mock from 3.8.1 to 3.8.2
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.8.1 to 3.8.2.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.8.1...v3.8.2)

---
updated-dependencies:
- dependency-name: pytest-mock
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 03:01:47 +00:00
Matthias
494e0529d2 Update conftest for leverage tiers 2022-07-10 19:31:14 +02:00
Robert Caulk
607455919e Change config parameter names to improve clarity and consistency throughout the code (!!breaking change, please check discord support channel for migration instructions or review templates/FreqaiExampleStrategy.py config_examples/config_freqai_futures.example.json file changes!!) 2022-07-10 12:35:44 +02:00
Matthias
819cc9c0e4 Fully align LightGBM with Catboost 2022-07-10 11:06:18 +02:00
Matthias
58b18770e3 Fix LightGBM missing argument in predict method 2022-07-10 11:05:35 +02:00
Matthias
9313a2d294 Update leverage tiers to latest version 2022-07-10 10:11:39 +02:00
Matthias
59b0fd1166 Merge pull request #7051 from freqtrade/gateio_fee_fix
Gateio fee fix
2022-07-10 09:45:24 +02:00
Matthias
ea5f41aa6d Version bump ccxt 2022-07-10 09:06:19 +02:00
Matthias
2e1061af64 Fix faulty LightGBM model 2022-07-09 08:21:42 +00:00
Matthias
aab59a8caf Bump ccxt to required version 2022-07-09 09:00:12 +02:00
Matthias
c98e7ea055 Revert allowing empty currency for futures 2022-07-09 08:57:15 +02:00
Matthias
b7167ec880 Fix wrong fee calclulation for gateio futures 2022-07-09 08:51:59 +02:00
Matthias
5b733a723d use "fees" for trades responses 2022-07-09 08:51:28 +02:00
Matthias
81f7d77d74 Allow fee currency to be empty for futures 2022-07-09 08:51:28 +02:00
Matthias
2499276fca Refactor calculate_fee_rate to take separate parameters instead of an "Order"
we passed in a trade object anyway
2022-07-09 08:51:28 +02:00
Matthias
e52f82b565 Add leverage to custom_stake_amount callback
closes #7047
2022-07-08 19:44:20 +02:00
Matthias
b39508f64d remove loadMarkets from "required" section,
it's now implied that all ccxt exchanges provide this method.
2022-07-07 19:44:54 +02:00
robcaulk
d9acdc9767 remove excess, increase no model warning clarity 2022-07-06 18:20:21 +02:00
Matthias
2dc46ca0b8 Add cost to partial test buy order 2022-07-06 07:12:13 +02:00
Matthias
dbc3376fe9 Add alias for gate to gateio 2022-07-06 07:12:13 +02:00
Matthias
da9dac64f2 Merge pull request #7045 from freqtrade/remove_abortion
replace the word "abortion" with "denied" in log messages
2022-07-05 20:41:13 +02:00
robcaulk
514f7d491c change rejected to denied 2022-07-05 12:58:43 +02:00
robcaulk
647f9b5460 replace the word abortion with rejected in log messages 2022-07-05 12:49:09 +02:00
robcaulk
4cac67fd66 Catch infrequent issue associated with grabbing first candle 2022-07-05 12:43:33 +02:00
Matthias
6f0721ae2b Update dry-order-fix to use sqlalchemy internals 2022-07-04 17:17:39 +02:00
Matthias
fe8083c7f8 Improve test for dry-run orderclosing 2022-07-04 17:17:01 +02:00
Matthias
6da3fa08e4 Update migrations to also support Postgres
closes #7038
2022-07-04 11:14:59 +02:00
Matthias
edc9a42a4c Merge pull request #7036 from freqtrade/dependabot/pip/develop/uvicorn-0.18.2
Bump uvicorn from 0.18.1 to 0.18.2
2022-07-04 09:11:37 +02:00
Matthias
14fb499a71 Merge pull request #7033 from freqtrade/dependabot/pip/develop/jsonschema-4.6.1
Bump jsonschema from 4.6.0 to 4.6.1
2022-07-04 09:11:19 +02:00
dependabot[bot]
5820fc3b44 Bump jsonschema from 4.6.0 to 4.6.1
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.6.0 to 4.6.1.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.6.0...v4.6.1)

---
updated-dependencies:
- dependency-name: jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 05:55:44 +00:00
Matthias
fe0a64154d Merge pull request #7037 from freqtrade/dependabot/pip/develop/ccxt-1.89.96
Bump ccxt from 1.89.14 to 1.89.96
2022-07-04 07:54:52 +02:00
Matthias
d993216ec2 Merge pull request #7035 from freqtrade/dependabot/pip/develop/requests-2.28.1
Bump requests from 2.28.0 to 2.28.1
2022-07-04 07:54:36 +02:00
Matthias
f589e13cf2 Merge pull request #7031 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.30
Bump prompt-toolkit from 3.0.29 to 3.0.30
2022-07-04 07:10:06 +02:00
dependabot[bot]
0a8a0c66b4 Bump requests from 2.28.0 to 2.28.1
Bumps [requests](https://github.com/psf/requests) from 2.28.0 to 2.28.1.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.0...v2.28.1)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 05:10:00 +00:00
dependabot[bot]
dd21d963fc Bump ccxt from 1.89.14 to 1.89.96
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.89.14 to 1.89.96.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.89.14...1.89.96)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 05:09:28 +00:00
Matthias
a7fa84f681 Merge pull request #7030 from freqtrade/dependabot/pip/develop/orjson-3.7.6
Bump orjson from 3.7.3 to 3.7.6
2022-07-04 07:09:09 +02:00
Matthias
05e8abb934 Merge pull request #7032 from freqtrade/dependabot/pip/develop/python-telegram-bot-13.13
Bump python-telegram-bot from 13.12 to 13.13
2022-07-04 07:08:22 +02:00
dependabot[bot]
9a8d03b1f5 Bump uvicorn from 0.18.1 to 0.18.2
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.18.1 to 0.18.2.
- [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.18.1...0.18.2)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 03:03:02 +00:00
dependabot[bot]
0555d7783c Bump python-telegram-bot from 13.12 to 13.13
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 13.12 to 13.13.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/v13.13/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v13.12...v13.13)

---
updated-dependencies:
- dependency-name: python-telegram-bot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 03:02:40 +00:00
dependabot[bot]
b16bb23cc8 Bump prompt-toolkit from 3.0.29 to 3.0.30
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.29 to 3.0.30.
- [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.29...3.0.30)

---
updated-dependencies:
- dependency-name: prompt-toolkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 03:02:34 +00:00
dependabot[bot]
92d189a84f Bump orjson from 3.7.3 to 3.7.6
Bumps [orjson](https://github.com/ijl/orjson) from 3.7.3 to 3.7.6.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.7.3...3.7.6)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-04 03:02:30 +00:00
Matthias
eda9464d30 Fix docs test 2022-07-03 19:54:29 +02:00
robcaulk
bd3a6ba2fe update backtesting to handle new output framework 2022-07-03 17:34:44 +02:00
robcaulk
8ac8d53c32 All LGBMRegressor model parameters are now set in config 2022-07-03 16:30:01 +02:00
robcaulk
a6077ac7f4 Merge feat/freqai into develop to get new features 2022-07-03 16:17:13 +02:00
Matthias
07aa372e2a Ensure bot_loop_start is called in hyperopt, too
closes #7001
2022-07-03 14:10:59 +02:00
Matthias
c5e6520fee Reorder methods in freqtradebot 2022-07-03 13:35:26 +02:00
robcaulk
4ff0ef7359 fix bug returning multiple targets for training 2022-07-03 12:15:59 +02:00
Matthias
f2fdc21374 Only use exit_tag if exit_type i exit_signal
closes #7027
2022-07-03 11:07:05 +02:00
Matthias
906c7b92fe Add enhance testcase to show problematic exit_reason behavior 2022-07-03 11:05:15 +02:00
robcaulk
ffb39a5029 black formatting on freqai files 2022-07-03 10:59:38 +02:00
Matthias
df8c9fc4e1 Merge pull request #7005 from freqtrade/dependabot/pip/develop/uvicorn-0.18.1
Bump uvicorn from 0.17.6 to 0.18.1
2022-07-03 07:52:09 +02:00
robcaulk
106131ff0f Rehaul organization of return values 2022-07-02 18:09:38 +02:00
robcaulk
93e1410ed9 first step toward cleaning output and enabling multimodel training per pair 2022-07-01 14:00:30 +02:00
robcaulk
6c7d02cb18 expose nu in the SVM outlier detection via svm_nu in config 2022-06-28 15:12:25 +02:00
Matthias
3c1380fbc6 Merge pull request #7009 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.18
Bump types-python-dateutil from 2.8.17 to 2.8.18
2022-06-28 08:02:33 +02:00
Matthias
86f4077024 update dateutil precommit 2022-06-28 07:37:54 +02:00
dependabot[bot]
f2bc35e058 Bump types-python-dateutil from 2.8.17 to 2.8.18
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.17 to 2.8.18.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 20:06:56 +00:00
Matthias
0a5225695a Merge pull request #7016 from freqtrade/dependabot/pip/develop/types-tabulate-0.8.11
Bump types-tabulate from 0.8.9 to 0.8.11
2022-06-27 22:05:45 +02:00
Matthias
74471e41db update tabulate precommit types 2022-06-27 18:23:00 +02:00
dependabot[bot]
8b1798522c Bump types-tabulate from 0.8.9 to 0.8.11
Bumps [types-tabulate](https://github.com/python/typeshed) from 0.8.9 to 0.8.11.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-tabulate
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 13:18:58 +00:00
Matthias
7de7425e24 Merge pull request #7007 from freqtrade/dependabot/pip/develop/time-machine-2.7.1
Bump time-machine from 2.7.0 to 2.7.1
2022-06-27 15:18:23 +02:00
Matthias
37dff8dc82 Merge pull request #7018 from freqtrade/dependabot/pip/develop/types-requests-2.28.0
Bump types-requests from 2.27.30 to 2.28.0
2022-06-27 15:17:57 +02:00
Matthias
0c69a08863 update requests precommit 2022-06-27 12:09:27 +02:00
dependabot[bot]
f6e058a327 Bump types-requests from 2.27.30 to 2.28.0
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.30 to 2.28.0.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 09:59:19 +00:00
dependabot[bot]
d60127a6d8 Bump time-machine from 2.7.0 to 2.7.1
Bumps [time-machine](https://github.com/adamchainz/time-machine) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/adamchainz/time-machine/releases)
- [Changelog](https://github.com/adamchainz/time-machine/blob/main/HISTORY.rst)
- [Commits](https://github.com/adamchainz/time-machine/compare/2.7.0...2.7.1)

---
updated-dependencies:
- dependency-name: time-machine
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 09:59:07 +00:00
Matthias
11a8151653 Merge pull request #7012 from freqtrade/dependabot/pip/develop/types-cachetools-5.2.1
Bump types-cachetools from 5.0.2 to 5.2.1
2022-06-27 11:54:43 +02:00
Matthias
e3abaaa1b7 Merge pull request #7019 from freqtrade/dependabot/pip/develop/pandas-1.4.3
Bump pandas from 1.4.2 to 1.4.3
2022-06-27 11:54:06 +02:00
robcaulk
7dfbd432d1 fix config saving bug, assign priorities to pairs in scanning, sleep the scanning loop to reduce CPU usage 2022-06-27 11:35:33 +02:00
dependabot[bot]
82ef97af7e Bump pandas from 1.4.2 to 1.4.3
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/main/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v1.4.2...v1.4.3)

---
updated-dependencies:
- dependency-name: pandas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 07:44:33 +00:00
Matthias
74fdda6846 Merge pull request #7017 from freqtrade/dependabot/pip/develop/ccxt-1.89.14
Bump ccxt from 1.88.15 to 1.89.14
2022-06-27 09:43:29 +02:00
Matthias
9eaf0400fa Merge pull request #7020 from freqtrade/dependabot/pip/develop/orjson-3.7.3
Bump orjson from 3.7.2 to 3.7.3
2022-06-27 09:10:46 +02:00
Matthias
01185ab483 update cachetools precommit 2022-06-27 07:59:26 +02:00
Matthias
8405bf767b Merge pull request #7006 from freqtrade/dependabot/pip/develop/pytest-mock-3.8.1
Bump pytest-mock from 3.7.0 to 3.8.1
2022-06-27 07:43:55 +02:00
dependabot[bot]
9a9d1a8974 Bump orjson from 3.7.2 to 3.7.3
Bumps [orjson](https://github.com/ijl/orjson) from 3.7.2 to 3.7.3.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.7.2...3.7.3)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 05:39:04 +00:00
dependabot[bot]
0ef2c812db Bump ccxt from 1.88.15 to 1.89.14
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.88.15 to 1.89.14.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.88.15...1.89.14)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 05:38:31 +00:00
Matthias
85d1b433bc Merge pull request #7013 from freqtrade/dependabot/pip/develop/tabulate-0.8.10
Bump tabulate from 0.8.9 to 0.8.10
2022-06-27 07:38:20 +02:00
Matthias
d8f616cf35 Merge pull request #7011 from freqtrade/dependabot/pip/develop/plotly-5.9.0
Bump plotly from 5.8.2 to 5.9.0
2022-06-27 07:37:33 +02:00
Matthias
870c25c81f Merge pull request #7010 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.39
Bump sqlalchemy from 1.4.37 to 1.4.39
2022-06-27 07:37:00 +02:00
Matthias
fb3bc189b5 Merge pull request #7008 from freqtrade/dependabot/pip/develop/mkdocs-material-8.3.8
Bump mkdocs-material from 8.3.6 to 8.3.8
2022-06-27 07:36:08 +02:00
dependabot[bot]
6510c8d330 Bump tabulate from 0.8.9 to 0.8.10
Bumps [tabulate](https://github.com/astanin/python-tabulate) from 0.8.9 to 0.8.10.
- [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.9...v0.8.10)

---
updated-dependencies:
- dependency-name: tabulate
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 03:03:00 +00:00
dependabot[bot]
efee148e43 Bump types-cachetools from 5.0.2 to 5.2.1
Bumps [types-cachetools](https://github.com/python/typeshed) from 5.0.2 to 5.2.1.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-cachetools
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 03:02:53 +00:00
dependabot[bot]
8b7dc031f7 Bump plotly from 5.8.2 to 5.9.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.8.2 to 5.9.0.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v5.8.2...v5.9.0)

---
updated-dependencies:
- dependency-name: plotly
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 03:02:51 +00:00
dependabot[bot]
963f38a690 Bump sqlalchemy from 1.4.37 to 1.4.39
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.37 to 1.4.39.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 03:02:46 +00:00
dependabot[bot]
45db2347dc Bump mkdocs-material from 8.3.6 to 8.3.8
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.3.6 to 8.3.8.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.3.6...8.3.8)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 03:02:29 +00:00
dependabot[bot]
4840c7d2fd Bump pytest-mock from 3.7.0 to 3.8.1
Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.7.0 to 3.8.1.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.7.0...v3.8.1)

---
updated-dependencies:
- dependency-name: pytest-mock
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 03:02:16 +00:00
dependabot[bot]
92dbb0d366 Bump uvicorn from 0.17.6 to 0.18.1
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.17.6 to 0.18.1.
- [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.17.6...0.18.1)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-27 03:02:07 +00:00
robcaulk
68bafa9517 archive config to the model folder, filter out features before returning dataframe to strategy (to alleviate frequi issues)` 2022-06-26 23:03:48 +02:00
robcaulk
051b99791d reduce unnecessary verbosity, fix error on first training sweep, add LightGBMPredictionModel 2022-06-26 19:04:23 +02:00
Matthias
b5d0bc997d Clarify stoploss behavior when not defining offset
closes #6828
2022-06-24 17:25:33 +02:00
Matthias
ca88ea50c5 Merge pull request #6859 from mkavinkumar1/get
Removed None in dict.get()
2022-06-23 21:45:13 +02:00
Matthias
2b07d34611 Revert several undesired changes 2022-06-23 20:47:51 +02:00
Matthias
8bf0bf10c5 Merge branch 'develop' into pr/SmartManoj/6859 2022-06-23 20:43:35 +02:00
Matthias
ddc355feb6 Bump numpy from 1.22.4 to 1.23.0 2022-06-23 08:07:22 +00:00
Matthias
90feccf33c slightly update custom dockerfile with add. comment
closes #6994
2022-06-23 07:17:24 +02:00
Surfer
06571e99aa Merge branch 'freqtrade:develop' into develop 2022-06-22 09:38:23 -04:00
Matthias
53e5483daa Store StopPrice for dry-run orders
closes #6996
2022-06-22 06:31:51 +02:00
Surfer
cc4e5b26f0 Merge branch 'freqtrade:develop' into develop 2022-06-21 14:16:03 -04:00
Surfer Admin
e2a94d75b4 Merge branch 'develop' of https://github.com/Surfableio/freqtrade into develop 2022-06-21 14:06:56 -04:00
Surfer Admin
405ea74f16 stopPrice 2022-06-21 14:06:41 -04:00
Matthias
3a0f31fe89 Merge pull request #6914 from freqtrade/leverage_tiers_async
Leverage tiers async
2022-06-21 10:18:40 +02:00
Robert Caulk
852706cd6b Fix default behavior for expiration_hours 2022-06-21 08:12:51 +02:00
Matthias
eebd624baf Merge pull request #6988 from freqtrade/dependabot/pip/develop/mkdocs-material-8.3.6
Bump mkdocs-material from 8.3.4 to 8.3.6
2022-06-20 09:44:14 +02:00
dependabot[bot]
15fac746a8 Bump mkdocs-material from 8.3.4 to 8.3.6
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.3.4 to 8.3.6.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.3.4...8.3.6)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 06:59:58 +00:00
Matthias
7756c11454 Merge pull request #6991 from freqtrade/dependabot/pip/develop/ccxt-1.88.15
Bump ccxt from 1.87.12 to 1.88.15
2022-06-20 08:59:16 +02:00
Matthias
5e8bfb576b Merge pull request #6989 from freqtrade/dependabot/pip/develop/types-cachetools-5.0.2
Bump types-cachetools from 5.0.1 to 5.0.2
2022-06-20 08:07:06 +02:00
Matthias
3189b284c0 Fix tests condition 2022-06-20 08:04:34 +02:00
Matthias
165755fb33 Merge pull request #6990 from freqtrade/dependabot/pip/develop/colorama-0.4.5
Bump colorama from 0.4.4 to 0.4.5
2022-06-20 08:02:25 +02:00
Matthias
1cd2b0504a Run regular tests for 3.9 under other ubuntu systems 2022-06-20 07:15:15 +02:00
dependabot[bot]
e1e3a903f9 Bump ccxt from 1.87.12 to 1.88.15
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.87.12 to 1.88.15.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.87.12...1.88.15)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 05:07:35 +00:00
dependabot[bot]
996372b8f6 Bump colorama from 0.4.4 to 0.4.5
Bumps [colorama](https://github.com/tartley/colorama) from 0.4.4 to 0.4.5.
- [Release notes](https://github.com/tartley/colorama/releases)
- [Changelog](https://github.com/tartley/colorama/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tartley/colorama/compare/0.4.4...0.4.5)

---
updated-dependencies:
- dependency-name: colorama
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 05:06:39 +00:00
Matthias
50c19ece53 Fix ccxt test gateio flukyness 2022-06-20 07:05:51 +02:00
Matthias
f9668ede4a Fix CI Syntax error 2022-06-20 07:02:12 +02:00
Matthias
0804fc7a3a CI should run ccxt tests only once 2022-06-20 07:01:35 +02:00
Matthias
55fb7656df Update pre-commit cachetools 2022-06-20 06:58:41 +02:00
dependabot[bot]
8406010260 Bump types-cachetools from 5.0.1 to 5.0.2
Bumps [types-cachetools](https://github.com/python/typeshed) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-cachetools
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-20 03:01:26 +00:00
robcaulk
b35c64b6c0 fix bug in backtest, typo in example strat 2022-06-19 16:41:09 +02:00
Matthias
0d967f93ba Improve performance of some RPC calls
These don't need orders to be loaded. As a side-effect, this will
also reduce the strain on the database.
2022-06-19 16:13:04 +02:00
Matthias
0809f9aef6 Add offset to trade response 2022-06-18 19:27:05 +02:00
Matthias
bb61250bfe Merge pull request #6987 from freqtrade/profit_metrics
Profit metrics
2022-06-18 17:20:20 +02:00
Matthias
0168343b76 Add trading-volume to api schema 2022-06-18 16:53:25 +02:00
Matthias
474e6705e6 Add Profit factor to backtesting 2022-06-18 16:35:40 +02:00
Matthias
53bfa7931d Add rudimentary test for prior bug
Test fails without the fix in 8c46d19071
2022-06-18 16:32:22 +02:00
Matthias
8c46d19071 Fix backtesting bug
balance was never released on cancelled trades
2022-06-18 16:27:54 +02:00
robcaulk
3599d18ff6 fix bug in follow_mode, thanks @blood4rc 2022-06-18 12:05:28 +02:00
Matthias
b7e4dea6c5 Document new Profit metrics 2022-06-18 11:43:50 +02:00
Matthias
40c9abc7e1 Add trading volume to /profit output 2022-06-18 11:40:32 +02:00
Matthias
6a15d36d14 Add Drawdown and profit_factor to /profit
#6816
2022-06-18 11:14:28 +02:00
Matthias
d77ce468ea Add "dry" hint to buy/sell messages
part of #6962
2022-06-18 09:40:53 +02:00
Matthias
03815cb81b Use fstrings in telegram messaging 2022-06-18 09:23:16 +02:00
Matthias
d62273294d Update /help for /fx to align with actual command name
closes #6985
2022-06-18 09:10:33 +02:00
Matthias
017fd03180 Fix but with late entries in backtesting 2022-06-18 09:05:22 +02:00
Matthias
616bf315cb gateio: futures market orders require IOC to be set. 2022-06-17 23:02:39 +02:00
Matthias
fda8248d41 Gateio allow market orders on futures markets 2022-06-17 22:43:24 +02:00
robcaulk
6da7a98857 add docstrings to new functions, remove superceded code 2022-06-17 16:16:23 +02:00
robcaulk
5e914d5756 improve model youth by constantly scanning pairs in dry/live and always training new models. Fix bug in DI return values 2022-06-17 16:06:51 +02:00
robcaulk
f631ae911b add model expiration feature, fix bug in DI return values 2022-06-17 14:55:40 +02:00
Matthias
6bdf9c2a94 Simplify trade profit calculations further 2022-06-17 11:17:05 +00:00
Matthias
91f9818ae3 Simplify trade calculations 2022-06-17 09:53:29 +00:00
Matthias
d7770c507b Remove implicit use of certain rates in profit calculations 2022-06-17 07:00:42 +00:00
Matthias
76cae8e8e3 Update tests to always provide rate to profit calculations 2022-06-17 06:55:31 +00:00
Matthias
575b4ead1a Update Test with funding_fee 0 2022-06-17 06:29:17 +00:00
Matthias
14a859c190 Improve some documentation around futures / leverage 2022-06-16 19:50:13 +02:00
Matthias
61040c9f8e Fix freqAI dockerfile not running freqai code ... 2022-06-16 19:35:16 +02:00
robcaulk
0b0688a91e ensure scanning purges models 2022-06-16 16:12:38 +02:00
Matthias
121edc3e42 Add freqAI docker file 2022-06-16 12:36:15 +00:00
Surfer
36f7315481 Merge branch 'freqtrade:develop' into develop 2022-06-16 08:19:57 -04:00
robcaulk
c5de0c49e4 first functional scanning commit 2022-06-16 00:24:18 +02:00
robcaulk
4d472a0ea1 merging datarehaul into scanning branch 2022-06-16 00:22:49 +02:00
Matthias
8f32fa5cb3 Avoid exception on exchange recycling if __init__ fails 2022-06-15 20:13:07 +02:00
Matthias
f9e2e87346 Improve some formatting and typehints 2022-06-15 20:03:36 +02:00
Matthias
ec40e79362 Merge pull request #6874 from froggleston/buy_reasons
Buy reasons
2022-06-15 19:06:00 +02:00
Matthias
e2e6c790be Minor doc update 2022-06-15 16:50:25 +02:00
froggleston
4a5ed5a273 Fix tests 2022-06-15 11:48:57 +01:00
froggleston
14110bd5ca Merge branch 'buy_reasons' of github.com:froggleston/freqtrade into buy_reasons 2022-06-15 11:25:24 +01:00
froggleston
c391ca08de Change backtesting-analysis options to space separated lists 2022-06-15 11:25:06 +01:00
Matthias
29d8aeb9b3 Don't fail on invalid parameter 2022-06-15 07:13:47 +02:00
Matthias
3c62df6b86 Ensure the same timestamp is used for backtest and signal export 2022-06-15 06:53:52 +02:00
froggleston
6bb342f23a Add export-filename support 2022-06-14 16:54:27 +01:00
Matthias
01a68e1060 Remove unnecessary check and condition 2022-06-13 20:48:49 +02:00
Matthias
1ffee96bad Fix protection parameters not loading from parameter file
closes #6978
2022-06-13 19:59:05 +02:00
Matthias
d5fd1f9c38 Improve order filled handling 2022-06-13 13:24:48 +00:00
Matthias
848a5d85c6 Add small stability fix to test 2022-06-13 13:24:48 +00:00
Matthias
d7901132b8 Merge pull request #6973 from freqtrade/dependabot/pip/develop/plotly-5.8.2
Bump plotly from 5.8.0 to 5.8.2
2022-06-13 10:52:15 +02:00
Matthias
dca639cf26 Merge pull request #6970 from freqtrade/dependabot/pip/develop/pymdown-extensions-9.5
Bump pymdown-extensions from 9.4 to 9.5
2022-06-13 10:03:11 +02:00
Matthias
11603e70c9 Merge pull request #6972 from freqtrade/dependabot/pip/develop/orjson-3.7.2
Bump orjson from 3.7.1 to 3.7.2
2022-06-13 10:02:55 +02:00
dependabot[bot]
35adeb6412 Bump plotly from 5.8.0 to 5.8.2
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.8.0 to 5.8.2.
- [Release notes](https://github.com/plotly/plotly.py/releases)
- [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.py/compare/v5.8.0...v5.8.2)

---
updated-dependencies:
- dependency-name: plotly
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 07:33:30 +00:00
dependabot[bot]
850f5d3842 Bump orjson from 3.7.1 to 3.7.2
Bumps [orjson](https://github.com/ijl/orjson) from 3.7.1 to 3.7.2.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.7.1...3.7.2)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 07:32:39 +00:00
Matthias
9923462907 Merge pull request #6971 from freqtrade/dependabot/pip/develop/requests-2.28.0
Bump requests from 2.27.1 to 2.28.0
2022-06-13 09:32:03 +02:00
Matthias
46a214e41a Merge pull request #6969 from freqtrade/dependabot/pip/develop/mypy-0.961
Bump mypy from 0.960 to 0.961
2022-06-13 09:31:51 +02:00
dependabot[bot]
fdca583c67 Bump pymdown-extensions from 9.4 to 9.5
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.4 to 9.5.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.4...9.5)

---
updated-dependencies:
- dependency-name: pymdown-extensions
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 07:07:39 +00:00
Matthias
29c38e0623 Merge pull request #6968 from freqtrade/dependabot/pip/develop/mkdocs-material-8.3.4
Bump mkdocs-material from 8.3.2 to 8.3.4
2022-06-13 09:07:02 +02:00
Matthias
a56ee4ee94 Merge pull request #6976 from freqtrade/dependabot/pip/develop/ccxt-1.87.12
Bump ccxt from 1.85.57 to 1.87.12
2022-06-13 09:06:46 +02:00
dependabot[bot]
cb2f89bca6 Bump requests from 2.27.1 to 2.28.0
Bumps [requests](https://github.com/psf/requests) from 2.27.1 to 2.28.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.27.1...v2.28.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 06:26:23 +00:00
dependabot[bot]
43b8b0a083 Bump mypy from 0.960 to 0.961
Bumps [mypy](https://github.com/python/mypy) from 0.960 to 0.961.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.960...v0.961)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 06:25:53 +00:00
dependabot[bot]
71f314d4c4 Bump ccxt from 1.85.57 to 1.87.12
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.85.57 to 1.87.12.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.85.57...1.87.12)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 06:25:35 +00:00
dependabot[bot]
ee0b9e3a5c Bump mkdocs-material from 8.3.2 to 8.3.4
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.3.2 to 8.3.4.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.3.2...8.3.4)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 06:25:18 +00:00
Matthias
5e4b3882e6 Merge pull request #6974 from freqtrade/dependabot/pip/develop/types-filelock-3.2.7
Bump types-filelock from 3.2.6 to 3.2.7
2022-06-13 08:25:10 +02:00
Matthias
4030a5df8e Merge pull request #6975 from freqtrade/dependabot/github_actions/develop/actions/setup-python-4
Bump actions/setup-python from 3 to 4
2022-06-13 08:24:20 +02:00
Matthias
e67d29cd2f Update more trades to use create_mock_trades 2022-06-13 07:17:13 +02:00
dependabot[bot]
70966c8a8f Bump actions/setup-python from 3 to 4
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 3 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 05:08:12 +00:00
Matthias
8fd245c28b Update pre-commit filelocktypes 2022-06-13 06:58:06 +02:00
Matthias
43c871f2f4 Use time-machine to stabilize time-sensitive tests 2022-06-13 06:49:31 +02:00
Matthias
390e600f55 Update statistics output 2022-06-13 06:46:34 +02:00
dependabot[bot]
40c7caac16 Bump types-filelock from 3.2.6 to 3.2.7
Bumps [types-filelock](https://github.com/python/typeshed) from 3.2.6 to 3.2.7.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-filelock
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-13 03:01:53 +00:00
Matthias
7619fd08d6 Update telegram tests to use mock_trades 2022-06-12 19:41:28 +02:00
Matthias
dff83ef620 Update telegram profit test to USDT 2022-06-12 17:30:01 +02:00
Matthias
56652c2b39 Improve test resiliance 2022-06-12 17:09:47 +02:00
Matthias
c981ad4608 Fix missing space 2022-06-12 08:31:02 +02:00
Matthias
75a248cf42 Fstring freqAI sample strategy, remove duplicate features 2022-06-11 19:56:37 +02:00
Matthias
2e1ed132f7 Merge pull request #6964 from freqtrade/rpc_rel_daily
Telegram / api daily relative profit
2022-06-11 19:31:32 +02:00
Matthias
c9761f4736 FreqUI should be installed by default when running setup.sh 2022-06-11 18:02:03 +02:00
Matthias
9c65fad73f Merge Pull request #6919 into develop 2022-06-11 17:49:32 +02:00
Matthias
4b70e03daa Add some rudimentary tsts for discord webhook integration 2022-06-11 17:49:23 +02:00
Matthias
fdfa94bcc3 make discord notifications fully configurable. 2022-06-11 17:43:46 +02:00
Matthias
f816c15e1e Update discord message format 2022-06-11 16:48:28 +02:00
Matthias
3a06337601 Update API to provide new values. 2022-06-11 11:28:45 +02:00
Matthias
9ba11f7bcc Update docs and tests for new daily command 2022-06-11 11:26:49 +02:00
Matthias
76827b31a9 Add relative profit to daily/weekly commands 2022-06-11 11:18:21 +02:00
Matthias
0a801c0223 Simplify daily RPC test 2022-06-11 08:58:36 +02:00
Matthias
1a5c3c587d Simplify weekly/monthly tests, convert to usdt 2022-06-11 08:53:37 +02:00
Matthias
ab6a306e07 Update daily test to USDT 2022-06-11 08:31:59 +02:00
Matthias
2c7c5f9a6e Update mock_usdt trade method 2022-06-10 20:47:52 +02:00
robcaulk
eb47c74096 merge datarehaul into main freqai branch 2022-06-10 20:26:19 +02:00
Matthias
76f87377ba Reduce decimals on FIAT daily column 2022-06-10 20:18:53 +02:00
Matthias
e8f8cd9d36 Merge pull request #6960 from italodamato/opt-ask-force-new-points
remove `random_state` condition when sampling random points
2022-06-10 19:45:36 +02:00
Italo
7142394121 remove random_state condition
otherwise the random sample always draws the same set of points
2022-06-10 09:46:45 +01:00
Matthias
ad3c01736e time aggregate to only query for data necessary
improves the query by not creating a full trade object.
2022-06-10 07:26:53 +02:00
Matthias
2218313f5c Merge pull request #6957 from freqtrade/rpc_consolidate_daily
Rpc consolidate daily
2022-06-10 06:39:59 +02:00
Matthias
2e67e2f911 Merge pull request #6958 from italodamato/opt-ask-force-new-points
don't overwrite is_random
2022-06-10 06:37:03 +02:00
Italo
dce9fdd0e4 don't overwrite is_random
this should fix issue #6746
2022-06-09 20:06:23 +01:00
Matthias
8fb743b91d improve variable wording 2022-06-09 20:13:26 +02:00
Matthias
dd32127014 Merge pull request #6944 from gaugau3000/develop
give extra info on rate origin for confirm_trade_*
2022-06-09 20:10:29 +02:00
Matthias
3c2ba99fc4 Improve sql cheatsheet docs 2022-06-09 19:57:56 +02:00
Matthias
a9c7ad8a0f Add warning about sqlite disabled foreign keys 2022-06-09 19:51:21 +02:00
Matthias
1ddd5f1901 Update docstring throughout the bot. 2022-06-09 19:41:08 +02:00
Matthias
88f8cbe172 Update tests to reflect new naming 2022-06-09 19:38:18 +02:00
Matthias
b211a5156f Add test for strategy_wrapper lazy loading 2022-06-09 19:36:15 +02:00
Matthias
a547001601 Reduce Telegram "unit" stats 2022-06-09 07:06:32 +02:00
Matthias
d4dd026310 Consolidate monthly stats to common method 2022-06-09 07:06:32 +02:00
Matthias
3cb15a2a54 Combine weekly and daily profit methods 2022-06-09 07:06:32 +02:00
Matthias
c550cd8b0d Simplify query in freqtradebot 2022-06-09 07:04:46 +02:00
Matthias
6a7ffd5483 Merge pull request #6952 from freqtrade/dependabot/docker/python-3.10.5-slim-bullseye
Bump python from 3.10.4-slim-bullseye to 3.10.5-slim-bullseye
2022-06-09 06:27:59 +02:00
dependabot[bot]
d265b8adb6 Bump python from 3.10.4-slim-bullseye to 3.10.5-slim-bullseye
Bumps python from 3.10.4-slim-bullseye to 3.10.5-slim-bullseye.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-09 03:01:48 +00:00
Matthias
7eacb847b0 Fix backtesting bug when order is not replaced 2022-06-08 20:21:45 +02:00
gautier pialat
ac40ae89b9 give extra info on rate origin for confirm_trade_*
Documentation :
Take into consideration the market buy/sell rates use case for the confirm_trade_entry and confirm_trade_exit callback function
2022-06-08 00:20:33 +02:00
Matthias
381d64833d version-bump ccxt 2022-06-07 21:05:31 +02:00
robcaulk
d9b79d94e4 increase candle update flexibility to allow long sequential trainings that may last more than one candle 2022-06-07 20:57:10 +02:00
robcaulk
66800c7a45 ensure newest candles are always appended 2022-06-07 20:24:23 +02:00
robcaulk
f8f25e36ef update example config/strat 2022-06-07 19:54:45 +02:00
robcaulk
15d049cffe detect if upper tf candles are new or not, append if so. Correct the epoch for candle update check 2022-06-07 19:49:20 +02:00
Matthias
ca281c5722 Merge pull request #6943 from freqtrade/cancel_outdated_orders
Cancel orders which can no longer be found after several days
2022-06-07 18:05:15 +02:00
Matthias
9534d6cca1 Cancel orders which can no longer be found after several days 2022-06-07 07:03:40 +02:00
robcaulk
cab8f517b4 add lock to datadrawer 2022-06-07 01:07:30 +02:00
robcaulk
4b26b6aaec add lock to any historic data access 2022-06-07 00:54:18 +02:00
Robert Caulk
3c2e314ee5 Fix bugs 2022-06-06 16:26:07 -06:00
Robert Caulk
e6c5e737a2 Fix other bugs 2022-06-06 16:24:32 -06:00
Robert Caulk
bf19055e53 Update function spelling 2022-06-06 15:56:12 -06:00
Robert Caulk
2451ed8c88 Quick bug fix 2022-06-06 15:11:54 -06:00
Matthias
5007024f63 Merge pull request #6940 from freqtrade/bt_orders
Open orders should also be shown in the UI
2022-06-06 13:44:21 +02:00
Matthias
de79192432 Merge pull request #6941 from freqtrade/ci/concurrency
Update CI to use github actions builtin concurrency
2022-06-06 13:36:55 +02:00
Matthias
057be50941 Remove old concurrency method 2022-06-06 11:11:47 +02:00
Matthias
4eb6e80b4f Merge pull request #6936 from freqtrade/dependabot/pip/develop/jsonschema-4.6.0
Bump jsonschema from 4.5.1 to 4.6.0
2022-06-06 11:03:40 +02:00
Matthias
c00a7b65af Merge pull request #6937 from freqtrade/dependabot/pip/develop/types-requests-2.27.30
Bump types-requests from 2.27.29 to 2.27.30
2022-06-06 11:00:40 +02:00
Matthias
0b806af487 Add orders column to btresult 2022-06-06 10:59:10 +02:00
Matthias
82c5a6b29d Update CI to use concurrency 2022-06-06 10:57:33 +02:00
Matthias
ea9b68badd Add updating freqtrade to updating desc 2022-06-06 10:54:26 +02:00
Matthias
99f6c75c40 Bump types-requests precommit 2022-06-06 10:22:19 +02:00
Matthias
e2948857bf Merge pull request #6938 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.37
Bump sqlalchemy from 1.4.36 to 1.4.37
2022-06-06 10:21:38 +02:00
Matthias
767de555a6 Merge pull request #6934 from freqtrade/dependabot/pip/develop/filelock-3.7.1
Bump filelock from 3.7.0 to 3.7.1
2022-06-06 10:20:50 +02:00
Matthias
73043f2ccc Merge pull request #6933 from freqtrade/dependabot/pip/develop/orjson-3.7.1
Bump orjson from 3.6.8 to 3.7.1
2022-06-06 10:20:35 +02:00
Matthias
55cda53325 Merge pull request #6935 from freqtrade/dependabot/pip/develop/mkdocs-material-8.3.2
Bump mkdocs-material from 8.2.16 to 8.3.2
2022-06-06 10:20:08 +02:00
Matthias
a96dce0f8f Merge pull request #6939 from freqtrade/dependabot/pip/develop/ccxt-1.84.97
Bump ccxt from 1.84.39 to 1.84.97
2022-06-06 10:19:48 +02:00
dependabot[bot]
05922e9ebc Bump ccxt from 1.84.39 to 1.84.97
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.84.39 to 1.84.97.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.84.39...1.84.97)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 03:02:15 +00:00
dependabot[bot]
4affa75ff5 Bump sqlalchemy from 1.4.36 to 1.4.37
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.36 to 1.4.37.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 03:02:07 +00:00
dependabot[bot]
963dc0221c Bump types-requests from 2.27.29 to 2.27.30
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.29 to 2.27.30.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 03:01:59 +00:00
dependabot[bot]
35316ec068 Bump jsonschema from 4.5.1 to 4.6.0
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.5.1 to 4.6.0.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.5.1...v4.6.0)

---
updated-dependencies:
- dependency-name: jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 03:01:55 +00:00
dependabot[bot]
6547f3aadb Bump mkdocs-material from 8.2.16 to 8.3.2
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.16 to 8.3.2.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.16...8.3.2)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 03:01:52 +00:00
dependabot[bot]
04cb49b7e4 Bump filelock from 3.7.0 to 3.7.1
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.7.0 to 3.7.1.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.7.0...3.7.1)

---
updated-dependencies:
- dependency-name: filelock
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 03:01:48 +00:00
dependabot[bot]
786bc36163 Bump orjson from 3.6.8 to 3.7.1
Bumps [orjson](https://github.com/ijl/orjson) from 3.6.8 to 3.7.1.
- [Release notes](https://github.com/ijl/orjson/releases)
- [Changelog](https://github.com/ijl/orjson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ijl/orjson/compare/3.6.8...3.7.1)

---
updated-dependencies:
- dependency-name: orjson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-06 03:01:44 +00:00
Matthias
79107fd062 Add minimal order object serialization 2022-06-05 22:12:27 +02:00
Matthias
8369d5bedd Include open orders in json responses 2022-06-05 22:12:27 +02:00
Matthias
c0ff554d5b Cleanup old, left open dry-run orders 2022-06-05 22:12:27 +02:00
Matthias
f709222943 Properly close out orders in backtesting 2022-06-05 22:12:27 +02:00
Matthias
c499bb051f Allow empty unfilledtimeout for webserver mode 2022-06-05 19:41:17 +02:00
Matthias
a790bad1e4 Add entry_tag to leverage callback
closes #6929
2022-06-05 10:24:54 +02:00
Matthias
27bea580d4 Fix rest-client script's force_enter
closes #6927
2022-06-05 09:40:04 +02:00
robcaulk
d6b8801f41 fix follower bug 2022-06-05 04:40:58 +02:00
robcaulk
e8c0dcf9f3 add debug message to timerange 2022-06-03 17:14:07 +02:00
robcaulk
f2762e3b4b fix bug in return_values() 2022-06-03 16:58:51 +02:00
robcaulk
16b4a5b71f rehaul of backend data management - increasing performance by holding history in memory, reducing load on the ratelimit by only pinging exchange once per candle. Improve code readability. 2022-06-03 15:19:46 +02:00
robcaulk
15a971346d catch infinity values when filtering 2022-06-02 17:13:20 +02:00
Robert Caulk
7d41542f93 process_only_new_candles in examplestrat should be True, thanks @Bloodhunter4rc 2022-06-02 07:24:08 -06:00
robcaulk
fea39254d9 fix custom_exit (thanks @paranoidandy) 2022-06-02 14:58:45 +02:00
robcaulk
b37c31cc21 fix ta-lib issue with simultaneous method access 2022-06-02 14:37:40 +02:00
robcaulk
4ac6ef2972 make defining period intervals more user friendly and flexible 2022-06-02 13:45:29 +02:00
robcaulk
ace951bf7e another queue bug fix for fresh starts 2022-06-02 13:28:06 +02:00
Anuj Shah
eb4adeab4d fix flake8 issues 2022-06-02 11:19:29 +05:30
Anuj Shah
45c47bda60 refactor into discord rpc module 2022-06-01 21:14:48 +05:30
Anuj Shah
afd8e85835 feat: add support for discord notification 2022-06-01 15:54:32 +05:30
robcaulk
833d25bda0 Save data after queue reorg 2022-06-01 08:05:38 +02:00
robcaulk
0b0dd8dd80 Force high priority pair to be trained before anything else. 2022-06-01 07:55:05 +02:00
Surfer Admin
7fe8b7661d Display the signal candle analyzed in telegram. 2022-05-31 15:46:43 -04:00
Matthias
34a44b9dd2 Fix backtesting bug when canceling orders
closes #6911
2022-05-31 20:32:41 +02:00
Matthias
66edbcd3d5 Fix slight backtesting bug in edge-case scenarios 2022-05-31 20:08:34 +02:00
robcaulk
7523ed825e automatically detect maximum required data based on user fed indicators (to avoid NaNs in dataset for rolling indicators), add new config parameter for backtesting to let users increase their startup_candles to accommodate high timeframe indicators, add docs to explain all. Add new feature for automatic indicator duplication according to user defined intervals (exhibited in example strat and configs now). 2022-05-31 18:42:27 +02:00
Matthias
3549176370 Update missleading docstring
closes #6913
2022-05-31 17:52:45 +02:00
Matthias
88845f6d88 Fix cancel order deleting trade
if one order was successfully filled, the trade cannot be deleted.

closes #6907
2022-05-31 17:49:51 +02:00
Matthias
eee337c764 Merge pull request #6906 from freqtrade/params_to_instance
Params to instance
2022-05-31 16:18:48 +02:00
robcaulk
9b3b08a2bb let follower purge old model files 2022-05-31 15:37:38 +02:00
robcaulk
bac4ced382 Ensure follower predictions are persistent and uniquely stored 2022-05-31 14:35:04 +02:00
Matthias
ea537b32c7 Update tests for leverage_tier_loading 2022-05-31 11:40:14 +00:00
robcaulk
70adf55643 Automatically detect and change follower data_path to accommodate remote systems 2022-05-31 12:35:09 +02:00
robcaulk
0306f5ca13 Add autopurge feature so that FreqAI cleans up after itself when it no longer needs old models on disk 2022-05-31 11:58:21 +02:00
Matthias
cce8d1aa4d Update get_market_leverage_tiers to be async 2022-05-31 08:48:34 +00:00
Matthias
be6e0813db Remove --strategy from analysis test 2022-05-31 06:53:03 +02:00
robcaulk
45f4f0f603 ensure follower sends back null arrays in case leader hasnt created a model file yet 2022-05-31 01:48:48 +02:00
robcaulk
29d2f59f12 fix PCA bug 2022-05-31 00:40:45 +02:00
robcaulk
606f18e5c1 Add follow_mode feature so that secondary bots can be launched with the same identifier and load models trained by the leader 2022-05-30 21:35:48 +02:00
Matthias
c285ad0e2b Remove --strategy parameters, update docs 2022-05-30 20:26:24 +02:00
Matthias
d950b0acbe Update documentation about dynamic parameters 2022-05-30 18:18:01 +02:00
robcaulk
5b4c649d43 detect variable sized dataframes coming from strat, adjust our stored/returned data accordingly 2022-05-30 13:55:46 +02:00
robcaulk
e229902381 fix bug in previous commit 2022-05-30 12:48:22 +02:00
robcaulk
a20651efd8 Increase performance by only predicting on most recent candle instead of full strat provided dataframe. Collect predictions and store them so that we can feed true predictions back to strategy (so that frequi isnt updating historic predictions based on newly trained models). 2022-05-30 11:37:05 +02:00
Matthias
d8df9fdccf Merge pull request #6900 from freqtrade/dependabot/pip/develop/types-requests-2.27.29
Bump types-requests from 2.27.27 to 2.27.29
2022-05-30 08:36:39 +02:00
Matthias
8e2c7e1298 extract detect_parameters to separate function 2022-05-30 07:26:26 +02:00
Matthias
f323cbc769 Bump types-requests precommit 2022-05-30 07:23:05 +02:00
Matthias
b73fd0ac69 Merge pull request #6899 from freqtrade/dependabot/pip/develop/mypy-0.960
Bump mypy from 0.950 to 0.960
2022-05-30 07:22:39 +02:00
Matthias
5bf021be2e Enhance hyperoptable strategy to test instance parameters 2022-05-30 07:08:37 +02:00
Matthias
eaa656f859 Hyperoptable parameters can be instance attributes 2022-05-30 07:07:47 +02:00
dependabot[bot]
2b2967f34e Bump types-requests from 2.27.27 to 2.27.29
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.27 to 2.27.29.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 04:54:54 +00:00
Matthias
7962092092 Merge pull request #6897 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.17
Bump types-python-dateutil from 2.8.16 to 2.8.17
2022-05-30 06:54:21 +02:00
Matthias
386d3e0353 Rename stop/roi loading method 2022-05-30 06:52:44 +02:00
Matthias
ad8ff10a05 Minor doc changes 2022-05-30 06:32:46 +02:00
Matthias
41052b4e1e Bump types dateutil precommit 2022-05-30 06:28:03 +02:00
Matthias
8837e1937b Merge pull request #6896 from freqtrade/dependabot/pip/develop/python-telegram-bot-13.12
Bump python-telegram-bot from 13.11 to 13.12
2022-05-30 06:27:25 +02:00
Matthias
d83b204f4b Merge pull request #6901 from freqtrade/dependabot/pip/develop/ccxt-1.84.39
Bump ccxt from 1.83.62 to 1.84.39
2022-05-30 06:25:39 +02:00
Matthias
5d801ff287 Merge pull request #6898 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.16
Bump mkdocs-material from 8.2.15 to 8.2.16
2022-05-30 06:22:16 +02:00
dependabot[bot]
23fa00e29a Bump ccxt from 1.83.62 to 1.84.39
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.83.62 to 1.84.39.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.83.62...1.84.39)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 03:02:26 +00:00
dependabot[bot]
a937f36997 Bump mypy from 0.950 to 0.960
Bumps [mypy](https://github.com/python/mypy) from 0.950 to 0.960.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.950...v0.960)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 03:02:13 +00:00
dependabot[bot]
9366c1d36f Bump mkdocs-material from 8.2.15 to 8.2.16
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.15 to 8.2.16.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.15...8.2.16)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 03:02:03 +00:00
dependabot[bot]
e7c78529e9 Bump types-python-dateutil from 2.8.16 to 2.8.17
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.16 to 2.8.17.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 03:01:58 +00:00
dependabot[bot]
b52fd0b4df Bump python-telegram-bot from 13.11 to 13.12
Bumps [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) from 13.11 to 13.12.
- [Release notes](https://github.com/python-telegram-bot/python-telegram-bot/releases)
- [Changelog](https://github.com/python-telegram-bot/python-telegram-bot/blob/v13.12/CHANGES.rst)
- [Commits](https://github.com/python-telegram-bot/python-telegram-bot/compare/v13.11...v13.12)

---
updated-dependencies:
- dependency-name: python-telegram-bot
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-30 03:01:56 +00:00
robcaulk
2f1a2c1cd7 allow users to store data in custom formats, update spot config to reflect better target horizon to training period ratio 2022-05-30 02:12:31 +02:00
robcaulk
d59eac3321 revert a79032b 2022-05-29 21:33:38 +02:00
Matthias
f65df4901e Update doc clarity 2022-05-29 20:53:09 +02:00
robcaulk
a79032bf75 fixing bug in training queue 2022-05-29 20:19:32 +02:00
Matthias
056047f635 Fix --help 2022-05-29 20:07:02 +02:00
robcaulk
3f72263278 allow pairs deeper in the queue to get trained if the higher priority pairs dont need training 2022-05-29 20:02:43 +02:00
robcaulk
cc6cae47ec allow pairs deeper in the queue to get trained if the higher priority pairs dont need training 2022-05-29 19:49:43 +02:00
robcaulk
4eb4753e20 allow subdaily retraining for backtesting 2022-05-29 17:44:35 +02:00
froggleston
9a068c0b14 Add test for each analysis group, remove default table output if not indicator-list 2022-05-29 16:25:31 +01:00
froggleston
24b02127ec Update docs 2022-05-29 15:42:34 +01:00
Matthias
e6affcc23e Move parameter file loading to hyper-mixin 2022-05-29 16:39:52 +02:00
Matthias
1ee08d22d2 Delay parameter init
closes #6894
2022-05-29 16:39:52 +02:00
robcaulk
0aa7162055 ensure the prediction is reset in the pair_dict after any trade exit, not just custom_exit 2022-05-29 16:36:46 +02:00
robcaulk
fe36b08fce fix key error in example strat 2022-05-29 16:26:34 +02:00
robcaulk
ce365eb9e3 improve example strat so that it has dynamic buy and sell logic according to original prediction 2022-05-29 14:45:46 +02:00
froggleston
df1c36e5aa Change command name, use load_backtest_stats for strategy resolving 2022-05-29 11:54:27 +01:00
froggleston
c59209a01a Merge branch 'buy_reasons' of github.com:froggleston/freqtrade into buy_reasons 2022-05-29 11:20:32 +01:00
froggleston
e7c5818d16 First pass changes for cleaning up 2022-05-29 11:20:11 +01:00
Matthias
a875a7dc40 Use unified stopPrice for binance 2022-05-29 11:01:01 +02:00
Matthias
f64f2b1ad8 Fix /stats Formatting issue in multi-message settings 2022-05-29 10:34:22 +02:00
robcaulk
4eb29c8810 Dont reset pair priority if it doesnt successfully train 2022-05-28 18:34:26 +02:00
robcaulk
83dd453723 catch errors occuring on background thread, and make sure to keep the ball rolling. Improve pair retraining queue. 2022-05-28 18:26:19 +02:00
robcaulk
e54614fa2f remove remnants of single threaded version, ensure pair queue priority is checked before retraining 2022-05-28 14:55:07 +02:00
robcaulk
2a4d1e2d64 fix bug in setting new timerange for retraining 2022-05-28 12:23:26 +02:00
robcaulk
7870a86e9a fix live retraining bug 2022-05-28 11:38:57 +02:00
robcaulk
0bf915054d handle key check correctly 2022-05-28 11:22:32 +02:00
robcaulk
c5a16e91fb throw user error if user tries to load models but feeds the wrong features (while using PCA) 2022-05-28 11:11:41 +02:00
Matthias
3e7bf6a9ef Remove imports in test_strategy2 2022-05-27 19:31:34 +02:00
Matthias
b04fe5d4ee Simplify test v2 strategy 2022-05-27 19:30:14 +02:00
robcaulk
b8f9c3557b dirty dirty, dont look here (hacking a flag to avoid reloading leverage_tiers in dry/live) 2022-05-27 13:56:34 +02:00
robcaulk
891fb87712 give load_cached_data_for_updating the right flags to avoid redownloading data in dry/live 2022-05-27 13:38:22 +02:00
robcaulk
65fdebab75 let load_pairs_histories load futures candles in live 2022-05-27 13:01:33 +02:00
robcaulk
c080571b7a help futures go dry/live with auto download feature 2022-05-27 12:23:32 +02:00
Matthias
24cf044646 Fix bybit spot mode 2022-05-27 08:18:04 +00:00
robcaulk
8a501831d6 fix the error logic on previous commit 2022-05-27 01:15:55 +02:00
robcaulk
23c30dbc10 add error for user trying to backtest with backtest_period<1 2022-05-27 00:43:52 +02:00
robcaulk
6193205012 fix bug for target_mean/std array merging in backtesting 2022-05-26 21:07:50 +02:00
Matthias
43b7955fc2 Fully rely on pathlib 2022-05-26 19:37:55 +02:00
Matthias
682daa4e94 Reset logging mixin to avoid random test failure 2022-05-26 18:05:40 +02:00
froggleston
145faf9817 Use tmpdir for testing 2022-05-26 11:06:38 +01:00
Matthias
da970cca82 Merge pull request #6888 from stash86/patch-1
fix typo
2022-05-26 06:32:44 +02:00
Stefano Ariestasia
e1c6cf5f91 fix typo 2022-05-26 10:12:50 +09:00
Matthias
537d10c627 Improve some typing 2022-05-25 20:43:43 +02:00
Matthias
3e66275c98 Refactor bot_start to separate function
to be reused further ...
2022-05-25 20:01:21 +02:00
Matthias
023f817179 Improve wording for supported futures exchanges 2022-05-25 19:37:32 +02:00
robcaulk
ff531c416f reduce complexity inside start_download_data() in an effort to appease flake8 2022-05-25 15:31:50 +02:00
robcaulk
d79983c791 try to pass flake8 2022-05-25 14:55:19 +02:00
robcaulk
7593339c14 small cleanup 2022-05-25 14:42:46 +02:00
robcaulk
b79d4e8876 Allow user to go live and start from pretrained models (after a completed backtest) by simply reusing the identifier config parameter while dry/live. 2022-05-25 14:40:32 +02:00
robcaulk
7486d9d9e2 proper validation of freqai config parameters 2022-05-25 12:37:25 +02:00
Matthias
b2968df5dc Fix some type problems 2022-05-25 10:13:37 +00:00
robcaulk
7ff3258607 remove assertions, log error if user has not assigned freqai in config, fix stratify bug 2022-05-25 11:43:45 +02:00
robcaulk
35bed842cb cleanup, add clarity to comments and docstrings 2022-05-25 11:31:03 +02:00
froggleston
21e6c14e1e Final test changes 2022-05-25 10:08:03 +01:00
froggleston
f5c2930889 Presume that pytest will call the cleanup call 2022-05-25 09:58:38 +01:00
froggleston
2873ca6d38 Add cleanup, adjust _print_table for indicators, add rsi to test output 2022-05-25 09:57:12 +01:00
Matthias
9e4c68a5b4 Merge pull request #6887 from freqtrade/ci_strategyTemplates
Run CI against strategy templates
2022-05-25 09:13:18 +02:00
Matthias
43f726ba8f Run CI against different templates 2022-05-25 06:34:05 +00:00
froggleston
edd474e663 Another test fix attempt 2022-05-24 21:21:20 +01:00
froggleston
22b9805e47 Fix all tests 2022-05-24 21:04:23 +01:00
froggleston
3adda84b96 Update docs, add test 2022-05-24 20:27:15 +01:00
Matthias
d6773bc32c Merge pull request #6886 from freqtrade/fix/typing
Fix/typing
2022-05-24 19:41:59 +02:00
Matthias
a8ee77cd5e Simplify backtesting typechecking 2022-05-24 19:13:35 +02:00
robcaulk
58b5abbaa6 improve multithreaded training queue system 2022-05-24 15:28:38 +02:00
robcaulk
31ae2b3060 alleviate FutureWarning in sklearn about ensuring svm model features are passed with identical order 2022-05-24 14:46:16 +02:00
froggleston
8c03ebb78f Fix group 0 table, add pathlib.Path use 2022-05-24 12:48:13 +01:00
robcaulk
255d35976e add priority metadata to pairs to avoid a sync of train time + train period 2022-05-24 12:58:53 +02:00
froggleston
80c6190c05 Fix analyze_commands setup 2022-05-24 11:47:26 +01:00
froggleston
ae1ede58da Fix import order 2022-05-24 11:47:26 +01:00
froggleston
a1a09a802b Add analyze_commands 2022-05-24 11:47:25 +01:00
froggleston
9488e8992d First commit for integrating buy_reasons into FT 2022-05-24 11:47:25 +01:00
robcaulk
059c285425 paying closer attention to managing live retraining on separate thread without affecting prediction of other coins on master thread 2022-05-24 12:01:01 +02:00
Matthias
7f3853bbcd Merge pull request #6883 from freqtrade/makeProcessCandlesTrue
Change default value of process_only_new_candles to True since False …
2022-05-24 07:03:14 +02:00
Matthias
904f094b80 Don't reassign method, but implement it properly 2022-05-24 06:59:54 +02:00
Matthias
23e089061b Merge pull request #6870 from freqtrade/should_exit_list
Should exit list
2022-05-24 06:57:50 +02:00
Matthias
0a713faca8 Fix some type errors 2022-05-24 06:54:16 +02:00
Matthias
f1a72e448a Align interfaces and strategy templates 2022-05-24 06:54:16 +02:00
Matthias
3f68c3b68e Update some types 2022-05-24 06:54:16 +02:00
Matthias
502404c0cc Use pyproject.toml instead of setup.cfg 2022-05-24 06:54:16 +02:00
Matthias
7f4161ff78 Add typehints to strategy wrapper 2022-05-24 06:54:16 +02:00
Matthias
07ec3b27fe Add typing information to retrier decorator 2022-05-24 06:54:16 +02:00
robcaulk
b0d2d13eb1 improve data persistence/mapping for live/dry. This accommodates quick reloads after crash and handles multi-pair cleanly 2022-05-23 21:05:05 +02:00
Matthias
42ae8ba6fb Refactor hyperopt parameters to separate file 2022-05-23 20:18:09 +02:00
robcaulk
e1c068ca66 add config asserts, use .get method with default values for optional functionality, move data_cleaning_* to freqai_interface (away from user custom pred model) since it is controlled by config params. 2022-05-23 12:07:09 +02:00
robcaulk
5c4014ee62 Change default value of process_only_new_candles to True since False is an uncommon usecase for expert strategy devs 2022-05-23 10:24:58 +02:00
robcaulk
dede128648 set process_only_new_candles to true in example strat 2022-05-23 10:15:59 +02:00
robcaulk
ee3cdd0ffe more cleanup 2022-05-23 09:55:58 +02:00
Matthias
063fc5174d Merge pull request #6877 from freqtrade/dependabot/pip/develop/types-filelock-3.2.6
Bump types-filelock from 3.2.5 to 3.2.6
2022-05-23 09:20:50 +02:00
Matthias
34b1231df3 Bump filelock-precommit 2022-05-23 08:32:46 +02:00
dependabot[bot]
b88dfe4297 Bump types-filelock from 3.2.5 to 3.2.6
Bumps [types-filelock](https://github.com/python/typeshed) from 3.2.5 to 3.2.6.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-filelock
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 06:32:06 +00:00
Matthias
bb1e1a9680 Merge pull request #6880 from freqtrade/dependabot/pip/develop/scikit-learn-1.1.1
Bump scikit-learn from 1.1.0 to 1.1.1
2022-05-23 08:31:55 +02:00
Matthias
2b79398dba Merge pull request #6879 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.16
Bump types-python-dateutil from 2.8.15 to 2.8.16
2022-05-23 08:31:03 +02:00
Matthias
f6e2c2c0da Merge pull request #6875 from freqtrade/dependabot/pip/develop/ccxt-1.83.62
Bump ccxt from 1.83.12 to 1.83.62
2022-05-23 08:30:42 +02:00
Matthias
cc3ec279c2 Bump dateutil types precommit 2022-05-23 06:57:49 +02:00
Matthias
734803aa44 Merge pull request #6882 from freqtrade/dependabot/pip/develop/types-requests-2.27.27
Bump types-requests from 2.27.25 to 2.27.27
2022-05-23 06:57:08 +02:00
dependabot[bot]
596aeec652 Bump scikit-learn from 1.1.0 to 1.1.1
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/1.1.0...1.1.1)

---
updated-dependencies:
- dependency-name: scikit-learn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 04:33:43 +00:00
Matthias
eb5fe9e3ae Merge pull request #6857 from froggleston/develop
Add support for fudging unavailable funding rates, allowing backtesti…
2022-05-23 06:31:51 +02:00
Matthias
66497c28e8 Bump pre-commit requests types 2022-05-23 06:28:11 +02:00
Matthias
c28cdc3d86 Merge pull request #6878 from freqtrade/dependabot/pip/develop/scipy-1.8.1
Bump scipy from 1.8.0 to 1.8.1
2022-05-23 06:26:55 +02:00
Matthias
8973554595 Merge pull request #6876 from freqtrade/dependabot/pip/develop/psutil-5.9.1
Bump psutil from 5.9.0 to 5.9.1
2022-05-23 06:25:37 +02:00
Matthias
26d5b22974 Merge pull request #6881 from freqtrade/dependabot/pip/develop/numpy-1.22.4
Bump numpy from 1.22.3 to 1.22.4
2022-05-23 06:25:13 +02:00
dependabot[bot]
7f5650699e Bump types-requests from 2.27.25 to 2.27.27
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.25 to 2.27.27.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 03:01:48 +00:00
dependabot[bot]
34657639f8 Bump numpy from 1.22.3 to 1.22.4
Bumps [numpy](https://github.com/numpy/numpy) from 1.22.3 to 1.22.4.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.22.3...v1.22.4)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 03:01:46 +00:00
dependabot[bot]
ff9dcfe789 Bump types-python-dateutil from 2.8.15 to 2.8.16
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.15 to 2.8.16.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 03:01:32 +00:00
dependabot[bot]
40f63ae51c Bump scipy from 1.8.0 to 1.8.1
Bumps [scipy](https://github.com/scipy/scipy) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: scipy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 03:01:30 +00:00
dependabot[bot]
f819fafa1c Bump psutil from 5.9.0 to 5.9.1
Bumps [psutil](https://github.com/giampaolo/psutil) from 5.9.0 to 5.9.1.
- [Release notes](https://github.com/giampaolo/psutil/releases)
- [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst)
- [Commits](https://github.com/giampaolo/psutil/compare/release-5.9.0...release-5.9.1)

---
updated-dependencies:
- dependency-name: psutil
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 03:01:20 +00:00
dependabot[bot]
27019339b5 Bump ccxt from 1.83.12 to 1.83.62
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.83.12 to 1.83.62.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.83.12...1.83.62)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-23 03:01:15 +00:00
robcaulk
3587bd82e1 cleanup superceded code 2022-05-23 00:10:36 +02:00
robcaulk
af0cc21af9 Enable hourly/minute retraining in live/dry. Suppress catboost folder output. Update config + constants + docs to reflect updates. 2022-05-23 00:06:26 +02:00
Matthias
e3beaae8be update hyperopt typing 2022-05-22 19:32:32 +02:00
Matthias
0b5544ef9e Stoploss fill should fill as "filled" notification
Closes #6873
2022-05-22 19:18:12 +02:00
robcaulk
42d95af829 Aggregated commit. Adding support vector machine for outlier detection, improve user interface to dry/live, better standardization, fix various other bugs 2022-05-22 17:51:49 +02:00
Matthias
938a66511a Update Documentation for new confirm_trade_exit behavior 2022-05-22 11:28:11 +02:00
Matthias
3692fcd3d5 Improve exit signal sequence 2022-05-22 11:01:18 +02:00
Matthias
ce3bfd59f5 Add explicit should_sell test 2022-05-22 10:31:29 +02:00
Matthias
b7388557a9 Update interface tests 2022-05-22 10:20:01 +02:00
Matthias
bdb904e714 Should_exit should return all sell signals 2022-05-22 10:17:49 +02:00
Matthias
1315d02437 Fix startup sending "longed" messages for open stoplosses 2022-05-22 09:01:46 +02:00
Matthias
26d394ca74 Add liquidation Price to api response 2022-05-22 08:54:27 +02:00
Matthias
ea8fda0dee Slightly improve test 2022-05-22 08:36:28 +02:00
Matthias
1ff1e3b43d Merge pull request #6869 from freqtrade/update_levtiers
Update leveraged tiers
2022-05-22 08:35:02 +02:00
Matthias
f006978caf Be more explicit in default value 2022-05-21 17:35:49 +02:00
Matthias
681ef13174 Relax dry-run leverage test-case to simplify future updates 2022-05-21 16:23:29 +02:00
Matthias
97abcf4b32 Add documentation for leverage_tiers update 2022-05-21 16:10:00 +02:00
Matthias
963cc17c18 Update leveraged tiers 2022-05-21 16:05:00 +02:00
Matthias
0d388b561b Add test for "combine_funding_and_mark", fix bug 2022-05-21 09:03:30 +02:00
Matthias
2df42a3035 Move "funding fillup" logic to exchange class 2022-05-21 08:50:39 +02:00
Matthias
6bd5535d6c Use exchange method to combine funding and mark candles 2022-05-21 08:31:34 +02:00
Matthias
0e158b66b0 Update docs link 2022-05-21 08:26:44 +02:00
froggleston
c499a92f57 Remove surplus mark columns, and make fillna on funding rate only 2022-05-20 11:48:53 +01:00
Matthias
0138114fc2 Merge pull request #6866 from freqtrade/dry_order_db
Dry orders from db
2022-05-20 12:10:09 +02:00
Matthias
c3e3188c6a Rename variable 2022-05-20 11:30:25 +02:00
Matthias
843bf0631e Remove Sponsored Promotions 2022-05-20 07:14:49 +02:00
Matthias
b3acfb3c6f Bump ccxt to 1.83.12
closes #6849
2022-05-20 06:55:51 +02:00
Matthias
2cf17e04be Init persistence for tests that use dry-run orders 2022-05-20 06:26:16 +02:00
robcaulk
c5ecf94177 move live retraining to separate thread. 2022-05-19 21:15:58 +02:00
Matthias
46ea135b6b Update dry-run considerations 2022-05-19 20:10:11 +02:00
Matthias
219363fffb Check for both ask and bid in SpreadFilter
closes #6865
2022-05-19 19:53:23 +02:00
Matthias
56a73575a1 Add explicit test for order_to_ccxt 2022-05-19 19:29:39 +02:00
robcaulk
1fae6c9ef7 keep model accessible in memory to avoid loading objects from disk during live/dry 2022-05-19 19:27:38 +02:00
robcaulk
67eb94c69d download-data will now check if freqai is active in config, and if so will also download data for corr_pairlist 2022-05-19 17:55:00 +02:00
robcaulk
89eacf2f47 Retrain model if FreqAI found a pretrained model but user strategy is not passing the expected features (user has changed the features in the strategy but has passed a the same config[freqai][identifier]). Logger warning output to user. 2022-05-19 17:15:50 +02:00
Matthias
5e18e51ce0 Fix some tests 2022-05-19 07:03:53 +02:00
Matthias
a3d9384bc0 Remove clean-dry-run code 2022-05-19 06:56:34 +02:00
Matthias
0a95ef6ab2 Don't reset open orders in dry-run on restart 2022-05-19 06:42:38 +02:00
froggleston
363098d32d Fix reversed makr/funding_rate columns 2022-05-18 12:56:43 +01:00
froggleston
736f9f4972 Fix docs and add outer join support for merging funding rates across full timerange 2022-05-18 12:47:37 +01:00
Matthias
d5486f17d8 Update Test to use StrategyV3 2022-05-18 10:57:19 +02:00
மனோஜ்குமார் பழனிச்சாமி
2b61aa282a Removed None in dict.get()
https://stackoverflow.com/a/12631641

Extra Changes: freqtrade\freqtradebot.py:70
freqtrade\plugins\pairlistmanager.py:31
2022-05-18 03:41:10 +05:30
froggleston
c41d4c4f45 Fix leverage docs 2022-05-17 22:37:48 +01:00
froggleston
37e4ede65c Fix flake issues 2022-05-17 22:32:17 +01:00
froggleston
bb758da940 Add support for fudging unavailable funding rates, allowing backtesting of timeranges where futures candles are available, but rates are not 2022-05-17 22:05:33 +01:00
robcaulk
c708dd3186 doc update thanks matthias 2022-05-17 20:46:23 +02:00
Matthias
c81b960791 Fix some typos 2022-05-17 19:58:36 +02:00
robcaulk
db66b82f6f accept open-ended timeranges from user 2022-05-17 19:50:06 +02:00
Matthias
7b9439f2e4 Merge pull request #6854 from eSeR1805/feat_bt_cancel_entry_reporting
BT: Reporting canceled/replaced entry orders
2022-05-17 19:26:44 +02:00
robcaulk
d1d451c27e auto populate features based on a prepended % in the strategy (remove feature assignment from config). Update doc/constants/example strategy to reflect change 2022-05-17 18:15:03 +02:00
robcaulk
8664e8f9a3 create a prediction_models folder where basic prediction models can live (similar to optimize/hyperopt-loss. Update resolver/docs/and gitignore to accommodate change 2022-05-17 17:13:38 +02:00
eSeR1805
34684ec86a Merge branch 'freqtrade:develop' into feat_bt_cancel_entry_reporting 2022-05-17 14:09:57 +03:00
eSeR1805
c6bf6779f8 Update docs BT sample report and details. 2022-05-17 14:09:01 +03:00
eSeR1805
bb7ffd8fbe Update testcases relying on BT results. 2022-05-17 14:08:35 +03:00
eSeR1805
0585b378b3 BT: Report canceled/replaced orders also. 2022-05-17 14:07:42 +03:00
eSeR1805
6e8f24f6a7 BT: track canceled/replaced orders also. 2022-05-17 14:07:02 +03:00
Matthias
8d46e16c46 Merge pull request #6848 from freqtrade/datahandler_case
Datahandler case insensitive
2022-05-17 09:34:11 +02:00
Matthias
1cd8ebc8c8 Merge pull request #6847 from freqtrade/use_Precise
Use precise
2022-05-17 09:33:39 +02:00
Matthias
6fd003c655 Merge pull request #6851 from eSeR1805/feat_bt_cancel_entry_reporting
BT: Reporting canceled trade entries
2022-05-17 07:05:26 +02:00
Matthias
b022680962 Merge pull request #6822 from SmartManoj/patch-10
fixed variable naming style
2022-05-17 06:34:39 +02:00
மனோஜ்குமார் பழனிச்சாமி
7cd0f8a7b1 Merge branch 'develop' into patch-10 2022-05-17 08:07:13 +05:30
eSeR1805
905b24bd4d Update BT report detailing. 2022-05-17 02:04:45 +03:00
eSeR1805
a2a8e4fdc7 Update doc BT sample report. 2022-05-17 02:01:27 +03:00
eSeR1805
99aea454b5 Update testcases to match reporting. 2022-05-17 01:42:48 +03:00
eSeR1805
f2e2e57237 Report trade entries canceled by user. 2022-05-17 01:41:31 +03:00
eSeR1805
fb7c0792c0 Track trade entries canceled by user. 2022-05-17 01:41:01 +03:00
Matthias
76637d3939 Simplify timeframe-transition 2022-05-16 20:10:52 +02:00
Matthias
2e65a1793d Add fallback to load 1M files as well as 1Mo files 2022-05-16 19:48:27 +02:00
Matthias
a1048fb619 Store monthly candles as "Mo" 2022-05-16 19:39:43 +02:00
Matthias
9607d04279 Improve ccxt imports 2022-05-16 19:22:07 +02:00
Matthias
d09b462930 Add rudimentary tests for Precise "builtin operator" workings 2022-05-16 19:21:38 +02:00
Matthias
c8e0fc926d Update to do Builtin Precise math 2022-05-16 19:21:38 +02:00
Matthias
a793cf8f05 Use ccxt's "precise" to do precise math 2022-05-16 19:21:38 +02:00
Matthias
528509f809 Extract get_price_side from get_rate 2022-05-16 19:20:13 +02:00
Matthias
860a15ff40 Merge pull request #6839 from freqtrade/dependabot/pip/develop/plotly-5.8.0
Bump plotly from 5.7.0 to 5.8.0
2022-05-16 19:18:43 +02:00
Matthias
1913565507 Merge pull request #6834 from stash86/patch-1
Missing \n on /help response
2022-05-16 10:39:46 +02:00
Matthias
c54919e4ce Merge pull request #6841 from freqtrade/dependabot/pip/develop/scikit-learn-1.1.0
Bump scikit-learn from 1.0.2 to 1.1.0
2022-05-16 10:02:58 +02:00
Matthias
d6c452a93e Merge pull request #6836 from freqtrade/dependabot/pip/develop/pyjwt-2.4.0
Bump pyjwt from 2.3.0 to 2.4.0
2022-05-16 10:01:59 +02:00
dependabot[bot]
f5183df0f1 Bump scikit-learn from 1.0.2 to 1.1.0
Bumps [scikit-learn](https://github.com/scikit-learn/scikit-learn) from 1.0.2 to 1.1.0.
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/1.0.2...1.1.0)

---
updated-dependencies:
- dependency-name: scikit-learn
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 04:37:41 +00:00
dependabot[bot]
bd65236e17 Bump pyjwt from 2.3.0 to 2.4.0
Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.3.0 to 2.4.0.
- [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.3.0...2.4.0)

---
updated-dependencies:
- dependency-name: pyjwt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 04:37:25 +00:00
Matthias
36d95a3a30 Merge pull request #6843 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.15
Bump mkdocs-material from 8.2.14 to 8.2.15
2022-05-16 06:36:52 +02:00
Matthias
f8e9dc0650 Merge pull request #6840 from freqtrade/dependabot/pip/develop/flake8-tidy-imports-4.8.0
Bump flake8-tidy-imports from 4.7.0 to 4.8.0
2022-05-16 06:36:28 +02:00
Matthias
66621d6723 Merge pull request #6838 from freqtrade/dependabot/pip/develop/fastapi-0.78.0
Bump fastapi from 0.76.0 to 0.78.0
2022-05-16 06:36:09 +02:00
Matthias
f015985062 Merge pull request #6837 from freqtrade/dependabot/pip/develop/time-machine-2.7.0
Bump time-machine from 2.6.0 to 2.7.0
2022-05-16 06:34:41 +02:00
Matthias
f1474cea7a Merge pull request #6842 from freqtrade/dependabot/pip/develop/ccxt-1.82.61
Bump ccxt from 1.81.81 to 1.82.61
2022-05-16 06:33:30 +02:00
Matthias
5c5b9534c1 Merge pull request #6844 from freqtrade/dependabot/pip/develop/filelock-3.7.0
Bump filelock from 3.6.0 to 3.7.0
2022-05-16 06:33:15 +02:00
dependabot[bot]
dd1b84f938 Bump filelock from 3.6.0 to 3.7.0
Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.6.0 to 3.7.0.
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.6.0...3.7.0)

---
updated-dependencies:
- dependency-name: filelock
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 03:02:00 +00:00
dependabot[bot]
a8b4066f85 Bump mkdocs-material from 8.2.14 to 8.2.15
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.14 to 8.2.15.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.14...8.2.15)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 03:01:57 +00:00
dependabot[bot]
9e44d69774 Bump ccxt from 1.81.81 to 1.82.61
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.81.81 to 1.82.61.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.81.81...1.82.61)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 03:01:53 +00:00
dependabot[bot]
9fc21686ed Bump flake8-tidy-imports from 4.7.0 to 4.8.0
Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 4.7.0 to 4.8.0.
- [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases)
- [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/main/HISTORY.rst)
- [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/4.7.0...4.8.0)

---
updated-dependencies:
- dependency-name: flake8-tidy-imports
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 03:01:40 +00:00
dependabot[bot]
748055892c Bump plotly from 5.7.0 to 5.8.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.7.0 to 5.8.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/v5.7.0...v5.8.0)

---
updated-dependencies:
- dependency-name: plotly
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 03:01:33 +00:00
dependabot[bot]
47c116a423 Bump fastapi from 0.76.0 to 0.78.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.76.0 to 0.78.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.76.0...0.78.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 03:01:28 +00:00
dependabot[bot]
4fc6857d87 Bump time-machine from 2.6.0 to 2.7.0
Bumps [time-machine](https://github.com/adamchainz/time-machine) from 2.6.0 to 2.7.0.
- [Release notes](https://github.com/adamchainz/time-machine/releases)
- [Changelog](https://github.com/adamchainz/time-machine/blob/main/HISTORY.rst)
- [Commits](https://github.com/adamchainz/time-machine/compare/2.6.0...2.7.0)

---
updated-dependencies:
- dependency-name: time-machine
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-16 03:01:25 +00:00
Stefano Ariestasia
2cb8eecf18 add space 2022-05-16 07:43:36 +09:00
Stefano Ariestasia
e21f6a7787 missing newline 2022-05-16 07:28:40 +09:00
Stefano Ariestasia
36e514e825 Merge branch 'freqtrade:develop' into patch-1 2022-05-16 07:27:11 +09:00
Matthias
8198bfd997 Merge pull request #6833 from freqtrade/python_310_main_versoin
Python 310 main version
2022-05-15 20:01:19 +02:00
Matthias
008ee14889 Improve ci to run on ubuntu 22.04 2022-05-15 19:29:42 +02:00
Matthias
3d36d35e30 Merge pull request #6825 from freqtrade/okx_history
Okx history
2022-05-15 19:27:45 +02:00
Matthias
86af3fe0e7 Update image versions from 3.9 to 3.10 2022-05-15 19:22:12 +02:00
robcaulk
80dcd88abf allow user to run config from anywhere on their system 2022-05-15 17:42:15 +02:00
robcaulk
9e94d28860 add timerange to backtest commnad 2022-05-15 17:42:15 +02:00
robcaulk
e5759d950b fix typo 2022-05-15 17:42:15 +02:00
robcaulk
f4296173e9 use bash visual in doc 2022-05-15 17:42:15 +02:00
robcaulk
717df891b1 use bash visual in doc 2022-05-15 17:42:15 +02:00
robcaulk
a8022c104a give beta testers more information in the doc 2022-05-15 17:42:15 +02:00
robcaulk
a7029e35b5 ensure informative pairs includes any combination of whitelist - corr_pairlist 2022-05-15 17:42:15 +02:00
robcaulk
9b3e5faebe create more flexible whitelist, avoid duplicating whitelist features into corr_pairlist, update docs 2022-05-15 17:42:15 +02:00
robcaulk
22bd5556ed add self-retraining functionality for live/dry 2022-05-15 17:42:15 +02:00
robcaulk
178c2014b0 appease mypy 2022-05-15 17:42:15 +02:00
robcaulk
a4f5811a5b fix flake8 issue in arguments.py 2022-05-15 17:42:15 +02:00
robcaulk
aae233bd6c try passing the check tests 2022-05-15 17:42:15 +02:00
robcaulk
f653ace24b another attempt at fixing datalength bug 2022-05-15 17:42:15 +02:00
robcaulk
b08c0888bb add USERPATH_FREQAIMODELS, remove return values from @abstract methods 2022-05-15 17:42:15 +02:00
robcaulk
b03c7b514d optional style for interfacing freqai with backtesting 2022-05-15 17:42:15 +02:00
robcaulk
e9a7b68bc1 revert constants.py and add changes 2022-05-15 17:42:15 +02:00
Matthias
a0b25938f4 Fix exit_reason assignment in backtesting 2022-05-15 17:41:59 +02:00
Matthias
a8f064a8cb Fix exit_reason assignment in live mode 2022-05-15 17:41:59 +02:00
robcaulk
3020218096 fix bug on backtest timerange 2022-05-15 17:41:34 +02:00
robcaulk
00ff0c9b91 ensure user defined timerange truncates final backtest so that we arent mismatching data lengths upon return to strategy. Rename DataHandler class to FreqaiDataKitchen 2022-05-15 17:41:34 +02:00
robcaulk
66715c5ba4 update doc 2022-05-15 17:41:34 +02:00
robcaulk
def71a0afe auto build full_timerange and self manage training_timerange 2022-05-15 17:41:34 +02:00
robcaulk
764f9449b4 fix logger, debug some flake8 appeasements 2022-05-15 17:41:34 +02:00
robcaulk
29c2d1d189 use logger in favor of print 2022-05-15 17:38:58 +02:00
robcaulk
99f7e44c30 flake8 passing, use pathlib in lieu of os.path to accommodate windows/mac OS 2022-05-15 17:38:58 +02:00
robcaulk
2600ba4e74 remove unused remnants 2022-05-15 17:38:58 +02:00
robcaulk
630d201546 remove trained_stake 2022-05-15 17:38:58 +02:00
robcaulk
b40f8f88ac cleaning and bug fixing 2022-05-15 17:38:58 +02:00
robcaulk
fc837c4daa add freqao backend machinery, user interface, documentation 2022-05-15 17:38:58 +02:00
Matthias
706994340f Fix bad docstring 2022-05-15 17:06:40 +02:00
Matthias
ebab02fce3 Merge pull request #6827 from eSeR1805/fix_readjust_entry_bt_sl
Fix: Refresh SL on entry order replacement
2022-05-15 16:41:18 +02:00
eSeR1805
cf001db396 Merge pull request #1 from xmatthias/bt_stop_attempt
Update stoploss handling for entry-order adjustment
2022-05-15 16:56:40 +03:00
Matthias
18fd3bb333 Update stoploss handling for entry-order adjustment 2022-05-15 15:45:39 +02:00
Matthias
9143e9ecb1 Add some safety measures for new startup_candles verification 2022-05-15 15:12:29 +02:00
Matthias
d60d0f64d2 Revert ohlcv_candle_limit logic for okx 2022-05-14 19:35:06 +02:00
Matthias
116b58e97c add "date_minus_candles" method 2022-05-14 19:30:42 +02:00
Matthias
a947a1316b Add test to ensure stoploss is set properly in live 2022-05-14 17:42:01 +02:00
Matthias
3b14439240 Slightly improve performance of order adjusts
Avoind  2nd call to `get_rate()`.

closes #6821
2022-05-14 16:16:32 +02:00
eSeR1805
c27e0a0a1b Allow SL refresh only if no filled entry orders. 2022-05-14 16:56:56 +03:00
eSeR1805
ec54b47b6e Flake fix. 2022-05-14 16:39:27 +03:00
eSeR1805
1c20fb7638 Refresh open_rate and stoploss on order replacement. 2022-05-14 16:37:04 +03:00
Matthias
5767d652bf Add explicit test and document behavior 2022-05-14 14:18:51 +02:00
Matthias
2a1368d508 Offsetfilter: add number_assets parameter
closes #6824
2022-05-14 14:16:13 +02:00
Matthias
bb1b283d95 Update some ohlcv_candle_limit calls 2022-05-14 13:44:10 +02:00
Matthias
111b04c9e6 Okx - conditional candle-length 2022-05-14 09:51:44 +02:00
Matthias
64668b11da add ohlcv_has_history - disabling kraken downloads 2022-05-14 09:10:38 +02:00
Matthias
8e9384e8e6 Merge pull request #6823 from mkavinkumar1/clean-bt
cleaned up backtesting
2022-05-13 21:00:06 +02:00
Matthias
80ebd8f875 Merge pull request #6820 from SmartManoj/patch-9
Corrected docstring
2022-05-13 19:29:47 +02:00
மனோஜ்குமார் பழனிச்சாமி
64670726a6 flake8 fix 2022-05-13 21:52:26 +05:30
மனோஜ்குமார் பழனிச்சாமி
9d13c87292 cleaned up backtesting
Solves the [bug](https://github.com/freqtrade/freqtrade/runs/6425715015?check_suite_focus=true)
2022-05-13 21:46:25 +05:30
மனோஜ்குமார் பழனிச்சாமி
71a80cab3a fixed variable naming style 2022-05-13 21:19:40 +05:30
மனோஜ்குமார் பழனிச்சாமி
8a3c2c6cad Corrected docstring
Discussed in Discord
2022-05-13 19:32:52 +05:30
Matthias
c299601ece Add warning about OKX futures backtesting data 2022-05-13 07:03:18 +02:00
Matthias
5444f4ee6f Merge pull request #6793 from mkavinkumar1/log
logged balance details
2022-05-12 19:11:28 +02:00
Matthias
891900c186 Merge pull request #6812 from freqtrade/db_migrate
Db migrate
2022-05-11 19:54:31 +02:00
Matthias
1fc041d0d6 Fix formatting issue 2022-05-11 19:39:56 +02:00
Matthias
ae463fcdf2 Merge pull request #6792 from mkavinkumar1/rpc
consistent exchange name
2022-05-11 19:23:36 +02:00
Matthias
7c1838427f Merge pull request #6814 from DJCrashdummy/patch-1
minor polish for explanation of `backtesting --breakdown`
2022-05-11 09:09:32 +02:00
DJCrashdummy
b2b503f043 minor polish for explanation of --breakdown
- corrected the command to fit the explanation
- added a little explanation how to read the weekly & monthly breakdown
2022-05-11 06:26:49 +00:00
DJCrashdummy
8a6a6ec911 corrected minor "typo" in formatting 2022-05-11 06:30:58 +02:00
Matthias
f374c9da70 PR cleanup 2022-05-11 06:30:40 +02:00
Matthias
044afdf7af Add better test scenario 2022-05-10 20:27:24 +02:00
Matthias
31cce741ac Add sequence migration 2022-05-10 07:13:51 +02:00
Matthias
269630e755 Add preliminary documentation for database conversion 2022-05-10 07:13:42 +02:00
Matthias
c19be34e71 Add rudimentary test for db migration 2022-05-09 20:58:40 +02:00
Matthias
0958c06b84 Implement database migration to other system 2022-05-09 20:58:40 +02:00
Matthias
c3b0f6b64b Add feature shell for database conversion 2022-05-09 20:58:40 +02:00
Matthias
0f499469fc Merge pull request #6796 from freqtrade/model_reorg
Model reorg
2022-05-09 20:15:45 +02:00
Matthias
e66e1317dc Merge pull request #6803 from freqtrade/dependabot/pip/develop/types-tabulate-0.8.9
Bump types-tabulate from 0.8.8 to 0.8.9
2022-05-09 08:00:20 +02:00
Matthias
54450bcb8c Merge pull request #6804 from freqtrade/dependabot/pip/develop/ccxt-1.81.81
Bump ccxt from 1.81.43 to 1.81.81
2022-05-09 07:13:18 +02:00
Matthias
35ec657ef1 Bump types-tabulate==0.8.9 precommit 2022-05-09 06:55:01 +02:00
dependabot[bot]
a5beacbdd0 Bump types-tabulate from 0.8.8 to 0.8.9
Bumps [types-tabulate](https://github.com/python/typeshed) from 0.8.8 to 0.8.9.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-tabulate
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 04:53:29 +00:00
Matthias
bfcb8c9b82 Merge pull request #6806 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.15
Bump types-python-dateutil from 2.8.14 to 2.8.15
2022-05-09 06:52:59 +02:00
Matthias
a69b8d2fb6 Merge pull request #6800 from freqtrade/dependabot/pip/develop/pre-commit-2.19.0
Bump pre-commit from 2.18.1 to 2.19.0
2022-05-09 06:52:43 +02:00
dependabot[bot]
2dd655eda0 Bump pre-commit from 2.18.1 to 2.19.0
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 2.18.1 to 2.19.0.
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v2.18.1...v2.19.0)

---
updated-dependencies:
- dependency-name: pre-commit
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 04:52:32 +00:00
Matthias
ad81cd280f Merge pull request #6805 from freqtrade/dependabot/pip/develop/flake8-tidy-imports-4.7.0
Bump flake8-tidy-imports from 4.6.0 to 4.7.0
2022-05-09 06:51:40 +02:00
Matthias
162a517411 Merge pull request #6802 from freqtrade/dependabot/pip/develop/fastapi-0.76.0
Bump fastapi from 0.75.2 to 0.76.0
2022-05-09 06:51:21 +02:00
Matthias
5f0c79cc47 Merge pull request #6801 from freqtrade/dependabot/pip/develop/jsonschema-4.5.1
Bump jsonschema from 4.4.0 to 4.5.1
2022-05-09 06:37:29 +02:00
Matthias
4e5a8ce87e Merge pull request #6799 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.14
Bump mkdocs-material from 8.2.12 to 8.2.14
2022-05-09 06:37:06 +02:00
dependabot[bot]
5080245a73 Bump ccxt from 1.81.43 to 1.81.81
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.81.43 to 1.81.81.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.81.43...1.81.81)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 04:32:48 +00:00
Matthias
0756027e33 BUmp types-python-dateutil precommit 2022-05-09 06:32:28 +02:00
Matthias
5f7b19cb56 Merge pull request #6798 from freqtrade/dependabot/pip/develop/cryptography-37.0.2
Bump cryptography from 37.0.1 to 37.0.2
2022-05-09 06:31:44 +02:00
dependabot[bot]
69b79cd799 Bump types-python-dateutil from 2.8.14 to 2.8.15
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.14 to 2.8.15.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 03:11:16 +00:00
dependabot[bot]
1ae74c1197 Bump flake8-tidy-imports from 4.6.0 to 4.7.0
Bumps [flake8-tidy-imports](https://github.com/adamchainz/flake8-tidy-imports) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/adamchainz/flake8-tidy-imports/releases)
- [Changelog](https://github.com/adamchainz/flake8-tidy-imports/blob/main/HISTORY.rst)
- [Commits](https://github.com/adamchainz/flake8-tidy-imports/compare/4.6.0...4.7.0)

---
updated-dependencies:
- dependency-name: flake8-tidy-imports
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 03:11:12 +00:00
dependabot[bot]
77a22a6b1c Bump fastapi from 0.75.2 to 0.76.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.75.2 to 0.76.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.75.2...0.76.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 03:10:38 +00:00
dependabot[bot]
74b309cf50 Bump jsonschema from 4.4.0 to 4.5.1
Bumps [jsonschema](https://github.com/python-jsonschema/jsonschema) from 4.4.0 to 4.5.1.
- [Release notes](https://github.com/python-jsonschema/jsonschema/releases)
- [Changelog](https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/python-jsonschema/jsonschema/compare/v4.4.0...v4.5.1)

---
updated-dependencies:
- dependency-name: jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 03:10:27 +00:00
dependabot[bot]
30cc8e92a1 Bump mkdocs-material from 8.2.12 to 8.2.14
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.12 to 8.2.14.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.12...8.2.14)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 03:10:15 +00:00
dependabot[bot]
df48399a90 Bump cryptography from 37.0.1 to 37.0.2
Bumps [cryptography](https://github.com/pyca/cryptography) from 37.0.1 to 37.0.2.
- [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/37.0.1...37.0.2)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-09 03:10:07 +00:00
Matthias
511afbcd9d Merge pull request #6797 from lukeingalls/patch-1
then -> than
2022-05-08 21:50:41 +02:00
Luke Ingalls
f71b2624ab then -> than 2022-05-08 10:07:22 -07:00
Matthias
30d6eeffd0 Fix migration bug 2022-05-08 17:49:13 +02:00
Matthias
b58e811b14 Move trade/order Models to their own class 2022-05-08 17:45:20 +02:00
Matthias
af1a5e0449 Extract base and Pairlock from models file 2022-05-08 17:38:06 +02:00
Matthias
3221726d85 Update migration to use boolean value
closes #6794
2022-05-08 17:29:42 +02:00
Matthias
ab91758c7e Merge pull request #6790 from eSeR1805/profit_reporting
Report profit only on filled entries.
2022-05-08 17:25:42 +02:00
Matthias
4a7515e66a Add test for 0.0 case 2022-05-08 16:04:06 +02:00
Matthias
1436bc1a70 Update list-strategies command
closes #6795
2022-05-08 15:30:44 +02:00
மனோஜ்குமார் பழனிச்சாமி
f43ae0ea43 logged balance details 2022-05-08 13:53:07 +05:30
மனோஜ்குமார் பழனிச்சாமி
d79b90a98f consistent exchange name 2022-05-08 12:46:58 +05:30
Matthias
45b328af2e explicitly call cleanup when cleaning backtest 2022-05-08 08:11:39 +02:00
eSeR1805
bfc7898654 Report profit only on filled entries. 2022-05-07 21:56:22 +03:00
Matthias
c9498d0117 Merge pull request #6692 from eSeR1805/feat_readjust_entry
Feature: Readjust Entry Order
2022-05-07 20:11:20 +02:00
Matthias
277e07589e update/fix some comments and docs 2022-05-07 17:47:37 +02:00
eSeR1805
eca8d16c61 Minor fix and enhancement for TC51. 2022-05-07 17:31:56 +03:00
Matthias
f5f599c7f0 Add LowProfitPairs only_per_side option 2022-05-07 15:25:15 +02:00
Matthias
26648e54cc Merge pull request #6789 from freqtrade/okx_positionmode
Okx positionmode
2022-05-07 14:30:44 +02:00
Matthias
dc0c1bf87d Only fetch accounts when authenticated. 2022-05-07 13:17:27 +02:00
Matthias
149704e748 Fix wrong type 2022-05-07 11:39:47 +02:00
Matthias
6fdcf3a10a Support both position modes on OKX 2022-05-07 10:58:41 +02:00
Matthias
2da284b921 Properly type side for create_order 2022-05-07 10:02:54 +02:00
Matthias
68a97a898d Disable scheduled notification in CI 2022-05-07 08:04:43 +02:00
Matthias
108903f7f0 Add DCA order adjust test 2022-05-06 19:50:10 +02:00
Matthias
70bac41d89 Add more backtest test scenarios 2022-05-06 19:50:10 +02:00
eSeR1805
182a6f475d Minor typos. 2022-05-06 10:13:29 +03:00
Matthias
5b3eaa3003 Ensure advanced strategy template is runnable 2022-05-06 06:42:08 +02:00
Matthias
d11c44940e Slightly reword docs
remove some Note-boxes - people tend to skip these.
2022-05-06 06:42:01 +02:00
Matthias
2d9be6dace move open_rate updating to close_bt_order 2022-05-05 19:50:16 +02:00
eSeR1805
29f1edbde7 Cleanup. Remove stray new line. 2022-05-05 12:24:32 +03:00
eSeR1805
495708df76 Merge branch 'develop' into feat_readjust_entry 2022-05-05 12:20:09 +03:00
eSeR1805
2bed0eab0c BT: Update trade open_rate on first filled order. 2022-05-05 12:19:05 +03:00
eSeR1805
25c74e26d1 Models:Trade: Revert trade open_rate update. 2022-05-05 12:18:19 +03:00
Matthias
1a37c6ff42 Bump ccxt to 1.81.43
fixes bug in okx live liquidation pricing
2022-05-05 07:05:00 +02:00
eSeR1805
ae01afdd0f Models:Trade: Fix open_rate updates. 2022-05-04 22:05:53 +03:00
eSeR1805
496bf84e3a Merge branch 'develop' into feat_readjust_entry 2022-05-04 21:43:41 +03:00
eSeR1805
dbecc097df Models:Trade: Update trade open_rate based on lastest order. 2022-05-04 21:34:45 +03:00
Sam Germain
10cbb5e67c test_exchange::test_taker_or_maker fixes 2022-05-04 00:10:09 -06:00
Sam Germain
86ad5dd02a test_exchange::test_taker_or_maker fixes 2022-05-04 00:08:41 -06:00
Sam Germain
dac9931b4a test_create_dry_run_order_fees 2022-05-03 23:56:49 -06:00
Sam Germain
5d9aee6b7e test_taker_or_maker 2022-05-03 23:56:49 -06:00
Sam Germain
e8803477df exchange/exchange add param taker_or_maker to add_dry_order_fee 2022-05-03 23:56:40 -06:00
Matthias
b73f770955 Merge pull request #6778 from markdregan/patch-1
Add bot_loop_start() call in plotting.py
2022-05-04 07:24:32 +02:00
Matthias
b2f33944ec Add preliminary backtesting test 2022-05-04 07:13:02 +02:00
Matthias
5c82cce06c Fix new test failures 2022-05-04 06:40:12 +02:00
Mark Regan
ce035a5947 Add bot_loop_start() call in plotting.py
plotting.py was missing a call to strategy.bot_loop_start() resulting in strategies using this callback to not work.

Made changes and confirmed plotting now works for strategies using bot_loop_start() callback.

LMK if anything else needed for PR.
2022-05-03 23:34:12 +01:00
Matthias
2705096ce6 Merge pull request #6777 from freqtrade/fix/contractsizefee
Fix fee handling for futures trades
2022-05-03 20:34:37 +02:00
Matthias
091cb4fb8d Reduce no stake amount verbosity
closes #6768
2022-05-03 19:42:17 +02:00
Matthias
eb996a152a Fix fee handling for futures trades 2022-05-03 19:06:17 +02:00
Matthias
65ab6d2468 Merge pull request #6771 from talentoscope/patch-1
Update setup.sh
2022-05-03 08:12:29 +02:00
talentoscope
8e1cdb9103 Update setup.sh
Added curl to dependencies for Debian systems
2022-05-02 23:20:13 +01:00
Matthias
88c8fe5570 Merge pull request #6715 from nicolaspapp/feat/relative-drawdown
Add relative drawdown
2022-05-02 21:09:14 +02:00
Matthias
7a57629918 Keep Backtest-metrics aligned 2022-05-02 20:08:38 +02:00
Matthias
3f64c6307f Maintain compatibility with old backtest results 2022-05-02 20:01:44 +02:00
Matthias
1e2523af61 Fix some assumptions on the data
available_capital is not guaranteed to be available, while dry-run-wallet is.
2022-05-02 19:44:14 +02:00
eSeR1805
52d510c331 Merge branch 'develop' into feat_readjust_entry 2022-05-02 18:30:05 +03:00
eSeR1805
4c74601073 Freqtradebot: Cleanup stray debug messages. 2022-05-02 18:22:41 +03:00
eSeR1805
59397cdd19 Freqtradebot: Fix full cancel logging location. 2022-05-02 18:09:28 +03:00
eSeR1805
b83cd95a02 Tests: add basic testcases for entry adjustment. 2022-05-02 18:07:48 +03:00
Matthias
c1b10bbb91 Merge pull request #6763 from freqtrade/dependabot/pip/develop/mypy-0.950
Bump mypy from 0.942 to 0.950
2022-05-02 09:13:08 +02:00
Matthias
46993ce3ae Merge pull request #6761 from freqtrade/dependabot/pip/develop/types-tabulate-0.8.8
Bump types-tabulate from 0.8.7 to 0.8.8
2022-05-02 09:12:52 +02:00
Matthias
2a6efab8a2 Don't use deprecated abstractclassmethod decorator 2022-05-02 06:24:52 +00:00
Matthias
38dffe1ed6 types-tabulate - pre-commit update 2022-05-02 08:11:05 +02:00
dependabot[bot]
24ce90ba9b Bump types-tabulate from 0.8.7 to 0.8.8
Bumps [types-tabulate](https://github.com/python/typeshed) from 0.8.7 to 0.8.8.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-tabulate
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 06:00:02 +00:00
Matthias
541ee436c5 Merge pull request #6759 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.36
Bump sqlalchemy from 1.4.35 to 1.4.36
2022-05-02 07:59:30 +02:00
Matthias
725706beab Merge pull request #6765 from freqtrade/dependabot/pip/develop/types-requests-2.27.25
Bump types-requests from 2.27.20 to 2.27.25
2022-05-02 07:59:14 +02:00
Matthias
24cb40fe98 Merge pull request #6758 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.14
Bump types-python-dateutil from 2.8.12 to 2.8.14
2022-05-02 07:24:32 +02:00
Matthias
e3c298e892 Merge pull request #6766 from freqtrade/dependabot/pip/develop/jinja2-3.1.2
Bump jinja2 from 3.1.1 to 3.1.2
2022-05-02 07:11:19 +02:00
dependabot[bot]
67dd9be95a Bump sqlalchemy from 1.4.35 to 1.4.36
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.35 to 1.4.36.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 05:00:17 +00:00
Matthias
bd07d356bd Merge pull request #6762 from freqtrade/dependabot/pip/develop/cryptography-37.0.1
Bump cryptography from 36.0.2 to 37.0.1
2022-05-02 06:59:27 +02:00
Matthias
71ae92274d Bump pre-commit dependency 2022-05-02 06:45:42 +02:00
Matthias
49c1b310c2 Bump pre-commit types 2022-05-02 06:44:30 +02:00
dependabot[bot]
ba28fa6c3c Bump cryptography from 36.0.2 to 37.0.1
Bumps [cryptography](https://github.com/pyca/cryptography) from 36.0.2 to 37.0.1.
- [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/36.0.2...37.0.1)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 04:31:35 +00:00
dependabot[bot]
9de0652b2c Bump jinja2 from 3.1.1 to 3.1.2
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.1 to 3.1.2.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.1...3.1.2)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 04:31:34 +00:00
Matthias
13dc0a0b4d Merge pull request #6764 from freqtrade/dependabot/pip/develop/ccxt-1.81.16
Bump ccxt from 1.80.61 to 1.81.16
2022-05-02 06:30:11 +02:00
Matthias
3f25fb2139 Merge pull request #6760 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.12
Bump mkdocs-material from 8.2.10 to 8.2.12
2022-05-02 06:29:37 +02:00
dependabot[bot]
093bea4230 Bump types-requests from 2.27.20 to 2.27.25
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.20 to 2.27.25.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 03:01:34 +00:00
dependabot[bot]
73aafb886b Bump ccxt from 1.80.61 to 1.81.16
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.80.61 to 1.81.16.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.80.61...1.81.16)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 03:01:33 +00:00
dependabot[bot]
4990534bf4 Bump mypy from 0.942 to 0.950
Bumps [mypy](https://github.com/python/mypy) from 0.942 to 0.950.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.942...v0.950)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 03:01:22 +00:00
dependabot[bot]
3d730661ee Bump mkdocs-material from 8.2.10 to 8.2.12
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.10 to 8.2.12.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.10...8.2.12)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 03:01:11 +00:00
dependabot[bot]
a0e27d82aa Bump types-python-dateutil from 2.8.12 to 2.8.14
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.12 to 2.8.14.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-02 03:01:00 +00:00
eSeR1805
04c51d2d1a Merge branch 'develop' into feat_readjust_entry 2022-05-01 21:42:15 +03:00
Nicolas Papp
7160f9085a Update summary examples 2022-05-01 12:32:12 -03:00
Nicolas Papp
f9244aad92 Fix on max drawdown formula to match tests 2022-05-01 12:25:53 -03:00
eSeR1805
4e43194dfe BT: Refactor open order management. 2022-05-01 18:06:20 +03:00
Matthias
582e30bca6 Merge pull request #6716 from freqtrade/pairlocks_direction
Pairlocks direction
2022-05-01 17:04:20 +02:00
Matthias
910addd02b Merge pull request #6753 from freqtrade/download_prepend
Download prepend
2022-05-01 15:15:16 +02:00
Matthias
995c48b642 Merge branch 'develop' into pairlocks_direction 2022-05-01 14:59:04 +02:00
Matthias
2cedbe5704 Fix documentation mishap 2022-05-01 14:50:36 +02:00
eSeR1805
9d205132d0 Revert unintended comment change. 2022-05-01 12:10:11 +03:00
eSeR1805
8c19953cdd Quick exit when order should be maintained. 2022-05-01 12:08:19 +03:00
Matthias
53a2f55cf0 Merge branch 'develop' into pr/nicolaspapp/6715 2022-05-01 10:03:10 +02:00
Matthias
d5fc923dcb Properly validate stoploss existence for optimize commands
closes #6740
2022-05-01 09:53:46 +02:00
Matthias
0c921e0116 Reorder api_backtesting test sequence 2022-04-30 20:08:40 +02:00
Matthias
5c1ac3cf95 Fix caching bug with freqUI backtesting 2022-04-30 19:55:13 +02:00
Matthias
93591f2a7b Merge pull request #6748 from SmartManoj/patch-8
Update PULL_REQUEST_TEMPLATE.md
2022-04-30 17:46:05 +02:00
Matthias
8b5d454b50 Fix subtle bug in trades download 2022-04-30 17:44:57 +02:00
Matthias
e49b3ef051 Improve message formatting 2022-04-30 17:35:11 +02:00
Matthias
f6a7e6b785 Add prepend option to download-data 2022-04-30 17:32:50 +02:00
Matthias
11d447cd5a Add support for download-data "until" 2022-04-30 15:42:41 +02:00
Matthias
e4df2b0b96 Revert unwanted changes 2022-04-30 14:55:52 +02:00
Matthias
4580127fa8 Small refactor 2022-04-30 14:51:57 +02:00
Matthias
c6c569b772 chore: split BTAnalyais to metrics 2022-04-30 14:47:27 +02:00
Matthias
4262f84744 Merge branch 'develop' into pr/nicolaspapp/6715 2022-04-30 14:22:18 +02:00
Matthias
2acb68e6e2 Move hyperopt-loss functions to their own package 2022-04-30 13:59:23 +02:00
eSeR1805
3be2afdd88 Merge branch 'develop' into feat_readjust_entry 2022-04-30 13:39:23 +03:00
eSeR1805
ad0c5d9440 Refactor entry adjustment for backtesting. 2022-04-30 13:38:17 +03:00
eSeR1805
f9977c26e7 Full cancel only for non DCA trades. 2022-04-30 12:55:03 +03:00
Matthias
bfae732ba4 Merge pull request #6627 from samgermain/bot-start
Added bot_start callback to strategy interface
2022-04-30 09:14:51 +02:00
Matthias
09b74cebce Move edge bot_loop_start to edge_cli
(otherwise it's called twice when running trade mode with edge on).
2022-04-30 08:55:07 +02:00
Sam Germain
8756e7d9a1 flake8 linting 2022-04-29 23:35:08 -06:00
Sam Germain
4a6f1e90c3 Merge branch 'develop' into bot-start 2022-04-29 22:23:42 -06:00
Sam Germain
23431a7106 removed invalid plotting and test_default_strategy tests for bot_start, edited edge test 2022-04-29 22:21:22 -06:00
Sam Germain
788d9f5b55 updated bot_start documentation with working example 2022-04-29 22:20:26 -06:00
Matthias
9029833c8c Merge pull request #6750 from erdieee/develop
Fix config_examples typo
2022-04-29 20:42:24 +02:00
erdieee
f23faac368 Fix config_examples typo 2022-04-29 20:10:50 +02:00
Matthias
43049e0465 Evict cache if parameter file changed
closes #6735
2022-04-29 19:44:17 +02:00
Matthias
fbd142844f Refactor bt-caching stuff to it's own module 2022-04-29 19:37:13 +02:00
மனோஜ்குமார் பழனிச்சாமி
f96c552c46 Update PULL_REQUEST_TEMPLATE.md
Added instructions as comments
2022-04-29 22:14:02 +05:30
Matthias
b60411b918 Merge pull request #6744 from freqtrade/orjson
Use ORJSON for http responses
2022-04-29 17:58:42 +02:00
Matthias
da7a6f58f9 Revert requiring stoploss for backtest/hyperopt 2022-04-29 17:46:33 +02:00
eSeR1805
09089b160e Merge branch 'develop' into feat_readjust_entry 2022-04-29 13:02:38 +03:00
Matthias
b6bee45e82 Exclude user_data from isort 2022-04-29 09:54:54 +00:00
Matthias
48ff788e82 Clarify that stoploss is required
closes #6740
2022-04-29 09:53:05 +00:00
Matthias
21df1b0db3 Use ORJSON for http responses 2022-04-29 07:17:31 +02:00
eSeR1805
17650d7e60 Maintain existing order. Update functionality and documentation 2022-04-29 00:10:17 +03:00
eSeR1805
eb23170c43 Merge branch 'develop' into feat_readjust_entry 2022-04-28 23:06:52 +03:00
Matthias
d1a61f9c61 Don't start futures backtest if leverage-tiers don't contain pair 2022-04-28 20:05:19 +02:00
Matthias
cb5c3316d1 Simplify log output 2022-04-28 19:43:52 +02:00
Matthias
4063ab27cf Merge pull request #6728 from turrisxyz/setup-permissions
chore: Set permissions for GitHub actions
2022-04-28 16:23:06 +02:00
Matthias
8962bffbe0 Merge branch 'develop' into setup-permissions 2022-04-28 14:51:33 +02:00
Matthias
4c95996069 Add Permissions for notify-complete job 2022-04-28 14:50:50 +02:00
Matthias
64072f76b9 Don't fail scheduled ci tasks due to notification 2022-04-28 14:40:47 +02:00
Matthias
e0d86307cb Merge pull request #6732 from freqtrade/remove_duplicate_liqprice_call
Don't call interest_rate and isolated_liq twice
2022-04-28 07:38:32 +02:00
Matthias
2ef1181e16 Simplify trade __repr__ 2022-04-28 07:33:30 +02:00
Matthias
1e83589641 Fix hyperopt 2022-04-28 06:59:03 +02:00
Matthias
ca49821df0 Fix race condition for loop 2022-04-28 06:29:14 +02:00
Matthias
46855221aa Fix rounding issue with contract-sized pairs for dry-run orders 2022-04-27 19:58:19 +02:00
Matthias
220927289d Update documentation to highlight futures supported exchanges 2022-04-27 19:10:04 +02:00
Matthias
2c0a7c5d74 Don't call interest_rate and isolated_liq twice 2022-04-27 17:13:58 +02:00
Matthias
30c9dc6975 Fix exit-signa being assigned when tag is set but no signal is present. 2022-04-27 13:53:11 +02:00
Matthias
ad7fbfab1b Slightly improved styling 2022-04-27 13:27:33 +02:00
Matthias
415dcc6a87 Merge pull request #6729 from rokups/rk/exit_tag
Add 'exit_tag' parameter to 'custom_exit_price' callback.
2022-04-27 07:07:28 +02:00
Matthias
108f11b1d7 Fix docs typos 2022-04-27 06:42:56 +02:00
Rokas Kupstys
6d99222320 Add 'exit_tag' parameter to 'custom_exit_price' callback. 2022-04-26 10:01:51 +03:00
Sam Germain
a35dc843ea removed asyncio from bot_start example 2022-04-25 22:39:58 -06:00
Nicolas Papp
bc5048e4f3 Update to backtesting.md 2022-04-25 23:50:47 -03:00
naveen
4cccf31a3e chore: Set permissions for GitHub actions
Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much.

- Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions

https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs

[Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)

Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
2022-04-26 01:07:59 +00:00
Sam Germain
7f035a9d53 added docs for bot_start 2022-04-25 17:59:50 -06:00
Sam Germain
810e190e16 added tests for bot_start 2022-04-25 17:48:57 -06:00
Sam Germain
e76c6e8ad3 added bot_start call to edge_positioning.__init__ 2022-04-25 17:48:57 -06:00
Sam Germain
e09b4498fa added bot_start call to plot/plotting 2022-04-25 17:48:57 -06:00
Sam Germain
4fd904e0a9 added bot_start to backtesting 2022-04-25 17:48:57 -06:00
Sam Germain
d92761b2b1 Revert "strategy callback on_whitelist_update"
This reverts commit 39798dc1192161c3060830dd4684571aa86b7821.
2022-04-25 17:48:43 -06:00
Sam Germain
bf7da35e31 strategy callback on_whitelist_update 2022-04-25 17:48:07 -06:00
Sam Germain
0b90e1d309 Added bot_start callback to strategy interface 2022-04-25 17:47:12 -06:00
Matthias
44000ae0b3 Fix CAGR missing for old results 2022-04-25 17:37:25 +02:00
Matthias
246a336f56 Merge pull request #6726 from froggleston/bt_concat
Move df append to pd concat
2022-04-25 16:03:27 +02:00
Matthias
e38c4883dc Merge pull request #6725 from freqtrade/cagr
Add CAGR calculation to backtesting
2022-04-25 16:02:39 +02:00
Matthias
9a5a57d848 Merge pull request #6724 from freqtrade/pre-commit-additional_updates
Check pre-commit verison updates
2022-04-25 14:57:45 +02:00
froggleston
431c539cbd Fix isort import order 2022-04-25 10:42:24 +01:00
Matthias
4444259078 Fix hyperopt-loss interface to enforce kwargs 2022-04-25 11:33:18 +02:00
froggleston
580da21dda Move df append to pd concat 2022-04-25 10:31:19 +01:00
Matthias
2b3f683960 Update pre-commit to exclude build-helpers 2022-04-25 11:23:45 +02:00
Matthias
500fdc2759 run mypy also against tests 2022-04-25 11:12:35 +02:00
Matthias
4143ebbeae Add CAGR calculation to backtesting 2022-04-25 10:51:11 +02:00
Matthias
fc118d0e95 Re-align dependencies 2022-04-25 10:19:31 +02:00
Matthias
6d576bc02d Check pre-commit verison updates 2022-04-25 10:18:04 +02:00
Matthias
7b02114ad2 Restrict trading pairs with too low precision
closes #6606
2022-04-25 09:49:51 +02:00
Matthias
86b3aac9ba Fix FTX not fetching the very latest data 2022-04-25 08:38:02 +02:00
Matthias
f45bafdb16 Merge pull request #6723 from freqtrade/strategy_v1_remove
Strategy v1 remove
2022-04-25 08:26:35 +02:00
Matthias
14a0dadd01 Merge pull request #6718 from freqtrade/dependabot/pip/develop/pytest-7.1.2
Bump pytest from 7.1.1 to 7.1.2
2022-04-25 08:23:34 +02:00
Matthias
f0c816f9e3 Merge pull request #6719 from freqtrade/dependabot/pip/develop/pymdown-extensions-9.4
Bump pymdown-extensions from 9.3 to 9.4
2022-04-25 07:43:30 +02:00
Matthias
ad6e5c5312 Test informative fallback again 2022-04-25 07:41:51 +02:00
Matthias
5ff2261b74 Improve test to explicitly test for dates 2022-04-25 07:32:32 +02:00
Matthias
9bc6bbe472 Improve test for max_drawdown calculations 2022-04-25 07:23:16 +02:00
Matthias
9bb0f1f675 Move legacy strategy to "broken strats" folder 2022-04-25 07:11:32 +02:00
Matthias
ec2582a4ae Update tests to no longer use Strategy V1 2022-04-25 07:02:09 +02:00
Matthias
562e36c3ec Remove Interface V1 support 2022-04-25 07:01:27 +02:00
dependabot[bot]
b4afbb0b0a Bump pymdown-extensions from 9.3 to 9.4
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.3 to 9.4.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.3...9.4)

---
updated-dependencies:
- dependency-name: pymdown-extensions
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-25 04:54:53 +00:00
Matthias
4ee862c7e3 Merge pull request #6717 from freqtrade/dependabot/pip/develop/ccxt-1.80.61
Bump ccxt from 1.79.81 to 1.80.61
2022-04-25 06:54:16 +02:00
Matthias
1aa07a0fe1 Merge pull request #6722 from freqtrade/dependabot/pip/develop/types-requests-2.27.20
Bump types-requests from 2.27.19 to 2.27.20
2022-04-25 06:54:03 +02:00
Matthias
ad17dce746 Merge pull request #6721 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.10
Bump mkdocs-material from 8.2.9 to 8.2.10
2022-04-25 06:53:33 +02:00
Matthias
5cc5d77b5f Merge pull request #6720 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.12
Bump types-python-dateutil from 2.8.11 to 2.8.12
2022-04-25 06:53:13 +02:00
dependabot[bot]
399be6f4e5 Bump types-requests from 2.27.19 to 2.27.20
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.19 to 2.27.20.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-25 03:17:53 +00:00
dependabot[bot]
9b39c83586 Bump mkdocs-material from 8.2.9 to 8.2.10
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.9 to 8.2.10.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.9...8.2.10)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-25 03:17:44 +00:00
dependabot[bot]
eee9fbb669 Bump types-python-dateutil from 2.8.11 to 2.8.12
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.11 to 2.8.12.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-25 03:17:38 +00:00
dependabot[bot]
5bfa2186a7 Bump pytest from 7.1.1 to 7.1.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.1 to 7.1.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.1.1...7.1.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-25 03:17:29 +00:00
dependabot[bot]
46ac46a5d3 Bump ccxt from 1.79.81 to 1.80.61
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.79.81 to 1.80.61.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.79.81...1.80.61)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-25 03:17:23 +00:00
Nicolas Papp
e8aec967dd Update on note 2022-04-24 17:42:52 -03:00
Nicolas Papp
086cc6be93 Correction on tests 2022-04-24 17:37:09 -03:00
Matthias
4de0fdbfca Minor edits found during review 2022-04-24 14:43:30 +02:00
Matthias
6623192108 improve doc wording 2022-04-24 14:39:13 +02:00
Matthias
737bdfe844 Use "side" parameter when calling Pairlocks 2022-04-24 14:33:24 +02:00
Matthias
144e4da96e Update stoploss guard tests 2022-04-24 14:33:24 +02:00
Matthias
b0a8bf3025 Show lock side 2022-04-24 14:33:24 +02:00
Matthias
4942d73693 update pairlock tests 2022-04-24 14:33:24 +02:00
Matthias
845f960a4e realign pairlock naming to side 2022-04-24 14:33:24 +02:00
Matthias
fc201bb4ff implement pairlock side further 2022-04-24 14:33:24 +02:00
Matthias
420836b1b2 Update test naming 2022-04-24 14:33:24 +02:00
Matthias
7c79d937e0 Properly type "side" parameter 2022-04-24 14:33:24 +02:00
Matthias
b7cada1edd Convert ProtectionReturn to dataclass 2022-04-24 14:33:24 +02:00
Matthias
9e199165b4 Update protection-interface to support per-side locks 2022-04-24 14:33:24 +02:00
Matthias
6ff3b178b0 Add direction column to pairlocks 2022-04-24 14:33:24 +02:00
Matthias
25c6c5e326 Update backtest sell terminology to exit 2022-04-24 14:30:50 +02:00
Matthias
3c17409bd7 Update buy to entry in backtesting 2022-04-24 14:28:15 +02:00
Matthias
3637549a5e Merge pull request #6714 from froggleston/develop
Update advanced backtesting docs to match fixed buy_reasons script
2022-04-23 19:25:58 +02:00
froggleston
acec564014 Update advanced backtesting docs to match fixed buy_reasons script 2022-04-23 17:18:38 +01:00
Nicolas Papp
0f943c482b PEP8 code compliance 2022-04-23 13:15:14 -03:00
Matthias
8cac0a47cc Fix joblib being in wrong requirements 2022-04-23 17:08:34 +02:00
Matthias
2d07cbce59 Fix bad pre-commit installation
closes #6713
2022-04-23 17:05:41 +02:00
Matthias
0807d3106f Remove unused import 2022-04-23 15:34:40 +02:00
Matthias
6408590a73 Merge pull request #6712 from freqtrade/ci/speed
Speed up ci by running coverage only where necessary
2022-04-23 15:01:19 +02:00
Matthias
12d03e6a91 Remove unused test methods 2022-04-23 14:53:47 +02:00
Matthias
d4e12371c2 Merge pull request #6558 from samgermain/recursive-strategy-folder
Recursively search subdirectories in config['user_data_dir']/strategies for a strategy
2022-04-23 14:23:53 +02:00
Matthias
b1ca47e3d6 Merge pull request #6707 from koradiyakaushal/develop
Ref: timeseries friendly merge_ordered in merge_informative_pair func…
2022-04-23 14:22:23 +02:00
Matthias
3586c2e984 Windows no random order 2022-04-23 14:22:06 +02:00
Matthias
c1a7fc873d Speed up ci by running coverage only where necessary 2022-04-23 11:47:10 +02:00
Matthias
f2912f8815 Improve mypy runs 2022-04-23 11:31:12 +02:00
Matthias
a2af7b4fd8 Test non-ffill approach 2022-04-23 11:25:20 +02:00
Matthias
1120392f39 Fix pre-commit indentation 2022-04-23 11:22:00 +02:00
Matthias
84f5a4d5bc Fix indentation 2022-04-23 10:51:24 +02:00
Matthias
30f314d580 windows compatibility of test 2022-04-23 10:44:11 +02:00
Matthias
89f16ad3a5 Merge pull request #6543 from froggleston/v3_fixes
Add support for storing buy candle indicator rows in backtesting results
2022-04-23 09:45:11 +02:00
Matthias
5a90d5ece6 Fix docstring quotes 2022-04-23 09:44:04 +02:00
Matthias
7328553c0b Merge pull request #6563 from italodamato/opt-ask-force-new-points
Optimize only new points
2022-04-23 09:43:33 +02:00
Matthias
580a2c6545 Don't repeat backtest-storing 2022-04-23 09:23:53 +02:00
Matthias
aa5345190e Test recursive strategy-listing 2022-04-23 09:19:18 +02:00
Matthias
f1f4846053 Merge branch 'develop' into pr/samgermain/6558 2022-04-23 09:16:28 +02:00
Matthias
ba92e09b7b list-strategies should find recursively as well 2022-04-23 09:11:50 +02:00
Matthias
c6927a1501 Fix argument spelling 2022-04-23 09:10:40 +02:00
Matthias
dff9d52b30 Remove hints on no longer used option, add very primitive test 2022-04-23 08:51:52 +02:00
froggleston
2fc4e5e117 Fix weird removal of comma 2022-04-22 18:54:02 +01:00
froggleston
b8ddf2d5cd Update docs 2022-04-22 18:49:28 +01:00
froggleston
767592a1d6 Add signals enum to 'export' cli option 2022-04-22 18:46:12 +01:00
Matthias
7f60364f63 Add doc-page to index 2022-04-22 06:38:51 +02:00
Patel Kaushal
ba305e93ed Ref: timeseries friendly merge_ordered in merge_informative_pair function 2022-04-21 18:35:41 +05:30
froggleston
f92997d378 Move signal candle generation into separate function 2022-04-20 14:05:33 +01:00
froggleston
933054a51c Move enable option text to make better sense 2022-04-20 13:54:50 +01:00
froggleston
ea7fb4e6e6 Revert docs to buy_reasons script version 2022-04-20 13:51:45 +01:00
froggleston
b3cb722646 Use joblib instead of pickle, add signal candle read/write test, move docs to new Advanced Backtesting doc 2022-04-20 13:38:52 +01:00
froggleston
9421d19cba Add documentation 2022-04-19 14:05:03 +01:00
froggleston
3ad1411f5e Fix imports 2022-04-19 13:08:01 +01:00
froggleston
aa5984930d Fix filename generation 2022-04-19 13:00:09 +01:00
froggleston
165f59325f Merge branch 'v3_fixes' of github.com:froggleston/freqtrade into v3_fixes 2022-04-19 12:48:29 +01:00
froggleston
84f486295d Add tests for new storing of backtest signal candles 2022-04-19 12:48:21 +01:00
Robert Davey
4b0f168e52 Merge branch 'freqtrade:develop' into v3_fixes 2022-04-19 12:10:30 +01:00
eSeR1805
76558f284f Fix user cancellation functionality. 2022-04-19 13:33:37 +03:00
eSeR1805
cea4f663d5 Merge branch 'develop' into feat_readjust_entry 2022-04-18 21:22:19 +03:00
eSeR1805
d24ee9032a Update usage in backtest. No functional update. 2022-04-18 21:21:38 +03:00
eSeR1805
d9f838a65f Update template usage to reflect changes. 2022-04-18 21:20:50 +03:00
eSeR1805
3166739ec9 Update strategy callback params and description. 2022-04-18 21:17:39 +03:00
eSeR1805
95e009b9cb Update adjustment functionality and add cancelation option 2022-04-18 21:16:45 +03:00
eSeR1805
2cac1b7dcc Add new (user cancellation) reason. 2022-04-18 21:14:35 +03:00
eSeR1805
541147c801 Update documentation to match feature changes. 2022-04-18 21:13:50 +03:00
Matthias
e4629a2730 Merge pull request #6694 from samgermain/notional-switch
switch notionalFloor -> minNotional and notionalCap -> maxNotional
2022-04-18 08:54:20 +02:00
Matthias
9b55b3875f Merge pull request #6700 from freqtrade/dependabot/pip/develop/types-requests-2.27.19
Bump types-requests from 2.27.16 to 2.27.19
2022-04-18 08:27:42 +02:00
Matthias
1ce20ea739 Bump requirements to 1.79.81, min-required to 1.79.69 2022-04-18 08:16:38 +02:00
Matthias
14ddd19584 Merge pull request #6696 from freqtrade/dependabot/pip/develop/fastapi-0.75.2
Bump fastapi from 0.75.1 to 0.75.2
2022-04-18 08:12:13 +02:00
dependabot[bot]
153b31c934 Bump types-requests from 2.27.16 to 2.27.19
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.16 to 2.27.19.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 06:11:57 +00:00
Matthias
3cae57cd91 Merge pull request #6702 from freqtrade/dependabot/pip/develop/nbconvert-6.5.0
Bump nbconvert from 6.4.5 to 6.5.0
2022-04-18 08:11:26 +02:00
Matthias
38254d2124 Merge pull request #6699 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.11
Bump types-python-dateutil from 2.8.10 to 2.8.11
2022-04-18 08:11:12 +02:00
Matthias
ef9d9e250f Merge pull request #6697 from freqtrade/dependabot/pip/develop/types-cachetools-5.0.1
Bump types-cachetools from 5.0.0 to 5.0.1
2022-04-18 08:10:51 +02:00
Matthias
63a774ac7f Merge pull request #6698 from freqtrade/dependabot/pip/develop/types-tabulate-0.8.7
Bump types-tabulate from 0.8.6 to 0.8.7
2022-04-18 08:10:37 +02:00
dependabot[bot]
b69483e3af Bump nbconvert from 6.4.5 to 6.5.0
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.4.5 to 6.5.0.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/6.4.5...6.5)

---
updated-dependencies:
- dependency-name: nbconvert
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 03:01:42 +00:00
dependabot[bot]
f020d129d7 Bump types-python-dateutil from 2.8.10 to 2.8.11
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.10 to 2.8.11.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 03:01:27 +00:00
dependabot[bot]
7d88dcb5f4 Bump types-tabulate from 0.8.6 to 0.8.7
Bumps [types-tabulate](https://github.com/python/typeshed) from 0.8.6 to 0.8.7.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-tabulate
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 03:01:24 +00:00
dependabot[bot]
2ff18e78c4 Bump types-cachetools from 5.0.0 to 5.0.1
Bumps [types-cachetools](https://github.com/python/typeshed) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-cachetools
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 03:01:22 +00:00
dependabot[bot]
a1e425a801 Bump fastapi from 0.75.1 to 0.75.2
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.75.1 to 0.75.2.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.75.1...0.75.2)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 03:01:19 +00:00
Sam Germain
80b34deb4d bump ccxt to 1.79.69 to account for https://github.com/ccxt/ccxt/pull/12873" 2022-04-17 14:38:34 -06:00
eSeR1805
17da4ca099 Use order_date_utc 2022-04-17 12:11:30 +03:00
Sam Germain
591a2fb7fc switch notionalFloor -> minNotional and notionalCap -> maxNotional 2022-04-16 21:47:44 -06:00
froggleston
34fb8dacd7 Fix isort complaints 2022-04-16 17:03:24 +01:00
froggleston
b738c4e695 Fix flake8 complaints 2022-04-16 16:49:20 +01:00
froggleston
7210a11730 Fix flake8 complaints 2022-04-16 16:37:06 +01:00
froggleston
a63affc5f1 Fix flake8 complaints 2022-04-16 16:32:04 +01:00
froggleston
f55a9940a7 Fix line spacing 2022-04-16 16:15:04 +01:00
froggleston
b1bcf9f33c Fix backtest_enable typo 2022-04-16 14:58:17 +01:00
froggleston
8990ba2709 Fix store signal candles 2022-04-16 14:49:53 +01:00
froggleston
21734c5de7 Add pickle import 2022-04-16 14:46:30 +01:00
froggleston
26ba899d7d Add constant, boolean check, rename option to fit with other x_enable, check that RunMode is BACKTEST 2022-04-16 14:37:36 +01:00
Robert Davey
afd3a32883 Merge branch 'develop' into v3_fixes 2022-04-16 14:23:13 +01:00
eSeR1805
698c25f133 Fix issues reported by flake. 2022-04-16 15:44:07 +03:00
eSeR1805
d65b64a46f Merge branch 'develop' into feat_readjust_entry 2022-04-16 15:20:50 +03:00
eSeR1805
237d116d8c Update existing tests to use the new func name. 2022-04-16 15:08:54 +03:00
eSeR1805
452f44206a Add new callback to advanced template. 2022-04-16 15:08:09 +03:00
eSeR1805
bf5799ef9e Add new functionality to backtesting. 2022-04-16 15:07:18 +03:00
eSeR1805
f8a7fdd5ed Add new callback to strategy interface. 2022-04-16 15:04:22 +03:00
eSeR1805
317c1e0746 Add option to handle_cancel_enter to prevent closing trade. 2022-04-16 15:03:44 +03:00
eSeR1805
76c545ba0d Reorganize, rename, redescribe and add new functionality 2022-04-16 15:03:09 +03:00
eSeR1805
e5d4f7766e Add new cancel reason for when replacing orders. 2022-04-16 14:44:41 +03:00
eSeR1805
16b6b08227 Update docs to include info on new functionality. 2022-04-16 14:42:41 +03:00
Matthias
4019c05fee Update entry/exit timeout documentation
the type of order is now an Order, no longer a dictionary.

closes #6691
2022-04-16 06:48:12 +02:00
Matthias
a4ec8984cd Merge pull request #6685 from freqtrade/bt_load_history
Backtesting load history
2022-04-15 16:06:20 +02:00
Matthias
75d6a92e62 Merge pull request #6689 from kokimame/avoid-case-amount-zero
Avoid ignoring the case precision amount = 0
2022-04-15 15:20:18 +02:00
Matthias
f61d4d36c3 Add test for 0 precision amount 2022-04-15 14:48:09 +02:00
kokimame
d23d830346 Avoid ignoring the case precision amount = 0 2022-04-15 00:35:11 +09:00
Italo
1153e65b3e fix flake8 2022-04-14 14:34:04 +01:00
Italo
340c0ea391 update is_random before asked_non_tried
is_random depends on asked_non_tried and needs to be updated first
2022-04-14 14:15:11 +01:00
Matthias
4acb77305a Don't break when running hyperopt-x tools on old resuts 2022-04-13 19:33:27 +02:00
Matthias
b1a6db8d29 Fix bad usage of base_currency 2022-04-13 19:24:21 +02:00
Italo
35cea6dcfa fix unique_list 2022-04-13 09:36:46 +01:00
Matthias
f89b64c972 Improve test by having multistrat.meta file available 2022-04-13 07:09:26 +02:00
Matthias
4ac54a76af Add strategy as mandatory argument 2022-04-13 06:47:39 +02:00
Italo
fa298d6f1c fix unique_list logic 2022-04-12 23:57:40 +01:00
Matthias
dd5693f4e5 Add note about binance Futures trading rules
closes #6683
2022-04-12 07:21:30 +02:00
Matthias
0c87702545 test for backtest history 2022-04-12 06:28:37 +02:00
Nicolas Papp
c8e4687833 Plots and hyperopt 2022-04-11 16:41:48 -03:00
Matthias
4254d86658 Move test-backtestfiles to separate directory 2022-04-11 20:32:02 +02:00
Matthias
85e7deb2cd Add loading of historic backtest result 2022-04-11 20:04:47 +02:00
Matthias
d9039152ba Add "get backtest historic results" endpoint 2022-04-11 19:44:47 +02:00
Nicolas Papp
178240aa6c Merge branch 'develop' of https://github.com/nicolaspapp/freqtrade into feat/relative-drawdown 2022-04-11 14:42:10 -03:00
Matthias
baefda80d1 Enable flake8 E226 rule 2022-04-11 18:02:06 +02:00
Matthias
1084787a38 Add note for Update releases 2022-04-11 17:48:39 +02:00
Matthias
43779232e1 Inlcude docs requirements in dev dependencies
developers should also be able to render the docs without further action.
2022-04-11 07:13:31 +02:00
Matthias
3e2d9725dd Merge pull request #6680 from freqtrade/dependabot/pip/develop/ccxt-1.78.62
Bump ccxt from 1.77.98 to 1.78.62
2022-04-11 07:12:12 +02:00
Matthias
7f9ea581ea Merge pull request #6681 from freqtrade/dependabot/pip/develop/prompt-toolkit-3.0.29
Bump prompt-toolkit from 3.0.28 to 3.0.29
2022-04-11 07:02:15 +02:00
Matthias
f688c6e568 Merge pull request #6679 from freqtrade/dependabot/pip/develop/plotly-5.7.0
Bump plotly from 5.6.0 to 5.7.0
2022-04-11 06:34:44 +02:00
dependabot[bot]
c93bed5e2b Bump ccxt from 1.77.98 to 1.78.62
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.77.98 to 1.78.62.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.77.98...1.78.62)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 04:28:17 +00:00
Matthias
0f6ef6c798 Merge pull request #6678 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.35
Bump sqlalchemy from 1.4.34 to 1.4.35
2022-04-11 06:27:08 +02:00
Matthias
75a0ed075b Merge pull request #6677 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.9
Bump mkdocs-material from 8.2.8 to 8.2.9
2022-04-11 06:26:50 +02:00
dependabot[bot]
5edae71d28 Bump prompt-toolkit from 3.0.28 to 3.0.29
Bumps [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) from 3.0.28 to 3.0.29.
- [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.28...3.0.29)

---
updated-dependencies:
- dependency-name: prompt-toolkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 03:01:53 +00:00
dependabot[bot]
739cd773c3 Bump plotly from 5.6.0 to 5.7.0
Bumps [plotly](https://github.com/plotly/plotly.py) from 5.6.0 to 5.7.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/v5.6.0...v5.7.0)

---
updated-dependencies:
- dependency-name: plotly
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 03:01:39 +00:00
dependabot[bot]
72fd4bf337 Bump sqlalchemy from 1.4.34 to 1.4.35
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.34 to 1.4.35.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 03:01:36 +00:00
dependabot[bot]
84fca32ed9 Bump mkdocs-material from 8.2.8 to 8.2.9
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.8 to 8.2.9.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.8...8.2.9)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-11 03:01:29 +00:00
Sam Germain
64e6729ae9 docs for recursive_strategy_search 2022-04-10 18:56:28 -06:00
Sam Germain
c876d42e36 safe check for recursive_strategy_search in strategy_resolver 2022-04-10 18:50:51 -06:00
Sam Germain
9070114417 Merge branch 'recursive-strategy-folder' of https://github.com/samgermain/freqtrade into recursive-strategy-folder 2022-04-10 18:45:09 -06:00
Sam Germain
d5ce868f1a removed 1 letter alias for recursive-strategy-folder 2022-04-10 18:44:33 -06:00
Nicolas Papp
47a6ef4f00 Max relative drawdown 2022-04-10 12:53:47 -03:00
Matthias
68fe7476c9 Update more terminology to forceexit 2022-04-10 15:56:29 +02:00
Matthias
77c840c2a4 Fix syntax-error in exit_reason migration 2022-04-10 15:10:13 +02:00
Matthias
9556af1e6c Improve documentation for config imports 2022-04-10 10:14:34 +02:00
Matthias
cd2e49bb60 Simplify downloading futures data code 2022-04-10 09:53:33 +02:00
Matthias
95f69a8c3b Remove some outdated TODO's 2022-04-10 09:53:33 +02:00
Matthias
1951ee8e29 Merge pull request #6615 from cyberjunky/cyber-forcesell-tg
Add selection buttons for trades to forcesell cmd in telegram
2022-04-10 09:51:35 +02:00
Matthias
2653d83fee Merge branch 'develop' into pr/cyberjunky/6615 2022-04-10 09:24:53 +02:00
Matthias
54633e90a7 Merge branch 'develop' into pr/italodamato/6563 2022-04-10 09:16:31 +02:00
Matthias
a99cbe459c Merge pull request #6671 from freqtrade/custom_exit_profit
Custom exit - call it independent of profit
2022-04-10 09:09:45 +02:00
Matthias
282804463c Add Documentation for /forceexit without parameter 2022-04-10 09:07:51 +02:00
Matthias
ffff45e76b simplify exit message 2022-04-10 08:44:49 +02:00
Matthias
850760bc00 Remove migration from very old database
(database without Orders table)
2022-04-10 08:43:30 +02:00
Matthias
46c18dfce2 Merge pull request #6670 from freqtrade/store_asset
store base and quote currency separately in the database
2022-04-10 08:42:28 +02:00
Matthias
105e7ea1a9 Merge pull request #6675 from zolbayars/update-plotting-documentation
Docs: update plotting doc to show strategy option is mandatory
2022-04-10 07:32:46 +02:00
zolbayars
09b41a6f8d Docs: update plotting doc to show strategy option is mandatory 2022-04-10 10:39:48 +08:00
Matthias
710089b46c Merge pull request #6673 from RafaelDorigo/develop
Update strategy_migration.md
2022-04-09 20:07:24 +02:00
RafaelDorigo
9f9219675f Update strategy_migration.md 2022-04-09 19:58:58 +02:00
Matthias
6ebd30db88 Merge pull request #6665 from freqtrade/config_from_config
Allow recursive loading of configuration files
2022-04-09 17:18:51 +02:00
Matthias
114591048c Always call custom_sell - also when there's a new enter signal 2022-04-09 17:17:49 +02:00
Matthias
139b65835c Only show long/short signals on telegram for non-spot markets 2022-04-09 17:09:17 +02:00
Matthias
ef18d09161 Call custom_exit also when the trade is not in profit and exit_profit_only is set. 2022-04-09 16:50:38 +02:00
Matthias
8e98a2ff9f api - provide assset_currency via API 2022-04-09 16:42:18 +02:00
Matthias
81b41183a5 Merge pull request #6668 from RafaelDorigo/develop
Fixed setup.sh
2022-04-09 15:35:26 +02:00
RafaelDorigo
e606051102 Fixed setup.sh 2022-04-09 11:53:47 +02:00
Matthias
f385e2c2b6 Update test to also cover "no trade found" scenario 2022-04-09 10:04:10 +02:00
Matthias
ebcb530d4f Log if no stake-amount is left for trade 2022-04-09 09:58:03 +02:00
Matthias
cbdaaf705c Merge pull request #6636 from mkavinkumar1/pre-commit
added pre-commit
2022-04-09 09:50:54 +02:00
Matthias
ddfc68d533 Add test case for interactive telegram exit 2022-04-09 09:41:01 +02:00
Matthias
9cd92ed48c Fix forceexit to work 2022-04-09 09:24:20 +02:00
Matthias
40eb3f274f Fix merge mistake 2022-04-09 08:36:22 +02:00
Matthias
392967a26f Update formatting 2022-04-08 18:07:01 +02:00
Matthias
967bbe99bb Merge branch 'develop' into pr/cyberjunky/6615 2022-04-08 18:05:27 +02:00
Matthias
16e64ddf97 Update docs for multi-config loading 2022-04-08 17:59:16 +02:00
Matthias
ecb0e43c2a Improve pre-commit docs 2022-04-08 17:50:32 +02:00
Matthias
b8556498ef Fix pre-commit to actually work 2022-04-08 17:46:53 +02:00
Matthias
238ff6c9fe Use better naming 2022-04-08 17:30:23 +02:00
Matthias
1435d26996 store config-file loading paths 2022-04-08 17:26:51 +02:00
Matthias
3427df0653 Add simple test for recursive loading 2022-04-08 16:11:18 +02:00
Matthias
1ea49ce864 Support nested configurations 2022-04-08 15:50:44 +02:00
Matthias
aee0cfd17a forcebuy_enable -> force_entry_enable 2022-04-08 13:39:41 +02:00
Italo
1559692e47 Update hyperopt.py
remove duplicates from list of asked points
2022-04-08 11:44:42 +01:00
Matthias
ef2f8be526 Merge pull request #6653 from mkavinkumar1/renaming-forceentry-forceexit
renamed forceentry forceexit
2022-04-08 12:31:48 +02:00
Matthias
075fc6d35e Apply suggestions from code review 2022-04-08 11:45:03 +02:00
மனோஜ்குமார் பழனிச்சாமி
0e9b348868 Update api_v1.py 2022-04-08 11:08:11 +05:30
மனோஜ்குமார் பழனிச்சாமி
ca400b8195 Updated requested changes in PR #6653 2022-04-08 10:45:05 +05:30
மனோஜ்குமார் பழனிச்சாமி
f7020df097 Updating requested changes in PR #6653 2022-04-08 07:07:51 +05:30
மனோஜ்குமார் பழனிச்சாமி
9417bb01dc Merge branch 'develop' into renaming-forceentry-forceexit 2022-04-08 00:01:51 +05:30
மனோஜ்குமார் பழனிச்சாமி
9ee53b5f9e Update docs/telegram-usage.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2022-04-07 23:55:07 +05:30
Matthias
1347107c1e extract load_from_files to load_config 2022-04-07 20:15:06 +02:00
Matthias
673b3034ee Simplify load_from_files 2022-04-07 20:05:51 +02:00
Matthias
bdd9f584fa Update some docs terminology 2022-04-07 20:04:16 +02:00
Matthias
a659bcb60b Update some docs terminology 2022-04-07 19:46:00 +02:00
Matthias
ea1c55b161 Update backtesting to use row instead of sell_row 2022-04-07 19:43:34 +02:00
Matthias
890694da08 Merge pull request #6661 from SmartManoj/patch-5
Update fiat_convert.py
2022-04-07 19:25:58 +02:00
Matthias
cbbbe8a5ba Fix test using existing config file, therefore becomming fluky 2022-04-07 09:08:17 +00:00
Matthias
3188d036a6 improve trading_mode handling
Ensure trading_mode is set by new-config
handle empty strings to default to spot.

closes #6663
2022-04-07 08:45:45 +00:00
மனோஜ்குமார் பழனிச்சாமி
7bf3475fbd Update fiat_convert.py 2022-04-07 10:28:55 +05:30
Matthias
299dd84cfe Merge pull request #6656 from freqtrade/use_sell_signal
Use sell signal -> use_exit_signal
2022-04-06 19:46:46 +02:00
Matthias
916764d4f2 Merge pull request #6658 from mkavinkumar1/rename-enter-side
renamed enter-side
2022-04-06 19:32:55 +02:00
Matthias
28b58712fb Add compatibility shim for trade.entry_trade 2022-04-06 19:13:46 +02:00
Matthias
d5ec79c0b9 Update deprecated settings to support non-nested transitions 2022-04-06 19:09:34 +02:00
Matthias
62d13a9f74 Fix test indentation 2022-04-06 16:03:11 +02:00
Matthias
146d6e7c6c Add UAH to supported fiat currencies
closes #6657
2022-04-06 06:43:06 +02:00
மனோஜ்குமார் பழனிச்சாமி
b751dd339a Update test_rpc_telegram.py 2022-04-06 07:23:43 +05:30
மனோஜ்குமார் பழனிச்சாமி
aa76191636 fixed tests 2022-04-06 07:19:00 +05:30
மனோஜ்குமார் பழனிச்சாமி
28f4a3b373 updated for PR #6653 2022-04-06 07:05:43 +05:30
மனோஜ்குமார் பழனிச்சாமி
7e97e58820 renamed enter-side 2022-04-06 06:32:13 +05:30
Matthias
8d95e76d26 Add tests for new naming definitions 2022-04-05 20:43:39 +02:00
Matthias
82e9f62381 Add missing setting in arguments.py 2022-04-05 20:27:32 +02:00
Matthias
a09637cbe1 Update migration documentation with new settings 2022-04-05 20:25:31 +02:00
Matthias
b1378efdeb ignore_roi_if_buy_signal -> ignore_roi_if_entry_signal 2022-04-05 20:21:39 +02:00
Matthias
5bafdb6108 Update testcase 2022-04-05 20:15:08 +02:00
Matthias
4897731030 use_sell_signal -> use_exit_signal 2022-04-05 20:10:20 +02:00
Matthias
5ce5c70be6 sell_profit_offset -> exit_profit_offset 2022-04-05 20:03:27 +02:00
Matthias
bba9629a2a Rename sell_profit_only to exit_profit_only 2022-04-05 20:00:35 +02:00
மனோஜ்குமார் பழனிச்சாமி
5fa96174e1 Update test_rpc.py 2022-04-05 16:58:30 +05:30
மனோஜ்குமார் பழனிச்சாமி
8442fb915f renamed 2022-04-05 16:01:53 +05:30
மனோஜ்குமார் பழனிச்சாமி
0d93916f79 Update developer.md 2022-04-05 11:28:22 +05:30
Matthias
5c01969969 Fix messed up doc rendering 2022-04-05 07:13:09 +02:00
மனோஜ்குமார் பழனிச்சாமி
57af08fde7 updated requested changes in PR #6636 2022-04-05 10:21:07 +05:30
Matthias
2a46e6a214 Change some sell terminology 2022-04-05 06:50:44 +02:00
Matthias
31bdaedc33 Fix messed up doc rendering 2022-04-05 06:47:55 +02:00
Matthias
d3e6fa19d5 Merge pull request #6648 from freqtrade/exit_type_rename
Exit type rename
2022-04-05 06:44:56 +02:00
Matthias
89355a212e Improve wording on strategy migration 2022-04-04 19:53:56 +02:00
Matthias
4cd4edf08b Update exit_reasons while migrating the database 2022-04-04 19:52:26 +02:00
Matthias
2b55f45be0 Improve deprecated documentation 2022-04-04 19:45:52 +02:00
Matthias
0db5d9f7fa Update telegram message formatting 2022-04-04 19:37:23 +02:00
Matthias
7d3116f9fb webhookbuy -> webhookentry 2022-04-04 19:32:27 +02:00
Matthias
eff636ba53 Update RPC message types to ENTRY 2022-04-04 19:29:15 +02:00
Matthias
125dff1dad Properly deprecate webhook settings (with transition) 2022-04-04 19:21:13 +02:00
Matthias
5ecb695e50 Update deprecated notification settings 2022-04-04 19:17:11 +02:00
Matthias
129a7c632c Update method names 2022-04-04 19:14:21 +02:00
Matthias
8a9839fb6d Update telegram notification settings 2022-04-04 19:10:44 +02:00
Matthias
0b88185c2c Sell-fill -> exit_fill 2022-04-04 19:08:50 +02:00
Matthias
8b33d9cdb2 sell_cancel -> exit_cancel 2022-04-04 19:07:20 +02:00
Matthias
6a0110aa3c Update webhook configuration 2022-04-04 19:05:36 +02:00
Matthias
6d9218cb34 sell_signal -> exit_signal 2022-04-04 17:11:11 +02:00
Matthias
1917527179 custom_sell -> custom_exit 2022-04-04 17:04:43 +02:00
Matthias
cd146bfa8f emergency_sell -> emergency_exit 2022-04-04 17:03:27 +02:00
Matthias
54ad130bb9 Update force_sell to force_exit 2022-04-04 16:59:27 +02:00
Matthias
33841da382 Slightly imporve Typing by reusing long/short type 2022-04-04 16:51:57 +02:00
Matthias
f8783c908e Add side to custom_entry_price 2022-04-04 16:48:27 +02:00
Matthias
61faee1e7d Merge pull request #6644 from freqtrade/dependabot/pip/develop/pandas-1.4.2
Bump pandas from 1.4.1 to 1.4.2
2022-04-04 10:54:15 +02:00
Matthias
0bb696bfed Merge pull request #6642 from freqtrade/dependabot/pip/develop/types-requests-2.27.16
Bump types-requests from 2.27.15 to 2.27.16
2022-04-04 07:38:01 +02:00
Matthias
2bca27b337 Merge pull request #6643 from freqtrade/dependabot/pip/develop/fastapi-0.75.1
Bump fastapi from 0.75.0 to 0.75.1
2022-04-04 07:37:50 +02:00
dependabot[bot]
ef65bece7b Bump pandas from 1.4.1 to 1.4.2
Bumps [pandas](https://github.com/pandas-dev/pandas) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Changelog](https://github.com/pandas-dev/pandas/blob/main/RELEASE.md)
- [Commits](https://github.com/pandas-dev/pandas/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: pandas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 05:05:50 +00:00
Matthias
ff1c486cf7 Merge pull request #6645 from freqtrade/dependabot/pip/develop/ccxt-1.77.98
Bump ccxt from 1.77.97 to 1.77.98
2022-04-04 07:04:50 +02:00
dependabot[bot]
655165ace0 Bump ccxt from 1.77.97 to 1.77.98
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.77.97 to 1.77.98.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.77.97...1.77.98)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 04:37:13 +00:00
Matthias
9e72d50e64 Merge pull request #6639 from freqtrade/dependabot/pip/develop/ccxt-1.77.97
Bump ccxt from 1.77.45 to 1.77.97
2022-04-04 06:34:16 +02:00
Matthias
9a68eeb649 Merge pull request #6640 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.34
Bump sqlalchemy from 1.4.32 to 1.4.34
2022-04-04 06:33:38 +02:00
Matthias
2c8df83e9a Merge pull request #6641 from freqtrade/dependabot/pip/develop/nbconvert-6.4.5
Bump nbconvert from 6.4.4 to 6.4.5
2022-04-04 06:26:07 +02:00
dependabot[bot]
d5ec95e8e0 Bump fastapi from 0.75.0 to 0.75.1
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.75.0 to 0.75.1.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.75.0...0.75.1)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 03:01:46 +00:00
dependabot[bot]
d668416d9c Bump types-requests from 2.27.15 to 2.27.16
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.15 to 2.27.16.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 03:01:37 +00:00
dependabot[bot]
225f6d1525 Bump nbconvert from 6.4.4 to 6.4.5
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.4.4 to 6.4.5.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/6.4.4...6.4.5)

---
updated-dependencies:
- dependency-name: nbconvert
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 03:01:35 +00:00
dependabot[bot]
20f032601a Bump sqlalchemy from 1.4.32 to 1.4.34
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.32 to 1.4.34.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 03:01:33 +00:00
dependabot[bot]
74ff9f551b Bump ccxt from 1.77.45 to 1.77.97
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.77.45 to 1.77.97.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.77.45...1.77.97)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-04 03:01:26 +00:00
Matthias
69491c1430 Update more wording to "exit" 2022-04-03 19:39:13 +02:00
Matthias
283d04a5ad Update docstring wording 2022-04-03 19:36:32 +02:00
Matthias
dc462e63fe update BTContainer use_sell_signal 2022-04-03 19:27:30 +02:00
Matthias
9dfb3db1aa Update local variable 2022-04-03 19:22:59 +02:00
மனோஜ்குமார் பழனிச்சாமி
e2a42d3027 added pre-commit 2022-04-03 18:57:58 +05:30
Ron Klinkien
dd61886341 Readded missing keyboard commands
Rename forcesell methods to forceexit
2022-04-03 12:29:29 +02:00
Matthias
8acffbc1d8 sell_type -> exit_type 2022-04-03 11:18:36 +02:00
Matthias
2d2bea17e7 sell_order_status -> exit_order_status 2022-04-03 11:17:01 +02:00
Matthias
d054916439 Merge pull request #6632 from freqtrade/short_terminology
Short terminology
2022-04-03 11:10:16 +02:00
Matthias
d94b73b396 Update some documentation 2022-04-03 10:44:27 +02:00
Matthias
a27c837d18 Update sell_reason to exit_reason 2022-04-03 10:41:35 +02:00
Matthias
cd78792f48 Improve some telegram terminology 2022-04-03 10:40:13 +02:00
Ron Klinkien
936ada5699 Fixed syntax error 2022-04-03 09:58:55 +02:00
Matthias
157f8f8139 Update some more sell_reason occurances 2022-04-03 08:17:17 +02:00
Matthias
e894f620c2 Improve compatibility 2022-04-03 08:15:23 +02:00
Matthias
240ca421af Merge pull request #6630 from SmartManoj/patch-4
checking exchange name with lower
2022-04-02 20:09:10 +02:00
Matthias
ec63cfd656 Add compatibility layer for backtesting results 2022-04-02 20:04:30 +02:00
Matthias
543aa74278 update sell_reason to exit_reason 2022-04-02 20:04:29 +02:00
Ron Klinkien
f89265e0fb Merge branch 'develop' into cyber-forcesell-tg 2022-04-02 20:02:42 +02:00
Matthias
39d925c295 Change to precise casing instead of .lower() 2022-04-02 19:48:01 +02:00
Matthias
b0fab3ad50 Properly handle empty dataframes after trimming
closes #6629
2022-04-02 16:16:29 +02:00
Matthias
f742d21690 Add test showing #6629 2022-04-02 16:16:26 +02:00
Matthias
7c5e730007 Merge pull request #6628 from topscoder/patch-2
Fixes CoinGecko typos in fiat_convert
2022-04-02 08:16:32 +02:00
மனோஜ்குமார் பழனிச்சாமி
40b4a9977e checking exchange name with lower 2022-04-02 11:23:06 +05:30
topscoder
60d52f0a20 Consistent CoinGecko naming in test_fiat_convert.py 2022-04-01 20:57:09 +02:00
topscoder
7db3c846b4 Fixes CoinGecko typos in fiat_convert.py 2022-04-01 20:52:16 +02:00
Matthias
0b40c37cc5 Merge pull request #6624 from samgermain/lev-docs
docs for shorting
2022-04-01 20:29:41 +02:00
Stefano Ariestasia
da0688b6aa Revert "Add exchange id for binance Futures"
This reverts commit 3c8387ab61.
2022-04-02 03:20:21 +09:00
Matthias
2f967f6df9 Slightly change wording, fix links 2022-04-01 20:01:57 +02:00
Sam Germain
b4b594c0dd docs on setting enter_short and exit_short 2022-04-01 06:02:32 -06:00
Sam Germain
476c6416cc docs/strategy-customization enter_short and exit_short 2022-04-01 05:59:59 -06:00
Sam Germain
3e10849e02 short docs added link to strategy migration guide 2022-04-01 05:55:00 -06:00
Stefano Ariestasia
3c8387ab61 Add exchange id for binance Futures 2022-04-01 20:48:13 +09:00
Sam Germain
dd7f9c6f8b docs for shorting 2022-04-01 05:47:26 -06:00
Matthias
b40c017af5 Merge pull request #6623 from stash86/patch-1
fix some typo
2022-04-01 12:49:03 +02:00
Stefano Ariestasia
0c096e4e03 fix some typo 2022-04-01 19:28:42 +09:00
Matthias
889fa7bac2 Add small offset to time to avoid random fails 2022-04-01 10:49:21 +02:00
Matthias
d1ea5ea856 Merge pull request #6622 from freqtrade/short_plot
Short plot
2022-04-01 09:18:37 +02:00
Ron Klinkien
f029702bd1 Fixed flake8 issues 2022-04-01 09:16:35 +02:00
Matthias
775305e9c4 Use correct candleconfig in plot endpoint 2022-04-01 08:57:58 +02:00
Matthias
fe3260aae2 Remove false statement about plotting futures data 2022-04-01 08:51:11 +02:00
Matthias
a13d4e5519 Renumber backtest-detail tests 2022-04-01 07:00:51 +02:00
Matthias
e3a624cf68 Fix futures plotting 2022-04-01 06:44:17 +02:00
Sam Germain
4b238987b0 plot.generate_candlestick_graph Added short equivelent, separating plotting scatter creation to a function 2022-04-01 06:27:42 +02:00
Matthias
c57d807845 Merge pull request #6552 from freqtrade/feat/short
Feat/short
2022-03-31 21:23:57 +02:00
Matthias
0c9bbc753f Fix random test failure by setting fixed time passed 2022-03-31 20:00:55 +02:00
Matthias
0cba4ec460 Fix doc typo 2022-03-31 19:14:11 +02:00
Sam Germain
2fe5a1594f Add conditional to recursive strategy searching if in config 2022-03-31 08:21:15 -06:00
Sam Germain
b4b809ff8e changed recursive to recursive_strategy_search 2022-03-31 08:16:21 -06:00
Sam Germain
f44ae494fb Added recursive to configuration 2022-03-31 08:12:02 -06:00
Sam Germain
185daf5772 add recursive command line option 2022-03-31 08:12:02 -06:00
Sam Germain
6df15a7af9 Recursively search subdirectories in user_data/strategies for a strategy 2022-03-31 08:12:02 -06:00
Ron Klinkien
3d8cfa7ea5 Several fixes
Code optimizations
2022-03-31 08:30:20 +02:00
Matthias
94274e4823 Remove order.leverage column 2022-03-31 06:57:16 +02:00
Matthias
e3471129f7 Update documentation structure, add links to migration page 2022-03-31 06:53:33 +02:00
Matthias
2d914c8e13 Simplify formatting in exchange class 2022-03-30 20:02:56 +02:00
Ron Klinkien
6c811b3de1 Made regex strings raw
Removed unwanted changes
2022-03-30 19:57:02 +02:00
Matthias
1f6ca29bbf Update comment 2022-03-30 19:38:25 +02:00
Matthias
8e7fa9f6c8 Update bot test formatting 2022-03-30 19:32:52 +02:00
Matthias
95b0e682b5 Merge pull request #6618 from samgermain/doc-help
Add trading mode to list-pairs and list-markets output in docs
2022-03-30 19:10:08 +02:00
Sam Germain
527c4277d8 Add trading mode to list-pairs and list-markets output in docs 2022-03-30 05:29:11 -06:00
Ron Klinkien
c42af7d095 Fixed typo in test file 2022-03-30 12:41:41 +02:00
Ron Klinkien
3ed7f3f2df Display all trade info in buttons
First step to fix tests for changed forcesell code
2022-03-30 12:28:30 +02:00
Italo
e85c7ca8ff remove blank line 2022-03-30 09:50:37 +01:00
Italo
8d4afc0eaf Merge branch 'opt-ask-force-new-points' of https://github.com/italodamato/freqtrade-1 into opt-ask-force-new-points 2022-03-30 09:49:07 +01:00
Italo
bad179ebaa fix merge mess
This reverts commit 9f171193ef.
2022-03-30 09:48:10 +01:00
Italo
b560248165 Merge branch 'develop' into opt-ask-force-new-points 2022-03-30 09:42:38 +01:00
Italo
3e24d01af4 fix flake8 2022-03-30 09:41:40 +01:00
Italo
9f171193ef Revert "Merge branch 'plot_hyperopt_stats' into opt-ask-force-new-points"
This reverts commit 4eb9cc6e8b, reversing
changes made to a3b401a762.
2022-03-30 09:39:07 +01:00
Matthias
2af31672c6 Merge pull request #6608 from stash86/patch-1
Add few lines to docs
2022-03-30 07:21:52 +02:00
Matthias
b91b7b4464 Fix hyperopt assigning sell_signal to wrong field 2022-03-30 07:16:48 +02:00
Matthias
9a7867971a Update wording to new pricing definition 2022-03-30 07:13:28 +02:00
Matthias
dafc2bf361 Merge branch 'develop' into feat/short 2022-03-30 07:09:41 +02:00
Matthias
e1ccbdb927 Merge pull request #6607 from freqtrade/short_pricing
Short pricing updates
2022-03-30 06:59:40 +02:00
Stefano Ariestasia
02aded68f9 Update strategy-customization.md 2022-03-30 08:37:35 +09:00
Stefano Ariestasia
4d5f6ed5e2 Update strategy-customization.md 2022-03-30 08:37:11 +09:00
Stefano Ariestasia
c615e4fcc2 updates 2022-03-30 08:35:49 +09:00
Italo
4eb9cc6e8b Merge branch 'plot_hyperopt_stats' into opt-ask-force-new-points 2022-03-30 00:30:33 +01:00
Italo
a3b401a762 highlight random points in hyperopt results table 2022-03-30 00:29:14 +01:00
Italo
229b0b037e reduce search loops 2022-03-29 19:33:35 +01:00
Matthias
ddb0254999 Merge pull request #6614 from krimsonkla/jmr/kucoin_ohlcv_candle_limit
Update kucoin candle limit
2022-03-29 20:18:52 +02:00
Matthias
f84b24dee9 Bump ccxt to 1.77.45
closes #6610
2022-03-29 20:06:25 +02:00
Matthias
7def1398c8 Merge pull request #6603 from adrianceding/fix_timeout
Fix using future data to fill when use timeout
2022-03-29 19:50:34 +02:00
Ron Klinkien
29d6725fb7 Allow forcesell to be a valid keyboard option 2022-03-29 19:41:49 +02:00
Ron Klinkien
46acc8352f Add selection buttons for trades to forcesell cmd in telegram 2022-03-29 19:19:07 +02:00
Matthias
648e969a7a Realign entry_pricing fields 2022-03-29 19:07:29 +02:00
Italo
a1816434b7 Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-03-29 17:24:40 +01:00
Jason Risch
6b57be35e9 Update kucoin candle limit 2022-03-29 07:23:45 -07:00
Matthias
c1657dfb7b Update / align documentation 2022-03-29 06:58:41 +02:00
Stefano Ariestasia
05db0067ee Add few missing info on shorting setup 2022-03-29 10:51:36 +09:00
Stefano Ariestasia
7c2e8420af Add note that enter_long must be set 2022-03-29 09:27:30 +09:00
Matthias
8ebef914e2 Update pricing documentation 2022-03-28 20:20:10 +02:00
Matthias
2d740230f7 price_last_balance renaming 2022-03-28 19:53:55 +02:00
Matthias
d7c6520268 Update remaining tests 2022-03-28 19:30:14 +02:00
Matthias
cee09493be Update market order validation 2022-03-28 19:25:46 +02:00
Matthias
440967e483 Update some tests 2022-03-28 19:17:22 +02:00
Matthias
88f6663f58 Merge pull request #6599 from freqtrade/dependabot/pip/develop/jinja2-3.1.1
Bump jinja2 from 3.0.3 to 3.1.1
2022-03-28 19:09:14 +02:00
Matthias
9aa821a953 Merge pull request #6604 from SmartManoj/patch-3
Corrected test_create_order
2022-03-28 16:19:03 +02:00
மனோஜ்குமார் பழனிச்சாமி
5552ad779c Corrected test_create_order 2022-03-28 19:31:12 +05:30
adriance
d6082c33a7 fix type error 2022-03-28 21:29:50 +08:00
adriance
a0971a3e2c fix using future data to fill when use timeout 2022-03-28 21:00:05 +08:00
Adriance
cb48071f1f Merge branch 'freqtrade:feat/short' into feat/short 2022-03-28 20:20:11 +08:00
dependabot[bot]
89e7b3705b Bump jinja2 from 3.0.3 to 3.1.1
Bumps [jinja2](https://github.com/pallets/jinja) from 3.0.3 to 3.1.1.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.0.3...3.1.1)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 08:25:34 +00:00
Matthias
ffd77fa418 Merge pull request #6594 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.8
Bump mkdocs-material from 8.2.5 to 8.2.8
2022-03-28 10:24:50 +02:00
Matthias
a6dc8dd902 Merge pull request #6597 from freqtrade/dependabot/pip/develop/mypy-0.942
Bump mypy from 0.941 to 0.942
2022-03-28 10:24:16 +02:00
Matthias
f70166270d Update pricing to use entry/exit pricing 2022-03-28 07:07:46 +02:00
Matthias
2f429bf7ec Merge pull request #6602 from freqtrade/dependabot/github_actions/develop/actions/cache-3
Bump actions/cache from 2 to 3
2022-03-28 06:51:47 +02:00
dependabot[bot]
3cffaed8df Bump mypy from 0.941 to 0.942
Bumps [mypy](https://github.com/python/mypy) from 0.941 to 0.942.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.941...v0.942)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 04:30:07 +00:00
dependabot[bot]
b321c0f5fb Bump mkdocs-material from 8.2.5 to 8.2.8
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.5 to 8.2.8.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.5...8.2.8)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 04:30:05 +00:00
Matthias
202c4573ba Merge pull request #6595 from freqtrade/dependabot/pip/develop/ccxt-1.77.36
Bump ccxt from 1.76.65 to 1.77.36
2022-03-28 06:29:16 +02:00
Matthias
b51e2e0391 Merge pull request #6598 from freqtrade/dependabot/pip/develop/types-requests-2.27.15
Bump types-requests from 2.27.14 to 2.27.15
2022-03-28 06:28:45 +02:00
Matthias
dc3998a03e Merge pull request #6596 from freqtrade/dependabot/pip/develop/mkdocs-1.3.0
Bump mkdocs from 1.2.3 to 1.3.0
2022-03-28 06:27:59 +02:00
Matthias
350c094cda Merge pull request #6593 from freqtrade/dependabot/pip/develop/pytest-asyncio-0.18.3
Bump pytest-asyncio from 0.18.2 to 0.18.3
2022-03-28 06:25:31 +02:00
Matthias
24be0228e2 Merge pull request #6601 from freqtrade/dependabot/github_actions/develop/peter-evans/dockerhub-description-3
Bump peter-evans/dockerhub-description from 2.4.3 to 3
2022-03-28 06:24:28 +02:00
dependabot[bot]
c570732157 Bump actions/cache from 2 to 3
Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 03:16:05 +00:00
dependabot[bot]
449af0ce9c Bump peter-evans/dockerhub-description from 2.4.3 to 3
Bumps [peter-evans/dockerhub-description](https://github.com/peter-evans/dockerhub-description) from 2.4.3 to 3.
- [Release notes](https://github.com/peter-evans/dockerhub-description/releases)
- [Commits](https://github.com/peter-evans/dockerhub-description/compare/v2.4.3...v3)

---
updated-dependencies:
- dependency-name: peter-evans/dockerhub-description
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 03:16:02 +00:00
dependabot[bot]
6f64e8da8d Bump types-requests from 2.27.14 to 2.27.15
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.14 to 2.27.15.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 03:01:48 +00:00
dependabot[bot]
8b1e2f55b4 Bump mkdocs from 1.2.3 to 1.3.0
Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.2.3 to 1.3.0.
- [Release notes](https://github.com/mkdocs/mkdocs/releases)
- [Commits](https://github.com/mkdocs/mkdocs/compare/1.2.3...1.3.0)

---
updated-dependencies:
- dependency-name: mkdocs
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 03:01:36 +00:00
dependabot[bot]
9ba8303823 Bump ccxt from 1.76.65 to 1.77.36
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.76.65 to 1.77.36.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.76.65...1.77.36)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 03:01:33 +00:00
dependabot[bot]
d45cec20ab Bump pytest-asyncio from 0.18.2 to 0.18.3
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.18.2 to 0.18.3.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Changelog](https://github.com/pytest-dev/pytest-asyncio/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.18.2...v0.18.3)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 03:01:22 +00:00
Matthias
9f863369bd Migrate bid/ask strategy to entry/exit pricing 2022-03-27 18:58:46 +02:00
Matthias
bcf326a035 Initial steps to change bid/ask pricing to enter/exit 2022-03-27 18:03:49 +02:00
Matthias
d1f61c4cf9 Use proper fee for DCA entries 2022-03-27 17:00:45 +02:00
Matthias
30cff1bd2c Update hdf5 to not raise naturalNaming warnings 2022-03-27 16:39:34 +02:00
Matthias
84777e255e Force-bump ccxt version to 1.77.29 2022-03-27 14:58:27 +02:00
Matthias
85bb2dcc8d Merge pull request #6590 from freqtrade/short_gateio
Fix gateio fee handling for futures
2022-03-27 14:57:36 +02:00
Matthias
0f1de435da Fix ccxt compat tests 2022-03-27 08:28:44 +02:00
Adriance
6629b6c828 Merge branch 'freqtrade:feat/short' into feat/short 2022-03-27 12:33:39 +08:00
Matthias
d244391860 no need to "abs" cost will be fixed in ccxt 2022-03-26 19:06:37 +01:00
Adriance
ad8eac960e Merge branch 'freqtrade:feat/short' into feat/short 2022-03-27 01:30:45 +08:00
Matthias
f509959bd4 Update 2022-03-26 16:26:31 +01:00
Matthias
fdc7077a2c Remove some unnecessary test arguments 2022-03-26 15:25:43 +01:00
Matthias
f5578aba48 Update trading_fee naming 2022-03-26 15:16:04 +01:00
Matthias
9b8a2435f8 Add tests for fetch_order gateio patch 2022-03-26 15:12:05 +01:00
Matthias
9a8c24ddf3 Update gateio to patch fees 2022-03-26 15:04:17 +01:00
Matthias
33229c91cb Add fetch_trading_fees endpoint 2022-03-26 13:53:36 +01:00
Matthias
5d3f2523e3 Merge pull request #6589 from freqtrade/short_timeout
Short timeout
2022-03-26 12:57:00 +01:00
Matthias
4424dcc2df Fix odd test 2022-03-26 12:01:28 +01:00
Matthias
0624817242 update unfilledtimeout settings to entry/exit 2022-03-26 11:55:11 +01:00
Matthias
60f2a12bd9 Fix wrong datetime conversion 2022-03-26 08:23:02 +01:00
Matthias
6f1b14c013 Update buy_timeout and sell_timeout methods 2022-03-25 19:57:06 +01:00
Matthias
973644de66 Fix bad import 2022-03-25 19:25:43 +01:00
Matthias
78fe29cc2d Merge pull request #6588 from samgermain/contracts
Add amount_to_contracts and order_contracts_to_amount to exchange.stoploss
2022-03-25 19:18:01 +01:00
Matthias
46f4227329 Check if symbol is not None 2022-03-25 18:11:02 +01:00
Matthias
50ba20ec9f Remove some unused test methods 2022-03-25 16:14:18 +01:00
Matthias
1c0946833d Fix bug in exit-count detection 2022-03-25 16:06:03 +01:00
Matthias
a682faf6b1 Merge pull request #6585 from mkavinkumar1/conftest
Removed old datetime keys and added timestamp
2022-03-25 15:57:37 +01:00
Matthias
81957e004d Revert false update 2022-03-25 15:38:38 +01:00
Matthias
b419d0043c Don't run CI directly on feat/short 2022-03-25 15:36:52 +01:00
Matthias
cd11ba3489 Fix naming in interface.py 2022-03-25 15:36:30 +01:00
Matthias
1ab6773257 Update todo-lev to todo 2022-03-25 15:17:46 +01:00
Matthias
f8e87e45a5 Merge pull request #6576 from samgermain/funding-tests
funding_fee tests
2022-03-25 15:11:45 +01:00
Sam Germain
d3ea14de68 test_stoploss_contract_size 2022-03-25 07:21:31 -06:00
Sam Germain
054b637001 Add amount_to_contracts and order_contracts_to_amount to stoploss 2022-03-25 06:56:05 -06:00
Matthias
743a7b7849 Merge branch 'develop' into feat/short 2022-03-25 10:04:18 +01:00
மனோஜ்குமார் பழனிச்சாமி
2cb24ed310 Added in ms
Just multiplied by 1000 as minuting checking in ms is not performed
2022-03-25 13:45:05 +05:30
Matthias
a004bcf00f Small refactor to backtesting 2022-03-25 08:03:32 +01:00
Matthias
a55bc9c1e4 Pin jinja in docs requirements 2022-03-25 08:02:27 +01:00
Matthias
5f71232d6f Fix doc typo 2022-03-25 07:03:50 +01:00
Matthias
dcfa3e8648 Update SellType to ExitType 2022-03-25 06:55:37 +01:00
Matthias
c07883b1f9 Move ExitCheckTuple to enums 2022-03-25 06:50:18 +01:00
Matthias
8d111d357a Update SellCheckTuple to new naming 2022-03-25 06:46:29 +01:00
Matthias
62e8c7b5b7 Rename parameter to avoid ambiguity 2022-03-25 06:39:57 +01:00
Matthias
d7f76ee452 Update confirm_trade_exit to use sell_reason terminology 2022-03-25 06:37:40 +01:00
மனோஜ்குமார் பழனிச்சாமி
3f98fcb0db all datetime included again 2022-03-25 09:19:39 +05:30
மனோஜ்குமார் பழனிச்சாமி
d94b84e38c datetime included again 2022-03-25 08:58:27 +05:30
Matthias
46ca773c25 Simplify some rpc code 2022-03-24 19:58:53 +01:00
Adriance
d961ddc2e2 Merge branch 'freqtrade:feat/short' into feat/short 2022-03-24 22:19:36 +08:00
Matthias
2442257856 Merge pull request #6540 from mkavinkumar1/patch-2
correcting docs for pricing of ask strategy
2022-03-24 08:02:46 +01:00
Matthias
dae9f4d877 Update doc clarity, partially revert prior commit 2022-03-24 06:50:25 +01:00
Matthias
83f6401820 Add additional endpoints to "has_optional" dict as comments 2022-03-23 19:56:29 +01:00
Matthias
08a55d4f6d Extract supported Exchanges to exchange.common 2022-03-23 19:51:44 +01:00
Matthias
e545ac1978 Revert condition to exploit lazy evaluation 2022-03-23 19:41:57 +01:00
Matthias
7d02e81857 Remove impossible TODO 2022-03-23 19:40:40 +01:00
Matthias
800d0c7f24 Ensure binance fallback file is included in releases 2022-03-23 19:40:34 +01:00
Matthias
3fa8327711 Remove sample_short_strategy - sample_strategy is a better long/short strategy example 2022-03-23 19:30:02 +01:00
மனோஜ்குமார் பழனிச்சாமி
094676def4 Removed old datetime keys and added timestamp 2022-03-23 20:47:55 +05:30
Matthias
de6519eb05 Update config builder to include okx for futures 2022-03-23 06:56:52 +01:00
Matthias
14f9d712dc Simplify okx lev_prep 2022-03-23 06:49:17 +01:00
Matthias
5791d0a394 Align kraken._get_params with okex 2022-03-23 06:49:07 +01:00
Matthias
8a708a9892 Don't assing attributes we never use 2022-03-23 06:48:23 +01:00
Matthias
71e746a060 fix missed "buy" wording in bot-basics 2022-03-23 06:48:00 +01:00
Matthias
b1e3ead88b Merge branch 'develop' into feat/short 2022-03-22 20:28:38 +01:00
Matthias
31253196ea Improve docs wording 2022-03-22 20:21:24 +01:00
Matthias
247635db79 Fix tests 2022-03-22 19:28:13 +01:00
Matthias
e7418cdcdb Remove obsolete note box
closes #6581
2022-03-22 19:03:22 +01:00
Italo
b5a346a46d Update hyperopt.py 2022-03-22 11:01:38 +00:00
Matthias
fa3c00c673 Remove some default arguments in history_utils 2022-03-22 07:20:21 +01:00
Matthias
99e9dfaebe Update missing documentation link 2022-03-22 07:02:40 +01:00
Matthias
46e86bd018 Update some hyperopt wording 2022-03-22 07:00:10 +01:00
Matthias
bc12fd6cbb Update backtest-result outputs to reflect new terminology 2022-03-22 06:47:20 +01:00
Matthias
5b4f343d36 Update buy output for backtesting 2022-03-22 06:45:36 +01:00
Matthias
08777abd85 Update backtesting output terminology to "exit" 2022-03-22 06:43:37 +01:00
Italo
2733aa33b6 Update hyperopt.py 2022-03-22 00:28:11 +00:00
Matthias
00287febc6 Merge pull request #6542 from TheJoeSchr/check_version_with_endswith
[develop] Check version with endswith
2022-03-21 22:17:39 +01:00
Matthias
487d3e891e Revert version to develop for now 2022-03-21 19:41:34 +01:00
Matthias
2c89da6bf7 Update code to properly behave when rounding open_date for funding fees 2022-03-21 19:38:27 +01:00
Matthias
4e52055a17 Merge pull request #6560 from freqtrade/inject_path_iresolver
Inject path to strategy loading
2022-03-21 19:09:14 +01:00
Matthias
35a4053dbe Merge pull request #6561 from adrianceding/fix_taker_stake_amount
Unified taker and maker's stake amount calculation logic
2022-03-21 19:07:00 +01:00
adriance
694e56cdc3 Merge branch 'fix_taker_stake_amount' into feat/short 2022-03-21 21:18:32 +08:00
Adriance
4a51ad27cf Merge branch 'freqtrade:feat/short' into feat/short 2022-03-21 21:17:25 +08:00
Italo
37a43019d6 fix
- clear cache before calling `ask`
- avoid errors in case asked_non_tried has less than n_points elements
2022-03-21 11:36:53 +00:00
Sam Germain
f03f586eeb funding_fee tests 2022-03-21 05:01:18 -06:00
Matthias
7eddc09c1c Merge pull request #6569 from freqtrade/dependabot/pip/develop/urllib3-1.26.9
Bump urllib3 from 1.26.8 to 1.26.9
2022-03-21 10:25:58 +01:00
Matthias
4db713318b Merge pull request #6568 from freqtrade/dependabot/pip/develop/types-tabulate-0.8.6
Bump types-tabulate from 0.8.5 to 0.8.6
2022-03-21 10:25:42 +01:00
Matthias
0a977291b6 Merge pull request #6571 from freqtrade/dependabot/pip/develop/mypy-0.941
Bump mypy from 0.940 to 0.941
2022-03-21 09:44:28 +01:00
dependabot[bot]
c28e0b0d0c Bump types-tabulate from 0.8.5 to 0.8.6
Bumps [types-tabulate](https://github.com/python/typeshed) from 0.8.5 to 0.8.6.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-tabulate
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 08:06:41 +00:00
dependabot[bot]
7170b585f9 Bump mypy from 0.940 to 0.941
Bumps [mypy](https://github.com/python/mypy) from 0.940 to 0.941.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.940...v0.941)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 08:06:25 +00:00
Matthias
47516ed353 Merge pull request #6567 from freqtrade/dependabot/pip/develop/types-requests-2.27.14
Bump types-requests from 2.27.12 to 2.27.14
2022-03-21 09:05:17 +01:00
Matthias
334452d3ee Merge pull request #6566 from freqtrade/dependabot/pip/develop/cryptography-36.0.2
Bump cryptography from 36.0.1 to 36.0.2
2022-03-21 06:32:47 +01:00
Matthias
9d756bc6a1 Merge pull request #6573 from freqtrade/dependabot/pip/develop/pytest-7.1.1
Bump pytest from 7.1.0 to 7.1.1
2022-03-21 06:32:17 +01:00
Matthias
c9dc07bdaa Merge pull request #6570 from freqtrade/dependabot/pip/develop/ccxt-1.76.65
Bump ccxt from 1.76.5 to 1.76.65
2022-03-21 06:32:06 +01:00
Matthias
2b63adf6c3 Merge pull request #6565 from freqtrade/dependabot/pip/develop/pymdown-extensions-9.3
Bump pymdown-extensions from 9.2 to 9.3
2022-03-21 06:31:51 +01:00
dependabot[bot]
057db5aaab Bump types-requests from 2.27.12 to 2.27.14
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.12 to 2.27.14.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 05:30:51 +00:00
Matthias
371f6bf90e Merge pull request #6572 from freqtrade/dependabot/pip/develop/types-python-dateutil-2.8.10
Bump types-python-dateutil from 2.8.9 to 2.8.10
2022-03-21 06:29:59 +01:00
dependabot[bot]
03090d8f3f Bump pytest from 7.1.0 to 7.1.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.1.0...7.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 03:01:45 +00:00
dependabot[bot]
1a37100bd4 Bump types-python-dateutil from 2.8.9 to 2.8.10
Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.8.9 to 2.8.10.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-python-dateutil
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 03:01:41 +00:00
dependabot[bot]
5a136f04df Bump ccxt from 1.76.5 to 1.76.65
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.76.5 to 1.76.65.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.76.5...1.76.65)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 03:01:33 +00:00
dependabot[bot]
59c7403b12 Bump urllib3 from 1.26.8 to 1.26.9
Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.8 to 1.26.9.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/1.26.9/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/1.26.8...1.26.9)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 03:01:23 +00:00
dependabot[bot]
1bc5d449a2 Bump cryptography from 36.0.1 to 36.0.2
Bumps [cryptography](https://github.com/pyca/cryptography) from 36.0.1 to 36.0.2.
- [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/36.0.1...36.0.2)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 03:01:16 +00:00
dependabot[bot]
f5e71a67fa Bump pymdown-extensions from 9.2 to 9.3
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 9.2 to 9.3.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/9.2...9.3)

---
updated-dependencies:
- dependency-name: pymdown-extensions
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-21 03:01:11 +00:00
Matthias
4fd0681265 Combine stake_amount recalculation 2022-03-20 20:00:30 +01:00
Italo
fca93d8dfe Update hyperopt.py 2022-03-20 16:12:06 +00:00
Matthias
22206d0d76 Merge pull request #6559 from freqtrade/short_docs
Futures strategy migration docs
2022-03-20 17:12:04 +01:00
Italo
f8a674f24d make robust in case all points have been tried 2022-03-20 16:08:38 +00:00
Italo
23f1a1904b more compact 2022-03-20 16:06:41 +00:00
Italo
0fd269e4f0 typo 2022-03-20 16:03:07 +00:00
Italo
e16bb1b34e Optimize only new points
Enforce points returned from `self.opt.ask` have not been already evaluated
2022-03-20 16:02:03 +00:00
Italo
112738d68d Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-03-20 15:42:53 +00:00
Italo
d796ce0935 Update hyperopt.py
1. Try to get points using `self.opt.ask` first
        2. Discard the points that have already been evaluated
        3. Retry using `self.opt.ask` up to 3 times
        4. If still some points are missing in respect to `n_points`, random sample some points
        5. Repeat until at least `n_points` points in the `asked_non_tried` list
        6. Return a list with legth truncated at `n_points`
2022-03-20 15:41:14 +00:00
Matthias
e9c4e6a69d Update derived strategy documentation 2022-03-20 13:21:09 +01:00
Matthias
6ec7b84b92 Modify hyperoptable strategy to use relative importing 2022-03-20 13:12:26 +01:00
Matthias
49e087df5b Allow Strategy subclassing in different files by enabling local imports 2022-03-20 13:07:06 +01:00
adriance
f01c9cd28c fix taker stake amount with leverage 2022-03-20 20:06:32 +08:00
Matthias
fcec071a08 Use order date to fetch trades
using the trade open-date may fail in case of several trade-entries spread over a longer timeperiod.

closes #6551
2022-03-20 09:46:51 +01:00
Matthias
8556e6a053 Automatically assign buy-tag to force-buys
closes #6544
2022-03-20 09:33:47 +01:00
Matthias
aceaa3faec remove last ticker_interval compatibility shim 2022-03-20 09:33:47 +01:00
Matthias
de8e869038 update missing "side" argument 2022-03-20 09:16:34 +01:00
Matthias
0f76b23733 update deprecation message for ticker_interval 2022-03-20 09:03:43 +01:00
Matthias
eb08b92180 Raise exception when ticker_interval is set. 2022-03-20 09:01:36 +01:00
Matthias
95f69b905a Remove ticker_interval support 2022-03-20 09:00:53 +01:00
Matthias
a64ca541a2 Merge pull request #6555 from freqtrade/inverse_leverage_minstake
Inverse leverage with stake detection
2022-03-20 08:38:59 +01:00
Matthias
c38f8a0e69 Update custom_sell() documentation 2022-03-20 08:33:53 +01:00
Matthias
d27a37be0d Update docs for populate_exit_trend 2022-03-20 08:30:14 +01:00
Matthias
59791b0659 Update populate_buy_trend to populate_entry_trend 2022-03-20 08:30:14 +01:00
Matthias
9d6d8043ee update FAQ to reflect new reality 2022-03-20 08:30:14 +01:00
Matthias
cd3ae7ebdf Update migration docs to include buy/entry trend migration 2022-03-20 08:30:14 +01:00
Matthias
25aba9c422 reformat leverage docs 2022-03-20 08:30:14 +01:00
Matthias
e51a1e1b20 Improve documentation, add "can_short" 2022-03-20 08:30:14 +01:00
Matthias
6a80c0f030 Add order_types migration docs 2022-03-20 08:30:14 +01:00
Matthias
7c7b0d1fcc Update documentation for time_in_force migration 2022-03-20 08:30:14 +01:00
Matthias
c89a68c1ab Alternative candle types 2022-03-20 08:30:14 +01:00
Matthias
36287a84cb enhance migration documentation 2022-03-20 08:30:14 +01:00
Matthias
23b98fbb73 Update some documentation for short trading 2022-03-20 08:30:14 +01:00
Matthias
72fd937a74 INTERFACE_VERSION to 3 2022-03-20 08:30:14 +01:00
Matthias
ee77ae3ada Add strategy-migration doc page 2022-03-20 08:30:14 +01:00
Matthias
052758bbac Refactor price and stake out of _enter_trade 2022-03-19 15:45:43 +01:00
Matthias
b292f28b35 Call leverage before custom_stake_amount to properly determine min-stake-amount 2022-03-19 15:44:37 +01:00
Matthias
35607ae03b Add test for min_leverage 2022-03-19 15:44:37 +01:00
Matthias
7d8ca63752 Merge pull request #6550 from freqtrade/short_tickerproblems
Short tickerproblems
2022-03-19 15:43:40 +01:00
Matthias
f44601d0cc Update ccxt-compat test config 2022-03-19 14:45:35 +01:00
Matthias
9f34f824af Fix hyperopt when using futures markets 2022-03-19 13:20:14 +01:00
Matthias
97c1316bf1 Add new validation to validate excludes 2022-03-18 19:26:54 +01:00
Matthias
d32153c8d3 Validate pricing configuration 2022-03-18 17:07:12 +01:00
Matthias
2791e799ee Rename tickers_has_quoteVolume 2022-03-18 16:49:37 +01:00
Matthias
1de5d2fb94 Remove unnecessary condition 2022-03-18 16:44:27 +01:00
Matthias
0c63c0bbb3 Update Gateio stoploss adjust 2022-03-18 10:41:38 +01:00
Matthias
f37038fb7d Fix gateio stoploss_adjust header 2022-03-18 10:35:00 +01:00
Matthias
7868e50141 Merge branch 'develop' into feat/short 2022-03-18 08:18:17 +01:00
Matthias
208a139d2b Incorporate fetch_bids_asks to allow binance spread filter to work
closes #6474
2022-03-18 07:08:16 +01:00
Matthias
fdce055061 Update deep_merge_dicts to disallow null-overrides 2022-03-18 06:58:22 +01:00
Matthias
73fc344eb1 Improve wording in docs 2022-03-18 06:38:54 +01:00
Matthias
b56aab0bdf Update Volumepairlist type 2022-03-18 06:34:35 +01:00
Matthias
f55db8e262 Spreadfilter should fail to start if fetchTickers is not supported 2022-03-17 20:21:10 +01:00
Matthias
1299a703e2 Implement fix for okx futures not having quoteVolume 2022-03-17 20:15:51 +01:00
Matthias
a13b633c56 update VOlumepairlist to also work without tickers 2022-03-17 20:11:56 +01:00
Matthias
b6a6aa48c9 Create separate _ft_has_futures dict 2022-03-17 20:05:05 +01:00
Matthias
b97522796b Merge pull request #6547 from freqtrade/short_bt_tests
Short bt tests
2022-03-17 17:20:42 +01:00
Matthias
96bf82dbc6 Remove gateio broker program 2022-03-17 17:06:10 +01:00
Matthias
6024fa482e Use brackets to break IF lines 2022-03-17 07:41:08 +01:00
Matthias
9b2ec5e653 Fix missleading variable naming 2022-03-17 06:58:08 +01:00
Matthias
20f02eb773 Add test for stoploss case 2022-03-16 21:28:24 +01:00
Matthias
2fab3de4d7 More backtest-detail tests 2022-03-16 20:12:09 +01:00
Matthias
295668d06c Add a few testcases 2022-03-16 20:12:09 +01:00
Matthias
d6309449cf Fix short bug where close_rate is wrongly adjusted 2022-03-16 20:12:09 +01:00
Matthias
c934f939e3 Update a few more short tests 2022-03-16 20:12:09 +01:00
Matthias
c0781a98e8 Add ROI test 2022-03-16 20:12:09 +01:00
Matthias
a89c1da19f Fix 2 bugs in ROI calculation 2022-03-16 20:12:09 +01:00
Matthias
298797cbfd Add stoploss short test 2022-03-16 20:12:09 +01:00
Matthias
c47b5b9087 Update bt_detail column descriptions 2022-03-16 20:12:00 +01:00
Matthias
84e9dc5001 Merge pull request #6537 from adrianceding/fs_fix
Add BT's leverage and short calculation
2022-03-16 19:25:19 +01:00
froggleston
162e94455b Add support for storing buy candle indicator rows in backtesting results 2022-03-16 12:16:24 +00:00
adriance
8f432fe468 Merge branch 'feat/short' into fs_fix 2022-03-16 14:22:08 +08:00
Matthias
7c9d2dd20a Fix a few more short bugs in backtesting 2022-03-16 07:00:50 +01:00
Joe Schr
47317e0f06 version: use 'contains' to check for "develop" instead of literal comparison 2022-03-15 21:08:37 +01:00
Kavinkumar
89aae71c32 correcting docs for pricing of ask strategy 2022-03-15 11:41:39 +05:30
adriance
ceba4d6e9b Remove meaningless code 2022-03-15 14:03:06 +08:00
Matthias
cbbdf00ddd Update comments in short backtest rates 2022-03-15 06:39:07 +01:00
Matthias
ebd61ebdef Merge pull request #6513 from samgermain/gateio-stoploss
Gateio stoploss on exchange
2022-03-15 06:27:54 +01:00
adriance
fd211166f0 fixed side error 2022-03-15 12:23:59 +08:00
adriance
7059892304 Optimize the code. Fix stop_rate judgment error 2022-03-15 12:04:02 +08:00
Matthias
12948aade6 Remove unused argument 2022-03-14 19:29:26 +01:00
Matthias
18030a30e7 Add exchange parameter to test-pairlist command
This will allow for quick tests of the same pairlist config against
multiple exchanges.
2022-03-14 19:21:58 +01:00
adriance
7dd57e8c04 format 2022-03-14 18:39:11 +08:00
adriance
31182c4d80 format 2022-03-14 18:38:44 +08:00
adriance
1d4eeacc6d fix test_backtest__enter_trade_futures row data error 2022-03-14 17:55:42 +08:00
Matthias
3b53ffb22f Merge pull request #6533 from freqtrade/dependabot/pip/develop/ccxt-1.76.5
Bump ccxt from 1.75.12 to 1.76.5
2022-03-14 07:58:49 +01:00
Matthias
8cb3158810 Merge pull request #6532 from freqtrade/dependabot/pip/develop/uvicorn-0.17.6
Bump uvicorn from 0.17.5 to 0.17.6
2022-03-14 07:14:18 +01:00
Matthias
717a4b82fe Merge pull request #6529 from freqtrade/dependabot/pip/develop/mypy-0.940
Bump mypy from 0.931 to 0.940
2022-03-14 07:14:01 +01:00
adriance
26a74220fd remove buy filled logic 2022-03-14 13:43:42 +08:00
adriance
bea38a2e7c remove filled date logic 2022-03-14 13:42:52 +08:00
dependabot[bot]
5462ff0ebc Bump mypy from 0.931 to 0.940
Bumps [mypy](https://github.com/python/mypy) from 0.931 to 0.940.
- [Release notes](https://github.com/python/mypy/releases)
- [Commits](https://github.com/python/mypy/compare/v0.931...v0.940)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 05:25:16 +00:00
Matthias
af1543ea37 Merge pull request #6534 from freqtrade/dependabot/pip/develop/types-requests-2.27.12
Bump types-requests from 2.27.11 to 2.27.12
2022-03-14 06:24:37 +01:00
Matthias
edda5b4ceb Merge pull request #6531 from freqtrade/dependabot/pip/develop/types-cachetools-5.0.0
Bump types-cachetools from 4.2.10 to 5.0.0
2022-03-14 06:24:22 +01:00
Matthias
a419e7012e Merge pull request #6535 from freqtrade/dependabot/pip/develop/nbconvert-6.4.4
Bump nbconvert from 6.4.2 to 6.4.4
2022-03-14 06:24:04 +01:00
Matthias
404d700a74 Raise min-requirement for ccxt 2022-03-14 06:23:48 +01:00
Matthias
c5cb617c92 Merge pull request #6536 from freqtrade/dependabot/pip/develop/numpy-1.22.3
Bump numpy from 1.22.2 to 1.22.3
2022-03-14 06:22:43 +01:00
Matthias
999a154213 Merge pull request #6530 from freqtrade/dependabot/pip/develop/pytest-7.1.0
Bump pytest from 7.0.1 to 7.1.0
2022-03-14 06:22:16 +01:00
adriance
a750369796 adjust none 2022-03-14 12:09:13 +08:00
adriance
f9e93cf3f8 fix buy filled date none 2022-03-14 11:55:36 +08:00
adriance
3d9c55d519 restore set_isolated_liq 2022-03-14 11:29:26 +08:00
adriance
c9bbc4a824 Merge branch 'feat/short' into fs_fix 2022-03-14 11:26:04 +08:00
dependabot[bot]
3fbe4a9944 Bump numpy from 1.22.2 to 1.22.3
Bumps [numpy](https://github.com/numpy/numpy) from 1.22.2 to 1.22.3.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.22.2...v1.22.3)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 03:01:30 +00:00
dependabot[bot]
a7133f1974 Bump nbconvert from 6.4.2 to 6.4.4
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 6.4.2 to 6.4.4.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Commits](https://github.com/jupyter/nbconvert/compare/6.4.2...6.4.4)

---
updated-dependencies:
- dependency-name: nbconvert
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 03:01:20 +00:00
dependabot[bot]
4cbdc9a74f Bump types-requests from 2.27.11 to 2.27.12
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.11 to 2.27.12.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 03:01:17 +00:00
dependabot[bot]
3fc1c94aba Bump ccxt from 1.75.12 to 1.76.5
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.75.12 to 1.76.5.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.75.12...1.76.5)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 03:01:14 +00:00
dependabot[bot]
3a0ad2f26e Bump uvicorn from 0.17.5 to 0.17.6
Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.17.5 to 0.17.6.
- [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.17.5...0.17.6)

---
updated-dependencies:
- dependency-name: uvicorn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 03:01:07 +00:00
dependabot[bot]
7764ad1541 Bump types-cachetools from 4.2.10 to 5.0.0
Bumps [types-cachetools](https://github.com/python/typeshed) from 4.2.10 to 5.0.0.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-cachetools
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 03:01:03 +00:00
dependabot[bot]
be5b0acfbd Bump pytest from 7.0.1 to 7.1.0
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.0.1 to 7.1.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.0.1...7.1.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-14 03:01:00 +00:00
Matthias
c63b5fbbbf Use last to get rates for /balance endpoints 2022-03-13 17:53:52 +01:00
Matthias
32c06f4a05 Improve test 2022-03-13 16:45:11 +01:00
Matthias
d5f0c6c78d Exclude alternative candletypes from timeframe check 2022-03-13 16:16:48 +01:00
Matthias
cfa9458bcc Merge branch 'develop' into feat/short 2022-03-13 15:38:12 +01:00
Matthias
3133be19e3 Update precisionfilter to use last instead of ask or bid. 2022-03-13 15:23:01 +01:00
Matthias
7146122f4a Update docstring 2022-03-13 15:06:32 +01:00
Matthias
b8b56d95f3 Update missleading docstring 2022-03-13 14:57:32 +01:00
Matthias
9107819c95 Fix order migration "forgetting" average 2022-03-13 14:42:15 +01:00
adriance
0fce0f64d1 Merge branch 'feat/short' into fs_fix 2022-03-13 14:41:22 +08:00
Matthias
099547c1ec Merge pull request #6527 from adrianceding/feat/short
fix duplicate long
2022-03-13 07:18:48 +01:00
adriance
52bf926066 fix duplicate long 2022-03-13 12:26:57 +08:00
adriance
56c4ea6619 Merge branch 'feat/short' into fs_fix 2022-03-13 12:13:33 +08:00
Sam Germain
843606c9cb gateio stoploss adjust 2022-03-12 20:14:23 -06:00
Sam Germain
91549d3254 Revert "stoploss_adjust fixed breaking tests"
This reverts commit 6f4d607902.
2022-03-12 20:07:56 -06:00
Sam Germain
7e7e596372 Revert "moved binance.stoploss_adjust to exchange class"
This reverts commit 6bb93bdc25.
2022-03-12 20:07:50 -06:00
Sam Germain
bf5afbcdbd Merge branch 'develop' into gateio-stoploss 2022-03-12 19:50:46 -06:00
Sam Germain
2ba79a32a0 Update docs/exchanges.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2022-03-12 19:42:40 -06:00
Matthias
f343036e66 Add stoploss-ordertypes mapping for gateio 2022-03-12 19:23:20 +01:00
Matthias
b8cbc4dcb7 Merge pull request #6523 from freqtrade/short_exit_trend
Update methods wording
2022-03-12 15:53:11 +01:00
Matthias
b044dd2c45 Update custom_sell to custom_exit 2022-03-12 11:37:56 +01:00
Matthias
fe62a71f4c Simplify implementation of "check_override" by extracting it to function 2022-03-12 10:58:48 +01:00
Matthias
6946203a7c Add tests and test-strategies for custom "implements" requirements 2022-03-12 10:05:16 +01:00
adriance
b5662d6547 Merge branch 'feat/short' into fs_fix 2022-03-12 16:50:27 +08:00
Matthias
9460fd8d75 Add Appropriate test for loading error 2022-03-12 09:49:20 +01:00
Matthias
28046c6a22 Change populate_buy_trend to populate_entry_trend 2022-03-12 09:38:28 +01:00
Matthias
efc313b28b Merge pull request #6512 from freqtrade/short_order_types
Short order types renamal
2022-03-12 09:32:16 +01:00
Matthias
7d1e487be5 Merge pull request #6522 from freqtrade/is_short_strat
Is short strat
2022-03-12 09:31:51 +01:00
Matthias
b9b5d749bb Fix typo causing an implicit bug 2022-03-12 08:58:59 +01:00
Matthias
12c909d8a8 Add can_short to sample strategies 2022-03-12 07:00:57 +01:00
Matthias
0aa170ac95 Check can_short in live-mode as well. 2022-03-12 06:58:22 +01:00
Matthias
20fc9459f2 Add test for can_short strategy attribute 2022-03-11 19:37:45 +01:00
Matthias
1c9dbb512a Initial attempt at is_short_strategy block 2022-03-11 19:29:40 +01:00
Matthias
7825d855cd Fix flake8 error in tests 2022-03-11 19:28:15 +01:00
Italo
d2a5448305 Update hyperopt.py 2022-03-11 17:38:32 +00:00
Italo
1a573d57b9 Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-03-11 17:36:00 +00:00
Matthias
11c76c3c89 Check if timeframe is available before calling exchange
closes #6517
2022-03-11 18:01:30 +01:00
adriance
51947ded6b Merge branch 'feat/short' into fs_fix 2022-03-11 22:35:35 +08:00
Matthias
24f480b4ce Double-check stoploss behaviour
closes #6508
2022-03-11 08:28:47 +01:00
Matthias
9ff52c0a93 Add test for emergencysell behaviour 2022-03-11 08:26:28 +01:00
Matthias
f6c263882d Update outdated TODO-lev 2022-03-10 07:09:48 +01:00
Matthias
cb9da78a27 Merge branch 'develop' into feat/short 2022-03-10 06:54:20 +01:00
Matthias
98755c1874 Fix wrong estimated output from /balance endpoints 2022-03-10 06:47:17 +01:00
Sam Germain
6f4d607902 stoploss_adjust fixed breaking tests 2022-03-09 19:31:51 -06:00
Sam Germain
7db28b1b16 gateio stoploss docs 2022-03-09 15:54:17 -06:00
Sam Germain
6bb93bdc25 moved binance.stoploss_adjust to exchange class 2022-03-09 15:47:16 -06:00
Matthias
0d754111e9 Fix dry-run-wallets bug in case of futures 2022-03-09 19:02:22 +01:00
Matthias
a837571e2b Improve dry-run-wallets in futures case test 2022-03-09 19:01:38 +01:00
Matthias
6e10439f90 Map usdt fiat to correct coingecko fiat 2022-03-09 17:35:41 +01:00
adriance
499e9c3e98 fix duration 2022-03-10 00:34:59 +08:00
adriance
d579febfec add filled time 2022-03-09 23:55:57 +08:00
adriance
14bce0b1c3 Merge branch 'feat/short' into fs_fix 2022-03-09 22:07:54 +08:00
adriance
1c86e69c34 use filled time calculate duration 2022-03-09 21:55:13 +08:00
adriance
82e0eca128 add short close rate calu 2022-03-09 20:00:06 +08:00
Sam Germain
d47274066e Added stoploss_on_exchange flag to gateio 2022-03-09 01:05:21 -06:00
Sam Germain
ae4742afcb test_fetch_stoploss_order_gateio and test_cancel_stoploss_order_gateio 2022-03-09 00:59:28 -06:00
Sam Germain
e3ced55f5c gateio.fetch_order and gateio.cancel_order 2022-03-09 00:45:50 -06:00
Sam Germain
61182f849b exchange.fetch_order and exchange.cancel_order added params argument 2022-03-09 00:45:10 -06:00
Matthias
93a91bdeee Update order_Types documentation 2022-03-09 07:44:21 +01:00
Matthias
50ab0dc6c5 Fix subtle bug 2022-03-09 07:04:59 +01:00
Matthias
51828a0b0b Update buy-signals to entry wording 2022-03-09 07:03:37 +01:00
Matthias
66afc233db Use Deprecated method for order_Time_in_force 2022-03-09 06:54:13 +01:00
Matthias
943d080f5e Add test for order-types migration 2022-03-09 06:37:08 +01:00
Matthias
420cc5c595 deprecated-setting moval should delete old setting 2022-03-09 06:37:08 +01:00
Matthias
5d4386f037 Implement order_types validation 2022-03-09 06:37:08 +01:00
Matthias
e492bf3159 Update order_types to use entry/exit definition 2022-03-09 06:37:08 +01:00
Matthias
f2ed6165e9 convert price to precision price before verifying stoploss adjustment
closes #6504
2022-03-08 19:35:30 +01:00
dingzhoufeng
9facd5b52a Merge branch 'feat/short' into fs_fix 2022-03-08 15:14:11 +08:00
Matthias
1ce55e88b4 Try to revert sequence in test 2022-03-08 07:10:59 +01:00
Matthias
b4ec2b3a5a Merge pull request #6507 from freqtrade/short_order_tif
Update order time in force to use entry/exit wording
2022-03-08 06:31:05 +01:00
dingzhoufeng
53ecdb931b add leverage 2022-03-08 12:26:43 +08:00
Matthias
3ff261e22c Update order time in force to use entry/exit wording 2022-03-07 19:55:15 +01:00
Matthias
17041b78fc Add stoploss-limit-ratio to full config sample 2022-03-07 19:39:15 +01:00
Matthias
da733a458d Merge pull request #6505 from freqtrade/rename_liq_col
rename column to liquidation_price
2022-03-07 19:02:39 +01:00
Matthias
d2a163e2cf rename column to liquidation_price 2022-03-07 17:16:33 +01:00
Matthias
f0252cf79d Merge pull request #6497 from freqtrade/dependabot/pip/develop/sqlalchemy-1.4.32
Bump sqlalchemy from 1.4.31 to 1.4.32
2022-03-07 12:52:15 +01:00
Matthias
2748b113ee Merge pull request #6495 from freqtrade/short_fixliq
Simplify and align liquidation price handling
2022-03-07 07:39:16 +01:00
Matthias
98acff8169 Merge pull request #6500 from freqtrade/dependabot/pip/develop/types-cachetools-4.2.10
Bump types-cachetools from 4.2.9 to 4.2.10
2022-03-07 07:04:31 +01:00
Matthias
26f6d8076d Merge pull request #6498 from freqtrade/dependabot/pip/develop/pytest-asyncio-0.18.2
Bump pytest-asyncio from 0.18.1 to 0.18.2
2022-03-07 06:25:20 +01:00
Matthias
82595f3a5d Merge pull request #6501 from freqtrade/dependabot/pip/develop/ccxt-1.75.12
Bump ccxt from 1.74.63 to 1.75.12
2022-03-07 06:25:07 +01:00
Matthias
805a04a6cb Merge pull request #6496 from freqtrade/dependabot/pip/develop/fastapi-0.75.0
Bump fastapi from 0.74.1 to 0.75.0
2022-03-07 06:24:56 +01:00
Matthias
07524e9f37 Merge pull request #6499 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.5
Bump mkdocs-material from 8.2.3 to 8.2.5
2022-03-07 06:24:40 +01:00
Matthias
749e0dd5a0 Merge pull request #6502 from freqtrade/dependabot/github_actions/develop/actions/setup-python-3
Bump actions/setup-python from 2 to 3
2022-03-07 06:24:14 +01:00
dependabot[bot]
3c83d8c74a Bump actions/setup-python from 2 to 3
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 3.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 05:24:08 +00:00
Matthias
46c3f56bf5 Merge pull request #6503 from freqtrade/dependabot/github_actions/develop/actions/checkout-3
Bump actions/checkout from 2 to 3
2022-03-07 06:23:41 +01:00
dependabot[bot]
25964f70d8 Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 03:12:15 +00:00
dependabot[bot]
0c8dd7e502 Bump ccxt from 1.74.63 to 1.75.12
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.74.63 to 1.75.12.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.74.63...1.75.12)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 03:01:33 +00:00
dependabot[bot]
f1d2cb9ce4 Bump types-cachetools from 4.2.9 to 4.2.10
Bumps [types-cachetools](https://github.com/python/typeshed) from 4.2.9 to 4.2.10.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-cachetools
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 03:01:25 +00:00
dependabot[bot]
1d63bb66a9 Bump mkdocs-material from 8.2.3 to 8.2.5
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.3 to 8.2.5.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.3...8.2.5)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 03:01:23 +00:00
dependabot[bot]
67a8b8b631 Bump pytest-asyncio from 0.18.1 to 0.18.2
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.18.1 to 0.18.2.
- [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases)
- [Commits](https://github.com/pytest-dev/pytest-asyncio/compare/v0.18.1...v0.18.2)

---
updated-dependencies:
- dependency-name: pytest-asyncio
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 03:01:19 +00:00
dependabot[bot]
708def3d96 Bump sqlalchemy from 1.4.31 to 1.4.32
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 1.4.31 to 1.4.32.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 03:01:15 +00:00
dependabot[bot]
d74e3091de Bump fastapi from 0.74.1 to 0.75.0
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.74.1 to 0.75.0.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.74.1...0.75.0)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 03:01:09 +00:00
Matthias
4988e56bfe Full config should still default to spot markets 2022-03-06 16:35:31 +01:00
Matthias
6360ef029c Simplify and align liquidation price handling 2022-03-06 16:27:55 +01:00
Matthias
612ede5e48 Merge pull request #6468 from samgermain/todos
todos
2022-03-06 16:03:05 +01:00
Matthias
667054e1ad Reorder methods in trade object 2022-03-06 15:07:07 +01:00
Matthias
46e17c9762 Fix stoploss_pct set wrongly for short trades 2022-03-06 15:07:04 +01:00
Matthias
cc38f0656d Explicitly check for None to determine if initial stoploss was set
closes #6460
2022-03-06 15:06:57 +01:00
Matthias
08d8dfaee6 Remove wrong import 2022-03-06 14:47:26 +01:00
Matthias
81d4a61353 Update more trades 2022-03-06 14:33:04 +01:00
Matthias
bc37f67e76 Add one more test 2022-03-06 14:18:25 +01:00
Matthias
76e5d5b232 Fix stake-amount handling for dry-run 2022-03-05 15:53:40 +01:00
Matthias
f571fee899 Merge pull request #6494 from freqtrade/stoploss_special_ccase
Explicitly check for None to determine if initial stoploss was set
2022-03-05 15:15:45 +01:00
Matthias
0bac7f824e Merge pull request #6492 from samgermain/feat/short
Merge develop into feat/short
2022-03-05 14:47:34 +01:00
Matthias
7a545f49af Improve test stability by making keys optional in the ccxt test-matrix 2022-03-05 14:15:58 +01:00
Matthias
be4bc4955c Explicitly check for None to determine if initial stoploss was set
closes #6460
2022-03-05 14:12:14 +01:00
Matthias
2b1a8f2fbb Update binance stoploss to use correct stop order for futures 2022-03-05 13:57:54 +01:00
Matthias
685820cc12 Fix failures due to non-happening rounding 2022-03-04 19:48:34 +01:00
Matthias
8943d42509 Update telegram notifications to properly detect shorts 2022-03-04 19:42:33 +01:00
Matthias
9576fab621 Re-remove amount to precision from trade entry 2022-03-04 07:16:06 +01:00
Matthias
cee126a2cf extract stop_limit-rate calculation 2022-03-04 07:10:14 +01:00
Matthias
62dcebee46 Update stoploss method to new functionality 2022-03-04 07:07:34 +01:00
Matthias
011cd58377 Adjust new stoploss tests to futures world 2022-03-04 06:58:34 +01:00
Matthias
7435b5ec96 Fix small merge errors 2022-03-04 06:58:21 +01:00
Matthias
0622654bcf Give tests a chance to pass 2022-03-04 06:50:42 +01:00
Sam Germain
488da9b875 Merge branch 'develop' into feat/short 2022-03-03 13:51:52 -06:00
Matthias
819b35747d Minor documentation updates 2022-03-03 20:24:06 +01:00
Matthias
c0e12d632f Add FTX ref links 2022-03-03 19:19:10 +01:00
Matthias
1d3ce5bef4 Remove duplicate call to init_db 2022-03-03 07:23:10 +01:00
Matthias
5ab72ac082 chore: realign enums imports 2022-03-03 07:07:33 +01:00
Matthias
9bcc79e118 Use parsed TradingMode from config 2022-03-03 07:06:13 +01:00
Matthias
5332c441b9 Fix fail test - add more TODO's 2022-03-03 07:00:10 +01:00
Matthias
f558d4b132 Merge pull request #6467 from samgermain/backtest-liq
Liquidation price in backtesting
2022-03-03 06:50:32 +01:00
Matthias
761ac6685a Merge pull request #6489 from samgermain/gateio-market
gateio market orders futures
2022-03-03 06:34:06 +01:00
Sam Germain
dfb72d8a2f gateio market orders futures 2022-03-02 21:37:53 -06:00
Italo
0804ef411b Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-03-03 01:44:41 +00:00
Matthias
e9456cdf15 Update trade response to use a single Order object 2022-03-02 19:58:08 +01:00
Matthias
17c9c3caf3 Enable orders via API 2022-03-02 19:58:08 +01:00
Sam Germain
8a9c6e27a5 docs/leverage.md: Added freqtrade_liquidation_price formula to docs 2022-03-02 12:53:24 -06:00
Matthias
eb30c40e0c Fix hyperopt for futures 2022-03-02 19:50:16 +01:00
Sam Germain
c9988e0aa2 test_backtest__enter_trade_futures comment calculations include liquidation buffer 2022-03-02 12:46:31 -06:00
Matthias
c5cf73e67b hdf5 datahandler should also create directory 2022-03-02 19:41:14 +01:00
Sam Germain
c0e11beced linting 2022-03-02 01:30:52 -06:00
Sam Germain
c0fb6f7e85 test_backtest__enter_trade_futures - fixed formula in comments 2022-03-02 01:26:47 -06:00
Matthias
d4fbb785b5 Merge pull request #6458 from stash86/pos_adjust
Hide sell_reason if a trade is still open
2022-03-02 07:23:49 +01:00
Matthias
1c4a7c25d7 Fix failing test 2022-03-02 07:14:36 +01:00
Matthias
478d440e80 Test backtesting with USDT pairs 2022-03-02 07:00:07 +01:00
Matthias
b18256c231 Merge pull request #6487 from samgermain/setup-gettext
setup.sh install gettext for mac
2022-03-02 06:39:27 +01:00
Matthias
71be547d82 Bump ccxt to 1.74.63
closes #6484
2022-03-02 06:26:00 +01:00
Sam Germain
abc8854b5a setup.sh install gettext for mac 2022-03-01 17:38:38 -06:00
Matthias
f74de1cca3 Improve Backtesting "wrong setup" message to include tradable_balance 2022-03-01 19:46:13 +01:00
Matthias
54165662ce Don't require unfilledtimeout, it's optional. 2022-03-01 19:41:26 +01:00
Matthias
69cfb0b278 Revert change to telegram - this should be handled at the source 2022-03-01 19:32:25 +01:00
Matthias
c2b90afa61 Merge branch 'develop' into pr/stash86/6458 2022-03-01 19:31:36 +01:00
Matthias
a2c9879375 Reset sell-reason if order is cancelled 2022-03-01 19:30:16 +01:00
Matthias
736a930152 Update small things 2022-03-01 19:23:14 +01:00
Matthias
f26247e8e0 Revert wrong version string 2022-03-01 19:08:04 +01:00
Matthias
e8206bc751 Simplify backtesting enter_Trade 2022-02-28 20:10:23 +01:00
Matthias
1b07ad92cf Merge branch 'feat/short' into pr/samgermain/6467 2022-02-28 20:07:19 +01:00
Matthias
c745f5828c Update comments to clarify it's supposed to be a "offline" call 2022-02-28 20:05:14 +01:00
Matthias
c39e7368ee Split backtesting test to properly initialize it 2022-02-28 19:58:44 +01:00
Matthias
e005439720 Merge pull request #6400 from freqtrade/short_dca
trade-adjustment for short trades
2022-02-28 19:47:50 +01:00
Matthias
79538368db Simplify liquidation price calculation 2022-02-28 19:47:21 +01:00
Matthias
ab46476e63 Rename get_liquidation method 2022-02-28 19:42:26 +01:00
Matthias
1d27cbd01f Simplify leverage_prep interface 2022-02-28 19:34:10 +01:00
Matthias
8e2d3445a7 Move leverage_prep calculations to exchange class 2022-02-28 19:29:42 +01:00
Matthias
bc92225441 Add todo about leverage_prep 2022-02-28 19:23:14 +01:00
Matthias
dca83b070d Merge pull request #6478 from freqtrade/dependabot/pip/develop/fastapi-0.74.1
Bump fastapi from 0.74.0 to 0.74.1
2022-02-28 07:08:02 +01:00
Matthias
68bc2a6107 Add huobi to ccxt compat tests 2022-02-28 07:00:52 +01:00
Matthias
a922c4df70 Merge pull request #6477 from freqtrade/dependabot/pip/develop/ccxt-1.74.43
Bump ccxt from 1.74.17 to 1.74.43
2022-02-28 06:52:18 +01:00
Matthias
cf22926cee Merge pull request #6475 from freqtrade/dependabot/pip/develop/mkdocs-material-8.2.3
Bump mkdocs-material from 8.2.1 to 8.2.3
2022-02-28 06:50:48 +01:00
Matthias
151841965a Merge pull request #6476 from freqtrade/dependabot/pip/develop/types-requests-2.27.11
Bump types-requests from 2.27.10 to 2.27.11
2022-02-28 06:34:34 +01:00
dependabot[bot]
207b211e5e Bump fastapi from 0.74.0 to 0.74.1
Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.74.0 to 0.74.1.
- [Release notes](https://github.com/tiangolo/fastapi/releases)
- [Commits](https://github.com/tiangolo/fastapi/compare/0.74.0...0.74.1)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:01:38 +00:00
dependabot[bot]
42fbec4172 Bump ccxt from 1.74.17 to 1.74.43
Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.74.17 to 1.74.43.
- [Release notes](https://github.com/ccxt/ccxt/releases)
- [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg)
- [Commits](https://github.com/ccxt/ccxt/compare/1.74.17...1.74.43)

---
updated-dependencies:
- dependency-name: ccxt
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:01:29 +00:00
dependabot[bot]
faf6a35ad7 Bump types-requests from 2.27.10 to 2.27.11
Bumps [types-requests](https://github.com/python/typeshed) from 2.27.10 to 2.27.11.
- [Release notes](https://github.com/python/typeshed/releases)
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-requests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:01:20 +00:00
dependabot[bot]
590944a600 Bump mkdocs-material from 8.2.1 to 8.2.3
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 8.2.1 to 8.2.3.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/8.2.1...8.2.3)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:01:17 +00:00
Sam Germain
1121965c6e liq backtesting tests 2022-02-27 14:28:28 -06:00
Matthias
7948224892 leverage_prep should also becalled after filling a entry ordre 2022-02-27 21:14:28 +01:00
Sam Germain
b103045a05 backtesting._enter_trade update liquidation price on increased position 2022-02-27 12:09:45 -06:00
Sam Germain
6fdcc714bf backtesting margin_mode key fix 2022-02-27 11:59:27 -06:00
Matthias
1ac360674c Update Readme quickstart
#6472
2022-02-27 17:37:46 +01:00
Matthias
437b12fab7 Use trade.* props where possible 2022-02-27 17:16:38 +01:00
Matthias
33be14e7e2 Update stake_amount calculation with multiple entries when using leverage 2022-02-27 17:09:29 +01:00
Matthias
0ebf40f390 Don't call amount_to_precision twice on entry 2022-02-27 15:57:44 +01:00
Matthias
5c2cca50e5 Minor updates, document no leverage changes 2022-02-27 15:44:23 +01:00
Matthias
1b6548c8d8 Don't modify leverage through DCA 2022-02-27 15:44:23 +01:00
Matthias
536f54cfc6 is_short for forceentries 2022-02-27 15:44:23 +01:00
Matthias
f0f5a50975 Update tests to test DCA for shorts 2022-02-27 15:44:23 +01:00
Matthias
eed516a5c6 Update DCA logic to some extend 2022-02-27 15:44:23 +01:00
Matthias
bcfa73d492 Add "nr_of_successfull_entries" 2022-02-27 15:44:23 +01:00
Matthias
5c9dddb7f3 Merge pull request #6466 from samgermain/stoploss
Leverage stoploss
2022-02-27 15:30:58 +01:00
Matthias
7b9880035b Remove wrong TODO-lev comment 2022-02-27 15:11:09 +01:00
Sam Germain
8af2ea754f add margin mode to backtesting 2022-02-26 14:11:21 -06:00
Sam Germain
7508f79b6c test_freqtradebot, is_short tests 2022-02-26 13:55:52 -06:00
Sam Germain
b363940baf Add TODO-lev comment in test_handle_stoploss_on_exchange 2022-02-26 13:55:37 -06:00
Sam Germain
499e21517b test_persistence tests for stoploss with leverage adjustements 2022-02-26 13:55:37 -06:00
Sam Germain
78194559f4 persistence.adjust_stop_loss accounts for leverage 2022-02-26 13:55:37 -06:00
Sam Germain
ac433eebfe stoploss in freqtradebot leverage adjustment 2022-02-26 13:55:37 -06:00
Sam Germain
6dbd249570 backtesting._enter_trade get liquidation_price and backtesting._leverage_prep 2022-02-26 13:55:01 -06:00
Matthias
92ad353169 Fix OKX exception 2022-02-26 20:13:24 +01:00
Matthias
12a1e27708 Merge pull request #6456 from samgermain/lev-tier-update
Lev tier update
2022-02-26 19:55:30 +01:00
Matthias
e9f3f3d859 Fix random test failure (2nd try) 2022-02-26 17:08:35 +01:00
Sam Germain
7dab70f1a5 test_ccxt_compat - ftx["futures"] = false 2022-02-26 09:45:15 -06:00
Sam Germain
64172bc98d removed TODOs in test_CCXT_compat 2022-02-26 09:27:38 -06:00
Sam Germain
fbcd260bf6 flake8 import issues 2022-02-26 09:05:51 -06:00
Sam Germain
af77358d6a updated test_load_leverage_tiers_okx 2022-02-26 09:05:51 -06:00
Sam Germain
b71fb1fdec upgrade CCXT to 1.74.22 2022-02-26 09:05:51 -06:00
Sam Germain
f5ea7827e0 removed gateio.get_max_leverage and gateio.get_maint_ratio_and_amt 2022-02-26 09:05:51 -06:00
Sam Germain
6cd01c45d5 exchange.get_leverage_tiers and exchange.get_market_leverage_tiers 2022-02-26 09:05:51 -06:00
Sam Germain
c7e87e86e2 added exception handlers to fetch_market_leverage_tiers 2022-02-26 09:05:51 -06:00
Sam Germain
421aa31c92 upgrade CCXT to 1.74.9 2022-02-26 09:05:51 -06:00
Sam Germain
b61cfada6d moved okex.load_leverage_tiers to new method 2022-02-26 09:05:51 -06:00
Matthias
79ddc9abaa Merge pull request #6423 from samgermain/wallet-amt
Futures wallet amount
2022-02-26 15:55:28 +01:00
Matthias
e25929f50a Update test to not fail randomly 2022-02-26 15:53:01 +01:00
Matthias
fdbd75501f Merge pull request #6465 from freqtrade/huobi
Huobi
2022-02-26 15:24:42 +01:00
Matthias
75868a851b Attempt Fix random test failure 2022-02-26 15:20:56 +01:00
Matthias
41316abb55 Sort supported exchanges alphabetically 2022-02-26 14:57:17 +01:00
Matthias
14d49e85af Update Huobi stoploss to shared method 2022-02-26 14:57:13 +01:00
Matthias
a1f2f6ddeb Updates required for huobi datadownload 2022-02-26 10:33:37 +01:00
Matthias
f3421dfa9f Use unified stopPrice argument 2022-02-26 10:33:37 +01:00
Matthias
1b91be08fe Add huobi to list of supported exchanges 2022-02-26 10:33:37 +01:00
Matthias
292c350885 Add stoploss support for huobi 2022-02-26 10:33:36 +01:00
Matthias
9504b3eb05 Improve huobi config generation 2022-02-26 10:33:11 +01:00
Matthias
ee7bc55727 Add huobi to Exchange setup 2022-02-26 10:33:11 +01:00
Matthias
2ec1a7b370 Add huobi exchange class 2022-02-26 10:33:11 +01:00
Matthias
f181cdeecd Merge pull request #6463 from freqtrade/stoploss_simplify
Stoploss simplify - kucoin stoploss on exchange
2022-02-26 10:31:50 +01:00
Matthias
3942b30ebf Add kraken TODO 2022-02-26 08:34:23 +01:00
Matthias
6caa5f7131 Update dry-run behaviour 2022-02-26 08:25:42 +01:00
Matthias
0749199097 Add stoploss tests for kucoin 2022-02-26 08:25:42 +01:00
Matthias
020729cf50 update docs about kucoin stoploss 2022-02-26 08:25:42 +01:00
Matthias
768b526c38 Add kucoin stoploss on exchange 2022-02-26 08:25:42 +01:00
Matthias
7ba92086c9 Make stoploss method more flexible 2022-02-26 08:25:42 +01:00
Matthias
ea197b79ca Add some more logic to stoploss 2022-02-26 08:25:42 +01:00
Matthias
1d57ce19eb Move stoploss -limit implemenentation to exchange class, as this seems to be used by multiple exchanges. 2022-02-26 08:25:42 +01:00
Italo
8d9d003671 Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-02-25 17:58:57 +00:00
Matthias
551fe7d820 Merge pull request #6440 from clover-es/feat/short
Add leverage strategy to new-strategy command
2022-02-25 15:18:46 +01:00
Stefano Ariestasia
df726a54f8 cater for case where sell limit order expired 2022-02-25 00:20:53 +00:00
Matthias
1c26ff4c4c Add dry run test 2022-02-24 20:05:56 +01:00
Matthias
9d55621f42 Test fetch_position exchange method 2022-02-24 20:05:56 +01:00
Matthias
9901decf0d Rename get_positions to fetch_positions to align with ccxt naming 2022-02-24 20:05:56 +01:00
Matthias
62c42a73e2 Add initial rpc test 2022-02-24 20:05:56 +01:00
Matthias
d07a24a54f Update tests for new wallet RPC structure 2022-02-24 20:05:56 +01:00
Matthias
13e74c5693 Add dry-run position wallet calculation 2022-02-24 20:05:56 +01:00
Matthias
6562511137 add trade_direction to trade object 2022-02-24 20:05:56 +01:00
Matthias
a2b17882e6 Don't use separate position field in /currency endpoint 2022-02-24 20:05:56 +01:00
Matthias
4b27bd9838 don't fetch free balance if we don't use it 2022-02-24 20:05:56 +01:00
Matthias
e54e6a7295 Update wallets to also keep Positions 2022-02-24 20:05:56 +01:00
Matthias
ed65692257 add get_position exchange wrapper 2022-02-24 20:05:56 +01:00
Sam Germain
9f4f65e457 exchange.get_balances minor fix 2022-02-24 20:05:56 +01:00
Sam Germain
f336e7fc5b exchange.get_balances futures shorts taken out 2022-02-24 20:05:56 +01:00
Sam Germain
f67e0bd6dd wallet amount for futures 2022-02-24 20:05:56 +01:00
Matthias
fd936e26ae Merge branch 'develop' into feat/short 2022-02-24 19:56:42 +01:00
Matthias
d973ba1f5d Add leverage callback to advanced template 2022-02-23 20:19:52 +01:00
Matthias
c51603b110 Slightly improve formatting, Point to documentation 2022-02-23 20:16:52 +01:00
Matthias
14b69405a2 Init persistence should be the innermost fixture 2022-02-23 10:43:04 +01:00
Matthias
ec34189f1b Attempt to fix random ci error 2022-02-23 08:47:20 +01:00
Matthias
8952829adc Merge branch 'develop' into feat/short 2022-02-23 06:28:15 +01:00
Guillermo Rodríguez
8e3839c74c Merge branch 'freqtrade:feat/short' into feat/short 2022-02-22 19:34:59 +01:00
Guillermo Rodríguez
95b63ea496 Add short signal to base strategy template 2022-02-22 19:33:52 +01:00
Matthias
70f4305dfa don't allow short trades in spot mode 2022-02-21 19:19:12 +01:00
Matthias
c3c815e794 Merge pull request #6425 from samgermain/stake-amount
leverage in trade.stake_amount calculation
2022-02-19 20:11:23 +01:00
Matthias
989edca622 Add test-case for cancel stake update with leverage 2022-02-18 06:41:15 +01:00
Matthias
8bdc77eb4d Add TODO-lev for tests which define is_short but don't use it 2022-02-18 06:38:51 +01:00
Matthias
f0cbc47bb1 Merge pull request #6373 from samgermain/leverage-tiers
Leverage tiers
2022-02-17 20:23:33 +01:00
Matthias
de8d789962 Fix test missing assert statement 2022-02-17 19:37:24 +01:00
Sam Germain
d9d9867a54 updated ccxt 2022-02-16 21:09:02 -06:00
Matthias
e981d644e1 Add toto-lev for order-leverage 2022-02-16 19:24:59 +01:00
Sam Germain
f452fce4cc Merge branch 'ccxt-compat' into leverage-tiers 2022-02-16 10:07:49 -06:00
Sam Germain
a37287d9ba test__get_params 2022-02-16 10:06:27 -06:00
Sam Germain
2015e9345d test_ccxt_compat maintenanceMarginRatio -> maintenanceMarginRate 2022-02-16 09:25:27 -06:00
Sam Germain
df86300729 test_ccxt_dry_run_liquidation_price 2022-02-16 09:22:22 -06:00
Sam Germain
124532a4b7 maintenanceMarginRatio -> maintenanceMarginRate 2022-02-16 09:04:43 -06:00
Sam Germain
dc73fccd3c removed test_ccxt_get_maintenance_ratio_and_amt 2022-02-16 09:03:50 -06:00
Sam Germain
a1e9e940dd test_ccxt_load_leverage_tiers 2022-02-16 08:51:39 -06:00
Sam Germain
a65dcc709e leverage in trade.stake_amount calculation 2022-02-16 08:09:43 -06:00
Sam Germain
ef5dae2770 ccxt_compat_tests for leverage tiers 2022-02-16 08:08:10 -06:00
Sam Germain
88a8ff2f4e Merge branch 'feat/short' into leverage-tiers 2022-02-16 08:05:51 -06:00
Matthias
de26844578 Merge pull request #6397 from samgermain/todos
edited todo-lev comments
2022-02-16 13:36:17 +01:00
Sam Germain
6697333118 Merge branch 'todos' of https://github.com/samgermain/freqtrade into todos 2022-02-16 05:47:49 -06:00
Sam Germain
a9eb8ce1bf added todos back in 2022-02-16 05:47:41 -06:00
Sam Germain
6f410d3096 fixed test_load_leverage_tiers 2022-02-16 05:44:11 -06:00
Sam Germain
c70050e750 fixed test_load_leverage_tiers 2022-02-16 05:26:52 -06:00
Sam Germain
183f85efe3 test_execute_entry fixed 2022-02-16 05:08:11 -06:00
Sam Germain
1f3d3d87f6 fixed tests 2022-02-16 04:52:26 -06:00
Sam Germain
3fe0e13bb1 expanded test_load_leverage_tiers 2022-02-16 04:37:11 -06:00
Sam Germain
3bfd9186f7 gateio.get_max_leverage small fix 2022-02-16 04:05:27 -06:00
Sam Germain
dbd2df6406 Merge branch 'leverage-tiers' of https://github.com/samgermain/freqtrade into leverage-tiers 2022-02-16 03:50:24 -06:00
Sam Germain
c9da6f480f gateio get_max_leverage and get_maintenance_ratio_and_amt temporary solution 2022-02-16 03:36:08 -06:00
Matthias
ff5b3c323a Fix okx trading mode 2022-02-16 09:13:49 +01:00
Italo
88459acbeb Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-02-15 19:10:49 +00:00
Matthias
7f7c395b10 Add exception handling for lev_prep in okx 2022-02-15 19:30:02 +01:00
Matthias
33cc5e0ac7 Use kwargs for set_leverage 2022-02-15 18:56:58 +01:00
Matthias
c37f03a638 Update static-markets to include futures pair 2022-02-15 08:04:16 +01:00
Matthias
1bae18c60a Update decorator locations 2022-02-15 07:11:07 +01:00
Matthias
324fdcedb1 Attempt test fix 2022-02-15 06:59:10 +01:00
Sam Germain
5f42ebfa4c Update candletype.py 2022-02-14 23:53:10 -06:00
Matthias
5ee5e0256b Clarify todo 2022-02-15 06:39:55 +01:00
Sam Germain
ae249a0f97 Merge branch 'leverage-tiers' of https://github.com/samgermain/freqtrade into leverage-tiers 2022-02-14 17:36:47 -06:00
Sam Germain
3753df26fc fixed tests 2022-02-14 17:34:59 -06:00
Sam Germain
f4a57b71e7 Filled in test_load_leverage_tiers_okx 2022-02-14 16:53:29 -06:00
Matthias
513669f834 Be verbose on okex startup to point out delay. 2022-02-14 19:44:05 +01:00
Matthias
515b3fdfd2 Version bump ccxt 2022-02-14 19:42:15 +01:00
Matthias
99e3e26542 Adjust ccxt test naming to align with the other tests 2022-02-14 19:14:44 +01:00
Sam Germain
a2b84561fe removed a todo 2022-02-14 10:00:03 -06:00
Sam Germain
5cd2501397 Merge branch 'leverage-tiers' of https://github.com/samgermain/freqtrade into leverage-tiers 2022-02-14 09:40:53 -06:00
Sam Germain
cfd438b966 fixed test_get_markets 2022-02-14 09:40:01 -06:00
Sam Germain
c1d08dd03a linting 2022-02-14 09:34:09 -06:00
Sam Germain
16e38592a9 test_get_markets created debugging param test_comment 2022-02-14 09:33:56 -06:00
Sam Germain
19783e0d39 edited todos 2022-02-14 09:02:55 -06:00
Matthias
09cc43b533 Test short trade exiting 2022-02-13 16:33:06 +01:00
Matthias
5b65448e56 Fix some todo-lev's in tests 2022-02-13 16:17:41 +01:00
Matthias
2523c12c71 Small enhancements and notes 2022-02-13 14:33:37 +01:00
Matthias
ad801e05f7 Filter loadable leverage tiers to stake-currency pairs 2022-02-13 13:05:57 +01:00
Matthias
96df311244 Rename test_okex to test_okx 2022-02-13 13:01:23 +01:00
Matthias
bc855b2a32 Update some missing mocks 2022-02-13 13:00:38 +01:00
Matthias
b98297786c Update failing mock 2022-02-13 12:56:32 +01:00
Matthias
7f0cedc769 Use "is_future" to check for futures markets 2022-02-13 12:54:49 +01:00
Matthias
eaf13f96f7 Use exchange_has to check for ccxt properties 2022-02-13 12:48:28 +01:00
Sam Germain
8fe3f0c933 fix breaking tests 2022-02-12 23:08:42 -06:00
Sam Germain
531b4d238c removed test_get_maintenance_margin_and_amt_gatio as its no longer relevant 2022-02-12 23:02:16 -06:00
Sam Germain
765c95f875 test_okex.test_get_maintenance_ratio_and_amt_okex change pair names 2022-02-12 23:02:16 -06:00
Sam Germain
e3bd40c3c7 added swap and linear to conftest markets 2022-02-12 23:02:16 -06:00
Sam Germain
7a0f7da128 okex loads all leverage tiers at beginning, removed get tiers for pair 2022-02-12 23:02:16 -06:00
Sam Germain
8657e99c26 trimmed down get_maintenance_ratio_and_amt, now requires fetchLeverageTiers 2022-02-12 23:02:16 -06:00
Sam Germain
e7430da5d7 test_ccxt_compat commented out unfinished tests 2022-02-12 23:02:16 -06:00
Sam Germain
03b3756e4b strengthened and fixed leverage_tier tests 2022-02-12 23:02:16 -06:00
Sam Germain
a6043e6a85 get_max_leverage test clean up 2022-02-12 23:02:16 -06:00
Sam Germain
4a1ed01708 get_maintenance_ratio_and_amt tests 2022-02-12 23:02:16 -06:00
Sam Germain
60a45ff394 exchange.get_max_leverage de-complex 2022-02-12 23:02:16 -06:00
Sam Germain
9e599455e7 test_execute_entry mocks get_max_leverage 2022-02-12 23:02:16 -06:00
Sam Germain
41ab20d949 get_max_leverage checks if the number of tiers is < 1 2022-02-12 23:02:15 -06:00
Sam Germain
3b43d42eaa Updated exchange tests 2022-02-12 23:02:15 -06:00
Sam Germain
fa2c9fc51f replaced mmr_key with unified maintenanceMarginRate 2022-02-12 23:02:15 -06:00
Sam Germain
e987e0e2a9 exchange minor fixes 2022-02-12 23:02:15 -06:00
Sam Germain
f3cb7e90e0 moved get_leverage_tiers_for_pair to be with other leverage_tier methods 2022-02-12 23:02:15 -06:00
Sam Germain
5f07546b86 moved leverage_tier caching to get_leverage_tiers_for_pair 2022-02-12 23:02:15 -06:00
Sam Germain
eb72e5cc42 Added some exchange leverage tier tests 2022-02-12 23:02:15 -06:00
Sam Germain
98f32e8964 fixed failing test_get_max_leverage 2022-02-12 23:02:15 -06:00
Sam Germain
3ebda1d29d Added test templated 2022-02-12 23:02:15 -06:00
Sam Germain
a0264f0651 test_get_max_pair_stake_amount with leverage 2022-02-12 23:02:15 -06:00
Sam Germain
fe56c8c91e mock get_max_pair_stake_amount in test_execute_entry 2022-02-12 23:02:15 -06:00
Sam Germain
18b4d0be95 fixed error with exchange.fill_leverage_tiers 2022-02-12 23:02:14 -06:00
Sam Germain
41d8330fbc freqtrade.exchange edited load_leverage_tiers 2022-02-12 23:02:14 -06:00
Sam Germain
0b717fbace okex.load_leverage_tiers 2022-02-12 23:02:14 -06:00
Sam Germain
68a778a983 moved leverage_tiers to a fixture 2022-02-12 23:02:14 -06:00
Sam Germain
42e36f44f8 replaced "leverage" with "tiers" 2022-02-12 23:02:14 -06:00
Sam Germain
6b9915bc73 moved fill_leverage_brackets and get_max_leverage to base exchange class, wrote parse_leverage_tier and load_leverage_brackets 2022-02-12 23:02:14 -06:00
Sam Germain
a99cf2eeed redid get_max_leverage 2022-02-12 23:02:07 -06:00
Sam Germain
720a86778e okex.get_max_pair_stake_amount 2022-02-12 23:01:39 -06:00
Sam Germain
ff915b241c test_okex test_get_maintenance_ratio_and_amt_okex 2022-02-12 23:01:39 -06:00
Sam Germain
a5aba4813d moved get_maintenance_ratio_and_amt to base.exchange. Wrote get_leverage_tiers. Added mmr_key to exchange._ft_has 2022-02-12 23:01:30 -06:00
Sam Germain
fc2d3649a1 edited todos 2022-02-12 16:23:14 -06:00
Matthias
ee5f05208e Merge pull request #6394 from samgermain/todos
todo removal
2022-02-12 15:44:42 +01:00
Matthias
fad243e28d Keep short edge support as regular TODO 2022-02-12 15:43:52 +01:00
Sam Germain
ca993c83ea todo removal 2022-02-11 23:37:31 -06:00
Matthias
50e474ded2 Merge pull request #6386 from samgermain/liq-buffer
Added liquidation_buffer to freqtradebot
2022-02-11 20:26:05 +01:00
Sam Germain
19a282ddb4 fixed broken test_get_liquidation_price 2022-02-11 19:38:59 +01:00
Sam Germain
7a79403d2c Update docs/leverage.md
Co-authored-by: Matthias <xmatthias@outlook.com>
2022-02-11 19:38:59 +01:00
Sam Germain
6ae85f9be1 fixed liq-buffer tests 2022-02-11 19:38:59 +01:00
Sam Germain
fb3a6e2ce8 added liquidation_buffer to constants.py 2022-02-11 19:38:59 +01:00
Sam Germain
3c3675ea1a moved liquidation_buffer to exchange class, add check for valid liquidation_buffer values 2022-02-11 19:38:59 +01:00
Sam Germain
305d3738d9 Documentation for liquidation_buffer 2022-02-11 19:38:59 +01:00
Sam Germain
e5d68f12d2 Added liquidation_buffer to freqtradebot 2022-02-11 19:38:58 +01:00
Matthias
f79873307d Run CI on feat/short branch 2022-02-11 19:16:57 +01:00
Matthias
0c6d92a7a6 Merge branch 'develop' into feat/short 2022-02-11 17:02:04 +01:00
Matthias
7237aa7edb Merge pull request #6385 from samgermain/bin-stop 2022-02-10 19:51:59 +01:00
Matthias
7c66f2776d Merge pull request #6384 from samgermain/compat-contract
test_ccxt__get_contract_size
2022-02-10 19:07:04 +01:00
Sam Germain
553da850ce binance futures stoploss 2022-02-10 09:43:32 -06:00
Sam Germain
52fed6e779 test_ccxt__get_contract_size 2022-02-10 06:59:43 -06:00
Matthias
ce9de243b7 Merge pull request #6375 from samgermain/todos
deleted outdated todos
2022-02-07 15:24:20 +01:00
Sam Germain
33b04b1992 deleted outdated todos 2022-02-07 02:47:18 -06:00
Italo
d03378b1df Update hyperopt.py 2022-02-06 15:32:59 +00:00
Italo
adf8f6b2d5 Update hyperopt.py 2022-02-06 10:33:49 +00:00
Matthias
412fe65344 Merge pull request #6316 from samgermain/max-amount
exchange.get_max_pair_stake_amount
2022-02-06 07:44:29 +01:00
Italo
6c1729e20b ignore warnings 2022-02-06 01:07:30 +00:00
Sam Germain
e0d42ad9a7 Update backtesting.py 2022-02-05 18:29:48 -06:00
Italo
6a4cae1f8c Update hyperopt.py 2022-02-06 00:17:48 +00:00
Italo
992eac9efa Update hyperopt.py 2022-02-05 17:36:19 +00:00
Matthias
2c5f7adf28 Merge pull request #6354 from samgermain/ccxt-compat-max-lev
wrote ccxt_compat.test_get_max_leverage_spot test_get_max_leverage_fu…
2022-02-05 17:14:33 +01:00
Matthias
870708a72a Version bump ccxt 2022-02-05 16:35:05 +01:00
Sam Germain
b5d10d1b2e updated ccxt 2022-02-05 08:18:05 -06:00
Sam Germain
ce676a9dd7 wrote ccxt_compat.test_get_max_leverage_spot test_get_max_leverage_futures 2022-02-04 17:55:49 -06:00
Sam Germain
8b57827676 exchange.get_max_pair_stake_amount hard set leverage to 0 2022-02-04 14:26:15 -06:00
Sam Germain
c0a593280e test_exchange.test_cancel_order_dry_run pass leverage to create_order 2022-02-04 04:54:16 -06:00
Sam Germain
dc6cb445fd Merge branch 'feat/short' into max-amount 2022-02-04 04:42:38 -06:00
Sam Germain
cc3cb645f3 Merge branch 'max-amount' of https://github.com/samgermain/freqtrade into max-amount 2022-02-04 04:41:54 -06:00
Sam Germain
1824ee6b73 removed TODO 2022-02-04 04:41:41 -06:00
Matthias
6afad6c99f Small change to todo comment 2022-02-04 07:20:27 +01:00
Matthias
5cc2a15b02 Merge pull request #6349 from samgermain/todos
Todos
2022-02-04 07:20:18 +01:00
Sam Germain
e7d71d01c0 removed plotting todo 2022-02-03 20:39:47 -06:00
Sam Germain
3ee2b7978c wallets.validate_stake_amount added param max_stake_available 2022-02-03 20:33:16 -06:00
Sam Germain
30c476e3c1 freqtradebot.get_valid_enter_price_and_stake gets min of stake_amount and max_stake_amount before calling wallets.validate_stake_amount 2022-02-03 20:33:16 -06:00
Sam Germain
a50f4d2c57 Exchange.createOrder added * as second param 2022-02-03 20:33:16 -06:00
Sam Germain
16c2d54482 updated margin_modes 2022-02-03 20:33:16 -06:00
Sam Germain
7465037906 freqtradebot.execute_entry test for too high stake amount 2022-02-03 20:33:16 -06:00
Sam Germain
c5cfd971f5 get_max_pair_stake_amount_tests 2022-02-03 20:33:16 -06:00
Sam Germain
8c680d75b9 moved max_stake_amount check for None to exchange.get_max_pair_stake_amount 2022-02-03 20:33:16 -06:00
Sam Germain
6b6b35ac1c check for max stake limit in freqtradebot and backtesting 2022-02-03 20:33:04 -06:00
Sam Germain
55d91f018f exchange._get_stake_amount_limit (merged min_pair_stake_amount and get_max_tradeable amount) 2022-02-03 20:33:04 -06:00
Sam Germain
ff5fffefb4 exchange.get_max_amount_tradable looks at cost also 2022-02-03 20:33:03 -06:00
Sam Germain
6e8420914e removed unnecessary CCXT checks in exchange.get_min_pair_stake_amount 2022-02-03 20:33:03 -06:00
Sam Germain
64ad810445 Revert "moved get_max_leverage to get_min_pair_stake_amount"
This reverts commit 90e48d5b98bcfb1452aa818a3274745eac395712.
2022-02-03 20:33:03 -06:00
Sam Germain
73319a74d3 moved get_max_leverage to get_min_pair_stake_amount 2022-02-03 20:33:03 -06:00
Sam Germain
f3b42b0ef3 wrote exchange.get_max_amount_tradable 2022-02-03 20:33:03 -06:00
Sam Germain
de557f1386 models.update removed TODO-lev 2022-02-03 17:48:34 -06:00
Sam Germain
99b8a8ca79 Revert "plot.generate_candlestick_graph Added short equivelent, separating plotting scatter creation to a function"
This reverts commit 0abba7f9b7299ba3c45df6a2ba6e35ad6a19c5a0.
2022-02-03 17:48:34 -06:00
Sam Germain
84dea0339b Added todo to freqtradebot._safe_exit_amount 2022-02-03 17:48:34 -06:00
Sam Germain
edc0e9c75f backtesting._get_ohlcv_as_lists changed candle_type to candle_type_def 2022-02-03 17:48:34 -06:00
Sam Germain
1f74cfe841 plot.generate_candlestick_graph Added short equivelent, separating plotting scatter creation to a function 2022-02-03 17:48:34 -06:00
Sam Germain
a31cf236e4 freqtradebot._safe_exit_amount, no _safe_exit_amount is needed for futures 2022-02-03 17:48:34 -06:00
Sam Germain
d5376c2c89 wrote freqtradebot.test_leverage_prep 2022-02-03 17:48:33 -06:00
Sam Germain
977f87659c edited backtesting._get_sell_trade_entry TODO: removed "Other fees" 2022-02-03 17:48:33 -06:00
Sam Germain
c47c54c16c removed strategy_test_v3.populate_sell_trend # TODO-lev: Add short logic, because it looked like the short logic was already there 2022-02-03 17:48:33 -06:00
Sam Germain
73d10b5c02 backtesting._get_ohlcv_as_lists removed # TODO-lev: Candle-type should be conditional, either "spot" or futures 2022-02-03 17:48:33 -06:00
Sam Germain
64bfa118e0 freqtradebot.handle_cancel_enter todo - Check edge cases, we dont want to make leverage > 1.0 if we dont have to 2022-02-03 17:48:33 -06:00
Sam Germain
bc6614df2d fixed failing tests in tests/commands/test_commands.py by adding NONE='' option to MarginMode 2022-02-03 17:48:33 -06:00
Sam Germain
f58b92bb86 exchange.create_order removed default for leverage 2022-02-03 17:48:08 -06:00
Sam Germain
09f0e7149f test__fetch_and_calculate_funding_fees_datetime_called # TODO-lev: test for longs 2022-02-02 12:42:13 -06:00
Sam Germain
179947fa72 New config (#6333)
* updated new-config to add trading_mode and margin_mode

* added trading_mode and margin_mode to config examples

* added okex config example

* new file:   config_examples/config_binance_futures.example.json

* removed trading_mode and margin_mode from base_config and binance and okex example

* deleted okex and futures config files

* updated full config file

* updated new-config command to add trading_mode and margin_mode to config

* new file:   config_examples/config_okex_futures.example.json

* removed config_okex_futures.example.json

* added trading_mode to test_start_new_config

* new-config asks exchange before asking futures

* Simplify trading_mode selection

* margin_mode is empty string for spot new configs

* build_config_commands sorted exchanges

* isort

Co-authored-by: Matthias <xmatthias@outlook.com>
2022-02-02 14:46:44 +01:00
Matthias
c3684e8a1a Merge pull request #6346 from samgermain/minor-fixes
Minor fixes for feat/short
2022-02-02 07:46:17 +01:00
Sam Germain
a741356d65 okex._lev_prep, removing rounding from default set_leverage 2022-02-02 00:28:57 -06:00
Sam Germain
8e51360f75 exchange._set_leverage rounds leverage 2022-02-02 00:09:58 -06:00
Sam Germain
8a64f6a27f exchange.set_margin_mode param swap 2022-02-02 00:09:53 -06:00
Sam Germain
386be2d889 set reduceOnly for futures exit orders 2022-02-02 00:08:50 -06:00
Sam Germain
b3477c4802 _api.fetch_funding_history argument pair->symbol 2022-02-02 00:08:50 -06:00
Matthias
fb4f8d94fb Merge pull request #6342 from samgermain/name-changes
Changed name Collateral to MarginMode, and collateral to margin_mode
2022-02-02 07:04:29 +01:00
Matthias
170152d620 Add note about plot-dataframe not supproting futures mode
part of #6224
2022-02-02 06:50:54 +01:00
Matthias
ac04d5852a change to margin_mode also in documentation 2022-02-02 06:41:42 +01:00
Sam Germain
30519aa3be Changed name Collateral -> MarginMode, collateral -> margin_mode, and _supported_trading_mode_margin_pairs -> _supported_trading_margin_pairs 2022-02-01 13:05:40 -06:00
Matthias
45e533fc3e Add leverage/short properties to api responses 2022-02-01 07:08:43 +01:00
Matthias
7dd50f78cf Small finetuning improving a comment 2022-02-01 06:37:13 +01:00
Matthias
2141e04a19 Merge pull request #5849 from freqtrade/isolated-liq
Isolated liq
2022-02-01 06:36:46 +01:00
Italo
ef03f2f3d2 Merge branch 'freqtrade-develop' into plot_hyperopt_stats 2022-02-01 01:07:15 +00:00
Italo
328b969801 Merge branch 'develop' of https://github.com/freqtrade/freqtrade into freqtrade-develop 2022-02-01 01:06:57 +00:00
Sam Germain
fc15e14707 Merge branch 'feat/short' into isolated-liq 2022-01-31 14:22:01 -06:00
Sam Germain
ed320bb2ac exchange.get_liquidation_price check length of positions 2022-01-31 14:01:06 -06:00
Sam Germain
9de63412c1 exchange.get_liquidation_price arguments are not optional 2022-01-31 14:00:52 -06:00
Sam Germain
6c4325b7a2 confest markets removed futures values from ETH/USDT 2022-01-31 13:44:57 -06:00
Matthias
d653d6bfc0 Merge pull request #6332 from samgermain/binance-max-lev
Binance max lev
2022-01-31 20:26:57 +01:00
Sam Germain
430051275a freqtradebot.leverage_prep moved wallet_balance to a variable 2022-01-31 13:21:27 -06:00
Sam Germain
8b9abd0051 test_get_maintenance_ratio_and_amt_gateio removed commented test that returns None 2022-01-31 13:18:31 -06:00
Matthias
de17993705 Fix random test failure when local config is found 2022-01-31 20:09:25 +01:00
Sam Germain
8190b0d83b binance.get_max_leverage adjustment 2022-01-31 12:49:18 -06:00
Sam Germain
a368f8b322 exchange.get_max_leverage changed variable names, made more effecient 2022-01-31 12:21:12 -06:00
Sam Germain
08e4a4a6dd binance.get_max_leverage_fix 2022-01-31 12:21:12 -06:00
Sam Germain
43db4c34d1 added okex back to unsupported exchanges 2022-01-31 12:18:30 -06:00
Sam Germain
2c1497b348 contracts_to_amount no longer in amount_to_precision 2022-01-31 12:18:30 -06:00
Sam Germain
b8f4cebce7 exchange.liquidation_price methods combined, dry_run check on exchange for liquidation price 2022-01-31 12:18:25 -06:00
Sam Germain
143c37d36f cleaned up liquidation price methods 2022-01-31 12:17:07 -06:00
Sam Germain
ede9012fcc removed TODO-levs about okex liquidation price 2022-01-31 12:17:07 -06:00
Sam Germain
d133a7c789 added isolated, futures to okex trading_mode_collateral_pairs 2022-01-31 12:17:07 -06:00
Sam Germain
88ce66650c Okex and Gateio liquidation_price formula are the same, moved liquidation_price to exchange.exchange class 2022-01-31 12:17:07 -06:00
Sam Germain
7f4894d68e okex.liquidation_price formula update 2022-01-31 12:17:07 -06:00
Sam Germain
fe037aa971 exchange.liquidation_price combined position and position_assets 2022-01-31 12:17:07 -06:00
Sam Germain
0b5c2e97b3 exchange._get_maintenance_ratio_and_amount 2022-01-31 12:17:07 -06:00
Sam Germain
e91aaa7d64 removed isolated_liq= 2022-01-31 12:16:43 -06:00
Sam Germain
5cf54bee4d removed excess decimals in test_binance 2022-01-31 12:16:43 -06:00
Sam Germain
0c13e387fe moved liquidation_price method to exchange classes 2022-01-31 12:16:43 -06:00
Sam Germain
5a97760bd1 binance.get_max_leverage divide by 0 warning 2022-01-31 12:16:43 -06:00
Sam Germain
1f8111d1c6 exchange.get_max_leverage pair is required 2022-01-31 12:16:43 -06:00
Sam Germain
caff7e227f binance.fill_leverage_brackets remove excess bracket 2022-01-31 12:16:43 -06:00
Sam Germain
e4b37c6462 freqtradebot.leverage_prep minor fixes 2022-01-31 12:16:43 -06:00
Sam Germain
1f1ac8ce9d test_get_liquidation_price/test_get_maintenance_ratio_and_amt_binance/fill_leverage_brackets/test_validate_trading_mode_and_collateral TODO comments 2022-01-31 12:16:43 -06:00
Sam Germain
c2f9201512 Added get_liquidation_price check 2022-01-31 12:16:43 -06:00
Sam Germain
bb2b2211d0 exchange.fill_leverage_brackets/get_maintenance_ratio_and_amt docstring and type specification 2022-01-31 12:16:43 -06:00
Sam Germain
b4a0611afc exchange.get_liquidation_price removed irrelevant comment 2022-01-31 12:16:43 -06:00
Sam Germain
0c8205ab3b replace single quote docstrings with double quote docstrings 2022-01-31 12:16:43 -06:00
Sam Germain
7abffee755 liquidation_price formula organize and comment clean up 2022-01-31 12:16:43 -06:00
Sam Germain
387a9fbf36 test_execute_entry liquidation_price test test_get_maintenance_ratio_and_amt_gateio 2022-01-31 12:16:38 -06:00
Sam Germain
2d545a2def fixed breaking tests for liquidation price 2022-01-31 12:15:54 -06:00
Sam Germain
1eee5373b9 gateio.get_maintenance_ratio_and_amt 2022-01-31 12:15:54 -06:00
Sam Germain
8889512887 freqtradebot.leverage_prep gets taker_fee_rate 2022-01-31 12:15:54 -06:00
Sam Germain
bff53c52af rewrite fill_leverage_brackets 2022-01-31 12:15:54 -06:00
Sam Germain
69a6223ca0 implemented binance.get_maintenance_ratio_and_amt 2022-01-31 12:15:54 -06:00
Sam Germain
ba5fc21d84 added isolated futures to supported modes for binance,gateio 2022-01-31 12:15:54 -06:00
Sam Germain
e0df7ee72a Changed variable names in binance.get_max_leverage 2022-01-31 12:15:54 -06:00
Sam Germain
42360592ba trimmed down liquidation_price variable and edited comments 2022-01-31 12:15:54 -06:00
Sam Germain
5796d95a95 Added gateio and okex isolated liquidation formulas 2022-01-31 12:15:54 -06:00
Sam Germain
ba02605d77 Isolated liq branch passes all tests and has the general structure that it is supposed to, but is patchy, and doesnt get the correct maintenance amt and maintenance margin rate yet 2022-01-31 12:15:54 -06:00
Sam Germain
eee7271ab8 Added live isolated-liq get 2022-01-31 12:15:54 -06:00
Arunavo Ray
778e3bcba6 Suppress incompatible type "Optional[float]"; expected "float" as the check exists. 2022-01-31 12:15:54 -06:00
Sam Germain
92c94bb62a added position and wallet_balance to LocalTrade.set_isolated_liq 2022-01-31 12:15:54 -06:00
Arunavo Ray
447312d4c8 Fixed parameter check which failed when 0.0 was passed 2022-01-31 12:15:54 -06:00
Sam Germain
d26a068adf rearanged isolated_liq in models a bit 2022-01-31 12:15:54 -06:00
Arunavo Ray
3709130eb7 Added Tests for Binance Liquidation price, shortened liquidation param names 2022-01-31 12:15:54 -06:00
Arunavo Ray
f9a2d1a71d Binance Liquidation Price Hedge-Mode Removed 2022-01-31 12:15:54 -06:00
Arunavo Ray
7119dc6e41 Converted kwargs to params 2022-01-31 12:15:54 -06:00
Sam Germain
80f4bae3fe Revert "Added Formulas to Calculate Liquidation Price of Binance USDⓈ-M Futures Contracts"
This reverts commit d343e84507.
2022-01-31 12:15:54 -06:00
Sam Germain
b30458f871 Revert "Added Margin Mode Check for Binance."
This reverts commit abcb9729e5.
2022-01-31 12:15:54 -06:00
Arunavo Ray
1299cff894 Added Margin Mode Check for Binance. 2022-01-31 12:15:54 -06:00
Arunavo Ray
60454334d9 Added Formulas to Calculate Liquidation Price of Binance USDⓈ-M Futures Contracts 2022-01-31 12:15:54 -06:00
Sam Germain
fe5e00361e separated test_leverage into test_interest and test_liquidation_price, and paramaterized tests 2022-01-31 12:15:54 -06:00
Sam Germain
a087d03db9 Added liquidation_price function 2022-01-31 12:15:54 -06:00
Matthias
f10ef7f2da Merge pull request #6334 from samgermain/todo
Removed PrecisionFilter liquidation price TODO-lev
2022-01-31 19:09:07 +01:00
Sam Germain
da0d2590b9 Removed PrecisionFilter liquidation price TODO-lev 2022-01-31 12:06:04 -06:00
Matthias
be866f04fa Merge pull request #6330 from samgermain/market-checks
Removed unnecessary CCXT market checks
2022-01-31 19:01:59 +01:00
Matthias
1b063739c0 Merge pull request #6331 from samgermain/todo
Todo-levs
2022-01-31 15:42:45 +01:00
Sam Germain
689174ea0d removed TODO-lev comments 2022-01-31 04:12:37 -06:00
Sam Germain
779b82b5b4 fixed test_get_min_pair_stake_amount by adding amount.min/max and cost.min/max to all markets 2022-01-31 03:02:17 -06:00
Sam Germain
5af3e1600d updated conftest to have limit keys and contractSize on every market 2022-01-31 03:01:44 -06:00
Sam Germain
29c5dfd4ca Removed unnecessary CCXT market checks 2022-01-31 02:40:10 -06:00
Matthias
cf7edace2b Merge pull request #6312 from freqtrade/short_informative_decorator
Short informative decorator
2022-01-30 15:33:52 +01:00
Matthias
000b8ff281 Merge pull request #6306 from freqtrade/short_forceentry
add `/forcelong` and `/forceshort` commands
2022-01-30 07:36:14 +01:00
Matthias
8a6823deb1 Convert InformativeData to dataclass 2022-01-29 19:59:54 +01:00
Matthias
ab932d8398 Properly detect default candle type 2022-01-29 14:31:58 +01:00
Matthias
463714832d Merge branch 'develop' into feat/short 2022-01-29 14:19:30 +01:00
Matthias
c620e38c7d Informative decorator updates for futures 2022-01-28 19:17:46 +01:00
Matthias
fdea4fcb1b Remove some todo's 2022-01-28 15:52:12 +01:00
Matthias
108018b30b Merge pull request #6231 from freqtrade/funding_rate_backtest
Funding rate backtest
2022-01-27 17:01:28 +01:00
Matthias
c4f71cc103 More forceenter updates 2022-01-27 07:38:11 +01:00
Matthias
6e72effbf0 Update forcebuy telegram tests 2022-01-27 06:31:45 +01:00
Matthias
0a52d79208 Update forcesell to work as forceexit 2022-01-26 20:17:00 +01:00
Matthias
066fb3ce00 Update rest-client with forceenter 2022-01-26 20:07:58 +01:00
Matthias
7afaf4b5d4 Add /forceshort command 2022-01-26 19:53:46 +01:00
Matthias
e2ddea79ee Add "market" to /show_config 2022-01-26 19:49:15 +01:00
Matthias
be7ce208dc Update tests to test forceenter endpoint 2022-01-26 19:24:01 +01:00
Matthias
48d8cd82af _rpc_forcebuy 2022-01-26 19:11:01 +01:00
Matthias
4998f3bdd7 Add order_side to forcebuy endpoint 2022-01-26 19:07:44 +01:00
Matthias
67651e013e Add /forceenter endpoint 2022-01-26 07:10:38 +01:00
Matthias
88ccfedd32 Improve wording of "no history found" error 2022-01-26 06:53:00 +01:00
Matthias
13978e9893 Merge pull request #6276 from clover-es/feat/short
Add support for shorts in strategy.stoploss_from_absolute()
2022-01-25 19:11:05 +01:00
Matthias
325fd8a780 Add test with absolute values 2022-01-25 06:44:20 +01:00
Matthias
f7be93aaa6 leverage limits can be None, so we need to check for that 2022-01-25 06:30:03 +01:00
Italo
a7ea06791a Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-01-24 21:46:33 +00:00
Matthias
4389ce1a8f Update helpers documentation for is_short 2022-01-24 19:12:28 +01:00
Italo
a2fb241a3b increase initial points to 64 2022-01-24 01:35:42 +00:00
Matthias
bf0b95b3d8 Improve backtest tests 2022-01-22 19:46:11 +01:00
Matthias
ad28543d4d Update kraken calculation 2022-01-22 19:46:11 +01:00
Matthias
d3713cf245 Fix fee test 2022-01-22 19:46:11 +01:00
Matthias
a0c0c4dcbe Update funding_fee formula to correctly calculate fees for long trades 2022-01-22 19:46:10 +01:00
Matthias
f26cd19146 Merge index and mark rates as part of dataload 2022-01-22 19:45:46 +01:00
Matthias
82c90c0049 Extract funding and mark mergin to separate method 2022-01-22 19:45:46 +01:00
Matthias
84c6d92d4c calculate_funding_fees is actually a public exchange interface (used in backtesting). 2022-01-22 19:45:46 +01:00
Matthias
e9e7fd749b Support funding-fees while running backtest 2022-01-22 19:45:43 +01:00
Matthias
a340d73edc Update funding_fee calculation test 2022-01-22 19:44:20 +01:00
Matthias
c6c97efed3 Remove unused method _get_funding_fee 2022-01-22 19:44:20 +01:00
Matthias
ef3a1ea8f2 Split funding fee calculation from Download 2022-01-22 19:44:20 +01:00
Guillermo Rodríguez
17ae6a0c78 Harmonize short parameter name in stoploss_from_open() 2022-01-22 18:01:56 +01:00
Guillermo Rodríguez
40cd478c6d Calculate stoploss_from_absolute for shorts 2022-01-22 18:01:02 +01:00
Matthias
f090dcc597 Merge branch 'develop' into feat/short 2022-01-22 17:56:01 +01:00
Italo
402747525f Merge pull request #1 from italodamato/develop 2022-01-22 15:40:57 +00:00
Italo
eacd1b0752 Merge branch 'plot_hyperopt_stats' into develop 2022-01-22 15:39:39 +00:00
Italo
0ce6c150ff set stoploss at trade creation 2022-01-22 14:06:45 +00:00
Italo
52206e6f41 add buy tag to plot 2022-01-20 17:15:05 +00:00
Italo
34d19dc108 Merge branch 'freqtrade:develop' into plot_hyperopt_stats 2022-01-20 11:37:54 +00:00
Matthias
e04956be0e Merge pull request #6185 from freqtrade/fix_funding_fee_calc
cleanup funding fee tests
2022-01-19 06:57:44 +01:00
Italo
2eec51bfcb Update requirements-hyperopt.txt 2022-01-19 02:00:14 +00:00
Italo
16a516a882 added plot functionality 2022-01-19 01:50:15 +00:00
Matthias
1fb48a1f53 Add TODO-lev for "stoploss_from_absolute". 2022-01-18 16:52:34 +01:00
Matthias
120639e84b Merge pull request #6228 from clover-es/feat/short
Stoploss from open for shorts
2022-01-18 16:49:58 +01:00
Matthias
6c7a4230ad Update comment about funding_fees calculation 2022-01-17 19:20:47 +01:00
Matthias
ff646441ce Reduce decimals in test 2022-01-17 19:20:42 +01:00
Matthias
bb738b518c FIx funding_fee calculation 2022-01-17 19:06:26 +01:00
Matthias
5bb48eaed0 Replace Nan with 0 or None in backtesting
part of #6224
2022-01-16 14:49:29 +01:00
Guillermo Rodríguez
d28287880c Add support for shorts in strategy.stoploss_from_open
Signed-off-by: Guillermo Rodríguez <guillebep@gmail.com>
2022-01-15 04:30:30 +01:00
Matthias
dd37e5cfb8 Fix compat-test failures due to wrong currency 2022-01-08 14:46:07 +01:00
Matthias
2fb9e7940a Improve "missing data" message 2022-01-08 14:39:09 +01:00
Matthias
dad080f56f Merge branch 'develop' into feat/short 2022-01-08 10:45:15 +01:00
Matthias
9fc7392817 Merge pull request #6184 from samgermain/todos
Removed rename Todos
2022-01-08 10:34:23 +01:00
Sam Germain
c61acb9f19 removed rename todos 2022-01-08 03:09:47 -06:00
Matthias
522496d9e2 Add Compatibility code for BT_DATA_COLUMNS 2022-01-07 17:17:35 +01:00
Matthias
46809f08fe Merge branch 'develop' into feat/short 2022-01-07 10:13:16 +01:00
Matthias
173524ea5b Merge pull request #6170 from freqtrade/contract_workaround
contractSize is a string coming from ccxt
2022-01-06 16:25:19 +01:00
Matthias
431fcdd76f contractSize is a string comming from ccxt 2022-01-06 13:53:27 +01:00
Matthias
7c3babc86c Fix failing ftx test 2022-01-06 13:40:12 +01:00
Matthias
72b2d4ab5f Update FTX to support new standardized futures format 2022-01-06 11:16:26 +01:00
Matthias
04f2097002 Merge pull request #6168 from samgermain/todos
Futures dust warning
2022-01-06 10:44:25 +01:00
Matthias
6ad521a0f7 Update apply_fee_conditional with note about futures 2022-01-06 10:22:28 +01:00
Matthias
c1d981749e Fix flake8 error 2022-01-06 10:09:41 +01:00
Matthias
8958f569aa Fix random funding_rate test failure 2022-01-05 20:37:26 +01:00
Sam Germain
3d22497177 add warning for futures dust to freqtradebot.apply_fee_conditional 2022-01-05 00:57:36 -06:00
Sam Germain
501f473164 Merge branch 'develop' into feat/short 2022-01-04 22:47:33 -06:00
Sam Germain
b2a1124a26 Merge branch 'feat/short' of https://github.com/freqtrade/freqtrade into feat/short 2022-01-04 00:17:42 -06:00
Matthias
e57c2d64a5 Merge pull request #5888 from samgermain/contract-sizes
Convert contract size to underlying asset size
2022-01-03 21:55:19 +01:00
Matthias
293ffeae67 Fix random test failure in funding test 2022-01-03 20:18:43 +01:00
Matthias
d8cb61278f Simplify contract conversion code
by reusing "get_contract_size"
2022-01-03 18:12:45 +01:00
Sam Germain
707a6507b5 removed redundant todos 2022-01-02 21:46:06 -06:00
Matthias
c7b1352184 Merge pull request #6148 from samgermain/todos
Removed some todo-lev comments
2022-01-02 14:43:07 +01:00
Matthias
35fe7239ed Also test mixed version (both long and short trades) 2022-01-02 13:17:49 +01:00
Matthias
7f88f9bf27 Revert unintended double-call of amount conversion 2022-01-02 13:11:29 +01:00
Sam Germain
67a5739501 fixed test_get_trades_for_order for contracts 2022-01-01 15:39:16 -06:00
Sam Germain
33ab3c1bea Removed some todo-lev comments 2022-01-01 14:10:24 -06:00
Sam Germain
14ae327459 grouped contract methods 2022-01-01 14:08:10 -06:00
Sam Germain
3e4912979a exchange.py: removed get funding rate history 2022-01-01 14:03:26 -06:00
Sam Germain
fcded264e6 removed exchange._get_mark_price_history 2022-01-01 13:53:26 -06:00
Sam Germain
3d4a5eab81 fixed flake8 error 2022-01-01 13:52:06 -06:00
Sam Germain
48567a1301 fixe broken test_get_min_pair_stake_amount 2022-01-01 13:52:06 -06:00
Sam Germain
230dd15ee7 fixed test_amount_to_precision 2022-01-01 13:52:06 -06:00
Sam Germain
f92d47a16b exchange._contracts_to_amount and exchange._amount_to_contracts safe checks 2022-01-01 13:52:06 -06:00
Sam Germain
6ab0e870c2 fixed breaking test test_amount_to_precision 2022-01-01 13:52:06 -06:00
Sam Germain
d105bb764a test__get_contract_size creates its own markets instead of using the markets from conftest 2022-01-01 13:52:06 -06:00
Sam Germain
a85566d6c3 test_exchange.test_create_order removed # assert api_mock.create_order.call_args[0][3] == 100 2022-01-01 13:52:06 -06:00
Matthias
8da596f66d Implement PR feedback 2022-01-01 13:52:01 -06:00
Sam Germain
49a6ebb454 exchange class contract methods safe check for symbol 2022-01-01 13:50:50 -06:00
Sam Germain
78d1a267f0 contract-sizes tests 2022-01-01 13:50:50 -06:00
Sam Germain
d0a300a2e1 Added TODOs 2022-01-01 13:50:49 -06:00
Sam Germain
4f6203e45f Added conversions from contract size to amount for objects returned from api 2022-01-01 13:50:43 -06:00
Sam Germain
e10ceb2362 Amount to precision has _amount_to_contract_size in it 2022-01-01 13:49:09 -06:00
Sam Germain
ee63f12236 Revert "Removed leverage param from get_min_pair_stake_amount"
This reverts commit 096588550ca1de5e5edf63cf7214af037d7bc93b.
2022-01-01 13:49:09 -06:00
Sam Germain
2df5993812 _contract_size_to_amount only impacts limits.amount and not limits.cost, put _get_stake_amount_considering_leverage back in 2022-01-01 13:49:09 -06:00
Sam Germain
ef6ad0e6d7 Removed leverage param from get_min_pair_stake_amount 2022-01-01 13:49:09 -06:00
Sam Germain
3f75531105 added methods _contract_size_to_amount and _amount_to_contract_size, added _amount_to_contract_size to create_order, added contract_size_to_amount to get_min_leverage 2022-01-01 13:49:09 -06:00
Matthias
ddfbe55e7c Merge branch 'develop' into feat/short 2022-01-01 19:16:49 +01:00
Matthias
64917275a9 Merge pull request #6143 from samgermain/todos
Todos
2021-12-31 17:02:14 +01:00
Matthias
c06496e66f Update some more TODO-lev's 2021-12-31 16:49:47 +01:00
Sam Germain
9a220f6cfe removed a few todos 2021-12-31 07:30:01 -06:00
Sam Germain
08b738a5d9 removed outdated todo in kraken 2021-12-31 06:26:13 -06:00
Sam Germain
46072be011 models.__init__ exception for no interest_rates on Margin trading 2021-12-31 06:20:00 -06:00
Sam Germain
867483170a binance.funding_fee_cutoff removed TODO-lev 2021-12-31 06:11:43 -06:00
Sam Germain
250edae193 test__async_get_historic_ohlcv parametrized candle_type 2021-12-31 06:00:56 -06:00
Matthias
4b79d435ad Merge pull request #6084 from aezomz/lev-telegram
Telegram and Webhook updates
2021-12-30 19:17:58 +01:00
Matthias
3c4eda14b1 Remove unused test parameter 2021-12-30 17:34:45 +01:00
Matthias
2395988bf8 Leverage defaults to 1.0, which should not be shown. 2021-12-30 17:32:36 +01:00
Matthias
45ac3b3562 Change formatting slightly 2021-12-30 17:18:46 +01:00
Aezo Teo
fa12098bff changed to suggestion 2021-12-30 20:05:17 +08:00
Matthias
1871165d21 Merge pull request #6127 from wadedyck/download_data_futures_fix
Download data futures fix
2021-12-29 19:08:38 +01:00
Matthias
73276f1351 Remove default argument from "download trades" test 2021-12-29 17:36:47 +01:00
Aezo Teo
642a6a8030 missed the edit for documentation 2021-12-29 21:51:56 +08:00
Aezo Teo
ee7cbcd69f fixed flake8 and mypy errors 2021-12-29 21:48:50 +08:00
Aezo Teo
b6092e2e3c amended L/S for status table 2021-12-29 21:30:31 +08:00
Aezo Teo
1f773671ed updated tests and telegram 2021-12-29 21:24:12 +08:00
Wade Dyck
ac06da40e4 Explicitly set the trading-mode to spot for the --dl-trades download test. 2021-12-28 11:43:42 -07:00
Matthias
b9237d2241 Merge pull request #6128 from wadedyck/futures_fixes
Futures fixes
2021-12-28 19:37:13 +01:00
Wade Dyck
5bb2d3baea Revert "Remove the guards against downloading data in futures mode."
This reverts commit 82cdfba494.
2021-12-28 11:35:17 -07:00
Wade Dyck
60dfadf446 Don't attempt to calculate funding fees when the initial timeframe hasn't been exceeded. 2021-12-27 16:51:47 -07:00
Wade Dyck
a26c82b7cc Also check candle_type_def when creating the pairlist and getting the ohlcv. 2021-12-27 16:51:02 -07:00
Wade Dyck
5743b3a0b7 When getting analyzed dataframes, use candle_type_def in the pair_key as that's how they're cached. 2021-12-27 13:29:25 -07:00
Wade Dyck
82cdfba494 Remove the guards against downloading data in futures mode. 2021-12-27 12:48:42 -07:00
Wade Dyck
3d9360bb8c When backtesting, pass the candle_type to load_data. 2021-12-27 11:46:05 -07:00
Wade Dyck
a5742b3bbc Fixes a failing test_history due to changed log message. 2021-12-27 11:26:49 -07:00
Wade Dyck
5b3f907b0c Fixes a download_data bug when in futures mode.
When specifying multiple pairs to download, the json filenames were
inconsistent due to the reassignment of candle_type. Also adds the
candle_type being downloaded to a log message.
2021-12-27 11:16:38 -07:00
Matthias
90c565006b Merge pull request #6043 from freqtrade/funding_fees
Funding fees
2021-12-20 07:15:30 +01:00
Aezo Teo
6e24274dca updated documentation for webhook 2021-12-19 23:58:58 +08:00
Matthias
a557451eee Okex uses 4h mark candle timeframe 2021-12-19 16:47:44 +01:00
Aezo Teo
ea418bc9ac added stats for long short 2021-12-19 23:24:46 +08:00
Matthias
ddce28c12d Update data downloading to include funding_fee downloads 2021-12-18 15:32:02 +01:00
Matthias
17bd990053 Update funding_fee freqtradebot test 2021-12-11 09:49:48 +01:00
Matthias
6948414e47 Remove no longer necessary method _get_mark_price_history 2021-12-10 19:54:49 +01:00
Matthias
a87d2d62bb Remove no longer needed method get_funding_rate_history 2021-12-10 19:52:02 +01:00
Matthias
aabca85a5f Update _calculate_funding_fees to reuse existing async infrastructure 2021-12-10 19:50:58 +01:00
Matthias
35f9549e98 Expose drop_incomplete from refresh_latest_ohlcv 2021-12-10 07:36:25 +01:00
Matthias
3f266e8c8c Improve ccxt_mark_price_test 2021-12-10 06:46:35 +01:00
Matthias
edd80c3006 Merge branch 'develop' into feat/short 2021-12-09 06:34:07 +01:00
Matthias
0c28d15dc1 Merge pull request #5780 from samgermain/mark-price-candles
Mark price candles
2021-12-09 06:24:54 +01:00
Matthias
2679744228 Explicit test for candletype get_default 2021-12-08 16:20:26 +01:00
Matthias
35afc7b478 Fix wrong tradingMOde comparison 2021-12-08 16:07:27 +01:00
Matthias
25e1142f89 Update Enum imports 2021-12-08 15:59:20 +01:00
Matthias
d079b444a6 Add optional "has" (as comment for now) 2021-12-08 14:48:56 +01:00
Matthias
9b9d61c6d6 Remove SPOT_ candletype 2021-12-08 14:38:09 +01:00
Matthias
d89cbda7b8 Use candle_type_def where possible 2021-12-08 14:15:54 +01:00
Matthias
222c293602 Add "defaultCandletype" 2021-12-08 13:17:20 +01:00
Matthias
dda7283f3e Remove unnecessary default parameters 2021-12-08 11:32:58 +01:00
Matthias
ac2fb08aea Small updates while reviewing 2021-12-07 20:21:49 +01:00
Matthias
f1c5a4d065 Use pair-reconstruction method wherever possible 2021-12-07 20:12:44 +01:00
Matthias
5b67be06c2 Update description of --candletypes 2021-12-07 20:00:12 +01:00
Matthias
b4d27973b1 Update ohlcv_get_pairs test 2021-12-07 19:57:18 +01:00
Matthias
37b013c157 Update hdf5 test 2021-12-07 19:50:16 +01:00
Matthias
a870e0962a Fix some obtruse (test)bugs 2021-12-07 07:25:00 +01:00
Matthias
ba1091b9e4 Improve dataprovider test 2021-12-07 07:11:36 +01:00
Matthias
cff950d783 Update test_convert_ohlcv_format to test as before
it did test conversion of multiple files, and that should be kept this
way.
2021-12-07 07:06:28 +01:00
Matthias
5a3b907132 Update converter tests 2021-12-07 06:59:27 +01:00
Matthias
a58c2c4f6c Update ccxt_compat tests to also test funding_rate 2021-12-07 06:31:39 +01:00
Matthias
ce0df08ac7 Update documentation of changed commands 2021-12-06 07:11:15 +01:00
Matthias
9d79501c13 Add candletypes argument for convert-data 2021-12-05 10:26:00 +01:00
Matthias
a80c3f6a1b Use exchange-dependant timeframe/candletype to get mark/index candles 2021-12-05 10:01:44 +01:00
Matthias
a7eb9f8a58 Fix random test failure 2021-12-05 09:41:24 +01:00
Matthias
1a08613498 Fix parameter sequence in mock 2021-12-04 15:13:06 +01:00
Matthias
5b779fd68b Update missing candle_type params 2021-12-03 16:44:05 +01:00
Matthias
e75f31ee86 Create correct Type for PairWithTimeFrame 2021-12-03 15:20:18 +01:00
Matthias
bead867940 Improve some typehints 2021-12-03 15:08:00 +01:00
Matthias
9421e6e61c Improve some tests 2021-12-03 14:57:09 +01:00
Matthias
69f371bf63 Update download-data to download necessary data for futures 2021-12-03 14:43:49 +01:00
Matthias
d30aaaeaaa Tests should also use CandleType 2021-12-03 14:27:04 +01:00
Matthias
2f17fa2765 Update more to use candleType 2021-12-03 14:15:35 +01:00
Matthias
5493212672 More candletype changes 2021-12-03 13:04:31 +01:00
Matthias
f33643cacf Add candletype from string 2021-12-03 12:46:18 +01:00
Matthias
f9cf59bb4d Candle_type to enum 2021-12-03 12:32:12 +01:00
Matthias
a87e256737 Add candleType enum 2021-12-03 12:12:33 +01:00
Matthias
e0e4369c8e list-available-pairs should be tradingmode dependent 2021-12-03 08:09:32 +01:00
Matthias
b578e31255 Align tests to have futures data in futures/ directory 2021-12-03 07:20:43 +01:00
Matthias
7baf11a497 Futures candles should go into a subdirectory 2021-12-03 07:04:53 +01:00
Matthias
fae7167bf3 Merge branch 'feat/short' into pr/samgermain/5780 2021-12-02 20:25:30 +01:00
Matthias
fb1599d21b Merge branch 'develop' into feat/short 2021-12-02 20:20:35 +01:00
Matthias
22cda87211 Update some tests after merge 2021-12-02 19:05:06 +01:00
Matthias
f4d0abc51a Merge branch 'feat/short' into pr/samgermain/5780 2021-12-02 07:09:37 +01:00
Matthias
f71b7a4e76 Merge branch 'develop' into feat/short 2021-12-02 06:53:15 +01:00
Matthias
77443d5abc Merge pull request #6011 from freqtrade/lev/backtesting
correctly apply leverage to backtesting
2021-12-01 19:49:40 +01:00
Matthias
67f3570bf3 Merge branch 'develop' into feat/short 2021-12-01 07:21:36 +01:00
Matthias
8b2fbb6432 Add leveraged backtest detail test 2021-11-30 20:42:18 +01:00
Matthias
a2a974fc6d correctly apply leverage to backtesting 2021-11-30 20:32:34 +01:00
Matthias
134b129d9d get_analyzed_df does not need a "candle_type" argument 2021-11-28 19:14:58 +01:00
Matthias
cb4efa6d56 Revert unnecessary formatting changes 2021-11-28 15:53:13 +01:00
Matthias
c20157e64f Add compatibility code for existing informative_pairs implementation 2021-11-28 15:43:04 +01:00
Matthias
0d6c933935 Improve and fix pair detection from available data 2021-11-28 15:25:57 +01:00
Matthias
0d1324718c Don't replace "-" when writing pair files 2021-11-28 15:08:02 +01:00
Matthias
7faa7539b4 Further enhance pair retrieval 2021-11-28 15:03:55 +01:00
Matthias
8d70672bee Enhance Regex to work for mark candles 2021-11-28 14:37:54 +01:00
Matthias
c096c7f5cb Add explicit tests for ohlcv regex 2021-11-28 14:34:46 +01:00
Matthias
107e124f60 Fix bug in exchange causing candles not to download 2021-11-27 17:00:06 +01:00
Matthias
bf8f1045ca Map binanceusdm to ft binance class 2021-11-27 16:46:17 +01:00
Matthias
504efbd6d4 Add futures argument to download-data command 2021-11-27 16:36:59 +01:00
Sam Germain
392128013f Updated ohlcv_get_available_data to recognize swap and futures pairs 2021-11-27 03:11:44 -06:00
Sam Germain
8761649fd7 Added candle_type in doc strings 2021-11-27 02:55:42 -06:00
Sam Germain
0183e313ac Merge branch 'mark-price-candles' of https://github.com/samgermain/freqtrade into mark-price-candles 2021-11-27 02:44:14 -06:00
Sam Germain
0d30b32fdd Formatting changes 2021-11-27 02:44:06 -06:00
Matthias
cc9ea1d466 Merge pull request #5935 from freqtrade/short_buy_tag_compat
Short buy tag compat
2021-11-26 06:29:56 +01:00
Matthias
51e54a666c Merge branch 'feat/short' into pr/samgermain/5780 2021-11-23 19:01:07 +01:00
Matthias
db16098981 Fix Tests 2021-11-23 17:43:37 +01:00
Matthias
047707f840 Merge pull request #5953 from samgermain/is-future-method-fix
Is future method fix
2021-11-23 11:33:53 +01:00
Sam Germain
586ca3b2fa removed is_market_future from binance and ftx 2021-11-23 11:09:31 +01:00
Sam Germain
70751b942c market_is_future fix 2021-11-23 01:50:23 -06:00
Matthias
ce0593c0e1 Merge branch 'develop' into feat/short 2021-11-23 07:35:26 +01:00
Sam Germain
920151934a Added candle_type to a lot of methods, wrote some tests 2021-11-21 17:48:14 -06:00
Sam Germain
e2f98a8dab replaced candle_type: Optional[str] = '' with candle_type: str = '' 2021-11-21 17:48:14 -06:00
Sam Germain
64a6abc541 Added candle type to ohlcv_get_available_data 2021-11-21 17:48:14 -06:00
Sam Germain
b4029533ec removed candle type from idatahandler.py 2021-11-21 17:48:14 -06:00
Sam Germain
c3b2929e75 Added template for test test_hdf5datahandler_ohlcv_load_and_resave 2021-11-21 17:48:14 -06:00
Sam Germain
843ca22a56 mark price test ohlcv_get_pairs 2021-11-21 17:48:14 -06:00
Sam Germain
91a11d01e9 Added XRP_USDT-1h-mark json testdat file, and test for ohlcv_load with candle_type=mark 2021-11-21 17:48:14 -06:00
Sam Germain
043ed3e330 Added candle_type tests for test_json_pair_data_filename 2021-11-21 17:48:14 -06:00
Sam Germain
12060a2d2c fixed error with fetch_ohlcv candndle_type 2021-11-21 17:48:14 -06:00
Sam Germain
a657707ca3 Added timedelta to exchange 2021-11-21 17:48:14 -06:00
Sam Germain
3d95533bf9 Removed candletype from converter methods 2021-11-21 17:48:14 -06:00
Sam Germain
ee2ad8ca97 updated historic data filenames to include the candle type 2021-11-21 17:48:14 -06:00
Sam Germain
c8162479d6 Added price as param to fetch_ohlcv 2021-11-21 17:48:14 -06:00
Matthias
c26c0b6822 Merge branch 'feat/short' into short_buy_tag_compat 2021-11-21 19:31:59 +01:00
Matthias
aad37bb8f3 Merge pull request #5924 from freqtrade/feat/leverage
call leverage methods
2021-11-21 19:30:27 +01:00
Matthias
63d94aa585 short should be allowed for all non-spot modes 2021-11-21 19:29:08 +01:00
Matthias
983484accd Remove fluky test (seconds still tick with time_machine) 2021-11-21 10:36:39 +01:00
Matthias
fb519a5b39 Add comment with reasoning to ignore leverage in min_amount calculation 2021-11-21 10:28:40 +01:00
Matthias
192ac88314 Update optimize-reports to enter_tag wording 2021-11-21 10:20:09 +01:00
Matthias
2a84526f04 Remove more buy_tag references 2021-11-21 10:05:56 +01:00
Matthias
36deced00b Remove more buy_tag references 2021-11-21 09:55:10 +01:00
Matthias
7d77aff289 Add some compatibility around buy_tag 2021-11-21 09:24:20 +01:00
Matthias
97ff7d1223 Merge branch 'develop' into feat/short 2021-11-21 09:13:53 +01:00
Matthias
7a8978abbb Make ohlcv data endpoint work correctly with new interface 2021-11-20 20:09:37 +01:00
Matthias
32a56bbd4a Merge pull request #5926 from samgermain/has-no-leverage
Trade.has_no_leverage makes more sense
2021-11-20 11:31:36 +01:00
Sam Germain
54ef52692f Trade.has_no_leverage makes more sense 2021-11-20 01:06:10 -06:00
Matthias
988f4d5190 Test leverage call in freqtradebot 2021-11-19 19:34:59 +01:00
Matthias
9aed76ba17 Integrate leverage() to freqtradebot 2021-11-19 19:23:48 +01:00
Matthias
6247608cc6 top/bottom cap leverage 2021-11-19 07:11:19 +01:00
Matthias
021d1b518c Call "leverage" to determine leverage to be used. 2021-11-18 20:55:45 +01:00
Matthias
5a8824171c Add short/long metrics to backtest result 2021-11-18 20:42:43 +01:00
Matthias
0a50017c84 Add long/short support to backtesting 2021-11-18 20:34:59 +01:00
Matthias
f40221dd9f Merge branch 'develop' into feat/short 2021-11-18 20:20:01 +01:00
Matthias
8638e6fe47 Simplify tradingmode parsing 2021-11-18 19:58:44 +01:00
Matthias
4f0a73010a Merge pull request #5890 from aezomz/todo-rpc
Todo-lev RPC tests and model
2021-11-17 06:58:07 +01:00
Matthias
cbb5025711 Merge pull request #5825 from freqtrade/futures_pairlist
Futures pairlist
2021-11-16 19:46:27 +01:00
aezo.teo
1ba2e275b8 updated test param format 2021-11-16 14:29:40 +08:00
Matthias
ce3c5b32f9 Fix test leakage in ccxt_compat 2021-11-16 07:04:56 +01:00
aezo.teo
c17c1611bd removed short_trades, updated schema, tests 2021-11-16 14:03:33 +08:00
Matthias
5cfc385d44 Versionbump ccxt 2021-11-16 06:40:29 +01:00
Matthias
75eccea88d Improve futures detection, add ccxt-compat test 2021-11-15 19:57:36 +01:00
Matthias
4e9b83e170 Merge branch 'feat/short' into futures_pairlist 2021-11-15 19:12:36 +01:00
aezo.teo
9c34208b15 Merge branch 'upstream-5890' into todo-rpc 2021-11-15 23:30:54 +08:00
Sam Germain
ff6b1f4421 Small changes 2021-11-14 21:01:08 -06:00
Sam Germain
f101419a47 Merge branch 'feat/short' into todo-rpc 2021-11-14 20:48:55 -06:00
Matthias
1b058d882d Simplify date rounding logic 2021-11-14 19:55:56 +01:00
Matthias
e7499b7c44 Improve leggibility of test 2021-11-14 19:53:08 +01:00
Matthias
da3ceb0904 Merge pull request #5779 from samgermain/funding-fee-dry-run
Funding fee dry run
2021-11-14 19:49:05 +01:00
Matthias
9102590365 Improve tests by also having a "Mixed" case 2021-11-14 19:22:12 +01:00
aezo.teo
a08572e907 Merge remote-tracking branch 'upstream/feat/short' into todo-rpc 2021-11-14 21:21:59 +08:00
aezo.teo
22f7c0fdc6 updated test cases 2021-11-14 21:04:24 +08:00
Matthias
b3afca2a9d Improve ccxt_compat test for funding rate 2021-11-14 13:37:09 +01:00
aezo.teo
92997c85f9 adding sides for rate and 1 more test case 2021-11-14 17:37:31 +08:00
Sam Germain
e7fad04eb9 Merge branch 'feat/short' into funding-fee-dry-run 2021-11-14 03:15:22 -06:00
aezo.teo
8df334515f added logic for is_short and tests 2021-11-14 16:52:38 +08:00
Matthias
8cfc531b32 Merge pull request #5887 from samgermain/common-ccxt-config
Common ccxt config
2021-11-14 09:52:06 +01:00
aezo.teo
30fbe0c79c added is_short and short_trades to schema 2021-11-14 16:51:03 +08:00
Matthias
984d3216c8 Merge pull request #5889 from samgermain/test-todos
TODO-lev trim
2021-11-14 09:27:33 +01:00
Matthias
38362e0ec5 Update test names 2021-11-14 09:02:25 +01:00
aezo.teo
8f66d8f942 Merge branch 'sam_5889' into todo-rpc 2021-11-14 13:26:32 +08:00
Sam Germain
86e5b480a8 test_strategy_test_v2 for shorts 2021-11-13 19:56:29 -06:00
Sam Germain
430aa0903f Removed redundent TODO-levs 2021-11-13 19:45:41 -06:00
Sam Germain
77f8f8658c test_rpc_telegram short test 2021-11-13 19:36:49 -06:00
Sam Germain
ca9805112d test_get_trades_proxy and test_select_order for shorts passes 2021-11-13 19:28:58 -06:00
Sam Germain
01ad65de68 test_rpc_apiserver.py 2021-11-13 19:22:43 -06:00
Sam Germain
3ce64dd4e9 Added test__ccxt_config for all exchanges with subclass files on freqtrade 2021-11-13 16:32:43 -06:00
Sam Germain
099bf7691e Updated bibox to combine parent _ccxt_config and minimized _ccxt_config tests 2021-11-13 16:23:59 -06:00
Sam Germain
3d86b18492 Added property _ft_has_default.ccxt_futures_name and removed subclass ccxt_config properties 2021-11-13 16:23:58 -06:00
Sam Germain
867ac3f82a Removed typing.List from bibox, hitbtc and kucoin 2021-11-13 06:21:17 -06:00
Sam Germain
3c509a1f9b New method for combining all funding fees within a time period 2021-11-13 04:45:23 -06:00
Matthias
6b40792f80 Merge branch 'feat/short' into funding-fee-dry-run 2021-11-12 08:06:29 +01:00
Matthias
8d4163d003 Add compat tests 2021-11-12 07:26:59 +01:00
Sam Germain
c8c2d89893 exchange.get_funding_fees returns 0 by default 2021-11-11 19:10:56 -06:00
Sam Germain
9a65f486ed updated exchangeError messages regarding fetch_funding_rate_history 2021-11-11 18:33:46 -06:00
Sam Germain
592b7e0ce3 All test_update_funding_fees tests pass 2021-11-11 17:49:32 -06:00
Matthias
76ced8acf6 Add some documentation to class 2021-11-11 20:34:52 +01:00
Matthias
68083b7fdd Fix sqlinsert failure in test 2021-11-11 20:07:56 +01:00
Matthias
2e451da08f Merge pull request #5874 from samgermain/update-todos
Removed unnecessary todo comments
2021-11-10 15:22:50 +01:00
Sam Germain
43174760ef Added exit trade funding_fees check but test fails because of sql integrity error test_update_funding_fees 2021-11-10 01:19:51 -06:00
Sam Germain
b87f8e7034 Removed unnecessary todo comments 2021-11-10 00:59:53 -06:00
Sam Germain
e713f5188f Merge branch 'funding-fee-dry-run' of https://github.com/samgermain/freqtrade into funding-fee-dry-run 2021-11-09 14:45:50 -06:00
Sam Germain
45e4354906 Merge branch 'feat/short' into funding-fee-dry-run 2021-11-09 14:45:10 -06:00
Matthias
4a67b33cb3 Fix some formatting 2021-11-09 19:40:42 +01:00
Matthias
e69a100c64 Merge branch 'feat/short' into pr/samgermain/5779 2021-11-09 19:34:57 +01:00
Matthias
d5438ed0a8 Fix docstring indents 2021-11-09 19:22:29 +01:00
Sam Germain
fbe9e73c5d better param for funding_fee_cutoff 2021-11-09 01:17:29 -06:00
Sam Germain
6c8501dadc Removed docstring indents 2021-11-09 01:00:57 -06:00
Sam Germain
d0b91b334e Merge branch 'feat/short' into funding-fee-dry-run 2021-11-08 04:44:57 -06:00
Sam Germain
090b3d29b7 Updated kraken._get_funding_fee docstring with notification that it won't work in the bot yet 2021-11-08 01:58:23 -06:00
Sam Germain
01229ad631 updated exchange.get_funding_fee_dates with better names 2021-11-08 01:58:23 -06:00
Sam Germain
7122cb2fe9 updated test_get_funding_fees to test for funding fees at beginning of trade also 2021-11-08 01:58:23 -06:00
Sam Germain
bea37e5ea3 moved dry run check for funding fees to exchange 2021-11-08 01:58:09 -06:00
Matthias
6cc3f65a83 Add --trading-mode parameter 2021-11-07 10:52:20 +01:00
Matthias
11b77cf94c Update test to new list-pairs format 2021-11-07 10:43:00 +01:00
Matthias
bfe3760f68 Add tests for margin mode 2021-11-07 10:43:00 +01:00
Matthias
0dd9a277d3 improve market_is_tradable tests 2021-11-07 10:43:00 +01:00
Matthias
534b0a5911 Some tests for new market checking 2021-11-07 10:43:00 +01:00
Matthias
3fac5c5bcd Update list-markets to work for futures/margin as well 2021-11-07 10:43:00 +01:00
Matthias
8990097d6f Enrich markets mock with "type" and "spot" info 2021-11-07 10:43:00 +01:00
Matthias
bfca9e7c09 Merge pull request #5853 from samgermain/okex
Added okex exchange class futures properties
2021-11-07 08:30:47 +01:00
Sam Germain
252e45ebf2 Merge branch 'feat/short' into funding-fee-dry-run 2021-11-06 22:46:00 -06:00
Sam Germain
04dc14a74c Added okex exchange class futures properties 2021-11-06 22:43:02 -06:00
Sam Germain
0c2501e11b Safer keys for funding_rate and mark_price dictionaries, based on rounding down the hour 2021-11-06 22:31:38 -06:00
Sam Germain
8bfcf4ee09 Fixed breaking exchange tests from _get_funding_fee_dates, and commented out kraken get_funding_fees tests 2021-11-06 22:05:38 -06:00
Sam Germain
b88482b2e9 Fixed millisecond timestamp issue errors with funding fees 2021-11-06 21:45:35 -06:00
Sam Germain
48b34c8fd0 Fixed issues with funding-fee being miscalculated on trade objects in freqtradebot 2021-11-06 21:03:18 -06:00
Sam Germain
f795288d90 Fixed timestamp/datetime issues for mark price, funding rate and _get_funding_fee_dates 2021-11-06 20:48:03 -06:00
Sam Germain
6e912c1053 Updated _get_funding_fee method names, added kraken._get_funding_fee 2021-11-06 17:39:21 -06:00
Matthias
e3a368a74e Merge pull request #5668 from samgermain/docs
Docs for leverage
2021-11-06 15:42:32 +01:00
Matthias
ebc38159b8 Merge branch 'develop' into feat/short 2021-11-06 15:24:52 +01:00
Sam Germain
cb97c6f388 Updated time to utc in test_update_funding_fees, some funding rate key errors because a timestamp is likely not in utc 2021-11-06 05:56:58 -06:00
Sam Germain
fd63fa7dda Updated test_update_funding_fees to compile fine but the assertion is incorrect 2021-11-06 05:42:41 -06:00
Rokas Kupstys
98b475a00b Use lambdas instead of a static number of side-effects. 2021-11-06 10:23:46 +02:00
Sam Germain
7171975a4f Removed interest formulas from docs 2021-11-05 01:59:54 -06:00
Matthias
ca2e888801 improve documentation formatting 2021-11-05 01:59:36 -06:00
Sam Germain
b620d46958 Updated formatting leverage.md 2021-11-05 01:56:35 -06:00
Sam Germain
b4de68e1bc Updated docs to include liquidation, own definitions 2021-11-05 01:56:16 -06:00
Sam Germain
68810eb4f3 Fixed warning 2021-11-05 01:56:16 -06:00
Sam Germain
4a0a215c45 moved lev docs to own file, updated config 2021-11-05 01:56:16 -06:00
Sam Germain
449710d662 Added collateral example 2021-11-05 01:56:16 -06:00
Sam Germain
2714c02842 Added docs for leverage and trading mode 2021-11-05 01:56:16 -06:00
Sam Germain
8a4236198f Added test_update_funding_fees in freqtradebot, test currently fails 2021-11-03 22:52:37 -06:00
Sam Germain
3de42da29a All funding fee test_exchange tests pass 2021-11-01 07:52:40 -06:00
Sam Germain
863e0bf837 Adding 1am tests to funding_fee_dates 2021-11-01 06:40:20 -06:00
Sam Germain
74b6335acf Adding timezone utc to test__get_funding_fee_dates 2021-11-01 06:34:22 -06:00
Sam Germain
ba95172d07 Finished test_calculate_funding_fees 2021-11-01 06:28:03 -06:00
Sam Germain
765ee5af50 Updated conftest funding_rate and mark_price 2021-11-01 02:51:59 -06:00
Sam Germain
33b0778c0a updated exchange.calculate_funding_fees to have default close_date 2021-11-01 01:13:37 -06:00
Sam Germain
8b9dfafdf4 Tests for _get_funding_fee_dates 2021-11-01 01:09:57 -06:00
Sam Germain
edfc3377c5 Updated exchange._get_funding_fee_dates to use new method funding_fee_cutoff 2021-11-01 01:09:11 -06:00
Sam Germain
77d247e179 Created fixtures mark_ohlcv and funding_rate_history 2021-11-01 01:04:42 -06:00
Sam Germain
5c52b21346 Added tests for funding_fee_dry_run 2021-10-31 22:24:27 -06:00
Sam Germain
f6924aca40 removed get_funding_rate_history from gateio 2021-10-31 01:24:02 -06:00
Sam Germain
2bfc812618 moved mark_ohlcv_price in _ft_has 2021-10-31 00:53:36 -06:00
Matthias
c094ac5762 Merge branch 'develop' into feat/short 2021-10-30 19:45:19 +02:00
Sam Germain
0ea8957ccc removed ftx get_mark_price_history, added variable mark_ohlcv_price, used fetch_ohlcv instead of fetch_mark_ohlcv inside get_mark_price_history 2021-10-29 20:07:24 -06:00
Sam Germain
a4892654da Removed params from _get_mark_price_history 2021-10-29 19:37:02 -06:00
Sam Germain
02ab3b1697 Switched mark_price endTime to until 2021-10-28 07:26:36 -06:00
Sam Germain
0b12107ef8 Updated error message in fetchFundingRateHistory 2021-10-28 07:22:47 -06:00
Sam Germain
44d9a07acd Fixed _get_funding_fee_dates method 2021-10-28 07:20:45 -06:00
Sam Germain
956352f041 Removed name_for_futures_market 2021-10-28 07:19:46 -06:00
Sam Germain
a2b1838c60 Merge branch 'feat/short' into funding-fee-dry-run 2021-10-25 22:00:09 -06:00
Matthias
4966619f1d Merge pull request #5773 from samgermain/gateio-futures
Gateio futures
2021-10-24 08:45:24 +02:00
Sam Germain
60478cb213 Add fill_leverage_brackets and get_max_leverage back in 2021-10-23 22:16:51 -06:00
Sam Germain
d99e0dac7b Added name for futures market property 2021-10-23 21:59:47 -06:00
Sam Germain
3eda9455b9 Added dry run capability to funding-fee 2021-10-23 21:59:47 -06:00
Sam Germain
2533d3b420 Added get_funding_rate_history method to exchange 2021-10-23 21:59:41 -06:00
Sam Germain
ef8b617eb2 gateio, ftx and binance all use same funding fee formula 2021-10-23 21:59:03 -06:00
Sam Germain
badc0fa445 Adjusted _get_funding_fee_method 2021-10-23 21:58:57 -06:00
Sam Germain
cba0a8cee6 adjusted funding fee formula binance 2021-10-23 21:58:17 -06:00
Sam Germain
2a26c6fbed Added backtesting methods back in 2021-10-23 21:33:37 -06:00
Sam Germain
ed91516f90 Changed future to swap 2021-10-23 14:10:09 -06:00
Sam Germain
1fa2600ee2 Added gateio to test__ccxt_config 2021-10-22 11:52:05 -06:00
Sam Germain
167f9aa8d9 Added gateio futures support, and added gatio to test_exchange exchanges variable 2021-10-22 11:52:05 -06:00
Sam Germain
aed22f7dad Merge branch 'develop' into feat/short 2021-10-22 11:45:27 -06:00
Matthias
21141bdcb3 Merge pull request #5732 from samgermain/new-max-lev
New max lev
2021-10-22 19:30:58 +02:00
Sam Germain
f07555fc84 removed binance constructor, added fill_leverage_brackets call to exchange constructor 2021-10-22 06:37:56 -06:00
Matthias
028e5de935 Remove space after @ decorator in tests 2021-10-20 16:53:24 +02:00
Sam Germain
0329da1a57 updated get_max_leverage to use new ccxt unified property 2021-10-20 08:36:48 -06:00
Sam Germain
3fffc315ac Merge branch 'develop' into feat/short 2021-10-20 08:11:53 -06:00
Matthias
79a91dc31b Merge pull request #5567 from samgermain/lev-freqtradebot
Lev freqtradebot
2021-10-20 15:48:07 +02:00
Matthias
dd59b23b49 Merge pull request #5763 from samgermain/test-ccxt-config
Test ccxt config
2021-10-20 15:41:26 +02:00
Sam Germain
8c80fb46c8 test__ccxt_config 2021-10-20 05:33:09 -06:00
Sam Germain
57d7009fd9 Added trading mode and collateral to constants.py 2021-10-18 01:21:41 -06:00
Sam Germain
faaa3ae9b1 Removed exit_short rpcmessagetype 2021-10-18 01:08:12 -06:00
Sam Germain
053aecf111 reformatted check_handle_timedout 2021-10-18 01:01:29 -06:00
Sam Germain
e4682b78c5 updates suggested on github 2021-10-18 00:28:32 -06:00
Matthias
ad2c88b991 Reduce test-code duplication by importing functions 2021-10-17 17:00:25 +02:00
Matthias
e8f98e473d Fix a few more tests 2021-10-17 11:08:54 +02:00
Matthias
198f3c5238 Merge branch 'feat/short' into pr/samgermain/5567 2021-10-17 10:41:03 +02:00
Matthias
69fdb8edfa Merge branch 'develop' into feat/short 2021-10-17 10:40:08 +02:00
Matthias
41b5e5627b Update stoploss test 2021-10-17 09:54:38 +02:00
Matthias
bc10b451fe Revert wrong condition 2021-10-17 09:46:39 +02:00
Matthias
e19d95b63e Fix stoploss test 2021-10-17 09:00:10 +02:00
Sam Germain
962f63a19a fixed failing test_execute_trade_exit_custom_exit_price 2021-10-14 05:28:08 -06:00
Sam Germain
5fbe76cd7e isolated conditionals in interface stoploss method 2021-10-14 05:10:28 -06:00
Sam Germain
0afd76c183 Fixed failing test_execute_trade_exit_market_order 2021-10-14 04:45:48 -06:00
Sam Germain
2dc402fbf7 Fixed failing test_handle_trade 2021-10-14 04:05:50 -06:00
Sam Germain
b0ce9612f8 Fixed sell_profit_only failing 2021-10-14 03:52:29 -06:00
Sam Germain
bcbe8f229c Merge branch 'feat/short' into lev-freqtradebot 2021-10-13 19:02:57 -06:00
Sam Germain
bd488cc086 Merge branch 'develop' into feat/short 2021-10-13 17:56:40 -06:00
Matthias
aed138ba03 Merge pull request #5377 from samgermain/funding-fee
Funding Fee (Futures)
2021-10-13 19:04:14 +02:00
Matthias
2c6290a100 Small updates to prevent random test failures 2021-10-13 07:04:21 +02:00
Sam Germain
0dbad19b40 trading_mode default null in models.Trade 2021-10-12 20:34:19 -06:00
Sam Germain
82742cd659 Merge branch 'funding-fee' of https://github.com/samgermain/freqtrade into funding-fee 2021-10-12 20:29:10 -06:00
Sam Germain
0fcc7eca62 Added more tests to test_update_funding_fees 2021-10-12 20:28:46 -06:00
Matthias
532a9341d2 Fix migration issue 2021-10-12 20:41:48 +02:00
Matthias
f290ff5c9a Re-add schedule.run_pending 2021-10-12 19:10:38 +02:00
Sam Germain
86cbd0039f Fixed bugs 2021-10-12 02:24:35 -06:00
Rokas Kupstys
437fadc258 Fix profitable trade registering as a loss due to fees. 2021-10-12 10:49:07 +03:00
Matthias
952d83ad24 Reenable additional test 2021-10-11 20:36:08 +02:00
Matthias
70000b5843 Use scheduler as Object, not the automatic Singleton 2021-10-11 20:28:23 +02:00
Sam Germain
2e7adb99da Fixed some breaking tests 2021-10-11 08:52:11 -06:00
Sam Germain
bdad604fab Added persistence futures tests 2021-10-11 07:48:31 -06:00
Sam Germain
01a9e90057 Added futures tests to test_persistence.test_calc_profit 2021-10-11 07:03:14 -06:00
Sam Germain
ae3688a18a Updated LocalTrade.calc_close_trade_value formula for shorting futures 2021-10-11 05:56:27 -06:00
Sam Germain
d5a1385fdc Changes described on github 2021-10-11 04:14:59 -06:00
Sam Germain
855b26f846 Parametrized more time machine tests in test_update_funding_fees 2021-10-11 01:31:21 -06:00
Sam Germain
3b962433fb Switched shcedule to perform every 15 minutes 2021-10-10 02:55:04 -06:00
Sam Germain
81cf4653a9 Fixed failing test_process_trade_creation, test_order_book_depth_of_market, test_handle_stoploss_on_exchange_trailing 2021-10-09 17:35:57 -06:00
Sam Germain
94f0be1fa9 Added is_short=(signal == SignalDirection.SHORT) inside freqtradebot.create_trade 2021-10-09 16:32:22 -06:00
Sam Germain
9513650ffe Fixed failing test_handle_stoploss_on_exchange_trailing 2021-10-09 16:20:25 -06:00
Sam Germain
9a6ffff5eb Added cost to limit_sell_order_usdt_open, fixing some tests 2021-10-09 15:50:18 -06:00
Sam Germain
85e86ec09d Fixed failing test_check_handle_timedout_buy_usercustom 2021-10-09 15:14:33 -06:00
Sam Germain
4fc4007975 Fixed failing test_check_handle_timedout_buy 2021-10-09 14:57:10 -06:00
Sam Germain
729957572b updated strategy stop_loss_reached to work for shorts 2021-10-09 14:39:11 -06:00
Sam Germain
d7e6b842ba Fixed failing tests test_cancel_all_open_orders, test_order_book_ask_strategy, test_order_book_depth_of_market, test_disable_ignore_roi_if_buy_signal 2021-10-09 14:12:17 -06:00
Sam Germain
95be5121ec Added bibox and hitbtc funding fee times 2021-10-09 13:14:41 -06:00
Sam Germain
b83933a10a Added gateio and kucoin funding fee times 2021-10-09 13:09:11 -06:00
Sam Germain
057b048f31 Started added timezone offset stuff 2021-10-09 12:27:40 -06:00
Sam Germain
795d51b68c Switched scheduler to get funding fees every hour for any exchange 2021-10-09 11:27:26 -06:00
Sam Germain
39be675f1f Adjusted time to utc in schedule 2021-10-09 10:52:07 -06:00
Sam Germain
7f7f377a90 updated a test, put in TODO-lev 2021-10-07 05:03:38 -06:00
Sam Germain
e367f84b06 Added more update_funding_fee tests, set exchange of default conf 2021-10-07 04:20:53 -06:00
Matthias
a4a5c1aad0 Fix scheduling test (a little bit) 2021-10-06 07:08:28 +02:00
Sam Germain
362c29c315 Added patch_get_signal(freqtrade, enter_long=False, enter_short=True, exit_short=True) a bunch 2021-10-05 03:15:28 -06:00
Sam Germain
d8ba3d8cde Added trade.is_short = is_short a lot 2021-10-05 02:16:17 -06:00
Sam Germain
c72aac4356 Added trade.is_short = is_short a lot 2021-10-05 02:13:29 -06:00
Sam Germain
29e582c6d9 Fixed time format for schedule and update_funding_fees conf is mocked better 2021-10-05 01:42:46 -06:00
Sam Germain
928c4edace removed side from execute_trade_exit 2021-10-03 23:22:51 -06:00
Sam Germain
9046caa27c fixed test_update_trade_state_sell 2021-10-03 23:13:34 -06:00
Matthias
6e1e1e00c2 Fix mock going into nirvana 2021-10-04 06:59:08 +02:00
Sam Germain
2a2b759419 patch_get_signal test updates 2021-10-03 17:41:01 -06:00
Sam Germain
d75934ce92 'is_short' -> is_short: test_freqtradebot 2021-10-03 04:44:39 -06:00
Sam Germain
56ff0a95a7 Merge branch 'feat/short' into lev-freqtradebot 2021-10-03 02:26:41 -06:00
Sam Germain
70db228f24 Merge branch 'feat/short' into funding-fee 2021-10-03 02:15:54 -06:00
Sam Germain
dcb9ce9513 isort 2021-10-03 02:14:52 -06:00
Sam Germain
d3f7207fe6 Merge branch 'develop' into feat/short 2021-10-03 02:12:25 -06:00
Sam Germain
09ef0781a1 switching limit_buy_order_usdt and limit_sell_order_usdt to limit_order(enter_side[is_short]) and limit_order(exit_side[is_short]) 2021-10-03 01:52:58 -06:00
Sam Germain
57d66cc0f7 Merge branch 'test-freqtradebot-usdt' into lev-freqtradebot 2021-10-02 20:51:50 -06:00
Sam Germain
3823ca4162 Merge branch 'test-freqtradebot-usdt' into lev-freqtradebot 2021-10-02 20:26:52 -06:00
Sam Germain
87ff65d31e Fixed failing test_handle_protections 2021-10-02 04:06:22 -06:00
Sam Germain
72388d3376 tried to solve test_update_funding_fees: 2021-10-02 03:52:00 -06:00
Sam Germain
b3656ddfc9 Merge branch 'feat/short' into lev-freqtradebot 2021-10-02 03:36:32 -06:00
Sam Germain
e8b4cf6eaa Merge branch 'develop' into feat/short 2021-10-02 03:15:12 -06:00
Sam Germain
9ea2dd05d8 Removed space in retrier 2021-10-01 21:21:59 -06:00
Sam Germain
77d3a8b457 Added bybit funding-fee times 2021-09-30 20:18:56 -06:00
Sam Germain
6e86bdb820 Added test_update_funding_fees 2021-09-29 23:11:01 -06:00
Sam Germain
ba60aad89d parameterized TradingMode in persistence 2021-09-29 22:59:09 -06:00
Sam Germain
157223f6ab datetime.utc -> datetime.now(timezone.utc) 2021-09-29 22:32:02 -06:00
Sam Germain
af6afd0ac2 Revert "Replace datetime.utcnow with datetime.now(timezone.utc)"
This reverts commit c4ac876183.
2021-09-29 22:27:21 -06:00
Sam Germain
993dc672b4 timestamp * 1000 in get_funding_fees_from_exchange 2021-09-29 22:18:15 -06:00
Sam Germain
c4ac876183 Replace datetime.utcnow with datetime.now(timezone.utc) 2021-09-29 22:16:44 -06:00
Sam Germain
545b62d746 Merge branch 'feat/short' into funding-fee 2021-09-27 23:34:09 -06:00
Sam Germain
1a132758d0 merged with feat/short 2021-09-27 23:26:20 -06:00
Matthias
d7ce9b9f6d Rename sample short strategy 2021-09-27 19:17:19 +02:00
Matthias
949f469a7f Merge pull request #5378 from samgermain/lev-strat
Lev-strat
2021-09-27 19:16:00 +02:00
Matthias
6fb0d14f80 changed naming for signal variable 2021-09-27 07:07:49 +02:00
Matthias
a926f54a25 Add "side" parameter to custom_stake_amount 2021-09-26 19:35:54 +02:00
Matthias
84e013de2d Update confirm_trade_entry to support "side" parameter 2021-09-26 19:33:22 +02:00
Matthias
4d49f1a0c7 Reset columns by dropping instead of resetting 2021-09-26 15:39:34 +02:00
Matthias
4fd00db630 Use "combined" enter_tag column 2021-09-26 15:22:37 +02:00
Matthias
2a678bdbb4 Update buy_tag column to long_tag 2021-09-26 08:37:44 +02:00
Matthias
a0ef89d910 Also support column-transition for V1 strategies 2021-09-22 20:52:55 +02:00
Matthias
0e13d57e57 Update advise_* methods to entry/exit 2021-09-22 20:42:31 +02:00
Matthias
4c6b1cd55b Add very simple short logic to test-strategy 2021-09-22 20:36:03 +02:00
Matthias
5928ba9c88 Test and document leverage strategy callback 2021-09-22 20:14:52 +02:00
Sam Germain
5113ceb6c8 added schedule to setup.py 2021-09-21 15:52:12 -06:00
Matthias
c791b95405 Use new TestStrategy (V3) by default in tests 2021-09-21 20:24:08 +02:00
Matthias
7a5c7e7020 Update some tests to use StrategyV3 2021-09-21 19:33:33 +02:00
Matthias
4b5cd891cd Add V3 test strategy 2021-09-21 07:12:46 +02:00
Sam Germain
d6b36231e7 added schedule to environment.yml 2021-09-20 23:12:17 -06:00
Matthias
cf2da3b45f Merge branch 'feat/short' into pr/samgermain/5378 2021-09-21 06:59:05 +02:00
Sam Germain
6db2813850 merged with feat/short 2021-09-19 20:33:08 -06:00
Sam Germain
043bfcd5ad Fixed a lot of failing tests" 2021-09-19 20:24:22 -06:00
Sam Germain
d7c7448632 merged lev-freqtradebot with lev-strat 2021-09-19 19:06:43 -06:00
Sam Germain
778f0d9d0a Merged feat/short into lev-strat 2021-09-19 17:44:12 -06:00
Sam Germain
60a678fea7 merged with feat/short 2021-09-19 17:02:09 -06:00
Sam Germain
d8d6f245a7 Fixed breaking tests in test_freqtradebot.py 2021-09-19 16:44:02 -06:00
Sam Germain
ee0ebdf0f2 merged with develop 2021-09-19 15:35:54 -06:00
Matthias
66c2034c3f Merge pull request #5387 from samgermain/lev-exchange
Lev exchange
2021-09-19 13:00:38 +02:00
Sam Germain
2d679177e5 Added in lev prep before creating api order 2021-09-19 03:05:58 -06:00
Sam Germain
fa74b95a01 reduced amount of code for leverage_brackets test 2021-09-19 02:33:28 -06:00
Sam Germain
ddc203ca69 remove %s in test_exchange unix time 2021-09-19 02:26:59 -06:00
Sam Germain
835e0e69fc removed leverage from create order api call 2021-09-19 02:23:05 -06:00
Sam Germain
2b6d134294 Merge branch 'feat/short' into lev-exchange 2021-09-19 01:57:30 -06:00
Sam Germain
ac4f5adfe2 switched since = int(since.timestamp()) from %s 2021-09-19 01:16:22 -06:00
Matthias
b83689f9ea Merge pull request #5541 from arunavo4/feat/short
[Feat/Short] Added Ftx Interest Calculation
2021-09-19 09:05:17 +02:00
Arunavo Ray
27bd30d266 fixed formatting issues 2021-09-19 11:42:29 +05:30
Arunavo Ray
c54259b4c5 Added ftx interest formula tests 2021-09-19 11:35:29 +05:30
ARUNAVO RAY
91cc8212f6 Merge branch 'freqtrade:feat/short' into feat/short 2021-09-19 11:26:33 +05:30
Sam Germain
979c6f2f26 moved leverage_brackets.json to exchange/binance_leverage_brackets.json 2021-09-18 03:49:15 -06:00
Matthias
a89c67787b Replace some more occurances of 'buy' 2021-09-18 09:23:53 +02:00
Sam Germain
2c21bbfa0c Fixed create order margin call count tests and made _ccxt_config a computed property 2021-09-17 16:45:02 -06:00
Matthias
4d558879e9 Merge branch 'feat/short' into pr/samgermain/5378 2021-09-17 19:33:35 +02:00
Matthias
d680fdf33a Merge branch 'develop' into feat/short 2021-09-17 11:16:37 +02:00
Sam Germain
2e8d00e877 temp commit message 2021-09-17 01:15:21 -06:00
Sam Germain
32e52cd460 Added leverage brackets dry run test 2021-09-17 00:41:00 -06:00
Sam Germain
798a0c9827 Tried to add call count to test_create_order 2021-09-17 00:10:53 -06:00
Sam Germain
0628790da9 merged lev-freqtradebot with feat/short 2021-09-16 23:49:43 -06:00
Sam Germain
8123579442 added trading mode to persistence tests 2021-09-16 23:47:44 -06:00
Sam Germain
e78f38c7b6 Merge branch 'feat/short' into funding-fee 2021-09-16 23:32:44 -06:00
Sam Germain
e7b6f3bfd1 removed changes to test_persistence 2021-09-16 23:32:23 -06:00
Sam Germain
ff5b402f58 Merge branch 'feat/short' into lev-exchange 2021-09-16 23:27:44 -06:00
Sam Germain
dced167ea2 fixed some stuff in the leverage brackets binance test 2021-09-16 23:23:36 -06:00
Sam Germain
57c7926515 leverage updates on exchange classes 2021-09-16 23:05:13 -06:00
Matthias
05e01847a0 Merge pull request #5579 from samgermain/paramatrize-test-persistence
Parametrize test persistence
2021-09-17 07:03:45 +02:00
Sam Germain
0ced05890a removed space between @ and pytest 2021-09-16 16:28:23 -06:00
Sam Germain
dec2f377ff Removed utils, moved get_sides to conftest 2021-09-16 16:25:02 -06:00
Sam Germain
a8657bb1ce Removed backtesting funding-fee code 2021-09-16 03:50:01 -06:00
Sam Germain
4c91126c49 some short freqtradebot parametrized tests 2021-09-16 03:23:45 -06:00
Sam Germain
e827ba1388 finished up funding fee formulas 2021-09-15 23:51:21 -06:00
Sam Germain
98b00e8daf merged with feat/short 2021-09-15 22:28:10 -06:00
Sam Germain
cbaf477bec changed kraken set lev implementation 2021-09-15 21:55:19 -06:00
Sam Germain
5fcb69a0b5 Parametrized test_persistence 2021-09-15 18:29:17 -06:00
Sam Germain
d604757056 Added is_short to conf tests 2021-09-14 21:10:38 -06:00
ARUNAVO RAY
9d21261d25 Merge branch 'freqtrade:feat/short' into feat/short 2021-09-15 06:46:33 +05:30
Sam Germain
d3ab2f887f merged with feat/short 2021-09-14 18:32:08 -06:00
Sam Germain
47677ccd91 Merge branch 'feat/short' into lev-exchange 2021-09-14 18:27:51 -06:00
Sam Germain
d77ab337bf merged with develop 2021-09-14 18:26:46 -06:00
Sam Germain
5f6384a961 Added tests to freqtradebot 2021-09-14 17:18:57 -06:00
Sam Germain
7e0eb0adcf merged with feat/short 2021-09-13 14:14:54 -06:00
Sam Germain
5225bd4a5b Merge branch 'develop' into feat/short 2021-09-13 14:02:23 -06:00
Sam Germain
17a5cc96fe Added set_margin_mode to create_order 2021-09-13 00:14:22 -06:00
Sam Germain
49acfc887f merged with lev-exchange 2021-09-13 00:00:22 -06:00
Sam Germain
2aaf60205e Merge branch 'feat/short' into lev-exchange 2021-09-12 23:41:34 -06:00
Sam Germain
83e1067af7 leverage to exchange.create_order 2021-09-12 23:39:08 -06:00
Sam Germain
1d7a8f667a Merge branch 'lev-exchange' into lev-freqtradebot 2021-09-12 03:15:32 -06:00
Sam Germain
e070bdd161 set leverage more thorough tests 2021-09-12 03:09:51 -06:00
Sam Germain
ad44048e29 customized set_leverage for different exchanges 2021-09-12 02:42:13 -06:00
Sam Germain
bc102d57c9 Updated set leverage to check trading mode 2021-09-12 02:09:31 -06:00
Sam Germain
0c1e5afc91 Added set leverage to create_order 2021-09-12 02:02:10 -06:00
Sam Germain
09418938fe Updated kraken fill leverage brackets and set_leverage 2021-09-12 01:51:09 -06:00
Sam Germain
1344c9f7fc _apply_leverage_to_min_stake_amount 2021-09-12 01:31:15 -06:00
Sam Germain
5b84298e03 kraken._apply_leverage_to_stake_amount 2021-09-12 00:03:02 -06:00
Matthias
a18bca640e Merge pull request #5551 from samgermain/comments-todos-formatting-log-messages
Comments todos formatting log messages
2021-09-11 08:08:23 +02:00
Sam Germain
b1067cee6c minor changes 2021-09-11 00:03:01 -06:00
Sam Germain
02521b4010 Merge branch 'lev-exchange' into lev-freqtradebot 2021-09-10 23:59:45 -06:00
Sam Germain
84c121652a Added more todos 2021-09-10 23:42:16 -06:00
Sam Germain
9de946fdac added collateral and trading mode to freqtradebot and leverage prep 2021-09-10 23:39:31 -06:00
Sam Germain
694460c8e0 merged with feat/short 2021-09-10 23:16:12 -06:00
Sam Germain
8e83cb4d64 temp commit message 2021-09-10 16:28:34 -06:00
Sam Germain
b0e05b92d3 Added minor changes from lev-exchange review 2021-09-10 13:39:42 -06:00
Sam Germain
cb155764eb Short side options in freqtradebot 2021-09-10 11:47:27 -06:00
Sam Germain
9f16464b12 Removed unnecessary TODOs 2021-09-10 10:32:46 -06:00
Sam Germain
83bd674ba7 Added side to execute_trade_exit 2021-09-10 03:25:54 -06:00
Sam Germain
d582ccd2e6 merged with lev-exchange 2021-09-10 03:05:13 -06:00
Sam Germain
6486b904b5 merged with feat/short 2021-09-10 02:57:17 -06:00
Sam Germain
1fa318c52a Merge branch 'feat/short' into lev-exchange 2021-09-10 02:51:34 -06:00
Sam Germain
77aa372909 Fixed test_ftx patch 2021-09-10 02:09:27 -06:00
Sam Germain
77fc21a16b Patched test_fill_leverage_brackets_ftx so that exchange._leverage_brackets doesn't retain the values from binance 2021-09-09 23:58:10 -06:00
Sam Germain
063861ada3 Added todos for short stoploss 2021-09-09 15:47:49 -06:00
Sam Germain
2c7cf794f5 Test for short exchange.stoploss exchange.stoploss_adjust 2021-09-09 15:47:49 -06:00
Sam Germain
785b71aec1 formatting 2021-09-09 15:47:49 -06:00
Sam Germain
9f96b977f6 removed interest method from exchange, will create a separate interest PR 2021-09-09 15:47:49 -06:00
Sam Germain
93da13212c test_fill_leverage_brackets_kraken and test_get_max_leverage_binance now pass but test_fill_leverage_brackets_ftx does not if called after test_get_max_leverage_binance 2021-09-09 15:47:49 -06:00
Sam Germain
9e73d02663 Added validating checks for trading_mode and collateral on each exchange 2021-09-09 15:47:49 -06:00
Sam Germain
d1c4030b88 fill_leverage_brackets usinge self.markets.items instead of self._api.markets.items 2021-09-09 15:47:49 -06:00
Sam Germain
619ecc9728 Added exceptions to exchange.interest_rate 2021-09-09 15:47:49 -06:00
Sam Germain
97d1306e34 Added retrier to exchange functions and reduced failing tests down to 2 2021-09-09 15:47:49 -06:00
Sam Germain
cd33f69c7e Wrote failing test_fill_leverage_brackets_binance 2021-09-09 15:47:49 -06:00
Sam Germain
2b7d94a855 Rearranged tests at end of ftx to match other exchanges 2021-09-09 15:47:49 -06:00
Sam Germain
0232f0fa18 Added failing fill_leverage_brackets test to test_kraken 2021-09-09 15:47:49 -06:00
Sam Germain
8d74233aa5 ftx.fill_leverage_brackets test 2021-09-09 15:47:49 -06:00
Sam Germain
8264cc546d Wrote dummy tests for exchange.get_interest_rate 2021-09-09 15:47:49 -06:00
Sam Germain
607e403eb2 split test_get_max_leverage into separate exchange files 2021-09-09 15:47:49 -06:00
Sam Germain
5708fee0e6 Wrote failing tests for exchange.set_leverage and exchange.set_margin_mode 2021-09-09 15:47:49 -06:00
Sam Germain
e6c9b8ffe5 completed set_margin_mode 2021-09-09 15:47:49 -06:00
Sam Germain
39fe381473 set margin mode exchange function 2021-09-09 15:47:49 -06:00
Sam Germain
3a4d247b64 Changed stoploss side on some tests 2021-09-09 15:47:49 -06:00
Sam Germain
f950f039a8 added tests for min stake amount with leverage 2021-09-09 15:47:49 -06:00
Sam Germain
8a5bad7c3e exchange - kraken - minor changes 2021-09-09 15:47:49 -06:00
Sam Germain
5748c9bc13 Added short functionality to exchange stoplss methods 2021-09-09 15:47:49 -06:00
Sam Germain
4ef1f0a977 Changed ftx set_leverage implementation 2021-09-09 15:47:49 -06:00
Sam Germain
16db8d70a5 Added error handlers to api functions and made a logger warning in fill_leverage_brackets 2021-09-09 15:47:49 -06:00
Sam Germain
c256dc3745 Removed some outdated TODOs and whitespace 2021-09-09 15:47:49 -06:00
Sam Germain
134a7ec59b Implemented fill_leverage_brackets get_max_leverage and set_leverage for binance, kraken and ftx. Wrote tests test_apply_leverage_to_stake_amount and test_get_max_leverage 2021-09-09 15:47:49 -06:00
Sam Germain
455bcf5389 Added TODOs to test files 2021-09-09 15:47:49 -06:00
Sam Germain
add7e74632 Added set_leverage function to exchange 2021-09-09 15:47:49 -06:00
Sam Germain
d262af35ca Removed setup leverage and transfer functions from exchange 2021-09-09 15:47:49 -06:00
Sam Germain
f4e26a616f Exchange stoploss function takes side 2021-09-09 15:47:49 -06:00
Sam Germain
ebf5310817 Added get_interest template method in exchange 2021-09-09 15:47:48 -06:00
Sam Germain
54dd9ce7ad Add prep functions to exchange 2021-09-09 15:47:48 -06:00
Matthias
efd6c037d1 Merge pull request #5556 from samgermain/feat/short
Merged feat/short with develop
2021-09-09 22:41:37 +02:00
Sam Germain
1f38088d7b Merged with develop 2021-09-09 13:56:46 -06:00
Sam Germain
e1a749a91e removed unnecessary caplog 2021-09-09 13:19:43 -06:00
Sam Germain
ee874f461c Removed TODO: change to exit-reason, exit_order_status 2021-09-09 13:14:48 -06:00
Sam Germain
f5b01443ad buy/short -> entry order, sell/exit_short -> exit order 2021-09-09 02:10:12 -06:00
Sam Germain
232d10f300 removed leverage/funding_fees 2021-09-09 01:45:57 -06:00
Sam Germain
dfb9937436 Added tests and docstring to exchange funding_fee methods, removed utils 2021-09-09 01:43:55 -06:00
Sam Germain
d54117990b Added funding_fee method headers to exchange, and implemented some of the methods 2021-09-09 01:19:34 -06:00
Sam Germain
d559b6d6c6 changed add_funding_fees template 2021-09-08 19:34:54 -06:00
Sam Germain
3eb0e6ac09 removed leverage/funding_fees 2021-09-08 19:31:27 -06:00
Sam Germain
36b8c87fb6 Added funding fee calculation methods to exchange classes 2021-09-08 19:31:04 -06:00
Sam Germain
cdefd15b28 separated hours_to_time to utils folder 2021-09-08 14:54:48 -06:00
Sam Germain
8bcd444775 real-time updates to funding-fee in freqtradebot 2021-09-08 14:15:25 -06:00
Sam Germain
2f4b566d99 reverted back exchange.get_funding_fees method 2021-09-08 13:46:52 -06:00
Sam Germain
af4a6effb7 added pair to fetch_funding_rate 2021-09-08 13:44:59 -06:00
Sam Germain
baaf516aa6 Added funding_times property to exchange 2021-09-08 13:44:42 -06:00
Sam Germain
695a8fc73b comment updates, formatting, TODOs 2021-09-08 03:09:39 -06:00
Sam Germain
1379ec7402 Updated log messages for freqtradebot 2021-09-08 03:04:01 -06:00
Sam Germain
5dda227342 comment change 2021-09-08 01:53:42 -06:00
Sam Germain
53006db2b7 Updated log messages for freqtradebot 2021-09-08 01:48:22 -06:00
Sam Germain
3057a5b9b8 freqtradebot local name changes 2021-09-08 01:40:22 -06:00
Sam Germain
f1a8b81896 sorted test interfac 2021-09-08 01:27:08 -06:00
Sam Germain
786dcb50eb safe_sell_amount -> safe_exit_amount 2021-09-08 01:20:52 -06:00
Sam Germain
323683d44f some more TODOs 2021-09-08 01:18:53 -06:00
Sam Germain
8ad53e99ce reupdate_buy_order_fees -> reupdate_enter_order_fees 2021-09-08 01:14:16 -06:00
Sam Germain
3656625747 comment updates, formatting, TODOs 2021-09-08 01:12:08 -06:00
Sam Germain
88a5a30a50 handle_cancel_buy/sell -> handle_cancel_enter/exit 2021-09-08 00:53:09 -06:00
Sam Germain
528d1438c9 sell_lock -> exit_lock 2021-09-08 00:49:04 -06:00
Sam Germain
8f38d6276f notify_buy -> notify_enter, notify_sell -> notify_exit 2021-09-08 00:45:55 -06:00
Sam Germain
763a6af224 sample strategy has short 2021-09-08 00:24:32 -06:00
Sam Germain
d811a73ec0 new rpc message types 2021-09-08 00:20:40 -06:00
Sam Germain
f8248f3771 comments, formatting 2021-09-08 00:19:21 -06:00
Sam Germain
e13b0414d8 Merge branch 'lev-strat' into lev-freqtradebot 2021-09-08 00:00:53 -06:00
Sam Germain
dc83e04f9b Merge branch 'feat/short' into lev-exchange 2021-09-07 22:13:20 -06:00
Sam Germain
ff790e8fd3 merged with caplog-clear-freqtradebot 2021-09-07 22:12:49 -06:00
Arunavo Ray
6da26f90aa Merge remote-tracking branch 'origin/feat/short' into feat/short 2021-09-07 12:28:38 +05:30
Arunavo Ray
d07c7f7f27 Added Ftx interest rate calculation 2021-09-07 12:28:23 +05:30
Arunavo Ray
5d3261e92f Added Ftx interest rate calculation 2021-09-07 12:24:39 +05:30
Sam Germain
f5248be043 Changed funding fee tracking method, need to get funding_rate and open prices at multiple candles 2021-09-06 15:47:24 -06:00
Sam Germain
8822b73f9c test_fill_leverage_brackets_kraken and test_get_max_leverage_binance now pass but test_fill_leverage_brackets_ftx does not if called after test_get_max_leverage_binance 2021-09-05 22:27:14 -06:00
Matthias
b752516f65 Edge should use new columns, too 2021-09-05 15:23:27 +02:00
Matthias
68b75af08e Fix bug with inversed sell signals in backtesting 2021-09-05 08:59:18 +02:00
Matthias
49350f2a8e Fix backtesting test 2021-09-05 08:36:22 +02:00
Sam Germain
23ba49fec2 Added validating checks for trading_mode and collateral on each exchange 2021-09-04 22:02:08 -06:00
Sam Germain
7eab855476 Merge branch 'feat/short' into lev-exchange 2021-09-04 20:15:36 -06:00
Sam Germain
d4389eb07d fill_leverage_brackets usinge self.markets.items instead of self._api.markets.items 2021-09-04 19:58:42 -06:00
Sam Germain
6ec2e40736 Added exceptions to exchange.interest_rate 2021-09-04 19:47:04 -06:00
Sam Germain
61fdf74ad9 Added retrier to exchange functions and reduced failing tests down to 2 2021-09-04 19:16:17 -06:00
Sam Germain
92e630eb69 Added get_funding_fees method to exchange 2021-09-04 16:40:53 -06:00
Sam Germain
d6d5bae2a1 New funding fee methods 2021-09-04 16:33:06 -06:00
Sam Germain
b854350e8d Changed funding fee implementation 2021-09-04 16:31:09 -06:00
Sam Germain
194bb24a55 Miscellaneous funding fee changes. Abandoning for a new method of tracking funding fee 2021-09-04 16:20:25 -06:00
Sam Germain
b7891485b3 Created FundingFee class and added funding_fee to LocalTrade and freqtradebot 2021-09-04 16:20:07 -06:00
Matthias
2e50948699 Fix some tests 2021-09-04 20:23:51 +02:00
Matthias
ca44d2e092 Merge branch 'feat/short' into pr/samgermain/5378 2021-09-04 19:54:34 +02:00
Sam Germain
aac1094078 Wrote failing test_fill_leverage_brackets_binance 2021-09-03 20:30:52 -06:00
Sam Germain
95bd0721ae Rearranged tests at end of ftx to match other exchanges 2021-09-03 20:30:19 -06:00
Sam Germain
c5d97d07a8 Added failing fill_leverage_brackets test to test_kraken 2021-09-03 20:29:46 -06:00
Sam Germain
01263663be ftx.fill_leverage_brackets test 2021-09-03 19:56:53 -06:00
Sam Germain
9d398924c6 Wrote dummy tests for exchange.get_interest_rate 2021-09-03 19:56:13 -06:00
Sam Germain
9b953f6e60 split test_get_max_leverage into separate exchange files 2021-09-03 19:25:16 -06:00
Sam Germain
1b20b4f3c7 Wrote failing tests for exchange.set_leverage and exchange.set_margin_mode 2021-09-03 19:00:04 -06:00
Sam Germain
c7a2e6c2c6 completed set_margin_mode 2021-09-03 18:11:39 -06:00
Sam Germain
073426f25c set margin mode exchange function 2021-09-01 23:40:32 -06:00
Matthias
5184cc7749 Merge branch 'develop' into feat/short 2021-09-02 07:03:14 +02:00
Matthias
b61735937c Replace Patch_get_signal with proper calls 2021-08-25 21:05:55 +02:00
Matthias
053d6d8ee1 Merge branch 'feat/short' into pr/samgermain/5378 2021-08-25 20:34:52 +02:00
Matthias
e1c3b7fd8c Merge branch 'develop' into feat/short 2021-08-25 20:31:40 +02:00
Matthias
cb4889398b Fix backtesting bug 2021-08-25 07:03:48 +02:00
Matthias
6b93c71d15 Small refactorings, use only enter_long columns 2021-08-25 06:49:06 +02:00
Matthias
b951f59f89 Fix patch_get_signal 2021-08-24 21:03:13 +02:00
Matthias
c004942588 Merge branch 'feat/short' into pr/samgermain/5378 2021-08-24 20:53:45 +02:00
Matthias
f4242106d9 Merge branch 'develop' into feat/short 2021-08-24 20:53:21 +02:00
Matthias
6524edbb4e Simplify should_exit interface 2021-08-24 20:47:54 +02:00
Matthias
f3b6a0a797 Fix some type errors 2021-08-24 20:40:35 +02:00
Matthias
f9f32a15bb Update plotting tests for new strategy interface 2021-08-24 20:30:42 +02:00
Matthias
9a03cb96f5 Update get_signal 2021-08-24 20:24:51 +02:00
Matthias
46285cd77e Fix some namings in freqtradebot 2021-08-24 20:07:39 +02:00
Matthias
b40f985b13 Add short-exit logic to backtesting 2021-08-24 20:02:40 +02:00
Matthias
eb71ee847c Rename backtest index constants 2021-08-24 06:56:06 +02:00
Matthias
11bd8e912e Fix some tests 2021-08-24 06:52:28 +02:00
Matthias
7a977a8eaf Merge branch 'feat/short' into pr/samgermain/5378 2021-08-24 06:28:16 +02:00
Matthias
957551ea97 Merge branch 'develop' into feat/short 2021-08-24 06:25:06 +02:00
Matthias
faf5cfa66d Update some tests for updated backtest interface 2021-08-23 21:35:28 +02:00
Matthias
7373b39015 Initial support for backtesting with short 2021-08-23 21:16:26 +02:00
Matthias
3e8164bfca Use proper exchange name in backtesting 2021-08-23 21:13:47 +02:00
Matthias
9add3bf808 Add enter_long compatibility layer 2021-08-23 21:12:46 +02:00
Sam Germain
07de5d11ca Removed a bug causing errors from freqtradebot 2021-08-23 00:25:08 -06:00
Sam Germain
317a454c0e Removed shorting from tests/optimize/hyperopts/default_hyperopt.py and created another tests/optimize/hyperopts/short_hyperopt.py with long and shorting 2021-08-23 00:24:49 -06:00
Sam Germain
61ad38500a Reverted freqtrade/templates/*hyperopt* files back to no shorting 2021-08-23 00:18:15 -06:00
Sam Germain
53b51ce8cf Reverted freqtrade/templates/sample_strategy back to no shorting, and created a separate sample short strategy 2021-08-23 00:17:20 -06:00
Sam Germain
0afeb269ad Removed unnecessary TODOs 2021-08-23 00:15:35 -06:00
Sam Germain
9f6b6f04b4 Added False to self.strategy.get_signal 2021-08-22 23:55:34 -06:00
Sam Germain
e5b2b64a3f Changed stoploss side on some tests 2021-08-22 23:36:36 -06:00
Sam Germain
0a624e70ee added tests for min stake amount with leverage 2021-08-22 23:28:03 -06:00
Sam Germain
8644449c33 Removed changes from tests/strategy/strats that hyperopted short parameters, because these are supposed to be legacy tests 2021-08-22 21:47:02 -06:00
Sam Germain
5ca3f49cb5 merged with feat/short after feat/short added styling and comment changes PR 2021-08-22 21:37:20 -06:00
Sam Germain
488d729574 Merge branch 'feat/short' into lev-exchange 2021-08-22 20:59:33 -06:00
Sam Germain
70ebf09871 exchange - kraken - minor changes 2021-08-22 20:58:22 -06:00
Matthias
d03444e5f8 Merge pull request #5447 from samgermain/lev-strat-name-changes
Lev strat name changes
2021-08-22 13:56:57 +02:00
Sam Germain
6ac0ab0233 Added short functionality to exchange stoplss methods 2021-08-21 21:10:03 -06:00
Sam Germain
a5be535cc9 strategy interface: removed some changes 2021-08-21 17:06:04 -06:00
Sam Germain
4ac2237937 Changed ftx set_leverage implementation 2021-08-21 16:26:04 -06:00
Sam Germain
f5fd8dcc05 Added error handlers to api functions and made a logger warning in fill_leverage_brackets 2021-08-21 01:13:51 -06:00
Sam Germain
84bc4dd740 Removed some outdated TODOs and whitespace 2021-08-20 18:50:02 -06:00
Sam Germain
97bb555d41 Implemented fill_leverage_brackets get_max_leverage and set_leverage for binance, kraken and ftx. Wrote tests test_apply_leverage_to_stake_amount and test_get_max_leverage 2021-08-20 18:23:21 -06:00
Sam Germain
55c070f1bb Added interface leverage method 2021-08-18 16:52:34 -06:00
Sam Germain
dc4090234d Added interface leverage method 2021-08-18 16:52:34 -06:00
Sam Germain
092780df9d condensed strategy methods down to 2 2021-08-18 16:52:34 -06:00
Sam Germain
d4a7d2d444 Added short and exit_short to strategy 2021-08-18 16:52:20 -06:00
Sam Germain
314359dd6e strategy interface changes to comments to mention shorting 2021-08-18 13:23:04 -06:00
Sam Germain
e2d5299116 Name changes for strategy 2021-08-18 13:22:54 -06:00
Sam Germain
180d92f879 Merge branch 'feat/short' into lev-exchange 2021-08-11 01:46:41 -06:00
Matthias
98fe3e73de Merge pull request #5381 from samgermain/interest-change
Changed interest implementation (Margin)
2021-08-09 11:58:08 +02:00
Matthias
599ae15460 Parametrize tests 2021-08-09 11:35:27 +02:00
Sam Germain
de4b0d1f7c Merged with feat/short 2021-08-09 00:24:25 -06:00
Sam Germain
06206335d9 Added tests for interest_function 2021-08-09 00:00:50 -06:00
Sam Germain
0733d69cda Added TODOs to test files 2021-08-08 23:24:38 -06:00
Sam Germain
53a6ce881c Added set_leverage function to exchange 2021-08-08 23:24:03 -06:00
Sam Germain
4ca1d25db1 Removed setup leverage and transfer functions from exchange 2021-08-08 23:24:03 -06:00
Sam Germain
2c0077abc7 Exchange stoploss function takes side 2021-08-08 23:24:03 -06:00
Sam Germain
b48b768757 Added get_interest template method in exchange 2021-08-08 23:24:03 -06:00
Sam Germain
120cad88af Add prep functions to exchange 2021-08-08 23:24:03 -06:00
Matthias
b3ca2d0c57 Merge pull request #5380 from samgermain/mg-to-lev
Replaced the term margin with leverage when it should say leverage (All comments)
2021-08-09 06:37:14 +02:00
Sam Germain
8e941e6836 Changed interest implementation 2021-08-08 17:09:17 -06:00
Sam Germain
0545a0ed3c Replaced the term margin with leverage when it should say leverage 2021-08-08 17:04:24 -06:00
Matthias
ecdecb02fa Merge pull request #5365 from samgermain/enums
Added leverage enums
2021-08-08 09:48:11 +02:00
Sam Germain
4630f69830 Removed short, exit_short from enums 2021-08-08 01:36:59 -06:00
Sam Germain
658f138e30 Added short_tag to SignalTagType 2021-08-07 20:08:52 -06:00
Sam Germain
71963e65f1 Removed ExchangeName Enum 2021-08-07 18:47:03 -06:00
Sam Germain
7e6b281b75 Merge branch 'feat/short' of https://github.com/freqtrade/freqtrade into feat/short 2021-08-07 01:43:56 -06:00
Matthias
92ed7c0bf8 Merge branch 'develop' into feat/short 2021-08-07 09:42:25 +02:00
Sam Germain
9988c293b5 Merge branch 'enums' into feat/short 2021-08-06 19:30:31 -06:00
Sam Germain
9b58c58609 Merge branch 'develop' into feat/short 2021-08-06 18:12:53 -06:00
Sam Germain
aec82b4647 Added empty everage/__init__.py 2021-08-06 01:37:34 -06:00
Sam Germain
50d185ccd8 Added exchange_name variables to exchange classes 2021-08-06 01:23:55 -06:00
Sam Germain
241bfc409f Added leverage enums 2021-08-05 23:29:26 -06:00
Matthias
797d7e5ce6 Merge pull request #5157 from samgermain/margin-db
Margin db
2021-08-04 06:57:36 +02:00
Matthias
07673ef47f Update Migrations to use the latest added columns 2021-08-03 10:25:59 +02:00
Sam Germain
5b6dbbd750 Changed order of buy_tag in migrations 2021-08-03 00:23:21 -06:00
Sam Germain
d88e2ae603 Merge branch 'develop' into margin-db 2021-08-02 23:58:44 -06:00
Sam Germain
ef429afb6f Removed is_oeing_trade is_closing_trade 2021-07-31 01:22:48 -06:00
Sam Germain
d6ffd23865 Merged with remote 2021-07-31 01:19:11 -06:00
Sam Germain
bc42516f68 test_update_limit_order has both a buy and sell leverage short order 2021-07-31 01:05:37 -06:00
Sam Germain
26be620f71 Removed LocalTrade.set_is_short 2021-07-31 00:20:25 -06:00
Sam Germain
fadb0de7c7 Removed excess modes stop_loss method, removed models.is_opening_side models.is_closing_side 2021-07-31 00:12:53 -06:00
Sam Germain
3fb7f983f8 Added is_short and leverage to __repr__ 2021-07-28 12:25:56 -06:00
Sam Germain
195badeb80 Changed liquidation_price to isolated_liq 2021-07-28 12:25:56 -06:00
Sam Germain
6ad9b535a9 persistence all to one test file, use more regular values like 2.0 for persistence tests 2021-07-28 12:25:56 -06:00
Sam Germain
a900570f1a Added enter_side and exit_side computed variables to persistence 2021-07-28 12:25:56 -06:00
Sam Germain
b801eaaa54 Changed the name of a test to match it's equivelent
Removed test-analysis-lev
2021-07-28 12:25:56 -06:00
Matthias
317f4ebce0 Boolean sqlite fix for orders table 2021-07-28 12:25:56 -06:00
Matthias
071f6309cc Try fix migration tests 2021-07-28 12:25:56 -06:00
Sam Germain
af8875574c updated mkdocs and leverage docs
Added tests for set_liquidation_price and set_stop_loss
updated params in interestmode enum
2021-07-28 12:25:56 -06:00
Sam Germain
256160740e Updated interest and ratio calculations to correct functions 2021-07-28 12:25:56 -06:00
Sam Germain
8e52a3a29c updated ratio_calc_profit function 2021-07-28 12:25:55 -06:00
Sam Germain
006a60e5a4 Added docstrings to methods 2021-07-28 12:25:55 -06:00
Sam Germain
b0476ebd3e All persistence margin tests pass
Flake8 compliant, passed mypy, ran isort .
2021-07-28 12:25:55 -06:00
Sam Germain
52def4e826 Changed InterestMode enum implementation 2021-07-28 12:25:55 -06:00
Sam Germain
60572c9e0d Took liquidation price out of order completely 2021-07-28 12:25:55 -06:00
Sam Germain
0fc9d6b6ac Moved leverage and is_short variables out of trade constructors and into conftest 2021-07-28 12:25:55 -06:00
Sam Germain
b7b6d87c27 Pass all but one test, because sqalchemy messes up 2021-07-28 12:25:55 -06:00
Sam Germain
737a62be52 set initial_stop_loss in stoploss helper 2021-07-28 12:25:55 -06:00
Sam Germain
f566d83839 Tried to add liquidation price to order object, caused a test to fail 2021-07-28 12:25:55 -06:00
Sam Germain
31fa6f9c25 updated timezone.utc time 2021-07-28 12:25:55 -06:00
Sam Germain
b1098f0120 Added liquidation_price check to test_stoploss_reinitialization_short 2021-07-28 12:25:55 -06:00
Sam Germain
811cea288d Added checks for making sure stop_loss doesn't go below liquidation_price 2021-07-28 12:25:55 -06:00
Sam Germain
0bd71f87d0 made leveraged test names unique
test_adjust_stop_loss_short, test_update_market_order_shortpasses
2021-07-28 12:25:55 -06:00
Sam Germain
286427c04a Moved interest calculation to an enum 2021-07-28 12:25:55 -06:00
Sam Germain
6787461d68 updated leverage.md 2021-07-28 12:25:55 -06:00
Sam Germain
be3a9390fe Switched migrations.py check for stake_currency back to open_rate, because stake_currency is no longer a variable 2021-07-28 12:25:55 -06:00
Sam Germain
5fc587c225 Removed exchange file modifications 2021-07-28 12:25:55 -06:00
Sam Germain
a4403c0814 fixed rpc_apiserver test fails, changed test_persistence_long to test_persistence_leverage 2021-07-28 12:25:55 -06:00
Sam Germain
0ffc85fed9 Set default leverage to 1.0 2021-07-28 12:25:55 -06:00
Sam Germain
78708b27f2 Updated tests to new persistence 2021-07-28 12:25:55 -06:00
Matthias
e0d42d2eb7 Fix migrations, revert some parts related to amount properties 2021-07-28 12:25:55 -06:00
Sam Germain
e4d4d1d1f1 Wrote all tests for shorting 2021-07-28 12:25:55 -06:00
Sam Germain
f194673001 Updated ratio calculation, updated short tests 2021-07-28 12:25:55 -06:00
Sam Germain
5ac03762f0 Kraken interest test comes really close to passing
Added more trades to conftest_trades
2021-07-28 12:25:55 -06:00
Sam Germain
df360fb281 Made borrowed a computed property 2021-07-28 12:25:55 -06:00
Sam Germain
68d3699c19 Turned amount into a computed property 2021-07-28 12:25:55 -06:00
Sam Germain
efcc2adacf About 15 margin tests pass 2021-07-28 12:25:55 -06:00
Sam Germain
f5d7deedf4 added exception checks to LocalTrade.leverage and LocalTrade.borrowed 2021-07-28 12:25:55 -06:00
Sam Germain
34073135b7 Added types to setters 2021-07-28 12:25:55 -06:00
Sam Germain
d07fe1586c Set leverage and borowed to computed properties 2021-07-28 12:25:55 -06:00
Sam Germain
c24ec89dc4 Started some pytests for short and leverage
1 short test passes
2021-07-28 12:25:55 -06:00
Sam Germain
b80f8ca0af Created interest function 2021-07-28 12:25:55 -06:00
Sam Germain
000932eed0 Adding templates for leverage/short tests
All previous pytests pass
2021-07-28 12:25:55 -06:00
Sam Germain
10979361c1 Added changes suggested in pull request, fixed breaking changes,
can run the bot again
2021-07-28 12:25:55 -06:00
Sam Germain
741ca0e58c Added changed to persistance/migrations 2021-07-28 12:25:55 -06:00
Sam Germain
7823a33cbb Updated Trade class 2021-07-28 12:25:55 -06:00
Sam Germain
c7e8439c76 Updated LocalTrade and Order classes 2021-07-28 12:25:55 -06:00
Sam Germain
10d214ccad Added is_short and leverage to __repr__ 2021-07-26 23:09:47 -06:00
Sam Germain
4fcae0d927 Changed liquidation_price to isolated_liq 2021-07-26 23:09:47 -06:00
Sam Germain
1918304c5b persistence all to one test file, use more regular values like 2.0 for persistence tests 2021-07-26 23:09:47 -06:00
Sam Germain
35fd8d6a02 Added enter_side and exit_side computed variables to persistence 2021-07-26 23:09:47 -06:00
Sam Germain
4b81fb31fb Changed the name of a test to match it's equivelent
Removed test-analysis-lev
2021-07-26 23:09:47 -06:00
Matthias
3d7a74551f Boolean sqlite fix for orders table 2021-07-26 23:09:47 -06:00
Matthias
9a03cae920 Try fix migration tests 2021-07-26 23:09:47 -06:00
Sam Germain
0d06d7e108 updated mkdocs and leverage docs
Added tests for set_liquidation_price and set_stop_loss
updated params in interestmode enum
2021-07-26 23:09:47 -06:00
Sam Germain
f1dc6b54ad Updated interest and ratio calculations to correct functions 2021-07-26 23:09:47 -06:00
Sam Germain
358f0303b9 updated ratio_calc_profit function 2021-07-26 23:09:47 -06:00
Sam Germain
546a7353df Added docstrings to methods 2021-07-26 23:09:47 -06:00
Sam Germain
7f75c978a0 All persistence margin tests pass
Flake8 compliant, passed mypy, ran isort .
2021-07-26 23:09:47 -06:00
Sam Germain
a368dfa7b5 Changed InterestMode enum implementation 2021-07-26 23:09:47 -06:00
Sam Germain
86888dbbf0 Took liquidation price out of order completely 2021-07-26 23:09:47 -06:00
Sam Germain
a19466c085 Moved leverage and is_short variables out of trade constructors and into conftest 2021-07-26 23:09:47 -06:00
Sam Germain
150df3eb88 Pass all but one test, because sqalchemy messes up 2021-07-26 23:09:46 -06:00
Sam Germain
98acb0f4ff set initial_stop_loss in stoploss helper 2021-07-26 23:09:46 -06:00
Sam Germain
dd6cc1153b Tried to add liquidation price to order object, caused a test to fail 2021-07-26 23:09:46 -06:00
Sam Germain
1414df5e27 updated timezone.utc time 2021-07-26 23:09:46 -06:00
Sam Germain
bb2a44735b Added liquidation_price check to test_stoploss_reinitialization_short 2021-07-26 23:09:46 -06:00
Sam Germain
2aa2b5bcff Added checks for making sure stop_loss doesn't go below liquidation_price 2021-07-26 23:09:46 -06:00
Sam Germain
3328707a1d made leveraged test names unique
test_adjust_stop_loss_short, test_update_market_order_shortpasses
2021-07-26 23:09:46 -06:00
Sam Germain
1b202ca22e Moved interest calculation to an enum 2021-07-26 23:09:46 -06:00
Sam Germain
d48f1083b0 updated leverage.md 2021-07-26 23:09:46 -06:00
Sam Germain
b6c8b60e65 Switched migrations.py check for stake_currency back to open_rate, because stake_currency is no longer a variable 2021-07-26 23:09:46 -06:00
Sam Germain
ffadc7426c Removed exchange file modifications 2021-07-26 23:09:46 -06:00
Sam Germain
c5ce8c6dd8 fixed rpc_apiserver test fails, changed test_persistence_long to test_persistence_leverage 2021-07-26 23:09:46 -06:00
Sam Germain
0d5749c508 Set default leverage to 1.0 2021-07-26 23:09:46 -06:00
Sam Germain
9ddb6981dd Updated tests to new persistence 2021-07-26 23:09:46 -06:00
Matthias
75b2c9ca1b Fix migrations, revert some parts related to amount properties 2021-07-26 23:09:46 -06:00
Sam Germain
25ff726921 Wrote all tests for shorting 2021-07-26 23:09:46 -06:00
Sam Germain
4d057b8047 Updated ratio calculation, updated short tests 2021-07-26 23:09:46 -06:00
Sam Germain
3a8a9eb255 Kraken interest test comes really close to passing
Added more trades to conftest_trades
2021-07-26 23:09:46 -06:00
Sam Germain
876386d2db Made borrowed a computed property 2021-07-26 23:09:46 -06:00
Sam Germain
2a50f4ff7b Turned amount into a computed property 2021-07-26 23:09:46 -06:00
Sam Germain
da81be9050 About 15 margin tests pass 2021-07-26 23:09:46 -06:00
Sam Germain
6f6deae376 added exception checks to LocalTrade.leverage and LocalTrade.borrowed 2021-07-26 23:09:46 -06:00
Sam Germain
c68a0f05d8 Added types to setters 2021-07-26 23:09:46 -06:00
Sam Germain
691a042e29 Set leverage and borowed to computed properties 2021-07-26 23:09:46 -06:00
Sam Germain
692c55088a Started some pytests for short and leverage
1 short test passes
2021-07-26 23:09:46 -06:00
Sam Germain
b6cc3f02bf Created interest function 2021-07-26 23:09:46 -06:00
Sam Germain
613eecf16a Adding templates for leverage/short tests
All previous pytests pass
2021-07-26 23:09:46 -06:00
Sam Germain
67341aa4f2 Added changes suggested in pull request, fixed breaking changes,
can run the bot again
2021-07-26 23:09:46 -06:00
Sam Germain
20dcd9a1a2 Added changed to persistance/migrations 2021-07-26 23:09:46 -06:00
Sam Germain
69e81100e4 Updated Trade class 2021-07-26 23:09:46 -06:00
Sam Germain
a27171b371 Updated LocalTrade and Order classes 2021-07-26 23:09:46 -06:00
318 changed files with 51947 additions and 9692 deletions

View File

@@ -24,4 +24,3 @@ Have you search for this feature before requesting it? It's highly likely that a
## Describe the enhancement ## Describe the enhancement
*Explain the enhancement you would like* *Explain the enhancement you would like*

View File

@@ -1,9 +1,9 @@
Thank you for sending your pull request. But first, have you included <!-- Thank you for sending your pull request. But first, have you included
unit tests, and is your code PEP8 conformant? [More details](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md) unit tests, and is your code PEP8 conformant? [More details](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md)
-->
## Summary ## Summary
Explain in one sentence the goal of this PR <!-- Explain in one sentence the goal of this PR -->
Solve the issue: #___ Solve the issue: #___
@@ -14,4 +14,4 @@ Solve the issue: #___
## What's new? ## What's new?
*Explain in details what this PR solve or improve. You can include visuals.* <!-- Explain in details what this PR solve or improve. You can include visuals. -->

View File

@@ -13,32 +13,36 @@ on:
schedule: schedule:
- cron: '0 5 * * 4' - cron: '0 5 * * 4'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
build_linux: build_linux:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [ ubuntu-18.04, ubuntu-20.04 ] os: [ ubuntu-18.04, ubuntu-20.04, ubuntu-22.04 ]
python-version: ["3.8", "3.9", "3.10"] python-version: ["3.8", "3.9", "3.10"]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Cache_dependencies - name: Cache_dependencies
uses: actions/cache@v2 uses: actions/cache@v3
id: cache id: cache
with: with:
path: ~/dependencies/ path: ~/dependencies/
key: ${{ runner.os }}-dependencies key: ${{ runner.os }}-dependencies
- name: pip cache (linux) - name: pip cache (linux)
uses: actions/cache@v2 uses: actions/cache@v3
if: runner.os == 'Linux' if: runner.os == 'Linux'
with: with:
path: ~/.cache/pip path: ~/.cache/pip
@@ -62,15 +66,15 @@ jobs:
- name: Tests - name: Tests
run: | run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc pytest --random-order --cov=freqtrade --cov-config=.coveragerc
if: matrix.python-version != '3.9' if: matrix.python-version != '3.9' || matrix.os != 'ubuntu-22.04'
- name: Tests incl. ccxt compatibility tests - name: Tests incl. ccxt compatibility tests
run: | run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc --longrun pytest --random-order --cov=freqtrade --cov-config=.coveragerc --longrun
if: matrix.python-version == '3.9' if: matrix.python-version == '3.9' && matrix.os == 'ubuntu-22.04'
- name: Coveralls - name: Coveralls
if: (runner.os == 'Linux' && matrix.python-version == '3.8') if: (runner.os == 'Linux' && matrix.python-version == '3.9')
env: env:
# Coveralls token. Not used as secret due to github not providing secrets to forked repositories # Coveralls token. Not used as secret due to github not providing secrets to forked repositories
COVERALLS_REPO_TOKEN: 6D1m0xupS3FgutfuGao8keFf9Hc0FpIXu COVERALLS_REPO_TOKEN: 6D1m0xupS3FgutfuGao8keFf9Hc0FpIXu
@@ -78,11 +82,13 @@ jobs:
# Allow failure for coveralls # Allow failure for coveralls
coveralls || true coveralls || true
- name: Backtesting - name: Backtesting (multi)
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp config_examples/config_bittrex.example.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy freqtrade new-strategy -s AwesomeStrategy
freqtrade new-strategy -s AwesomeStrategyMin --template minimal
freqtrade backtesting --datadir tests/testdata --strategy-list AwesomeStrategy AwesomeStrategyMin -i 5m
- name: Hyperopt - name: Hyperopt
run: | run: |
@@ -100,7 +106,7 @@ jobs:
- name: Mypy - name: Mypy
run: | run: |
mypy freqtrade scripts mypy freqtrade scripts tests
- name: Discord notification - name: Discord notification
uses: rjstone/discord-webhook-notify@v1 uses: rjstone/discord-webhook-notify@v1
@@ -118,22 +124,22 @@ jobs:
python-version: ["3.8", "3.9", "3.10"] python-version: ["3.8", "3.9", "3.10"]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Cache_dependencies - name: Cache_dependencies
uses: actions/cache@v2 uses: actions/cache@v3
id: cache id: cache
with: with:
path: ~/dependencies/ path: ~/dependencies/
key: ${{ runner.os }}-dependencies key: ${{ runner.os }}-dependencies
- name: pip cache (macOS) - name: pip cache (macOS)
uses: actions/cache@v2 uses: actions/cache@v3
if: runner.os == 'macOS' if: runner.os == 'macOS'
with: with:
path: ~/Library/Caches/pip path: ~/Library/Caches/pip
@@ -158,22 +164,14 @@ jobs:
- name: Tests - name: Tests
run: | run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc pytest --random-order
- name: Coveralls
if: (runner.os == 'Linux' && 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 - name: Backtesting
run: | run: |
cp config_examples/config_bittrex.example.json config.json cp config_examples/config_bittrex.example.json config.json
freqtrade create-userdir --userdir user_data freqtrade create-userdir --userdir user_data
freqtrade backtesting --datadir tests/testdata --strategy SampleStrategy freqtrade new-strategy -s AwesomeStrategyAdv --template advanced
freqtrade backtesting --datadir tests/testdata --strategy AwesomeStrategyAdv
- name: Hyperopt - name: Hyperopt
run: | run: |
@@ -210,15 +208,15 @@ jobs:
python-version: ["3.8", "3.9", "3.10"] python-version: ["3.8", "3.9", "3.10"]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Pip cache (Windows) - name: Pip cache (Windows)
uses: actions/cache@preview uses: actions/cache@v3
with: with:
path: ~\AppData\Local\pip\Cache path: ~\AppData\Local\pip\Cache
key: ${{ matrix.os }}-${{ matrix.python-version }}-pip key: ${{ matrix.os }}-${{ matrix.python-version }}-pip
@@ -229,7 +227,7 @@ jobs:
- name: Tests - name: Tests
run: | run: |
pytest --random-order --cov=freqtrade --cov-config=.coveragerc pytest --random-order
- name: Backtesting - name: Backtesting
run: | run: |
@@ -249,7 +247,7 @@ jobs:
- name: Mypy - name: Mypy
run: | run: |
mypy freqtrade scripts mypy freqtrade scripts tests
- name: Discord notification - name: Discord notification
uses: rjstone/discord-webhook-notify@v1 uses: rjstone/discord-webhook-notify@v1
@@ -259,19 +257,34 @@ jobs:
details: Test Failed details: Test Failed
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }} webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
mypy_version_check:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: pre-commit dependencies
run: |
pip install pyaml
python build_helpers/pre_commit_update.py
docs_check: docs_check:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Documentation syntax - name: Documentation syntax
run: | run: |
./tests/test_docs.sh ./tests/test_docs.sh
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.8 python-version: "3.10"
- name: Documentation build - name: Documentation build
run: | run: |
@@ -287,19 +300,14 @@ jobs:
details: Freqtrade doc test failed! details: Freqtrade doc test failed!
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }} webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
cleanup-prior-runs:
runs-on: ubuntu-20.04
steps:
- name: Cleanup previous runs on this branch
uses: rokroskar/workflow-run-cleanup-action@v0.3.3
if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/stable' && github.repository == 'freqtrade/freqtrade'"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
# Notify only once - when CI completes (and after deploy) in case it's successfull # Notify only once - when CI completes (and after deploy) in case it's successfull
notify-complete: notify-complete:
needs: [ build_linux, build_macos, build_windows, docs_check ] needs: [ build_linux, build_macos, build_windows, docs_check, mypy_version_check ]
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
# Discord notification can't handle schedule events
if: (github.event_name != 'schedule')
permissions:
repository-projects: read
steps: steps:
- name: Check user permission - name: Check user permission
@@ -319,18 +327,18 @@ jobs:
webhookUrl: ${{ secrets.DISCORD_WEBHOOK }} webhookUrl: ${{ secrets.DISCORD_WEBHOOK }}
deploy: deploy:
needs: [ build_linux, build_macos, build_windows, docs_check ] needs: [ build_linux, build_macos, build_windows, docs_check, mypy_version_check ]
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade' if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: 3.8 python-version: "3.9"
- name: Extract branch name - name: Extract branch name
shell: bash shell: bash
@@ -343,7 +351,7 @@ jobs:
python setup.py sdist bdist_wheel python setup.py sdist bdist_wheel
- name: Publish to PyPI (Test) - name: Publish to PyPI (Test)
uses: pypa/gh-action-pypi-publish@master uses: pypa/gh-action-pypi-publish@v1.5.1
if: (github.event_name == 'release') if: (github.event_name == 'release')
with: with:
user: __token__ user: __token__
@@ -351,7 +359,7 @@ jobs:
repository_url: https://test.pypi.org/legacy/ repository_url: https://test.pypi.org/legacy/
- name: Publish to PyPI - name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@master uses: pypa/gh-action-pypi-publish@v1.5.1
if: (github.event_name == 'release') if: (github.event_name == 'release')
with: with:
user: __token__ user: __token__
@@ -391,7 +399,7 @@ jobs:
- name: Discord notification - name: Discord notification
uses: rjstone/discord-webhook-notify@v1 uses: rjstone/discord-webhook-notify@v1
if: always() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) if: always() && ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) && (github.event_name != 'schedule')
with: with:
severity: info severity: info
details: Deploy Succeeded! details: Deploy Succeeded!
@@ -405,7 +413,7 @@ jobs:
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade' if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'release') && github.repository == 'freqtrade/freqtrade'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Extract branch name - name: Extract branch name
shell: bash shell: bash

View File

@@ -8,11 +8,10 @@ jobs:
dockerHubDescription: dockerHubDescription:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v3
- name: Docker Hub Description - name: Docker Hub Description
uses: peter-evans/dockerhub-description@v2.4.3 uses: peter-evans/dockerhub-description@v3
env: env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKERHUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} DOCKERHUB_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKERHUB_REPOSITORY: freqtradeorg/freqtrade DOCKERHUB_REPOSITORY: freqtradeorg/freqtrade

8
.gitignore vendored
View File

@@ -7,10 +7,15 @@ logfile.txt
user_data/* user_data/*
!user_data/strategy/sample_strategy.py !user_data/strategy/sample_strategy.py
!user_data/notebooks !user_data/notebooks
!user_data/models
!user_data/freqaimodels
user_data/freqaimodels/*
user_data/models/*
user_data/notebooks/* user_data/notebooks/*
freqtrade-plot.html freqtrade-plot.html
freqtrade-profit-plot.html freqtrade-profit-plot.html
freqtrade/rpc/api_server/ui/* freqtrade/rpc/api_server/ui/*
build_helpers/ta-lib/*
# Macos related # Macos related
.DS_Store .DS_Store
@@ -80,6 +85,8 @@ instance/
# Sphinx documentation # Sphinx documentation
docs/_build/ docs/_build/
# Mkdocs documentation
site/
# PyBuilder # PyBuilder
target/ target/
@@ -105,3 +112,4 @@ target/
!config_examples/config_ftx.example.json !config_examples/config_ftx.example.json
!config_examples/config_full.example.json !config_examples/config_full.example.json
!config_examples/config_kraken.example.json !config_examples/config_kraken.example.json
!config_examples/config_freqai.example.json

46
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,46 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pycqa/flake8
rev: "4.0.1"
hooks:
- id: flake8
# stages: [push]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v0.942"
hooks:
- id: mypy
exclude: build_helpers
additional_dependencies:
- types-cachetools==5.2.1
- types-filelock==3.2.7
- types-requests==2.28.8
- types-tabulate==0.8.11
- types-python-dateutil==2.8.19
# stages: [push]
- repo: https://github.com/pycqa/isort
rev: "5.10.1"
hooks:
- id: isort
name: isort (python)
# stages: [push]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
hooks:
- id: end-of-file-fixer
exclude: |
(?x)^(
tests/.*|
.*\.svg
)$
- id: mixed-line-ending
- id: debug-statements
- id: check-ast
- id: trailing-whitespace
exclude: |
(?x)^(
.*\.md
)$

View File

@@ -7,4 +7,3 @@ ignore=vendor
[TYPECHECK] [TYPECHECK]
ignored-modules=numpy,talib,talib.abstract ignored-modules=numpy,talib,talib.abstract

View File

@@ -1,4 +1,4 @@
FROM python:3.9.9-slim-bullseye as base FROM python:3.10.6-slim-bullseye as base
# Setup env # Setup env
ENV LANG C.UTF-8 ENV LANG C.UTF-8

View File

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

View File

@@ -9,10 +9,6 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is
![freqtrade](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/freqtrade-screenshot.png) ![freqtrade](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/freqtrade-screenshot.png)
## Sponsored promotion
[![tokenbot-promo](https://raw.githubusercontent.com/freqtrade/freqtrade/develop/docs/assets/TokenBot-Freqtrade-banner.png)](https://tokenbot.com/?utm_source=github&utm_medium=freqtrade&utm_campaign=algodevs)
## Disclaimer ## Disclaimer
This software is for educational purposes only. Do not risk money which This software is for educational purposes only. Do not risk money which
@@ -30,14 +26,23 @@ hesitate to read the source code and understand the mechanism of this bot.
Please read the [exchange specific notes](docs/exchanges.md) to learn about eventual, special configurations needed for each exchange. Please read the [exchange specific notes](docs/exchanges.md) to learn about eventual, special configurations needed for each exchange.
- [X] [Binance](https://www.binance.com/) ([*Note for binance users](docs/exchanges.md#binance-blacklist)) - [X] [Binance](https://www.binance.com/)
- [X] [Bittrex](https://bittrex.com/) - [X] [Bittrex](https://bittrex.com/)
- [X] [FTX](https://ftx.com) - [X] [FTX](https://ftx.com/#a=2258149)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Huobi](http://huobi.com/)
- [X] [Kraken](https://kraken.com/) - [X] [Kraken](https://kraken.com/)
- [X] [OKX](https://www.okx.com/) - [X] [OKX](https://okx.com/) (Former OKEX)
- [ ] [potentially many others](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_ - [ ] [potentially many others](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
### Supported Futures Exchanges (experimental)
- [X] [Binance](https://www.binance.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [OKX](https://okx.com/).
Please make sure to read the [exchange specific notes](docs/exchanges.md), as well as the [trading with leverage](docs/leverage.md) documentation before diving in.
### Community tested ### Community tested
Exchanges confirmed working by the community: Exchanges confirmed working by the community:
@@ -58,6 +63,7 @@ Please find the complete documentation on the [freqtrade website](https://www.fr
- [x] **Dry-run**: Run the bot without paying money. - [x] **Dry-run**: Run the bot without paying money.
- [x] **Backtesting**: Run a simulation of your buy/sell strategy. - [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] **Strategy Optimization by machine learning**: Use machine learning to optimize your buy/sell strategy parameters with real exchange data.
- [X] **Adaptive prediction modeling**: Build a smart strategy with FreqAI that self-trains to the market via adaptive machine learning methods. [Learn more](https://www.freqtrade.io/en/stable/freqai/)
- [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/stable/edge/). - [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/stable/edge/).
- [x] **Whitelist crypto-currencies**: Select which crypto-currency you want to trade or use dynamic whitelists. - [x] **Whitelist crypto-currencies**: Select which crypto-currency you want to trade or use dynamic whitelists.
- [x] **Blacklist crypto-currencies**: Select which crypto-currency you want to avoid. - [x] **Blacklist crypto-currencies**: Select which crypto-currency you want to avoid.
@@ -68,15 +74,9 @@ Please find the complete documentation on the [freqtrade website](https://www.fr
## Quick start ## Quick start
Freqtrade provides a Linux/macOS script to install all dependencies and help you to configure the bot. Please refer to the [Docker Quickstart documentation](https://www.freqtrade.io/en/stable/docker_quickstart/) on how to get started quickly.
```bash For further (native) installation methods, please refer to the [Installation documentation page](https://www.freqtrade.io/en/stable/installation/).
git clone -b develop https://github.com/freqtrade/freqtrade.git
cd freqtrade
./setup.sh --install
```
For any other type of installation please refer to [Installation doc](https://www.freqtrade.io/en/stable/installation/).
## Basic Usage ## Basic Usage
@@ -133,7 +133,8 @@ Telegram is not mandatory. However, this is a great way to control your bot. Mor
- `/stopbuy`: Stop entering new trades. - `/stopbuy`: Stop entering new trades.
- `/status <trade_id>|[table]`: Lists all or specific open trades. - `/status <trade_id>|[table]`: Lists all or specific open trades.
- `/profit [<n>]`: Lists cumulative profit from all finished trades, over the last n days. - `/profit [<n>]`: Lists cumulative profit from all finished trades, over the last n days.
- `/forcesell <trade_id>|all`: Instantly sells the given trade (Ignoring `minimum_roi`). - `/forceexit <trade_id>|all`: Instantly exits the given trade (Ignoring `minimum_roi`).
- `/fx <trade_id>|all`: Alias to `/forceexit`
- `/performance`: Show performance of each finished trade grouped by pair - `/performance`: Show performance of each finished trade grouped by pair
- `/balance`: Show account balance per currency. - `/balance`: Show account balance per currency.
- `/daily <n>`: Shows profit or loss per day, over the last n days. - `/daily <n>`: Shows profit or loss per day, over the last n days.
@@ -193,7 +194,7 @@ Issues labeled [good first issue](https://github.com/freqtrade/freqtrade/labels/
The clock must be accurate, synchronized 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 ### Minimum hardware required
To run this bot we recommend you a cloud instance with a minimum of: To run this bot we recommend you a cloud instance with a minimum of:

View File

@@ -4,7 +4,7 @@ else
INSTALL_LOC=${1} INSTALL_LOC=${1}
fi fi
echo "Installing to ${INSTALL_LOC}" echo "Installing to ${INSTALL_LOC}"
if [ ! -f "${INSTALL_LOC}/lib/libta_lib.a" ]; then if [ -n "$2" ] || [ ! -f "${INSTALL_LOC}/lib/libta_lib.a" ]; then
tar zxvf ta-lib-0.4.0-src.tar.gz tar zxvf ta-lib-0.4.0-src.tar.gz
cd ta-lib \ cd ta-lib \
&& sed -i.bak "s|0.00000001|0.000000000000000001 |g" src/ta_func/ta_utility.h \ && sed -i.bak "s|0.00000001|0.000000000000000001 |g" src/ta_func/ta_utility.h \
@@ -17,11 +17,17 @@ if [ ! -f "${INSTALL_LOC}/lib/libta_lib.a" ]; then
cd .. && rm -rf ./ta-lib/ cd .. && rm -rf ./ta-lib/
exit 1 exit 1
fi fi
which sudo && sudo make install || make install if [ -z "$2" ]; then
if [ -x "$(command -v apt-get)" ]; then which sudo && sudo make install || make install
echo "Updating library path using ldconfig" if [ -x "$(command -v apt-get)" ]; then
sudo ldconfig echo "Updating library path using ldconfig"
sudo ldconfig
fi
else
# Don't install with sudo
make install
fi fi
cd .. && rm -rf ./ta-lib/ cd .. && rm -rf ./ta-lib/
else else
echo "TA-lib already installed, skipping installation" echo "TA-lib already installed, skipping installation"

View File

@@ -0,0 +1,42 @@
# File used in CI to ensure pre-commit dependencies are kept uptodate.
import sys
from pathlib import Path
import yaml
pre_commit_file = Path('.pre-commit-config.yaml')
require_dev = Path('requirements-dev.txt')
with require_dev.open('r') as rfile:
requirements = rfile.readlines()
# Extract types only
type_reqs = [r.strip('\n') for r in requirements if r.startswith('types-')]
with pre_commit_file.open('r') as file:
f = yaml.load(file, Loader=yaml.FullLoader)
mypy_repo = [repo for repo in f['repos'] if repo['repo']
== 'https://github.com/pre-commit/mirrors-mypy']
hooks = mypy_repo[0]['hooks'][0]['additional_dependencies']
errors = []
for hook in hooks:
if hook not in type_reqs:
errors.append(f"{hook} is missing in requirements-dev.txt.")
for req in type_reqs:
if req not in hooks:
errors.append(f"{req} is missing in pre-config file.")
if errors:
for e in errors:
print(e)
sys.exit(1)
sys.exit(0)

View File

@@ -6,10 +6,12 @@ export DOCKER_BUILDKIT=1
# Replace / with _ to create a valid tag # Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g") TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot TAG_PLOT=${TAG}_plot
TAG_FREQAI=${TAG}_freqai
TAG_PI="${TAG}_pi" TAG_PI="${TAG}_pi"
TAG_ARM=${TAG}_arm TAG_ARM=${TAG}_arm
TAG_PLOT_ARM=${TAG_PLOT}_arm TAG_PLOT_ARM=${TAG_PLOT}_arm
TAG_FREQAI_ARM=${TAG_FREQAI}_arm
CACHE_IMAGE=freqtradeorg/freqtrade_cache CACHE_IMAGE=freqtradeorg/freqtrade_cache
echo "Running for ${TAG}" echo "Running for ${TAG}"
@@ -38,11 +40,13 @@ fi
docker tag freqtrade:$TAG_ARM ${CACHE_IMAGE}:$TAG_ARM docker tag freqtrade:$TAG_ARM ${CACHE_IMAGE}:$TAG_ARM
docker build --cache-from freqtrade:${TAG_ARM} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_PLOT_ARM} -f docker/Dockerfile.plot . docker build --cache-from freqtrade:${TAG_ARM} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_PLOT_ARM} -f docker/Dockerfile.plot .
docker build --cache-from freqtrade:${TAG_ARM} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG_ARM} -t freqtrade:${TAG_FREQAI_ARM} -f docker/Dockerfile.freqai .
docker tag freqtrade:$TAG_PLOT_ARM ${CACHE_IMAGE}:$TAG_PLOT_ARM docker tag freqtrade:$TAG_PLOT_ARM ${CACHE_IMAGE}:$TAG_PLOT_ARM
docker tag freqtrade:$TAG_FREQAI_ARM ${CACHE_IMAGE}:$TAG_FREQAI_ARM
# Run backtest # Run backtest
docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG_ARM} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV2 docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG_ARM} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "failed running backtest" echo "failed running backtest"
@@ -53,6 +57,7 @@ docker images
# docker push ${IMAGE_NAME} # docker push ${IMAGE_NAME}
docker push ${CACHE_IMAGE}:$TAG_PLOT_ARM docker push ${CACHE_IMAGE}:$TAG_PLOT_ARM
docker push ${CACHE_IMAGE}:$TAG_FREQAI_ARM
docker push ${CACHE_IMAGE}:$TAG_ARM docker push ${CACHE_IMAGE}:$TAG_ARM
# Create multi-arch image # Create multi-arch image
@@ -66,6 +71,9 @@ docker manifest push -p ${IMAGE_NAME}:${TAG}
docker manifest create ${IMAGE_NAME}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM} ${CACHE_IMAGE}:${TAG_PLOT} docker manifest create ${IMAGE_NAME}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM} ${CACHE_IMAGE}:${TAG_PLOT}
docker manifest push -p ${IMAGE_NAME}:${TAG_PLOT} docker manifest push -p ${IMAGE_NAME}:${TAG_PLOT}
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI_ARM} ${CACHE_IMAGE}:${TAG_FREQAI}
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI}
# Tag as latest for develop builds # Tag as latest for develop builds
if [ "${TAG}" = "develop" ]; then if [ "${TAG}" = "develop" ]; then
docker manifest create ${IMAGE_NAME}:latest ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG} docker manifest create ${IMAGE_NAME}:latest ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG}

View File

@@ -5,6 +5,7 @@
# Replace / with _ to create a valid tag # Replace / with _ to create a valid tag
TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g") TAG=$(echo "${BRANCH_NAME}" | sed -e "s/\//_/g")
TAG_PLOT=${TAG}_plot TAG_PLOT=${TAG}_plot
TAG_FREQAI=${TAG}_freqai
TAG_PI="${TAG}_pi" TAG_PI="${TAG}_pi"
PI_PLATFORM="linux/arm/v7" PI_PLATFORM="linux/arm/v7"
@@ -49,11 +50,13 @@ fi
docker tag freqtrade:$TAG ${CACHE_IMAGE}:$TAG docker tag freqtrade:$TAG ${CACHE_IMAGE}:$TAG
docker build --cache-from freqtrade:${TAG} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG} -t freqtrade:${TAG_PLOT} -f docker/Dockerfile.plot . docker build --cache-from freqtrade:${TAG} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG} -t freqtrade:${TAG_PLOT} -f docker/Dockerfile.plot .
docker build --cache-from freqtrade:${TAG} --build-arg sourceimage=${CACHE_IMAGE} --build-arg sourcetag=${TAG} -t freqtrade:${TAG_FREQAI} -f docker/Dockerfile.freqai .
docker tag freqtrade:$TAG_PLOT ${CACHE_IMAGE}:$TAG_PLOT docker tag freqtrade:$TAG_PLOT ${CACHE_IMAGE}:$TAG_PLOT
docker tag freqtrade:$TAG_FREQAI ${CACHE_IMAGE}:$TAG_FREQAI
# Run backtest # Run backtest
docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV2 docker run --rm -v $(pwd)/config_examples/config_bittrex.example.json:/freqtrade/config.json:ro -v $(pwd)/tests:/tests freqtrade:${TAG} backtesting --datadir /tests/testdata --strategy-path /tests/strategy/strats/ --strategy StrategyTestV3
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "failed running backtest" echo "failed running backtest"
@@ -64,6 +67,7 @@ docker images
docker push ${CACHE_IMAGE} docker push ${CACHE_IMAGE}
docker push ${CACHE_IMAGE}:$TAG_PLOT docker push ${CACHE_IMAGE}:$TAG_PLOT
docker push ${CACHE_IMAGE}:$TAG_FREQAI
docker push ${CACHE_IMAGE}:$TAG docker push ${CACHE_IMAGE}:$TAG

View File

@@ -8,21 +8,23 @@
"dry_run": true, "dry_run": true,
"cancel_open_orders_on_exit": false, "cancel_open_orders_on_exit": false,
"unfilledtimeout": { "unfilledtimeout": {
"buy": 10, "entry": 10,
"sell": 10, "exit": 10,
"exit_timeout_count": 0, "exit_timeout_count": 0,
"unit": "minutes" "unit": "minutes"
}, },
"bid_strategy": { "entry_pricing": {
"ask_last_balance": 0.0, "price_side": "same",
"use_order_book": true, "use_order_book": true,
"order_book_top": 1, "order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": { "check_depth_of_market": {
"enabled": false, "enabled": false,
"bids_to_ask_delta": 1 "bids_to_ask_delta": 1
} }
}, },
"ask_strategy": { "exit_pricing": {
"price_side": "same",
"use_order_book": true, "use_order_book": true,
"order_book_top": 1 "order_book_top": 1
}, },
@@ -88,7 +90,7 @@
}, },
"bot_name": "freqtrade", "bot_name": "freqtrade",
"initial_state": "running", "initial_state": "running",
"forcebuy_enable": false, "force_entry_enable": false,
"internals": { "internals": {
"process_throttle_secs": 5 "process_throttle_secs": 5
} }

View File

@@ -8,21 +8,23 @@
"dry_run": true, "dry_run": true,
"cancel_open_orders_on_exit": false, "cancel_open_orders_on_exit": false,
"unfilledtimeout": { "unfilledtimeout": {
"buy": 10, "entry": 10,
"sell": 10, "exit": 10,
"exit_timeout_count": 0, "exit_timeout_count": 0,
"unit": "minutes" "unit": "minutes"
}, },
"bid_strategy": { "entry_pricing": {
"price_side": "same",
"use_order_book": true, "use_order_book": true,
"ask_last_balance": 0.0,
"order_book_top": 1, "order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": { "check_depth_of_market": {
"enabled": false, "enabled": false,
"bids_to_ask_delta": 1 "bids_to_ask_delta": 1
} }
}, },
"ask_strategy":{ "exit_pricing":{
"price_side": "same",
"use_order_book": true, "use_order_book": true,
"order_book_top": 1 "order_book_top": 1
}, },
@@ -85,7 +87,7 @@
}, },
"bot_name": "freqtrade", "bot_name": "freqtrade",
"initial_state": "running", "initial_state": "running",
"forcebuy_enable": false, "force_entry_enable": false,
"internals": { "internals": {
"process_throttle_secs": 5 "process_throttle_secs": 5
} }

View File

@@ -0,0 +1,96 @@
{
"trading_mode": "futures",
"margin_mode": "isolated",
"max_open_trades": 5,
"stake_currency": "USDT",
"stake_amount": 200,
"tradable_balance_ratio": 1,
"fiat_display_currency": "USD",
"dry_run": true,
"timeframe": "3m",
"dry_run_wallet": 1000,
"cancel_open_orders_on_exit": true,
"unfilledtimeout": {
"entry": 10,
"exit": 30
},
"exchange": {
"name": "binance",
"key": "",
"secret": "",
"ccxt_config": {
"enableRateLimit": true
},
"ccxt_async_config": {
"enableRateLimit": true,
"rateLimit": 200
},
"pair_whitelist": [
"1INCH/USDT",
"ALGO/USDT"
],
"pair_blacklist": []
},
"entry_pricing": {
"price_side": "same",
"use_order_book": true,
"order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"exit_pricing": {
"price_side": "other",
"use_order_book": true,
"order_book_top": 1
},
"pairlists": [
{
"method": "StaticPairList"
}
],
"freqai": {
"enabled": true,
"startup_candles": 10000,
"purge_old_models": true,
"train_period_days": 15,
"backtest_period_days": 7,
"live_retrain_hours": 0,
"identifier": "uniqe-id",
"feature_parameters": {
"include_timeframes": [
"3m",
"15m",
"1h"
],
"include_corr_pairlist": [
"BTC/USDT",
"ETH/USDT"
],
"label_period_candles": 20,
"include_shifted_candles": 2,
"DI_threshold": 0.9,
"weight_factor": 0.9,
"principal_component_analysis": false,
"use_SVM_to_remove_outliers": true,
"stratify_training_data": 0,
"indicator_max_period_candles": 20,
"indicator_periods_candles": [10, 20]
},
"data_split_parameters": {
"test_size": 0.33,
"random_state": 1
},
"model_training_parameters": {
"n_estimators": 1000
}
},
"bot_name": "",
"force_entry_enable": true,
"initial_state": "running",
"internals": {
"process_throttle_secs": 5
}
}

View File

@@ -8,21 +8,23 @@
"dry_run": true, "dry_run": true,
"cancel_open_orders_on_exit": false, "cancel_open_orders_on_exit": false,
"unfilledtimeout": { "unfilledtimeout": {
"buy": 10, "entry": 10,
"sell": 10, "exit": 10,
"exit_timeout_count": 0, "exit_timeout_count": 0,
"unit": "minutes" "unit": "minutes"
}, },
"bid_strategy": { "entry_pricing": {
"ask_last_balance": 0.0, "price_side": "same",
"use_order_book": true, "use_order_book": true,
"order_book_top": 1, "order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": { "check_depth_of_market": {
"enabled": false, "enabled": false,
"bids_to_ask_delta": 1 "bids_to_ask_delta": 1
} }
}, },
"ask_strategy": { "exit_pricing": {
"price_side": "same",
"use_order_book": true, "use_order_book": true,
"order_book_top": 1 "order_book_top": 1
}, },
@@ -87,7 +89,7 @@
}, },
"bot_name": "freqtrade", "bot_name": "freqtrade",
"initial_state": "running", "initial_state": "running",
"forcebuy_enable": false, "force_entry_enable": false,
"internals": { "internals": {
"process_throttle_secs": 5 "process_throttle_secs": 5
} }

View File

@@ -5,6 +5,7 @@
"tradable_balance_ratio": 0.99, "tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD", "fiat_display_currency": "USD",
"amount_reserve_percent": 0.05, "amount_reserve_percent": 0.05,
"available_capital": 1000,
"amend_last_stake_amount": false, "amend_last_stake_amount": false,
"last_stake_amount_min_ratio": 0.5, "last_stake_amount_min_ratio": 0.5,
"dry_run": true, "dry_run": true,
@@ -15,11 +16,13 @@
"trailing_stop_positive": 0.005, "trailing_stop_positive": 0.005,
"trailing_stop_positive_offset": 0.0051, "trailing_stop_positive_offset": 0.0051,
"trailing_only_offset_is_reached": false, "trailing_only_offset_is_reached": false,
"use_sell_signal": true, "use_exit_signal": true,
"sell_profit_only": false, "exit_profit_only": false,
"sell_profit_offset": 0.0, "exit_profit_offset": 0.0,
"ignore_roi_if_buy_signal": false, "ignore_roi_if_entry_signal": false,
"ignore_buying_expired_candle_after": 300, "ignore_buying_expired_candle_after": 300,
"trading_mode": "spot",
"margin_mode": "",
"minimal_roi": { "minimal_roi": {
"40": 0.0, "40": 0.0,
"30": 0.01, "30": 0.01,
@@ -28,39 +31,41 @@
}, },
"stoploss": -0.10, "stoploss": -0.10,
"unfilledtimeout": { "unfilledtimeout": {
"buy": 10, "entry": 10,
"sell": 10, "exit": 10,
"exit_timeout_count": 0, "exit_timeout_count": 0,
"unit": "minutes" "unit": "minutes"
}, },
"bid_strategy": { "entry_pricing": {
"price_side": "bid", "price_side": "same",
"use_order_book": true, "use_order_book": true,
"ask_last_balance": 0.0,
"order_book_top": 1, "order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": { "check_depth_of_market": {
"enabled": false, "enabled": false,
"bids_to_ask_delta": 1 "bids_to_ask_delta": 1
} }
}, },
"ask_strategy":{ "exit_pricing":{
"price_side": "ask", "price_side": "same",
"use_order_book": true, "use_order_book": true,
"order_book_top": 1 "order_book_top": 1,
"price_last_balance": 0.0
}, },
"order_types": { "order_types": {
"buy": "limit", "entry": "limit",
"sell": "limit", "exit": "limit",
"emergencysell": "market", "emergency_exit": "market",
"forcesell": "market", "force_exit": "market",
"forcebuy": "market", "force_entry": "market",
"stoploss": "market", "stoploss": "market",
"stoploss_on_exchange": false, "stoploss_on_exchange": false,
"stoploss_on_exchange_interval": 60 "stoploss_on_exchange_interval": 60,
"stoploss_on_exchange_limit_ratio": 0.99
}, },
"order_time_in_force": { "order_time_in_force": {
"buy": "gtc", "entry": "gtc",
"sell": "gtc" "exit": "gtc"
}, },
"pairlists": [ "pairlists": [
{"method": "StaticPairList"}, {"method": "StaticPairList"},
@@ -88,6 +93,7 @@
"secret": "your_exchange_secret", "secret": "your_exchange_secret",
"password": "", "password": "",
"log_responses": false, "log_responses": false,
// "unknown_fee_rate": 1,
"ccxt_config": {}, "ccxt_config": {},
"ccxt_async_config": {}, "ccxt_async_config": {},
"pair_whitelist": [ "pair_whitelist": [
@@ -135,23 +141,24 @@
"status": "on", "status": "on",
"warning": "on", "warning": "on",
"startup": "on", "startup": "on",
"buy": "on", "entry": "on",
"buy_fill": "on", "entry_fill": "on",
"sell": { "exit": {
"roi": "off", "roi": "off",
"emergency_sell": "off", "emergency_exit": "off",
"force_sell": "off", "force_exit": "off",
"sell_signal": "off", "exit_signal": "off",
"trailing_stop_loss": "off", "trailing_stop_loss": "off",
"stop_loss": "off", "stop_loss": "off",
"stoploss_on_exchange": "off", "stoploss_on_exchange": "off",
"custom_sell": "off" "custom_exit": "off"
}, },
"sell_fill": "on", "exit_fill": "on",
"buy_cancel": "on", "entry_cancel": "on",
"sell_cancel": "on", "exit_cancel": "on",
"protection_trigger": "off", "protection_trigger": "off",
"protection_trigger_global": "on" "protection_trigger_global": "on",
"show_candle": "off"
}, },
"reload": true, "reload": true,
"balance_dust_level": 0.01 "balance_dust_level": 0.01
@@ -170,7 +177,7 @@
"bot_name": "freqtrade", "bot_name": "freqtrade",
"db_url": "sqlite:///tradesv3.sqlite", "db_url": "sqlite:///tradesv3.sqlite",
"initial_state": "running", "initial_state": "running",
"forcebuy_enable": false, "force_entry_enable": false,
"internals": { "internals": {
"process_throttle_secs": 5, "process_throttle_secs": 5,
"heartbeat_interval": 60 "heartbeat_interval": 60
@@ -178,6 +185,8 @@
"disable_dataframe_checks": false, "disable_dataframe_checks": false,
"strategy": "SampleStrategy", "strategy": "SampleStrategy",
"strategy_path": "user_data/strategies/", "strategy_path": "user_data/strategies/",
"recursive_strategy_search": false,
"add_config_files": [],
"dataformat_ohlcv": "json", "dataformat_ohlcv": "json",
"dataformat_trades": "jsongz" "dataformat_trades": "jsongz"
} }

View File

@@ -8,21 +8,23 @@
"dry_run": true, "dry_run": true,
"cancel_open_orders_on_exit": false, "cancel_open_orders_on_exit": false,
"unfilledtimeout": { "unfilledtimeout": {
"buy": 10, "entry": 10,
"sell": 10, "exit": 10,
"exit_timeout_count": 0, "exit_timeout_count": 0,
"unit": "minutes" "unit": "minutes"
}, },
"bid_strategy": { "entry_pricing": {
"price_side": "same",
"use_order_book": true, "use_order_book": true,
"ask_last_balance": 0.0,
"order_book_top": 1, "order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": { "check_depth_of_market": {
"enabled": false, "enabled": false,
"bids_to_ask_delta": 1 "bids_to_ask_delta": 1
} }
}, },
"ask_strategy":{ "exit_pricing":{
"price_side": "same",
"use_order_book": true, "use_order_book": true,
"order_book_top": 1 "order_book_top": 1
}, },
@@ -93,7 +95,7 @@
}, },
"bot_name": "freqtrade", "bot_name": "freqtrade",
"initial_state": "running", "initial_state": "running",
"forcebuy_enable": false, "force_entry_enable": false,
"internals": { "internals": {
"process_throttle_secs": 5 "process_throttle_secs": 5
}, },

View File

@@ -1,4 +1,4 @@
FROM python:3.9.9-slim-bullseye as base FROM python:3.9.12-slim-bullseye as base
# Setup env # Setup env
ENV LANG C.UTF-8 ENV LANG C.UTF-8

View File

@@ -7,4 +7,5 @@ FROM freqtradeorg/freqtrade:develop
# The below dependency - pyti - serves as an example. Please use whatever you need! # The below dependency - pyti - serves as an example. Please use whatever you need!
RUN pip install --user pyti RUN pip install --user pyti
# Switch back to user (only if you required root above)
# USER ftuser # USER ftuser

9
docker/Dockerfile.freqai Normal file
View File

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

View File

@@ -0,0 +1,102 @@
# Advanced Backtesting Analysis
## Analyze the buy/entry and sell/exit tags
It can be helpful to understand how a strategy behaves according to the buy/entry tags used to
mark up different buy conditions. You might want to see more complex statistics about each buy and
sell condition above those provided by the default backtesting output. You may also want to
determine indicator values on the signal candle that resulted in a trade opening.
!!! Note
The following buy reason analysis is only available for backtesting, *not hyperopt*.
We need to run backtesting with the `--export` option set to `signals` to enable the exporting of
signals **and** trades:
``` bash
freqtrade backtesting -c <config.json> --timeframe <tf> --strategy <strategy_name> --timerange=<timerange> --export=signals
```
This will tell freqtrade to output a pickled dictionary of strategy, pairs and corresponding
DataFrame of the candles that resulted in buy signals. Depending on how many buys your strategy
makes, this file may get quite large, so periodically check your `user_data/backtest_results`
folder to delete old exports.
Before running your next backtest, make sure you either delete your old backtest results or run
backtesting with the `--cache none` option to make sure no cached results are used.
If all goes well, you should now see a `backtest-result-{timestamp}_signals.pkl` file in the
`user_data/backtest_results` folder.
To analyze the entry/exit tags, we now need to use the `freqtrade backtesting-analysis` command
with `--analysis-groups` option provided with space-separated arguments (default `0 1 2`):
``` bash
freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 1 2 3 4
```
This command will read from the last backtesting results. The `--analysis-groups` option is
used to specify the various tabular outputs showing the profit fo each group or trade,
ranging from the simplest (0) to the most detailed per pair, per buy and per sell tag (4):
* 1: profit summaries grouped by enter_tag
* 2: profit summaries grouped by enter_tag and exit_tag
* 3: profit summaries grouped by pair and enter_tag
* 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large)
More options are available by running with the `-h` option.
### Using export-filename
Normally, `backtesting-analysis` uses the latest backtest results, but if you wanted to go
back to a previous backtest output, you need to supply the `--export-filename` option.
You can supply the same parameter to `backtest-analysis` with the name of the final backtest
output file. This allows you to keep historical versions of backtest results and re-analyse
them at a later date:
``` bash
freqtrade backtesting -c <config.json> --timeframe <tf> --strategy <strategy_name> --timerange=<timerange> --export=signals --export-filename=/tmp/mystrat_backtest.json
```
You should see some output similar to below in the logs with the name of the timestamped
filename that was exported:
```
2022-06-14 16:28:32,698 - freqtrade.misc - INFO - dumping json to "/tmp/mystrat_backtest-2022-06-14_16-28-32.json"
```
You can then use that filename in `backtesting-analysis`:
```
freqtrade backtesting-analysis -c <config.json> --export-filename=/tmp/mystrat_backtest-2022-06-14_16-28-32.json
```
### Tuning the buy tags and sell tags to display
To show only certain buy and sell tags in the displayed output, use the following two options:
```
--enter-reason-list : Space-separated list of enter signals to analyse. Default: "all"
--exit-reason-list : Space-separated list of exit signals to analyse. Default: "all"
```
For example:
```bash
freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 2 --enter-reason-list enter_tag_a enter_tag_b --exit-reason-list roi custom_exit_tag_a stop_loss
```
### Outputting signal candle indicators
The real power of `freqtrade backtesting-analysis` comes from the ability to print out the indicator
values present on signal candles to allow fine-grained investigation and tuning of buy signal
indicators. To print out a column for a given set of indicators, use the `--indicator-list`
option:
```bash
freqtrade backtesting-analysis -c <config.json> --analysis-groups 0 2 --enter-reason-list enter_tag_a enter_tag_b --exit-reason-list roi custom_exit_tag_a stop_loss --indicator-list rsi rsi_1h bb_lowerband ema_9 macd macdsignal
```
The indicators have to be present in your strategy's main DataFrame (either for your main
timeframe or for informative timeframes) otherwise they will simply be ignored in the script
output.

View File

@@ -56,7 +56,7 @@ Currently, the arguments are:
* `results`: DataFrame containing the resulting trades. * `results`: DataFrame containing the resulting trades.
The following columns are available in results (corresponds to the output-file of backtesting when used with `--export trades`): The following columns are available in results (corresponds to the output-file of backtesting when used with `--export trades`):
`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` `pair, profit_ratio, profit_abs, open_date, open_rate, fee_open, close_date, close_rate, fee_close, amount, trade_duration, is_open, exit_reason, stake_amount, min_rate, max_rate, stop_loss_ratio, stop_loss_abs`
* `trade_count`: Amount of trades (identical to `len(results)`) * `trade_count`: Amount of trades (identical to `len(results)`)
* `min_date`: Start date of the timerange used * `min_date`: Start date of the timerange used
* `min_date`: End date of the timerange used * `min_date`: End date of the timerange used
@@ -98,6 +98,23 @@ class MyAwesomeStrategy(IStrategy):
!!! Note !!! Note
All overrides are optional and can be mixed/matched as necessary. All overrides are optional and can be mixed/matched as necessary.
### Dynamic parameters
Parameters can also be defined dynamically, but must be available to the instance once the * [`bot_start()` callback](strategy-callbacks.md#bot-start) has been called.
``` python
class MyAwesomeStrategy(IStrategy):
def bot_start(self, **kwargs) -> None:
self.buy_adx = IntParameter(20, 30, default=30, optimize=True)
# ...
```
!!! Warning
Parameters created this way will not show up in the `list-strategies` parameter count.
### Overriding Base estimator ### Overriding Base estimator
You can define your own estimator for Hyperopt by implementing `generate_estimator()` in the Hyperopt subclass. You can define your own estimator for Hyperopt by implementing `generate_estimator()` in the Hyperopt subclass.

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
docs/assets/freqai_algo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

View File

@@ -20,13 +20,14 @@ usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[--dry-run-wallet DRY_RUN_WALLET] [--dry-run-wallet DRY_RUN_WALLET]
[--timeframe-detail TIMEFRAME_DETAIL] [--timeframe-detail TIMEFRAME_DETAIL]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]] [--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
[--export {none,trades}] [--export-filename PATH] [--export {none,trades,signals}]
[--export-filename PATH]
[--breakdown {day,week,month} [{day,week,month} ...]] [--breakdown {day,week,month} [{day,week,month} ...]]
[--cache {none,day,week,month}] [--cache {none,day,week,month}]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME -i TIMEFRAME, --timeframe TIMEFRAME
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`). Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
--timerange TIMERANGE --timerange TIMERANGE
Specify what timerange of data to use. Specify what timerange of data to use.
@@ -63,18 +64,17 @@ optional arguments:
`30m`, `1h`, `1d`). `30m`, `1h`, `1d`).
--strategy-list STRATEGY_LIST [STRATEGY_LIST ...] --strategy-list STRATEGY_LIST [STRATEGY_LIST ...]
Provide a space-separated list of strategies to Provide a space-separated list of strategies to
backtest. Please note that ticker-interval needs to be backtest. Please note that timeframe needs to be set
set either in config or via command line. When using either in config or via command line. When using this
this together with `--export trades`, the strategy- together with `--export trades`, the strategy-name is
name is injected into the filename (so `backtest- injected into the filename (so `backtest-data.json`
data.json` becomes `backtest-data-SampleStrategy.json` becomes `backtest-data-SampleStrategy.json`
--export {none,trades} --export {none,trades,signals}
Export backtest results (default: trades). Export backtest results (default: trades).
--export-filename PATH --export-filename PATH, --backtest-filename PATH
Save backtest results to the file with this filename. Use this filename for backtest results.Requires
Requires `--export` to be set as well. Example: `--export` to be set as well. Example: `--export-filen
`--export-filename=user_data/backtest_results/backtest ame=user_data/backtest_results/backtest_today.json`
_today.json`
--breakdown {day,week,month} [{day,week,month} ...] --breakdown {day,week,month} [{day,week,month} ...]
Show backtesting breakdown per [day, week, month]. Show backtesting breakdown per [day, week, month].
--cache {none,day,week,month} --cache {none,day,week,month}
@@ -274,57 +274,68 @@ A backtesting result will look like that:
| XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 0 23 34.3 | | XRP/BTC | 35 | 0.66 | 22.96 | 0.00114897 | 11.48 | 3:49:00 | 12 0 23 34.3 |
| ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 0 15 31.8 | | ZEC/BTC | 22 | -0.46 | -10.18 | -0.00050971 | -5.09 | 2:22:00 | 7 0 15 31.8 |
| TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 0 243 43.4 | | TOTAL | 429 | 0.36 | 152.41 | 0.00762792 | 76.20 | 4:12:00 | 186 0 243 43.4 |
========================================================= SELL REASON STATS ========================================================== ========================================================= EXIT REASON STATS ==========================================================
| Sell Reason | Sells | Wins | Draws | Losses | | Exit Reason | Sells | Wins | Draws | Losses |
|:-------------------|--------:|------:|-------:|--------:| |:-------------------|--------:|------:|-------:|--------:|
| trailing_stop_loss | 205 | 150 | 0 | 55 | | trailing_stop_loss | 205 | 150 | 0 | 55 |
| stop_loss | 166 | 0 | 0 | 166 | | stop_loss | 166 | 0 | 0 | 166 |
| sell_signal | 56 | 36 | 0 | 20 | | exit_signal | 56 | 36 | 0 | 20 |
| force_sell | 2 | 0 | 0 | 2 | | force_exit | 2 | 0 | 0 | 2 |
====================================================== LEFT OPEN TRADES REPORT ====================================================== ====================================================== LEFT OPEN TRADES REPORT ======================================================
| Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Win Draw Loss Win% | | Pair | Buys | Avg Profit % | Cum Profit % | Tot Profit BTC | Tot Profit % | Avg Duration | Win Draw Loss Win% |
|:---------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|--------------------:| |:---------|-------:|---------------:|---------------:|-----------------:|---------------:|:---------------|--------------------:|
| ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 0 0 100 | | ADA/BTC | 1 | 0.89 | 0.89 | 0.00004434 | 0.44 | 6:00:00 | 1 0 0 100 |
| LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 0 0 100 | | LTC/BTC | 1 | 0.68 | 0.68 | 0.00003421 | 0.34 | 2:00:00 | 1 0 0 100 |
| TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 0 0 100 | | TOTAL | 2 | 0.78 | 1.57 | 0.00007855 | 0.78 | 4:00:00 | 2 0 0 100 |
=============== SUMMARY METRICS =============== ================== SUMMARY METRICS ==================
| Metric | Value | | Metric | Value |
|-----------------------+---------------------| |-----------------------------+---------------------|
| Backtesting from | 2019-01-01 00:00:00 | | Backtesting from | 2019-01-01 00:00:00 |
| Backtesting to | 2019-05-01 00:00:00 | | Backtesting to | 2019-05-01 00:00:00 |
| Max open trades | 3 | | Max open trades | 3 |
| | | | | |
| Total/Daily Avg Trades| 429 / 3.575 | | Total/Daily Avg Trades | 429 / 3.575 |
| Starting balance | 0.01000000 BTC | | Starting balance | 0.01000000 BTC |
| Final balance | 0.01762792 BTC | | Final balance | 0.01762792 BTC |
| Absolute profit | 0.00762792 BTC | | Absolute profit | 0.00762792 BTC |
| Total profit % | 76.2% | | Total profit % | 76.2% |
| Trades per day | 3.575 | | CAGR % | 460.87% |
| Avg. stake amount | 0.001 BTC | | Profit factor | 1.11 |
| Total trade volume | 0.429 BTC | | Avg. stake amount | 0.001 BTC |
| | | | Total trade volume | 0.429 BTC |
| Best Pair | LSK/BTC 26.26% | | | |
| Worst Pair | ZEC/BTC -10.18% | | Long / Short | 352 / 77 |
| Best Trade | LSK/BTC 4.25% | | Total profit Long % | 1250.58% |
| Worst Trade | ZEC/BTC -10.25% | | Total profit Short % | -15.02% |
| Best day | 0.00076 BTC | | Absolute profit Long | 0.00838792 BTC |
| Worst day | -0.00036 BTC | | Absolute profit Short | -0.00076 BTC |
| Days win/draw/lose | 12 / 82 / 25 | | | |
| Avg. Duration Winners | 4:23:00 | | Best Pair | LSK/BTC 26.26% |
| Avg. Duration Loser | 6:55:00 | | Worst Pair | ZEC/BTC -10.18% |
| Rejected Buy signals | 3089 | | Best Trade | LSK/BTC 4.25% |
| Entry/Exit Timeouts | 0 / 0 | | Worst Trade | ZEC/BTC -10.25% |
| | | | Best day | 0.00076 BTC |
| Min balance | 0.00945123 BTC | | Worst day | -0.00036 BTC |
| Max balance | 0.01846651 BTC | | Days win/draw/lose | 12 / 82 / 25 |
| Drawdown (Account) | 13.33% | | Avg. Duration Winners | 4:23:00 |
| Drawdown | 0.0015 BTC | | Avg. Duration Loser | 6:55:00 |
| Drawdown high | 0.0013 BTC | | Rejected Entry signals | 3089 |
| Drawdown low | -0.0002 BTC | | Entry/Exit Timeouts | 0 / 0 |
| Drawdown Start | 2019-02-15 14:10:00 | | Canceled Trade Entries | 34 |
| Drawdown End | 2019-04-11 18:15:00 | | Canceled Entry Orders | 123 |
| Market change | -5.88% | | Replaced Entry Orders | 89 |
=============================================== | | |
| Min balance | 0.00945123 BTC |
| Max balance | 0.01846651 BTC |
| Max % of account underwater | 25.19% |
| Absolute Drawdown (Account) | 13.33% |
| Drawdown | 0.0015 BTC |
| Drawdown high | 0.0013 BTC |
| Drawdown low | -0.0002 BTC |
| Drawdown Start | 2019-02-15 14:10:00 |
| Drawdown End | 2019-04-11 18:15:00 |
| Market change | -5.88% |
=====================================================
``` ```
### Backtesting report table ### Backtesting report table
@@ -345,9 +356,9 @@ The column `Avg Profit %` shows the average profit for all trades made while the
The column `Tot Profit %` shows instead the total profit % in relation to the starting balance. The column `Tot Profit %` shows instead the total profit % in relation to the starting balance.
In the above results, we have a starting balance of 0.01 BTC and an absolute profit of 0.00762792 BTC - so the `Tot Profit %` will be `(0.00762792 / 0.01) * 100 ~= 76.2%`. In the above results, we have a starting balance of 0.01 BTC and an absolute profit of 0.00762792 BTC - so the `Tot Profit %` will be `(0.00762792 / 0.01) * 100 ~= 76.2%`.
Your strategy performance is influenced by your buy strategy, your sell strategy, and also by the `minimal_roi` and `stop_loss` you have set. Your strategy performance is influenced by your buy strategy, your exit strategy, and also by the `minimal_roi` and `stop_loss` you have set.
For example, if your `minimal_roi` is only `"0": 0.01` you cannot expect the bot to make more profit than 1% (because it will sell every time a trade reaches 1%). For example, if your `minimal_roi` is only `"0": 0.01` you cannot expect the bot to make more profit than 1% (because it will exit every time a trade reaches 1%).
```json ```json
"minimal_roi": { "minimal_roi": {
@@ -359,14 +370,14 @@ On the other hand, if you set a too high `minimal_roi` like `"0": 0.55`
(55%), there is almost no chance that the bot will ever reach this profit. (55%), there is almost no chance that the bot will ever reach this profit.
Hence, keep in mind that your performance is an integral mix of all different elements of the strategy, your configuration, and the crypto-currency pairs you have set up. Hence, keep in mind that your performance is an integral mix of all different elements of the strategy, your configuration, and the crypto-currency pairs you have set up.
### Sell reasons table ### Exit reasons table
The 2nd table contains a recap of sell reasons. The 2nd table contains a recap of exit reasons.
This table can tell you which area needs some additional work (e.g. all or many of the `sell_signal` trades are losses, so you should work on improving the sell signal, or consider disabling it). This table can tell you which area needs some additional work (e.g. all or many of the `exit_signal` trades are losses, so you should work on improving the exit signal, or consider disabling it).
### Left open trades table ### Left open trades table
The 3rd table contains all trades the bot had to `forcesell` at the end of the backtesting period to present you the full picture. The 3rd table contains all trades the bot had to `force_exit` at the end of the backtesting period to present you the full picture.
This is necessary to simulate realistic behavior, since the backtest period has to end at some point, while realistically, you could leave the bot running forever. This is necessary to simulate realistic behavior, since the backtest period has to end at some point, while realistically, you could leave the bot running forever.
These trades are also included in the first table, but are also shown separately in this table for clarity. These trades are also included in the first table, but are also shown separately in this table for clarity.
@@ -376,43 +387,55 @@ The last element of the backtest report is the summary metrics table.
It contains some useful key metrics about performance of your strategy on backtesting data. It contains some useful key metrics about performance of your strategy on backtesting data.
``` ```
=============== SUMMARY METRICS =============== ================== SUMMARY METRICS ==================
| Metric | Value | | Metric | Value |
|-----------------------+---------------------| |-----------------------------+---------------------|
| Backtesting from | 2019-01-01 00:00:00 | | Backtesting from | 2019-01-01 00:00:00 |
| Backtesting to | 2019-05-01 00:00:00 | | Backtesting to | 2019-05-01 00:00:00 |
| Max open trades | 3 | | Max open trades | 3 |
| | | | | |
| Total/Daily Avg Trades| 429 / 3.575 | | Total/Daily Avg Trades | 429 / 3.575 |
| Starting balance | 0.01000000 BTC | | Starting balance | 0.01000000 BTC |
| Final balance | 0.01762792 BTC | | Final balance | 0.01762792 BTC |
| Absolute profit | 0.00762792 BTC | | Absolute profit | 0.00762792 BTC |
| Total profit % | 76.2% | | Total profit % | 76.2% |
| Avg. stake amount | 0.001 BTC | | CAGR % | 460.87% |
| Total trade volume | 0.429 BTC | | Profit factor | 1.11 |
| | | | Avg. stake amount | 0.001 BTC |
| Best Pair | LSK/BTC 26.26% | | Total trade volume | 0.429 BTC |
| Worst Pair | ZEC/BTC -10.18% | | | |
| Best Trade | LSK/BTC 4.25% | | Long / Short | 352 / 77 |
| Worst Trade | ZEC/BTC -10.25% | | Total profit Long % | 1250.58% |
| Best day | 0.00076 BTC | | Total profit Short % | -15.02% |
| Worst day | -0.00036 BTC | | Absolute profit Long | 0.00838792 BTC |
| Days win/draw/lose | 12 / 82 / 25 | | Absolute profit Short | -0.00076 BTC |
| Avg. Duration Winners | 4:23:00 | | | |
| Avg. Duration Loser | 6:55:00 | | Best Pair | LSK/BTC 26.26% |
| Rejected Buy signals | 3089 | | Worst Pair | ZEC/BTC -10.18% |
| Entry/Exit Timeouts | 0 / 0 | | Best Trade | LSK/BTC 4.25% |
| | | | Worst Trade | ZEC/BTC -10.25% |
| Min balance | 0.00945123 BTC | | Best day | 0.00076 BTC |
| Max balance | 0.01846651 BTC | | Worst day | -0.00036 BTC |
| Drawdown (Account) | 13.33% | | Days win/draw/lose | 12 / 82 / 25 |
| Drawdown | 0.0015 BTC | | Avg. Duration Winners | 4:23:00 |
| Drawdown high | 0.0013 BTC | | Avg. Duration Loser | 6:55:00 |
| Drawdown low | -0.0002 BTC | | Rejected Entry signals | 3089 |
| Drawdown Start | 2019-02-15 14:10:00 | | Entry/Exit Timeouts | 0 / 0 |
| Drawdown End | 2019-04-11 18:15:00 | | Canceled Trade Entries | 34 |
| Market change | -5.88% | | Canceled Entry Orders | 123 |
=============================================== | Replaced Entry Orders | 89 |
| | |
| Min balance | 0.00945123 BTC |
| Max balance | 0.01846651 BTC |
| Max % of account underwater | 25.19% |
| Absolute Drawdown (Account) | 13.33% |
| Drawdown | 0.0015 BTC |
| Drawdown high | 0.0013 BTC |
| Drawdown low | -0.0002 BTC |
| Drawdown Start | 2019-02-15 14:10:00 |
| Drawdown End | 2019-04-11 18:15:00 |
| Market change | -5.88% |
=====================================================
``` ```
@@ -423,6 +446,8 @@ It contains some useful key metrics about performance of your strategy on backte
- `Final balance`: Final balance - starting balance + absolute profit. - `Final balance`: Final balance - starting balance + absolute profit.
- `Absolute profit`: Profit made in stake currency. - `Absolute profit`: Profit made in stake currency.
- `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital Starting capital) / Starting capital`. - `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital Starting capital) / Starting capital`.
- `CAGR %`: Compound annual growth rate.
- `Profit factor`: profit / loss.
- `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount. - `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount.
- `Total trade volume`: Volume generated on the exchange to reach the above profit. - `Total trade volume`: Volume generated on the exchange to reach the above profit.
- `Best Pair` / `Worst Pair`: Best and worst performing pair, and it's corresponding `Cum Profit %`. - `Best Pair` / `Worst Pair`: Best and worst performing pair, and it's corresponding `Cum Profit %`.
@@ -430,14 +455,22 @@ It contains some useful key metrics about performance of your strategy on backte
- `Best day` / `Worst day`: Best and worst day based on daily profit. - `Best day` / `Worst day`: Best and worst day based on daily profit.
- `Days win/draw/lose`: Winning / Losing days (draws are usually days without closed trade). - `Days win/draw/lose`: Winning / Losing days (draws are usually days without closed trade).
- `Avg. Duration Winners` / `Avg. Duration Loser`: Average durations for winning and losing trades. - `Avg. Duration Winners` / `Avg. Duration Loser`: Average durations for winning and losing trades.
- `Rejected Buy signals`: Buy signals that could not be acted upon due to max_open_trades being reached. - `Rejected Entry signals`: Trade entry signals that could not be acted upon due to `max_open_trades` being reached.
- `Entry/Exit Timeouts`: Entry/exit orders which did not fill (only applicable if custom pricing is used). - `Entry/Exit Timeouts`: Entry/exit orders which did not fill (only applicable if custom pricing is used).
- `Canceled Trade Entries`: Number of trades that have been canceled by user request via `adjust_entry_price`.
- `Canceled Entry Orders`: Number of entry orders that have been canceled by user request via `adjust_entry_price`.
- `Replaced Entry Orders`: Number of entry orders that have been replaced by user request via `adjust_entry_price`.
- `Min balance` / `Max balance`: Lowest and Highest Wallet balance during the backtest period. - `Min balance` / `Max balance`: Lowest and Highest Wallet balance during the backtest period.
- `Drawdown (Account)`: Maximum Account Drawdown experienced. Calculated as $(Absolute Drawdown) / (DrawdownHigh + startingBalance)$. - `Max % of account underwater`: Maximum percentage your account has decreased from the top since the simulation started.
Calculated as the maximum of `(Max Balance - Current Balance) / (Max Balance)`.
- `Absolute Drawdown (Account)`: Maximum Account Drawdown experienced. Calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`.
- `Drawdown`: Maximum, absolute drawdown experienced. Difference between Drawdown High and Subsequent Low point. - `Drawdown`: Maximum, absolute drawdown experienced. Difference between Drawdown High and Subsequent Low point.
- `Drawdown high` / `Drawdown low`: Profit at the beginning and end of the largest drawdown period. A negative low value means initial capital lost. - `Drawdown high` / `Drawdown low`: Profit at the beginning and end of the largest drawdown period. A negative low value means initial capital lost.
- `Drawdown Start` / `Drawdown End`: Start and end datetime 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. - `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.
- `Long / Short`: Split long/short values (Only shown when short trades were made).
- `Total profit Long %` / `Absolute profit Long`: Profit long trades only (Only shown when short trades were made).
- `Total profit Short %` / `Absolute profit Short`: Profit short trades only (Only shown when short trades were made).
### Daily / Weekly / Monthly breakdown ### Daily / Weekly / Monthly breakdown
@@ -446,7 +479,7 @@ You can get an overview over daily / weekly or monthly results by using the `--b
To visualize daily and weekly breakdowns, you can use the following: To visualize daily and weekly breakdowns, you can use the following:
``` bash ``` bash
freqtrade backtesting --strategy MyAwesomeStrategy --breakdown day month freqtrade backtesting --strategy MyAwesomeStrategy --breakdown day week
``` ```
``` output ``` output
@@ -462,7 +495,7 @@ freqtrade backtesting --strategy MyAwesomeStrategy --breakdown day month
``` ```
The output will show a table containing the realized absolute Profit (in stake currency) for the given timeperiod, as well as wins, draws and losses that materialized (closed) on this day. The output will show a table containing the realized absolute Profit (in stake currency) for the given timeperiod, as well as wins, draws and losses that materialized (closed) on this day. Below that there will be a second table for the summarized values of weeks indicated by the date of the closing Sunday. The same would apply to a monthly breakdown indicated by the last day of the month.
### Backtest result caching ### Backtest result caching
@@ -481,35 +514,54 @@ You can then load the trades to perform further analysis as shown in the [data a
Since backtesting lacks some detailed information about what happens within a candle, it needs to take a few assumptions: Since backtesting lacks some detailed information about what happens within a candle, it needs to take a few assumptions:
- Exchange [trading limits](#trading-limits-in-backtesting) are respected
- Buys happen at open-price - Buys happen at open-price
- All orders are filled at the requested price (no slippage, no unfilled orders) - All orders are filled at the requested price (no slippage, no unfilled orders)
- Sell-signal sells happen at open-price of the consecutive candle - Exit-signal exits 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 - Exit-signal is favored over Stoploss, because exit-signals are assumed to trigger on candle's open
- ROI - 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%) - exits are compared to high - but the ROI value is used (e.g. ROI = 2%, high=5% - so the exit 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 - exits are never "below the candle", so a ROI of 2% may result in a exit 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) - Forceexits caused by `<N>=-1` ROI entries use low as exit 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, but the loss will be `2 * fees` higher than the stoploss price - Stoploss exits 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 - Stoploss is evaluated before ROI within one candle. So you can often see more trades with the `stoploss` exit 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 - Low happens before high for stoploss, protecting capital first
- Trailing stoploss - Trailing stoploss
- Trailing Stoploss is only adjusted if it's below the candle's low (otherwise it would be triggered) - Trailing Stoploss is only adjusted if it's below the candle's low (otherwise it would be triggered)
- On trade entry candles that trigger trailing stoploss, the "minimum offset" (`stop_positive_offset`) is assumed (instead of high) - and the stop is calculated from this point - On trade entry candles that trigger trailing stoploss, the "minimum offset" (`stop_positive_offset`) is assumed (instead of high) - and the stop is calculated from this point
- High happens first - adjusting stoploss - High happens first - adjusting stoploss
- Low uses the adjusted stoploss (so sells with large high-low difference are backtested correctly) - Low uses the adjusted stoploss (so exits 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 - 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) - Exit-reason does not explain if a trade was positive or negative, just what triggered the exit (this can look odd if negative ROI values are used)
- Evaluation sequence (if multiple signals happen on the same candle) - Evaluation sequence (if multiple signals happen on the same candle)
- Sell-signal - Exit-signal
- ROI (if not stoploss)
- Stoploss - Stoploss
- ROI
- Trailing 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. 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. Also, keep in mind that past results don't guarantee future success.
In addition to the above assumptions, strategy authors should carefully read the [Common Mistakes](strategy-customization.md#common-mistakes-when-developing-strategies) section, to avoid using data in backtesting which is not available in real market conditions. In addition to the above assumptions, strategy authors should carefully read the [Common Mistakes](strategy-customization.md#common-mistakes-when-developing-strategies) section, to avoid using data in backtesting which is not available in real market conditions.
### Improved backtest accuracy ### Trading limits in backtesting
Exchanges have certain trading limits, like minimum base currency, or minimum stake (quote) currency.
These limits are usually listed in the exchange documentation as "trading rules" or similar.
Backtesting (as well as live and dry-run) does honor these limits, and will ensure that a stoploss can be placed below this value - so the value will be slightly higher than what the exchange specifies.
Freqtrade has however no information about historic limits.
This can lead to situations where trading-limits are inflated by using a historic price, resulting in minimum amounts > 50$.
For example:
BTC minimum tradable amount is 0.001.
BTC trades at 22.000\$ today (0.001 BTC is related to this) - but the backtesting period includes prices as high as 50.000\$.
Today's minimum would be `0.001 * 22_000` - or 22\$.
However the limit could also be 50$ - based on `0.001 * 50_000` in some historic setting.
## Improved backtest accuracy
One big limitation of backtesting is it's inability to know how prices moved intra-candle (was high before close, or viceversa?). One big limitation of backtesting is it's inability to know how prices moved intra-candle (was high before close, or viceversa?).
So assuming you run backtesting with a 1h timeframe, there will be 4 prices for that candle (Open, High, Low, Close). So assuming you run backtesting with a 1h timeframe, there will be 4 prices for that candle (Open, High, Low, Close).
@@ -524,7 +576,7 @@ freqtrade backtesting --strategy AwesomeStrategy --timeframe 1h --timeframe-deta
``` ```
This will load 1h data as well as 5m data for the timeframe. The strategy will be analyzed with the 1h timeframe - and for every "open trade candle" (candles where a trade is open) the 5m data will be used to simulate intra-candle movements. This will load 1h data as well as 5m data for the timeframe. The strategy will be analyzed with the 1h timeframe - and for every "open trade candle" (candles where a trade is open) the 5m data will be used to simulate intra-candle movements.
All callback functions (`custom_sell()`, `custom_stoploss()`, ... ) will be running for each 5m candle once the trade is opened (so 12 times in the above example of 1h timeframe, and 5m detailed timeframe). All callback functions (`custom_exit()`, `custom_stoploss()`, ... ) will be running for each 5m candle once the trade is opened (so 12 times in the above example of 1h timeframe, and 5m detailed timeframe).
`--timeframe-detail` must be smaller than the original timeframe, otherwise backtesting will fail to start. `--timeframe-detail` must be smaller than the original timeframe, otherwise backtesting will fail to start.

View File

@@ -20,30 +20,34 @@ All profit calculations of Freqtrade include fees. For Backtesting / Hyperopt /
## Bot execution logic ## Bot execution logic
Starting freqtrade in dry-run or live mode (using `freqtrade trade`) will start the bot and start the bot iteration loop. Starting freqtrade in dry-run or live mode (using `freqtrade trade`) will start the bot and start the bot iteration loop.
By default, loop runs every few seconds (`internals.process_throttle_secs`) and does roughly the following in the following sequence: This will also run the `bot_start()` callback.
By default, the bot loop runs every few seconds (`internals.process_throttle_secs`) and performs the following actions:
* Fetch open trades from persistence. * Fetch open trades from persistence.
* Calculate current list of tradable pairs. * Calculate current list of tradable pairs.
* Download ohlcv data for the pairlist including all [informative pairs](strategy-customization.md#get-data-for-non-tradeable-pairs) * Download OHLCV data for the pairlist including all [informative pairs](strategy-customization.md#get-data-for-non-tradeable-pairs)
This step is only executed once per Candle to avoid unnecessary network traffic. This step is only executed once per Candle to avoid unnecessary network traffic.
* Call `bot_loop_start()` strategy callback. * Call `bot_loop_start()` strategy callback.
* Analyze strategy per pair. * Analyze strategy per pair.
* Call `populate_indicators()` * Call `populate_indicators()`
* Call `populate_buy_trend()` * Call `populate_entry_trend()`
* Call `populate_sell_trend()` * Call `populate_exit_trend()`
* Check timeouts for open orders. * Check timeouts for open orders.
* Calls `check_buy_timeout()` strategy callback for open buy orders. * Calls `check_entry_timeout()` strategy callback for open entry orders.
* Calls `check_sell_timeout()` strategy callback for open sell orders. * Calls `check_exit_timeout()` strategy callback for open exit orders.
* Verifies existing positions and eventually places sell orders. * Calls `adjust_entry_price()` strategy callback for open entry orders.
* Considers stoploss, ROI and sell-signal, `custom_sell()` and `custom_stoploss()`. * Verifies existing positions and eventually places exit orders.
* Determine sell-price based on `ask_strategy` configuration setting or by using the `custom_exit_price()` callback. * Considers stoploss, ROI and exit-signal, `custom_exit()` and `custom_stoploss()`.
* Before a sell order is placed, `confirm_trade_exit()` strategy callback is called. * Determine exit-price based on `exit_pricing` configuration setting or by using the `custom_exit_price()` callback.
* Before a exit order is placed, `confirm_trade_exit()` strategy callback is called.
* Check position adjustments for open trades if enabled by calling `adjust_trade_position()` and place additional order if required. * Check position adjustments for open trades if enabled by calling `adjust_trade_position()` and place additional order if required.
* Check if trade-slots are still available (if `max_open_trades` is reached). * Check if trade-slots are still available (if `max_open_trades` is reached).
* Verifies buy signal trying to enter new positions. * Verifies entry signal trying to enter new positions.
* Determine buy-price based on `bid_strategy` configuration setting, or by using the `custom_entry_price()` callback. * Determine entry-price based on `entry_pricing` configuration setting, or by using the `custom_entry_price()` callback.
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
* Determine stake size by calling the `custom_stake_amount()` callback. * Determine stake size by calling the `custom_stake_amount()` callback.
* Before a buy order is placed, `confirm_trade_entry()` strategy callback is called. * Before an entry order is placed, `confirm_trade_entry()` strategy callback is called.
This loop will be repeated again and again until the bot is stopped. This loop will be repeated again and again until the bot is stopped.
@@ -52,17 +56,21 @@ 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. [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. * Load historic data for configured pairlist.
* Calls `bot_start()` once.
* Calls `bot_loop_start()` once. * Calls `bot_loop_start()` once.
* Calculate indicators (calls `populate_indicators()` once per pair). * Calculate indicators (calls `populate_indicators()` once per pair).
* Calculate buy / sell signals (calls `populate_buy_trend()` and `populate_sell_trend()` once per pair). * Calculate entry / exit signals (calls `populate_entry_trend()` and `populate_exit_trend()` once per pair).
* Loops per candle simulating entry and exit points. * Loops per candle simulating entry and exit points.
* Confirm trade buy / sell (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy). * Check for Order timeouts, either via the `unfilledtimeout` configuration, or via `check_entry_timeout()` / `check_exit_timeout()` strategy callbacks.
* Calls `adjust_entry_price()` strategy callback for open entry orders.
* Check for trade entry signals (`enter_long` / `enter_short` columns).
* Confirm trade entry / exits (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy).
* Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle). * Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle).
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
* Determine stake size by calling the `custom_stake_amount()` callback. * Determine stake size by calling the `custom_stake_amount()` callback.
* Check position adjustments for open trades if enabled and call `adjust_trade_position()` to determine if an additional order is requested. * Check position adjustments for open trades if enabled and call `adjust_trade_position()` to determine if an additional order is requested.
* Call `custom_stoploss()` and `custom_sell()` to find custom exit points. * Call `custom_stoploss()` and `custom_exit()` to find custom exit points.
* For sells based on sell-signal and custom-sell: Call `custom_exit_price()` to determine exit price (Prices are moved to be within the closing candle). * For exits based on exit-signal and custom-exit: Call `custom_exit_price()` to determine exit price (Prices are moved to be within the closing candle).
* Check for Order timeouts, either via the `unfilledtimeout` configuration, or via `check_buy_timeout()` / `check_sell_timeout()` strategy callbacks.
* Generate backtest report output * Generate backtest report output
!!! Note !!! Note

View File

@@ -11,7 +11,7 @@ Per default, the bot loads the configuration from the `config.json` file, locate
You can specify a different configuration file used by the bot with the `-c/--config` command-line option. You can specify a different configuration file used by the bot with the `-c/--config` command-line option.
If you used the [Quick start](installation.md/#quick-start) method for installing 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. the bot, the installation script should have already created the default configuration file (`config.json`) for you.
If the default configuration file is not created we recommend to use `freqtrade new-config --config config.json` to generate a basic configuration file. If the default configuration file is not created we recommend to use `freqtrade new-config --config config.json` to generate a basic configuration file.
@@ -53,20 +53,72 @@ FREQTRADE__EXCHANGE__SECRET=<yourExchangeSecret>
Multiple configuration files can be specified and used by the bot or the bot can read its configuration parameters from the process standard input stream. Multiple configuration files can be specified and used by the bot or the bot can read its configuration parameters from the process standard input stream.
You can specify additional configuration files in `add_config_files`. Files specified in this parameter will be loaded and merged with the initial config file. The files are resolved relative to the initial configuration file.
This is similar to using multiple `--config` parameters, but simpler in usage as you don't have to specify all files for all commands.
!!! Tip "Use multiple configuration files to keep secrets secret" !!! Tip "Use multiple configuration files to keep secrets secret"
You can use a 2nd configuration file containing your secrets. That way you can share your "primary" configuration file, while still keeping your API keys for yourself. You can use a 2nd configuration file containing your secrets. That way you can share your "primary" configuration file, while still keeping your API keys for yourself.
``` json title="user_data/config.json"
"add_config_files": [
"config-private.json"
]
```
``` bash
freqtrade trade --config user_data/config.json <...>
```
The 2nd file should only specify what you intend to override.
If a key is in more than one of the configurations, then the "last specified configuration" wins (in the above example, `config-private.json`).
For one-off commands, you can also use the below syntax by specifying multiple "--config" parameters.
``` bash ``` bash
freqtrade trade --config user_data/config.json --config user_data/config-private.json <...> freqtrade trade --config user_data/config.json --config user_data/config-private.json <...>
``` ```
The 2nd file should only specify what you intend to override.
If a key is in more than one of the configurations, then the "last specified configuration" wins (in the above example, `config-private.json`). This is equivalent to the example above - but `config-private.json` is specified as cli argument.
??? Note "config collision handling"
If the same configuration setting takes place in both `config.json` and `config-import.json`, then the parent configuration wins.
In the below case, `max_open_trades` would be 3 after the merging - as the reusable "import" configuration has this key overwritten.
``` json title="user_data/config.json"
{
"max_open_trades": 3,
"stake_currency": "USDT",
"add_config_files": [
"config-import.json"
]
}
```
``` json title="user_data/config-import.json"
{
"max_open_trades": 10,
"stake_amount": "unlimited",
}
```
Resulting combined configuration:
``` json title="Result"
{
"max_open_trades": 3,
"stake_currency": "USDT",
"stake_amount": "unlimited"
}
```
## Configuration parameters ## Configuration parameters
The table below will list all configuration parameters available. The table below will list all configuration parameters available.
Freqtrade can also load many options via command line (CLI) arguments (check out the commands `--help` output for details). Freqtrade can also load many options via command line (CLI) arguments (check out the commands `--help` output for details).
### Configuration option prevalence
The prevalence for all Options is as follows: The prevalence for all Options is as follows:
- CLI arguments override any other option - CLI arguments override any other option
@@ -74,6 +126,8 @@ The prevalence for all Options is as follows:
- Configuration files are used in sequence (the last file wins) and override Strategy configurations. - Configuration files are used in sequence (the last file wins) and override Strategy configurations.
- Strategy configurations are only used if they are not set via configuration or command-line arguments. These options are marked with [Strategy Override](#parameters-in-the-strategy) in the below table. - Strategy configurations are only used if they are not set via configuration or command-line arguments. These options are marked with [Strategy Override](#parameters-in-the-strategy) in the below table.
### Parameters table
Mandatory parameters are marked as **Required**, which means that they are required to be set in one of the possible ways. Mandatory parameters are marked as **Required**, which means that they are required to be set in one of the possible ways.
| Parameter | Description | | Parameter | Description |
@@ -86,41 +140,51 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade). <br>*Defaults to `false`.* <br> **Datatype:** Boolean | `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade). <br>*Defaults to `0.5`.* <br> **Datatype:** Float (as ratio) | `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade). <br>*Defaults to `0.5`.* <br> **Datatype:** Float (as ratio)
| `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals. <br>*Defaults to `0.05` (5%).* <br> **Datatype:** Positive Float as ratio. | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals. <br>*Defaults to `0.05` (5%).* <br> **Datatype:** Positive Float as ratio.
| `timeframe` | The timeframe (former ticker interval) to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** String | `timeframe` | The timeframe to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). Usually missing in configuration, and specified in the strategy. [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** String
| `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency). <br> **Datatype:** String | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency). <br> **Datatype:** String
| `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode. <br>*Defaults to `true`.* <br> **Datatype:** Boolean | `dry_run` | **Required.** Define if the bot must be in Dry Run or production mode. <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in Dry Run mode.<br>*Defaults to `1000`.* <br> **Datatype:** Float | `dry_run_wallet` | Define the starting amount in stake currency for the simulated wallet used by the bot running in Dry Run mode.<br>*Defaults to `1000`.* <br> **Datatype:** Float
| `cancel_open_orders_on_exit` | Cancel open orders when the `/stop` RPC command is issued, `Ctrl+C` is pressed or the bot dies unexpectedly. When set to `true`, this allows you to use `/stop` to cancel unfilled and partially filled orders in the event of a market crash. It does not impact open positions. <br>*Defaults to `false`.* <br> **Datatype:** Boolean | `cancel_open_orders_on_exit` | Cancel open orders when the `/stop` RPC command is issued, `Ctrl+C` is pressed or the bot dies unexpectedly. When set to `true`, this allows you to use `/stop` to cancel unfilled and partially filled orders in the event of a market crash. It does not impact open positions. <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean | `process_only_new_candles` | Enable processing of indicators only when new candles arrive. If false each loop populates the indicators, this will mean the same candle is processed many times creating system load but can be useful of your strategy depends on tick data not only candle. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `minimal_roi` | **Required.** Set the threshold as ratio the bot will use to sell a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict | `minimal_roi` | **Required.** Set the threshold as ratio the bot will use to exit a trade. [More information below](#understand-minimal_roi). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
| `stoploss` | **Required.** Value as ratio of the stoploss used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Float (as ratio) | `stoploss` | **Required.** Value as ratio of the stoploss used by the bot. More details in the [stoploss documentation](stoploss.md). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Float (as ratio)
| `trailing_stop` | Enables trailing stoploss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md#trailing-stop-loss). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Boolean | `trailing_stop` | Enables trailing stoploss (based on `stoploss` in either configuration or strategy file). More details in the [stoploss documentation](stoploss.md#trailing-stop-loss). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Boolean
| `trailing_stop_positive` | Changes stoploss once profit has been reached. More details in the [stoploss documentation](stoploss.md#trailing-stop-loss-custom-positive-loss). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Float | `trailing_stop_positive` | 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_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 | `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
| `fee` | Fee used during backtesting / dry-runs. Should normally not be configured, which has freqtrade fall back to the exchange default fee. Set as ratio (e.g. 0.001 = 0.1%). Fee is applied twice for each trade, once when buying, once when selling. <br> **Datatype:** Float (as ratio) | `fee` | Fee used during backtesting / dry-runs. Should normally not be configured, which has freqtrade fall back to the exchange default fee. Set as ratio (e.g. 0.001 = 0.1%). Fee is applied twice for each trade, once when buying, once when selling. <br> **Datatype:** Float (as ratio)
| `unfilledtimeout.buy` | **Required.** How long (in minutes or seconds) 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 | `futures_funding_rate` | User-specified funding rate to be used when historical funding rates are not available from the exchange. This does not overwrite real historical rates. It is recommended that this be set to 0 unless you are testing a specific coin and you understand how the funding rate will affect freqtrade's profit calculations. [More information here](leverage.md#unavailable-funding-rates) <br>*Defaults to None.*<br> **Datatype:** Float
| `unfilledtimeout.sell` | **Required.** How long (in minutes or seconds) 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 | `trading_mode` | Specifies if you want to trade regularly, trade with leverage, or trade contracts whose prices are derived from matching cryptocurrency prices. [leverage documentation](leverage.md). <br>*Defaults to `"spot"`.* <br> **Datatype:** String
| `margin_mode` | When trading with leverage, this determines if the collateral owned by the trader will be shared or isolated to each trading pair [leverage documentation](leverage.md). <br> **Datatype:** String
| `liquidation_buffer` | A ratio specifying how large of a safety net to place between the liquidation price and the stoploss to prevent a position from reaching the liquidation price [leverage documentation](leverage.md). <br>*Defaults to `0.05`.* <br> **Datatype:** Float
| | **Unfilled timeout**
| `unfilledtimeout.entry` | **Required.** How long (in minutes or seconds) the bot will wait for an unfilled entry 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.exit` | **Required.** How long (in minutes or seconds) the bot will wait for an unfilled exit 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.unit` | Unit to use in unfilledtimeout setting. Note: If you set unfilledtimeout.unit to "seconds", "internals.process_throttle_secs" must be inferior or equal to timeout [Strategy Override](#parameters-in-the-strategy). <br> *Defaults to `minutes`.* <br> **Datatype:** String | `unfilledtimeout.unit` | Unit to use in unfilledtimeout setting. Note: If you set unfilledtimeout.unit to "seconds", "internals.process_throttle_secs" must be inferior or equal to timeout [Strategy Override](#parameters-in-the-strategy). <br> *Defaults to `minutes`.* <br> **Datatype:** String
| `unfilledtimeout.exit_timeout_count` | How many times can exit orders time out. Once this number of timeouts is reached, an emergency sell is triggered. 0 to disable and allow unlimited order cancels. [Strategy Override](#parameters-in-the-strategy).<br>*Defaults to `0`.* <br> **Datatype:** Integer | `unfilledtimeout.exit_timeout_count` | How many times can exit orders time out. Once this number of timeouts is reached, an emergency exit is triggered. 0 to disable and allow unlimited order cancels. [Strategy Override](#parameters-in-the-strategy).<br>*Defaults to `0`.* <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`). | | **Pricing**
| `bid_strategy.ask_last_balance` | **Required.** Interpolate the bidding price. More information [below](#buy-price-without-orderbook-enabled). | `entry_pricing.price_side` | Select the side of the spread the bot should look at to get the entry rate. [More information below](#buy-price-side).<br> *Defaults to `same`.* <br> **Datatype:** String (either `ask`, `bid`, `same` or `other`).
| `bid_strategy.use_order_book` | Enable buying using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled). <br> **Datatype:** Boolean | `entry_pricing.price_last_balance` | **Required.** Interpolate the bidding price. More information [below](#entry-price-without-orderbook-enabled).
| `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book "price_side" to buy. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in [Order Book Bids](#buy-price-with-orderbook-enabled). <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer | `entry_pricing.use_order_book` | Enable entering using the rates in [Order Book Entry](#entry-price-with-orderbook-enabled). <br> *Defaults to `True`.*<br> **Datatype:** Boolean
| `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market). <br>*Defaults to `false`.* <br> **Datatype:** Boolean | `entry_pricing.order_book_top` | Bot will use the top N rate in Order Book "price_side" to enter a trade. I.e. a value of 2 will allow the bot to pick the 2nd entry in [Order Book Entry](#entry-price-with-orderbook-enabled). <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market) <br> *Defaults to `0`.* <br> **Datatype:** Float (as ratio) | `entry_pricing. check_depth_of_market.enabled` | Do not enter if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `ask_strategy.price_side` | Select the side of the spread the bot should look at to get the sell rate. [More information below](#sell-price-side).<br> *Defaults to `ask`.* <br> **Datatype:** String (either `ask` or `bid`). | `entry_pricing. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market) <br> *Defaults to `0`.* <br> **Datatype:** Float (as ratio)
| `ask_strategy.bid_last_balance` | Interpolate the selling price. More information [below](#sell-price-without-orderbook-enabled). | `exit_pricing.price_side` | Select the side of the spread the bot should look at to get the exit rate. [More information below](#exit-price-side).<br> *Defaults to `same`.* <br> **Datatype:** String (either `ask`, `bid`, `same` or `other`).
| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled). <br> **Datatype:** Boolean | `exit_pricing.price_last_balance` | Interpolate the exiting price. More information [below](#exit-price-without-orderbook-enabled).
| `ask_strategy.order_book_top` | Bot will use the top N rate in Order Book "price_side" to sell. I.e. a value of 2 will allow the bot to pick the 2nd ask rate in [Order Book Asks](#sell-price-with-orderbook-enabled)<br>*Defaults to `1`.* <br> **Datatype:** Positive Integer | `exit_pricing.use_order_book` | Enable exiting of open trades using [Order Book Exit](#exit-price-with-orderbook-enabled). <br> *Defaults to `True`.*<br> **Datatype:** Boolean
| `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 | `exit_pricing.order_book_top` | Bot will use the top N rate in Order Book "price_side" to exit. I.e. a value of 2 will allow the bot to pick the 2nd ask rate in [Order Book Exit](#exit-price-with-orderbook-enabled)<br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
| `sell_profit_only` | Wait until the bot reaches `sell_profit_offset` before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `sell_profit_offset` | Sell-signal is only active above this value. Only active in combination with `sell_profit_only=True`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
| `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
| `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
| `custom_price_max_distance_ratio` | Configure maximum distance ratio between current and custom entry or exit price. <br>*Defaults to `0.02` 2%).*<br> **Datatype:** Positive float | `custom_price_max_distance_ratio` | Configure maximum distance ratio between current and custom entry or exit price. <br>*Defaults to `0.02` 2%).*<br> **Datatype:** Positive float
| | **TODO**
| `use_exit_signal` | Use exit signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
| `exit_profit_only` | Wait until the bot reaches `exit_profit_offset` before taking an exit decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `exit_profit_offset` | Exit-signal is only active above this value. Only active in combination with `exit_profit_only=True`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
| `ignore_roi_if_entry_signal` | Do not exit if the entry signal is still active. This setting takes preference over `minimal_roi` and `use_exit_signal`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
| `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 (`"entry"`, `"exit"`, `"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 entry and exit orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy). <br> **Datatype:** Dict
| `position_adjustment_enable` | Enables the strategy to use position adjustments (additional buys or sells). [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.*<br> **Datatype:** Boolean
| `max_entry_position_adjustment` | Maximum additional order(s) for each open trade on top of the first entry Order. Set it to `-1` for unlimited additional orders. [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `-1`.*<br> **Datatype:** Positive Integer or -1
| | **Exchange**
| `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename). <br> **Datatype:** String | `exchange.name` | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename). <br> **Datatype:** String
| `exchange.sandbox` | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.<br> **Datatype:** Boolean | `exchange.sandbox` | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.<br> **Datatype:** Boolean
| `exchange.key` | API key to use for the exchange. Only required when you are in production mode.<br>**Keep it in secret, do not disclose publicly.** <br> **Datatype:** String | `exchange.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
@@ -137,21 +201,29 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `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 | `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
| `exchange.unknown_fee_rate` | Fallback value to use when calculating trading fees. This can be useful for exchanges which have fees in non-tradable currencies. The value provided here will be multiplied with the "fee cost".<br>*Defaults to `None`<br> **Datatype:** float | `exchange.unknown_fee_rate` | Fallback value to use when calculating trading fees. This can be useful for exchanges which have fees in non-tradable currencies. The value provided here will be multiplied with the "fee cost".<br>*Defaults to `None`<br> **Datatype:** float
| `exchange.log_responses` | Log relevant exchange responses. For debug mode only - use with care.<br>*Defaults to `false`<br> **Datatype:** Boolean | `exchange.log_responses` | Log relevant exchange responses. For debug mode only - use with care.<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 | `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
| | **Plugins**
| `edge.*` | Please refer to [edge configuration document](edge.md) for detailed explanation of all possible configuration options.
| `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 | `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). <br> **Datatype:** List of Dicts | `protections` | Define one or more protections to be used. [More information](plugins.md#protections). <br> **Datatype:** List of Dicts
| | **Telegram**
| `telegram.enabled` | Enable the usage of Telegram. <br> **Datatype:** Boolean | `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.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 | `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
| `telegram.balance_dust_level` | Dust-level (in stake currency) - currencies with a balance below this will not be shown by `/balance`. <br> **Datatype:** float | `telegram.balance_dust_level` | Dust-level (in stake currency) - currencies with a balance below this will not be shown by `/balance`. <br> **Datatype:** float
| `telegram.reload` | Allow "reload" buttons on telegram messages. <br>*Defaults to `True`.<br> **Datatype:** boolean
| `telegram.notification_settings.*` | Detailed notification settings. Refer to the [telegram documentation](telegram-usage.md) for details.<br> **Datatype:** dictionary
| | **Webhook**
| `webhook.enabled` | Enable usage of Webhook notifications <br> **Datatype:** Boolean | `webhook.enabled` | Enable usage of Webhook notifications <br> **Datatype:** Boolean
| `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String | `webhook.url` | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookbuy` | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String | `webhook.webhookentry` | Payload to send on entry. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookbuycancel` | Payload to send on buy order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String | `webhook.webhookentrycancel` | Payload to send on entry order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhooksell` | Payload to send on sell. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String | `webhook.webhookentryfill` | Payload to send on entry order filled. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhooksellcancel` | Payload to send on sell order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String | `webhook.webhookexit` | Payload to send on exit. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookexitcancel` | Payload to send on exit order cancel. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookexitfill` | Payload to send on exit order filled. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String | `webhook.webhookstatus` | Payload to send on status calls. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details. <br> **Datatype:** String
| | **Rest API / FreqUI**
| `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details. <br> **Datatype:** Boolean | `api_server.enabled` | Enable usage of API Server. See the [API Server documentation](rest-api.md) for more details. <br> **Datatype:** Boolean
| `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details. <br> **Datatype:** IPv4 | `api_server.listen_ip_address` | Bind IP address. See the [API Server documentation](rest-api.md) for more details. <br> **Datatype:** IPv4
| `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details. <br>**Datatype:** Integer between 1024 and 65535 | `api_server.listen_port` | Bind Port. See the [API Server documentation](rest-api.md) for more details. <br>**Datatype:** Integer between 1024 and 65535
@@ -159,21 +231,22 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `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.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 | `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 | `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 | | **Other**
| `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` | `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 | `force_entry_enable` | Enables the RPC Commands to force a Trade entry. 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 | `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, or minimum loop duration for one bot iteration loop. 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.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 | `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 | `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
| `recursive_strategy_search` | Set to `true` to recursively search sub-directories inside `user_data/strategies` for a strategy. <br> **Datatype:** Boolean
| `user_data_dir` | Directory containing user data. <br> *Defaults to `./user_data/`*. <br> **Datatype:** String | `user_data_dir` | Directory containing user data. <br> *Defaults to `./user_data/`*. <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
| `logfile` | Specifies logfile name. Uses a rolling strategy for log file rotation for 10 files with the 1MB limit per file. <br> **Datatype:** String
| `add_config_files` | Additional config files. These files will be loaded and merged with the current config file. The files are resolved relative to the initial file.<br> *Defaults to `[]`*. <br> **Datatype:** List of strings
| `dataformat_ohlcv` | Data format to use to store historical candle (OHLCV) data. <br> *Defaults to `json`*. <br> **Datatype:** String | `dataformat_ohlcv` | Data format to use to store historical candle (OHLCV) data. <br> *Defaults to `json`*. <br> **Datatype:** String
| `dataformat_trades` | Data format to use to store historical trades data. <br> *Defaults to `jsongz`*. <br> **Datatype:** String | `dataformat_trades` | Data format to use to store historical trades data. <br> *Defaults to `jsongz`*. <br> **Datatype:** String
| `position_adjustment_enable` | Enables the strategy to use position adjustments (additional buys or sells). [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.*<br> **Datatype:** Boolean
| `max_entry_position_adjustment` | Maximum additional order(s) for each open trade on top of the first entry Order. Set it to `-1` for unlimited additional orders. [More information here](strategy-callbacks.md#adjust-trade-position). <br> [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `-1`.*<br> **Datatype:** Positive Integer or -1
### Parameters in the strategy ### Parameters in the strategy
@@ -193,10 +266,10 @@ Values set in the configuration file always overwrite values set in the strategy
* `order_time_in_force` * `order_time_in_force`
* `unfilledtimeout` * `unfilledtimeout`
* `disable_dataframe_checks` * `disable_dataframe_checks`
* `use_sell_signal` - `use_exit_signal`
* `sell_profit_only` * `exit_profit_only`
* `sell_profit_offset` - `exit_profit_offset`
* `ignore_roi_if_buy_signal` - `ignore_roi_if_entry_signal`
* `ignore_buying_expired_candle_after` * `ignore_buying_expired_candle_after`
* `position_adjustment_enable` * `position_adjustment_enable`
* `max_entry_position_adjustment` * `max_entry_position_adjustment`
@@ -325,10 +398,10 @@ See the example below:
```json ```json
"minimal_roi": { "minimal_roi": {
"40": 0.0, # Sell after 40 minutes if the profit is not negative "40": 0.0, # Exit after 40 minutes if the profit is not negative
"30": 0.01, # Sell after 30 minutes if there is at least 1% profit "30": 0.01, # Exit after 30 minutes if there is at least 1% profit
"20": 0.02, # Sell after 20 minutes if there is at least 2% profit "20": 0.02, # Exit after 20 minutes if there is at least 2% profit
"0": 0.04 # Sell immediately if there is at least 4% profit "0": 0.04 # Exit immediately if there is at least 4% profit
}, },
``` ```
@@ -337,14 +410,14 @@ This parameter can be set in either Strategy or Configuration file. If you use i
`minimal_roi` value from the strategy file. `minimal_roi` value from the strategy file.
If it is not set in either Strategy or Configuration, a default of 1000% `{"0": 10}` is used, and minimal ROI is disabled unless your trade generates 1000% profit. If it is not set in either Strategy or Configuration, a default of 1000% `{"0": 10}` is used, and minimal ROI is disabled unless your trade generates 1000% profit.
!!! Note "Special case to forcesell after a specific time" !!! Note "Special case to forceexit 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. A special case presents using `"<N>": -1` as ROI. This forces the bot to exit a trade after N Minutes, no matter if it's positive or negative, so represents a time-limited force-exit.
### Understand forcebuy_enable ### Understand force_entry_enable
The `forcebuy_enable` configuration parameter enables the usage of forcebuy commands via Telegram and REST API. The `force_entry_enable` configuration parameter enables the usage of force-enter (`/forcelong`, `/forceshort`) 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 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. For example, you can send `/forceenter ETH/BTC` to the bot, which will result in freqtrade buying the pair and holds it until a regular exit-signal (ROI, stoploss, /forceexit) appears.
This can be dangerous with some strategies, so use with care. This can be dangerous with some strategies, so use with care.
@@ -371,29 +444,27 @@ For example, if your strategy is using a 1h timeframe, and you only want to buy
### Understand order_types ### Understand order_types
The `order_types` configuration parameter maps actions (`buy`, `sell`, `stoploss`, `emergencysell`, `forcesell`, `forcebuy`) to order-types (`market`, `limit`, ...) as well as configures stoploss to be on the exchange and defines stoploss on exchange update interval in seconds. The `order_types` configuration parameter maps actions (`entry`, `exit`, `stoploss`, `emergency_exit`, `force_exit`, `force_entry`) to order-types (`market`, `limit`, ...) as well as configures stoploss to be on the exchange and defines stoploss on exchange update interval in seconds.
This allows to enter using limit orders, exit using limit-orders, and create stoplosses using market orders.
It also allows to set the
stoploss "on exchange" which means stoploss order would be placed immediately once the buy order is fulfilled.
This allows to buy using limit orders, sell using
limit-orders, and create stoplosses using market orders. It also allows to set the
stoploss "on exchange" which means stoploss order would be placed immediately once
the buy order is fulfilled.
`order_types` set in the configuration file overwrites values set in the strategy as a whole, so you need to configure the whole `order_types` dictionary in one place. `order_types` set in the configuration file overwrites values set in the strategy as a whole, so you need to configure the whole `order_types` dictionary in one place.
If this is configured, the following 4 values (`buy`, `sell`, `stoploss` and If this is configured, the following 4 values (`entry`, `exit`, `stoploss` and `stoploss_on_exchange`) need to be present, otherwise, the bot will fail to start.
`stoploss_on_exchange`) need to be present, otherwise, the bot will fail to start.
For information on (`emergencysell`,`forcesell`, `forcebuy`, `stoploss_on_exchange`,`stoploss_on_exchange_interval`,`stoploss_on_exchange_limit_ratio`) please see stop loss documentation [stop loss on exchange](stoploss.md) For information on (`emergency_exit`,`force_exit`, `force_entry`, `stoploss_on_exchange`,`stoploss_on_exchange_interval`,`stoploss_on_exchange_limit_ratio`) please see stop loss documentation [stop loss on exchange](stoploss.md)
Syntax for Strategy: Syntax for Strategy:
```python ```python
order_types = { order_types = {
"buy": "limit", "entry": "limit",
"sell": "limit", "exit": "limit",
"emergencysell": "market", "emergency_exit": "market",
"forcebuy": "market", "force_entry": "market",
"forcesell": "market", "force_exit": "market",
"stoploss": "market", "stoploss": "market",
"stoploss_on_exchange": False, "stoploss_on_exchange": False,
"stoploss_on_exchange_interval": 60, "stoploss_on_exchange_interval": 60,
@@ -405,11 +476,11 @@ Configuration:
```json ```json
"order_types": { "order_types": {
"buy": "limit", "entry": "limit",
"sell": "limit", "exit": "limit",
"emergencysell": "market", "emergency_exit": "market",
"forcebuy": "market", "force_entry": "market",
"forcesell": "market", "force_exit": "market",
"stoploss": "market", "stoploss": "market",
"stoploss_on_exchange": false, "stoploss_on_exchange": false,
"stoploss_on_exchange_interval": 60 "stoploss_on_exchange_interval": 60
@@ -432,7 +503,7 @@ Configuration:
If `stoploss_on_exchange` is enabled and the stoploss is cancelled manually on the exchange, then the bot will create a new stoploss order. 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 "Warning: stoploss_on_exchange failures" !!! Warning "Warning: stoploss_on_exchange failures"
If stoploss on exchange creation fails for some reason, then an "emergency sell" is initiated. By default, this will sell the asset using a market order. The order-type for the emergency-sell can be changed by setting the `emergencysell` value in the `order_types` dictionary - however, this is not advised. If stoploss on exchange creation fails for some reason, then an "emergency exit" is initiated. By default, this will exit the trade using a market order. The order-type for the emergency-exit can be changed by setting the `emergency_exit` value in the `order_types` dictionary - however, this is not advised.
### Understand order_time_in_force ### Understand order_time_in_force
@@ -462,8 +533,8 @@ The possible values are: `gtc` (default), `fok` or `ioc`.
``` python ``` python
"order_time_in_force": { "order_time_in_force": {
"buy": "gtc", "entry": "gtc",
"sell": "gtc" "exit": "gtc"
}, },
``` ```
@@ -509,10 +580,10 @@ creating trades on the exchange.
```json ```json
"exchange": { "exchange": {
"name": "bittrex", "name": "bittrex",
"key": "key", "key": "key",
"secret": "secret", "secret": "secret",
... ...
} }
``` ```
@@ -529,7 +600,7 @@ Once you will be happy with your bot performance running in the Dry-run mode, yo
* Market orders fill based on orderbook volume the moment the order is placed. * Market orders fill based on orderbook volume the moment the order is placed.
* Limit orders fill once the price reaches the defined level - or time out based on `unfilledtimeout` settings. * Limit orders fill once the price reaches the defined level - or time out based on `unfilledtimeout` settings.
* In combination with `stoploss_on_exchange`, the stop_loss price is assumed to be filled. * 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. * Open orders (not trades, which are stored in the database) are kept open after bot restarts, with the assumption that they were not filled while being offline.
## Switch to production mode ## Switch to production mode

View File

@@ -122,5 +122,6 @@ Best avoid relative paths, since this starts at the storage location of the jupy
* [Strategy debugging](strategy_analysis_example.md) - also available as Jupyter notebook (`user_data/notebooks/strategy_analysis_example.ipynb`) * [Strategy debugging](strategy_analysis_example.md) - also available as Jupyter notebook (`user_data/notebooks/strategy_analysis_example.ipynb`)
* [Plotting](plotting.md) * [Plotting](plotting.md)
* [Tag Analysis](advanced-backtesting.md)
Feel free to submit an issue or Pull Request enhancing this document if you would like to share ideas on how to best analyze the data. Feel free to submit an issue or Pull Request enhancing this document if you would like to share ideas on how to best analyze the data.

View File

@@ -29,6 +29,8 @@ usage: freqtrade download-data [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[--erase] [--erase]
[--data-format-ohlcv {json,jsongz,hdf5}] [--data-format-ohlcv {json,jsongz,hdf5}]
[--data-format-trades {json,jsongz,hdf5}] [--data-format-trades {json,jsongz,hdf5}]
[--trading-mode {spot,margin,futures}]
[--prepend]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@@ -59,6 +61,9 @@ optional arguments:
--data-format-trades {json,jsongz,hdf5} --data-format-trades {json,jsongz,hdf5}
Storage format for downloaded trades data. (default: Storage format for downloaded trades data. (default:
`jsongz`). `jsongz`).
--trading-mode {spot,margin,futures}
Select Trading mode
--prepend Allow data prepending.
Common arguments: Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages). -v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
@@ -154,10 +159,21 @@ freqtrade download-data --exchange binance --pairs .*/USDT
- To change the exchange used to download the historical data from, please use a different configuration file (you'll probably need to adjust rate limits etc.) - To change the exchange used to download the historical data from, please use a different configuration file (you'll probably need to adjust rate limits etc.)
- To use `pairs.json` from some other directory, use `--pairs-file some_other_dir/pairs.json`. - To use `pairs.json` from some other directory, use `--pairs-file some_other_dir/pairs.json`.
- To download historical candle (OHLCV) data for only 10 days, use `--days 10` (defaults to 30 days). - To download historical candle (OHLCV) data for only 10 days, use `--days 10` (defaults to 30 days).
- To download historical candle (OHLCV) data from a fixed starting point, use `--timerange 20200101-` - which will download all data from January 1st, 2020. Eventually set end dates are ignored. - To download historical candle (OHLCV) data from a fixed starting point, use `--timerange 20200101-` - which will download all data from January 1st, 2020.
- Use `--timeframes` to specify what timeframe download the historical candle (OHLCV) data for. Default is `--timeframes 1m 5m` which will download 1-minute and 5-minute data. - Use `--timeframes` to specify what timeframe download the historical candle (OHLCV) data for. Default is `--timeframes 1m 5m` which will download 1-minute and 5-minute data.
- To use exchange, timeframe and list of pairs as defined in your configuration file, use the `-c/--config` option. With this, the script uses the whitelist defined in the config as the list of currency pairs to download data for and does not require the pairs.json file. You can combine `-c/--config` with most other options. - To use exchange, timeframe and list of pairs as defined in your configuration file, use the `-c/--config` option. With this, the script uses the whitelist defined in the config as the list of currency pairs to download data for and does not require the pairs.json file. You can combine `-c/--config` with most other options.
#### Download additional data before the current timerange
Assuming you downloaded all data from 2022 (`--timerange 20220101-`) - but you'd now like to also backtest with earlier data.
You can do so by using the `--prepend` flag, combined with `--timerange` - specifying an end-date.
``` bash
freqtrade download-data --exchange binance --pairs ETH/USDT XRP/USDT BTC/USDT --prepend --timerange 20210101-20220101
```
!!! Note
Freqtrade will ignore the end-date in this mode if data is available, updating the end-date to the existing data start point.
### Data format ### Data format
@@ -193,11 +209,14 @@ usage: freqtrade convert-data [-h] [-v] [--logfile FILE] [-V] [-c PATH]
{json,jsongz,hdf5} --format-to {json,jsongz,hdf5} --format-to
{json,jsongz,hdf5} [--erase] {json,jsongz,hdf5} [--erase]
[-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...]] [-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...]]
[--exchange EXCHANGE]
[--trading-mode {spot,margin,futures}]
[--candle-types {spot,,futures,mark,index,premiumIndex,funding_rate} [{spot,,futures,mark,index,premiumIndex,funding_rate} ...]]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...] -p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
Show profits for only these pairs. Pairs are space- Limit command to these pairs. Pairs are space-
separated. separated.
--format-from {json,jsongz,hdf5} --format-from {json,jsongz,hdf5}
Source format for data conversion. Source format for data conversion.
@@ -208,6 +227,12 @@ optional arguments:
-t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...] -t {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...], --timeframes {1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} [{1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,2w,1M,1y} ...]
Specify which tickers to download. Space-separated Specify which tickers to download. Space-separated
list. Default: `1m 5m`. list. Default: `1m 5m`.
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no
config is provided.
--trading-mode {spot,margin,futures}
Select Trading mode
--candle-types {spot,,futures,mark,index,premiumIndex,funding_rate} [{spot,,futures,mark,index,premiumIndex,funding_rate} ...]
Select candle type to use
Common arguments: Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages). -v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
@@ -224,6 +249,7 @@ Common arguments:
Path to directory with historical backtesting data. Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH --userdir PATH, --user-data-dir PATH
Path to userdata directory. Path to userdata directory.
``` ```
##### Example converting data ##### Example converting data
@@ -347,6 +373,7 @@ usage: freqtrade list-data [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [--exchange EXCHANGE] [--userdir PATH] [--exchange EXCHANGE]
[--data-format-ohlcv {json,jsongz,hdf5}] [--data-format-ohlcv {json,jsongz,hdf5}]
[-p PAIRS [PAIRS ...]] [-p PAIRS [PAIRS ...]]
[--trading-mode {spot,margin,futures}]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@@ -356,8 +383,10 @@ optional arguments:
Storage format for downloaded candle (OHLCV) data. Storage format for downloaded candle (OHLCV) data.
(default: `json`). (default: `json`).
-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...] -p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]
Show profits for only these pairs. Pairs are space- Limit command to these pairs. Pairs are space-
separated. separated.
--trading-mode {spot,margin,futures}
Select Trading mode
Common arguments: Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages). -v, --verbose Verbose mode (-vv for more, -vvv to get all messages).

View File

@@ -24,6 +24,10 @@ Please refer to [pairlists](plugins.md#pairlists-and-pairlist-handlers) instead.
Did only download the latest 500 candles, so was ineffective in getting good backtest data. Did only download the latest 500 candles, so was ineffective in getting good backtest data.
Removed in 2019-7-dev (develop branch) and in freqtrade 2019.8. Removed in 2019-7-dev (develop branch) and in freqtrade 2019.8.
### `ticker_interval` (now `timeframe`)
Support for `ticker_interval` terminology was deprecated in 2020.6 in favor of `timeframe` - and compatibility code was removed in 2022.3.
### Allow running multiple pairlists in sequence ### Allow running multiple pairlists in sequence
The former `"pairlist"` section in the configuration has been removed, and is replaced by `"pairlists"` - being a list to specify a sequence of pairlists. The former `"pairlist"` section in the configuration has been removed, and is replaced by `"pairlists"` - being a list to specify a sequence of pairlists.
@@ -34,7 +38,7 @@ The old section of configuration parameters (`"pairlist"`) has been deprecated i
Since only quoteVolume can be compared between assets, the other options (bidVolume, askVolume) have been deprecated in 2020.4, and have been removed in 2020.9. Since only quoteVolume can be compared between assets, the other options (bidVolume, askVolume) have been deprecated in 2020.4, and have been removed in 2020.9.
### Using order book steps for sell price ### Using order book steps for exit price
Using `order_book_min` and `order_book_max` used to allow stepping the orderbook and trying to find the next ROI slot - trying to place sell-orders early. Using `order_book_min` and `order_book_max` used to allow stepping the orderbook and trying to find the next ROI slot - trying to place sell-orders early.
As this does however increase risk and provides no benefit, it's been removed for maintainability purposes in 2021.7. As this does however increase risk and provides no benefit, it's been removed for maintainability purposes in 2021.7.
@@ -43,3 +47,30 @@ As this does however increase risk and provides no benefit, it's been removed fo
Using separate hyperopt files was deprecated in 2021.4 and was removed in 2021.9. Using separate hyperopt files was deprecated in 2021.4 and was removed in 2021.9.
Please switch to the new [Parametrized Strategies](hyperopt.md) to benefit from the new hyperopt interface. Please switch to the new [Parametrized Strategies](hyperopt.md) to benefit from the new hyperopt interface.
## Strategy changes between V2 and V3
Isolated Futures / short trading was introduced in 2022.4. This required major changes to configuration settings, strategy interfaces, ...
We have put a great effort into keeping compatibility with existing strategies, so if you just want to continue using freqtrade in spot markets, there are no changes necessary.
While we may drop support for the current interface sometime in the future, we will announce this separately and have an appropriate transition period.
Please follow the [Strategy migration](strategy_migration.md) guide to migrate your strategy to the new format to start using the new functionalities.
### webhooks - changes with 2022.4
#### `buy_tag` has been renamed to `enter_tag`
This should apply only to your strategy and potentially to webhooks.
We will keep a compatibility layer for 1-2 versions (so both `buy_tag` and `enter_tag` will still work), but support for this in webhooks will disappear after that.
#### Naming changes
Webhook terminology changed from "sell" to "exit", and from "buy" to "entry".
* `webhookbuy` -> `webhookentry`
* `webhookbuyfill` -> `webhookentryfill`
* `webhookbuycancel` -> `webhookentrycancel`
* `webhooksell` -> `webhookexit`
* `webhooksellfill` -> `webhookexitfill`
* `webhooksellcancel` -> `webhookexitcancel`

View File

@@ -26,6 +26,9 @@ Alternatively (e.g. if your system is not supported by the setup.sh script), fol
This will install all required tools for development, including `pytest`, `flake8`, `mypy`, and `coveralls`. This will install all required tools for development, including `pytest`, `flake8`, `mypy`, and `coveralls`.
Then install the git hook scripts by running `pre-commit install`, so your changes will be verified locally before committing.
This avoids a lot of waiting for CI already, as some basic formatting checks are done locally on your machine.
Before opening a pull request, please familiarize yourself with our [Contributing Guidelines](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md). Before opening a pull request, please familiarize yourself with our [Contributing Guidelines](https://github.com/freqtrade/freqtrade/blob/develop/CONTRIBUTING.md).
### Devcontainer setup ### Devcontainer setup
@@ -65,6 +68,36 @@ def test_method_to_test(caplog):
``` ```
### Debug configuration
To debug freqtrade, we recommend VSCode with the following launch configuration (located in `.vscode/launch.json`).
Details will obviously vary between setups - but this should work to get you started.
``` json
{
"name": "freqtrade trade",
"type": "python",
"request": "launch",
"module": "freqtrade",
"console": "integratedTerminal",
"args": [
"trade",
// Optional:
// "--userdir", "user_data",
"--strategy",
"MyAwesomeStrategy",
]
},
```
Command line arguments can be added in the `"args"` array.
This method can also be used to debug a strategy, by setting the breakpoints within the strategy.
A similar setup can also be taken for Pycharm - using `freqtrade` as module name, and setting the command line arguments as "parameters".
!!! Note "Startup directory"
This assumes that you have the repository checked out, and the editor is started at the repository root level (so setup.py is at the top level of your repository).
## ErrorHandling ## ErrorHandling
Freqtrade Exceptions all inherit from `FreqtradeException`. Freqtrade Exceptions all inherit from `FreqtradeException`.
@@ -197,11 +230,12 @@ For that reason, they must implement the following methods:
* `global_stop()` * `global_stop()`
* `stop_per_pair()`. * `stop_per_pair()`.
`global_stop()` and `stop_per_pair()` must return a ProtectionReturn tuple, which consists of: `global_stop()` and `stop_per_pair()` must return a ProtectionReturn object, which consists of:
* lock pair - boolean * lock pair - boolean
* lock until - datetime - until when should the pair be locked (will be rounded up to the next new candle) * 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 * reason - string, used for logging and storage in the database
* lock_side - long, short or '*'.
The `until` portion should be calculated using the provided `calculate_lock_end()` method. The `until` portion should be calculated using the provided `calculate_lock_end()` method.
@@ -220,13 +254,13 @@ Protections can have 2 different ways to stop trading for a limited :
##### Protections - per pair ##### Protections - per pair
Protections that implement the per pair approach must set `has_local_stop=True`. 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). The method `stop_per_pair()` will be called whenever a trade closed (exit order completed).
##### Protections - global protection ##### 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). 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. 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). The method `global_stop()` will be called whenever a trade closed (exit order completed).
##### Protections - calculating lock end time ##### Protections - calculating lock end time
@@ -264,7 +298,7 @@ Additional tests / steps to complete:
* Check if balance shows correctly (*) * Check if balance shows correctly (*)
* Create market order (*) * Create market order (*)
* Create limit order (*) * Create limit order (*)
* Complete trade (buy + sell) (*) * Complete trade (enter + exit) (*)
* Compare result calculation between exchange and bot * Compare result calculation between exchange and bot
* Ensure fees are applied correctly (check the database against the exchange) * Ensure fees are applied correctly (check the database against the exchange)
@@ -310,6 +344,32 @@ The output will show the last entry from the Exchange as well as the current UTC
If the day shows the same day, then the last candle can be assumed as incomplete and should be dropped (leave the setting `"ohlcv_partial_candle"` from the exchange-class untouched / True). Otherwise, set `"ohlcv_partial_candle"` to `False` to not drop Candles (shown in the example above). If the day shows the same day, then the last candle can be assumed as incomplete and should be dropped (leave the setting `"ohlcv_partial_candle"` from the exchange-class untouched / True). Otherwise, set `"ohlcv_partial_candle"` to `False` to not drop Candles (shown in the example above).
Another way is to run this command multiple times in a row and observe if the volume is changing (while the date remains the same). Another way is to run this command multiple times in a row and observe if the volume is changing (while the date remains the same).
### Update binance cached leverage tiers
Updating leveraged tiers should be done regularly - and requires an authenticated account with futures enabled.
``` python
import ccxt
import json
from pathlib import Path
exchange = ccxt.binance({
'apiKey': '<apikey>',
'secret': '<secret>'
'options': {'defaultType': 'future'}
})
_ = exchange.load_markets()
lev_tiers = exchange.fetch_leverage_tiers()
# Assumes this is running in the root of the repository.
file = Path('freqtrade/exchange/binance_leverage_tiers.json')
json.dump(dict(sorted(lev_tiers.items())), file.open('w'), indent=2)
```
This file should then be contributed upstream, so others can benefit from this, too.
## Updating example notebooks ## Updating example notebooks
To keep the jupyter notebooks aligned with the documentation, the following should be ran after updating a example notebook. To keep the jupyter notebooks aligned with the documentation, the following should be ran after updating a example notebook.

View File

@@ -222,7 +222,7 @@ usage: freqtrade edge [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME -i TIMEFRAME, --timeframe TIMEFRAME
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`). Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
--timerange TIMERANGE --timerange TIMERANGE
Specify what timerange of data to use. Specify what timerange of data to use.

View File

@@ -1,6 +1,6 @@
# Exchange-specific Notes # Exchange-specific Notes
This page combines common gotchas and informations which are exchange-specific and most likely don't apply to other exchanges. This page combines common gotchas and Information which are exchange-specific and most likely don't apply to other exchanges.
## Exchange configuration ## Exchange configuration
@@ -57,13 +57,35 @@ This configuration enables kraken, as well as rate-limiting to avoid bans from t
Binance supports [time_in_force](configuration.md#understand-order_time_in_force). Binance supports [time_in_force](configuration.md#understand-order_time_in_force).
!!! Tip "Stoploss on Exchange" !!! Tip "Stoploss on Exchange"
Binance supports `stoploss_on_exchange` and uses stop-loss-limit orders. It provides great advantages, so we recommend to benefit from it. Binance supports `stoploss_on_exchange` and uses `stop-loss-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange..
### Binance Blacklist ### Binance Blacklist
For Binance, please add `"BNB/<STAKE>"` to your blacklist to avoid issues. For Binance, please add `"BNB/<STAKE>"` to your blacklist to avoid issues.
Accounts having BNB accounts use this to pay for fees - if your first trade happens to be on `BNB`, further trades will consume this position and make the initial BNB trade unsellable as the expected amount is not there anymore. Accounts having BNB accounts use this to pay for fees - if your first trade happens to be on `BNB`, further trades will consume this position and make the initial BNB trade unsellable as the expected amount is not there anymore.
### Binance Futures
Binance has specific (unfortunately complex) [Futures Trading Quantitative Rules](https://www.binance.com/en/support/faq/4f462ebe6ff445d4a170be7d9e897272) which need to be followed, and which prohibit a too low stake-amount (among others) for too many orders.
Violating these rules will result in a trading restriction.
When trading on Binance Futures market, orderbook must be used because there is no price ticker data for futures.
``` jsonc
"entry_pricing": {
"use_order_book": true,
"order_book_top": 1,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"exit_pricing": {
"use_order_book": true,
"order_book_top": 1
},
```
### Binance sites ### Binance sites
Binance has been split into 2, and users must use the correct ccxt exchange ID for their exchange, otherwise API keys are not recognized. Binance has been split into 2, and users must use the correct ccxt exchange ID for their exchange, otherwise API keys are not recognized.
@@ -177,12 +199,21 @@ Kucoin requires a passphrase for each api key, you will therefore need to add th
Kucoin supports [time_in_force](configuration.md#understand-order_time_in_force). Kucoin supports [time_in_force](configuration.md#understand-order_time_in_force).
!!! Tip "Stoploss on Exchange"
Kucoin 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 of stoploss shall be used.
### Kucoin Blacklists ### Kucoin Blacklists
For Kucoin, please add `"KCS/<STAKE>"` to your blacklist to avoid issues. For Kucoin, please add `"KCS/<STAKE>"` to your blacklist to avoid issues.
Accounts having KCS accounts use this to pay for fees - if your first trade happens to be on `KCS`, further trades will consume this position and make the initial KCS trade unsellable as the expected amount is not there anymore. Accounts having KCS accounts use this to pay for fees - if your first trade happens to be on `KCS`, further trades will consume this position and make the initial KCS trade unsellable as the expected amount is not there anymore.
## OKX ## Huobi
!!! Tip "Stoploss on Exchange"
Huobi supports `stoploss_on_exchange` and uses `stop-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange.
## OKX (former OKEX)
OKX requires a passphrase for each api key, you will therefore need to add this key into the configuration so your exchange section looks as follows: OKX requires a passphrase for each api key, you will therefore need to add this key into the configuration so your exchange section looks as follows:
@@ -199,8 +230,16 @@ OKX requires a passphrase for each api key, you will therefore need to add this
!!! Warning !!! Warning
OKX only provides 100 candles per api call. Therefore, the strategy will only have a pretty low amount of data available in backtesting mode. OKX only provides 100 candles per api call. Therefore, the strategy will only have a pretty low amount of data available in backtesting mode.
!!! Warning "Futures"
OKX Futures has the concept of "position mode" - which can be Net or long/short (hedge mode).
Freqtrade supports both modes - but changing the mode mid-trading is not supported and will lead to exceptions and failures to place trades.
OKX also only provides MARK candles for the past ~3 months. Backtesting futures prior to that date will therefore lead to slight deviations, as funding-fees cannot be calculated correctly without this data.
## Gate.io ## Gate.io
!!! Tip "Stoploss on Exchange"
Gate.io supports `stoploss_on_exchange` and uses `stop-loss-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange..
Gate.io allows the use of `POINT` to pay for fees. As this is not a tradable currency (no regular market available), automatic fee calculations will fail (and default to a fee of 0). Gate.io allows the use of `POINT` to pay for fees. As this is not a tradable currency (no regular market available), automatic fee calculations will fail (and default to a fee of 0).
The configuration parameter `exchange.unknown_fee_rate` can be used to specify the exchange rate between Point and the stake currency. Obviously, changing the stake-currency will also require changes to this value. The configuration parameter `exchange.unknown_fee_rate` can be used to specify the exchange rate between Point and the stake currency. Obviously, changing the stake-currency will also require changes to this value.

View File

@@ -6,13 +6,15 @@ Freqtrade supports spot trading only.
### Can I open short positions? ### Can I open short positions?
No, Freqtrade does not support trading with margin / leverage, and cannot open short positions. Freqtrade can open short positions in futures markets.
This requires the strategy to be made for this - and `"trading_mode": "futures"` in the configuration.
Please make sure to read the [relevant documentation page](leverage.md) first.
In some cases, your exchange may provide leveraged spot tokens which can be traded with Freqtrade eg. BTCUP/USD, BTCDOWN/USD, ETHBULL/USD, ETHBEAR/USD, etc... In spot markets, you can in some cases use leveraged spot tokens, which reflect an inverted pair (eg. BTCUP/USD, BTCDOWN/USD, ETHBULL/USD, ETHBEAR/USD,...) which can be traded with Freqtrade.
### Can I trade options or futures? ### Can I trade options or futures?
No, options and futures trading are not supported. Futures trading is supported for selected exchanges.
## Beginner Tips & Tricks ## Beginner Tips & Tricks
@@ -77,7 +79,7 @@ You can use "current" market data by using the [dataprovider](strategy-customiza
### Is there a setting to only SELL the coins being held and not perform anymore BUYS? ### Is there a setting to only SELL the coins being held and not perform anymore BUYS?
You can use the `/stopbuy` command in Telegram to prevent future buys, followed by `/forcesell all` (sell all open trades). You can use the `/stopbuy` command in Telegram to prevent future buys, followed by `/forceexit all` (sell all open trades).
### I want to run multiple bots on the same machine ### I want to run multiple bots on the same machine
@@ -117,10 +119,10 @@ As the message says, your exchange does not support market orders and you have o
To fix this, redefine order types in the strategy to use "limit" instead of "market": To fix this, redefine order types in the strategy to use "limit" instead of "market":
``` ``` python
order_types = { order_types = {
... ...
'stoploss': 'limit', "stoploss": "limit",
... ...
} }
``` ```

769
docs/freqai.md Normal file
View File

@@ -0,0 +1,769 @@
![freqai-logo](assets/freqai_doc_logo.svg)
# FreqAI
FreqAI is a module designed to automate a variety of tasks associated with training a predictive model to generate market forecasts given a set of input features.
Among the the features included:
* **Self-adaptive retraining**: retrain models during live deployments to self-adapt to the market in an unsupervised manner.
* **Rapid feature engineering**: create large rich feature sets (10k+ features) based on simple user created strategies.
* **High performance**: adaptive retraining occurs on separate thread (or on GPU if available) from inferencing and bot trade operations. Keep newest models and data in memory for rapid inferencing.
* **Realistic backtesting**: emulate self-adaptive retraining with backtesting module that automates past retraining.
* **Modifiable**: use the generalized and robust architecture for incorporating any machine learning library/method available in Python. Seven examples available.
* **Smart outlier removal**: remove outliers from training and prediction sets using a variety of outlier detection techniques.
* **Crash resilience**: model storage to disk to make reloading from a crash fast and easy (and purge obsolete files for sustained dry/live runs).
* **Automated data normalization**: normalize the data in a smart and statistically safe way.
* **Automatic data download**: compute the data download timerange and update historic data (in live deployments).
* **Clean incoming data** safe NaN handling before training and prediction.
* **Dimensionality reduction**: reduce the size of the training data via Principal Component Analysis.
* **Deploy bot fleets**: set one bot to train models while a fleet of other bots inference into the models and handle trades.
## Quick start
The easiest way to quickly test FreqAI is to run it in dry run with the following command
```bash
freqtrade trade --config config_examples/config_freqai.example.json --strategy FreqaiExampleStrategy --freqaimodel LightGBMRegressor --strategy-path freqtrade/templates
```
where the user will see the boot-up process of auto-data downloading, followed by simultaneous training and trading.
The example strategy, example prediction model, and example config can all be found in
`freqtrade/templates/FreqaiExampleStrategy.py`, `freqtrade/freqai/prediction_models/LightGBMRegressor.py`,
`config_examples/config_freqai.example.json`, respectively.
## General approach
The user provides FreqAI with a set of custom *base* indicators (created inside the strategy the same way
a typical Freqtrade strategy is created) as well as target values which look into the future.
FreqAI trains a model to predict the target value based on the input of custom indicators for each pair in the whitelist. These models are consistently retrained to adapt to market conditions. FreqAI offers the ability to both backtest strategies (emulating reality with periodic retraining) and deploy dry/live. In dry/live conditions, FreqAI can be set to constant retraining in a background thread in an effort to keep models as young as possible.
An overview of the algorithm is shown here to help users understand the data processing pipeline and the model usage.
![freqai-algo](assets/freqai_algo.png)
## Background and vocabulary
**Features** are the quantities with which a model is trained. $X_i$ represents the
vector of all features for a single candle. In FreqAI, the user
builds the features from anything they can construct in the strategy.
**Labels** are the target values with which the weights inside a model are trained
toward. Each set of features is associated with a single label, which is also
defined within the strategy by the user. These labels intentionally look into the
future, and are not available to the model during dryrun/live/backtesting.
**Training** refers to the process of feeding individual feature sets into the
model with associated labels with the goal of matching input feature sets to associated labels.
**Train data** is a subset of the historic data which is fed to the model during
training to adjust weights. This data directly influences weight connections in the model.
**Test data** is a subset of the historic data which is used to evaluate the
intermediate performance of the model during training. This data does not
directly influence nodal weights within the model.
## Install prerequisites
The normal Freqtrade install process will ask the user if they wish to install FreqAI dependencies. The user should reply "yes" to this question if they wish to use FreqAI. If the user did not reply yes, they can manually install these dependencies after the install with:
``` bash
pip install -r requirements-freqai.txt
```
!!! Note
Catboost will not be installed on arm devices (raspberry, Mac M1, ARM based VPS, ...), since Catboost does not provide wheels for this platform.
### Usage with docker
For docker users, a dedicated tag with freqAI dependencies is available as `:freqai`.
As such - you can replace the image line in your docker-compose file with `image: freqtradeorg/freqtrade:develop_freqai`.
This image contains the regular freqAI dependencies. Similar to native installs, Catboost will not be available on ARM based devices.
## Configuring FreqAI
### Parameter table
The table below will list all configuration parameters available for FreqAI.
Mandatory parameters are marked as **Required**, which means that they are required to be set in one of the possible ways.
| Parameter | Description |
|------------|-------------|
| `freqai` | **Required.** The parent dictionary containing all the parameters below for controlling FreqAI. <br> **Datatype:** dictionary.
| `identifier` | **Required.** A unique name for the current model. This can be reused to reload pre-trained models/data. <br> **Datatype:** string.
| `train_period_days` | **Required.** Number of days to use for the training data (width of the sliding window). <br> **Datatype:** positive integer.
| `backtest_period_days` | **Required.** Number of days to inference into the trained model before sliding the window and retraining. This can be fractional days, but beware that the user provided `timerange` will be divided by this number to yield the number of trainings necessary to complete the backtest. <br> **Datatype:** Float.
| `live_retrain_hours` | Frequency of retraining during dry/live runs. Default set to 0, which means it will retrain as often as possible. <br> **Datatype:** Float > 0.
| `follow_mode` | If true, this instance of FreqAI will look for models associated with `identifier` and load those for inferencing. A `follower` will **not** train new models. `False` by default. <br> **Datatype:** boolean.
| `startup_candles` | Number of candles needed for *backtesting only* to ensure all indicators are non NaNs at the start of the first train period. <br> **Datatype:** positive integer.
| `fit_live_predictions_candles` | Computes target (label) statistics from prediction data, instead of from the training data set. Number of candles is the number of historical candles it uses to generate the statistics. <br> **Datatype:** positive integer.
| `purge_old_models` | Tell FreqAI to delete obsolete models. Otherwise, all historic models will remain on disk. Defaults to `False`. <br> **Datatype:** boolean.
| `expiration_hours` | Ask FreqAI to avoid making predictions if a model is more than `expiration_hours` old. Defaults to 0 which means models never expire. <br> **Datatype:** positive integer.
| | **Feature Parameters**
| `feature_parameters` | A dictionary containing the parameters used to engineer the feature set. Details and examples shown [here](#feature-engineering) <br> **Datatype:** dictionary.
| `include_corr_pairlist` | A list of correlated coins that FreqAI will add as additional features to all `pair_whitelist` coins. All indicators set in `populate_any_indicators` will be created for each coin in this list, and that set of features is added to the base asset feature set. <br> **Datatype:** list of assets (strings).
| `include_timeframes` | A list of timeframes that all indicators in `populate_any_indicators` will be created for and added as features to the base asset feature set. <br> **Datatype:** list of timeframes (strings).
| `label_period_candles` | Number of candles into the future that the labels are created for. This is used in `populate_any_indicators`, refer to `templates/FreqaiExampleStrategy.py` for detailed usage. The user can create custom labels, making use of this parameter not. <br> **Datatype:** positive integer.
| `include_shifted_candles` | Parameter used to add a sense of temporal recency to flattened regression type input data. `include_shifted_candles` takes all features, duplicates and shifts them by the number indicated by user. <br> **Datatype:** positive integer.
| `DI_threshold` | Activates the Dissimilarity Index for outlier detection when above 0, explained in detail [here](#removing-outliers-with-the-dissimilarity-index). <br> **Datatype:** positive float (typically below 1).
| `weight_factor` | Used to set weights for training data points according to their recency, see details and a figure of how it works [here](#controlling-the-model-learning-process). <br> **Datatype:** positive float (typically below 1).
| `principal_component_analysis` | Ask FreqAI to automatically reduce the dimensionality of the data set using PCA. <br> **Datatype:** boolean.
| `use_SVM_to_remove_outliers` | Ask FreqAI to train a support vector machine to detect and remove outliers from the training data set as well as from incoming data points. <br> **Datatype:** boolean.
| `svm_params` | All parameters available in Sklearn's `SGDOneClassSVM()`. E.g. `nu` *Very* broadly, is the percentage of data points that should be considered outliers. `shuffle` is by default false to maintain reproducibility. But these and all others can be added/changed in this dictionary. <br> **Datatype:** dictionary.
| `stratify_training_data` | This value is used to indicate the stratification of the data. e.g. 2 would set every 2nd data point into a separate dataset to be pulled from during training/testing. <br> **Datatype:** positive integer.
| `indicator_max_period_candles` | The maximum *period* used in `populate_any_indicators()` for indicator creation. FreqAI uses this information in combination with the maximum timeframe to calculate how many data points it should download so that the first data point does not have a NaN <br> **Datatype:** positive integer.
| `indicator_periods_candles` | A list of integers used to duplicate all indicators according to a set of periods and add them to the feature set. <br> **Datatype:** list of positive integers.
| `use_DBSCAN_to_remove_outliers` | Inactive by default. If true, FreqAI clusters data using DBSCAN to identify and remove outliers from training and prediction data. <br> **Datatype:** float (fraction of 1).
| | **Data split parameters**
| `data_split_parameters` | Include any additional parameters available from Scikit-learn `test_train_split()`, which are shown [here](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) <br> **Datatype:** dictionary.
| `test_size` | Fraction of data that should be used for testing instead of training. <br> **Datatype:** positive float below 1.
| `shuffle` | Shuffle the training data points during training. Typically for time-series forecasting, this is set to False. <br> **Datatype:** boolean.
| | **Model training parameters**
| `model_training_parameters` | A flexible dictionary that includes all parameters available by the user selected library. For example, if the user uses `LightGBMRegressor`, then this dictionary can contain any parameter available by the `LightGBMRegressor` [here](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMRegressor.html). If the user selects a different model, then this dictionary can contain any parameter from that different model. <br> **Datatype:** dictionary.
| `n_estimators` | A common parameter among regressors which sets the number of boosted trees to fit <br> **Datatype:** integer.
| `learning_rate` | A common parameter among regressors which sets the boosting learning rate. <br> **Datatype:** float.
| `n_jobs`, `thread_count`, `task_type` | Different libraries use different parameter names to control the number of threads used for parallel processing or whether or not it is a `task_type` of `gpu` or `cpu`. <br> **Datatype:** float.
| | **Extraneous parameters**
| `keras` | If your model makes use of keras (typical of Tensorflow based prediction models), activate this flag so that the model save/loading follows keras standards. Default value `false` <br> **Datatype:** boolean.
| `conv_width` | The width of a convolutional neural network input tensor. This replaces the need for `shift` by feeding in historical data points as the second dimension of the tensor. Technically, this parameter can also be used for regressors, but it only adds computational overhead and does not change the model training/prediction. Default value, 2 <br> **Datatype:** integer.
### Important FreqAI dataframe key patterns
Here are the values the user can expect to include/use inside the typical strategy dataframe (`df[]`):
| DataFrame Key | Description |
|------------|-------------|
| `df['&*']` | Any dataframe column prepended with `&` in `populate_any_indicators()` is treated as a training target inside FreqAI (typically following the naming convention `&-s*`). These same dataframe columns names are fed back to the user as the predictions. For example, the user wishes to predict the price change in the next 40 candles (similar to `templates/FreqaiExampleStrategy.py`) by setting `df['&-s_close']`. FreqAI makes the predictions and gives them back to the user under the same key (`df['&-s_close']`) to be used in `populate_entry/exit_trend()`. <br> **Datatype:** depends on the output of the model.
| `df['&*_std/mean']` | The standard deviation and mean values of the user defined labels during training (or live tracking with `fit_live_predictions_candles`). Commonly used to understand rarity of prediction (use the z-score as shown in `templates/FreqaiExampleStrategy.py` to evaluate how often a particular prediction was observed during training (or historically with `fit_live_predictions_candles`)<br> **Datatype:** float.
| `df['do_predict']` | An indication of an outlier, this return value is integer between -1 and 2 which lets the user understand if the prediction is trustworthy or not. `do_predict==1` means the prediction is trustworthy. If the [Dissimilarity Index](#removing-outliers-with-the-dissimilarity-index) is above the user defined threshold, it will subtract 1 from `do_predict`. If `use_SVM_to_remove_outliers()` is active, then the Support Vector Machine (SVM) may also detect outliers in training and prediction data. In this case, the SVM will also subtract one from `do_predict`. A particular case is when `do_predict == 2`, it means that the model has expired due to `expired_hours`. <br> **Datatype:** integer between -1 and 2.
| `df['DI_values']` | The raw Dissimilarity Index values to give the user a sense of confidence in the prediction. Lower DI means the data point is closer to the trained parameter space. <br> **Datatype:** float.
| `df['%*']` | Any dataframe column prepended with `%` in `populate_any_indicators()` is treated as a training feature inside FreqAI. For example, the user can include the rsi in the training feature set (similar to `templates/FreqaiExampleStrategy.py`) by setting `df['%-rsi']`. See more details on how this is done [here](#building-the-feature-set). <br>**Note**: since the number of features prepended with `%` can multiply very quickly (10s of thousands of features is easily engineered using the multiplictative functionality described in the `feature_parameters` table.) these features are removed from the dataframe upon return from FreqAI. If the user wishes to keep a particular type of feature for plotting purposes, you can prepend it with `%%`. <br> **Datatype:** depends on the output of the model.
### Example config file
The user interface is isolated to the typical config file. A typical FreqAI config setup could include:
```json
"freqai": {
"startup_candles": 10000,
"purge_old_models": true,
"train_period_days": 30,
"backtest_period_days": 7,
"identifier" : "unique-id",
"feature_parameters" : {
"include_timeframes": ["5m","15m","4h"],
"include_corr_pairlist": [
"ETH/USD",
"LINK/USD",
"BNB/USD"
],
"label_period_candles": 24,
"include_shifted_candles": 2,
"weight_factor": 0,
"indicator_max_period_candles": 20,
"indicator_periods_candles": [10, 20]
},
"data_split_parameters" : {
"test_size": 0.25,
"random_state": 42
},
"model_training_parameters" : {
"n_estimators": 100,
"random_state": 42,
"learning_rate": 0.02,
"task_type": "CPU",
},
}
```
### Feature engineering
Features are added by the user inside the `populate_any_indicators()` method of the strategy
by prepending indicators with `%` and labels are added by prepending `&`.
There are some important components/structures that the user *must* include when building their feature set.
Another structure to consider is the location of the labels at the bottom of the example function (below `if set_generalized_indicators:`).
This is where the user will add single features and labels to their feature set to avoid duplication from
various configuration parameters which multiply the feature set such as `include_timeframes`.
```python
def populate_any_indicators(
self, pair, df, tf, informative=None, set_generalized_indicators=False
):
"""
Function designed to automatically generate, name and merge features
from user indicated timeframes in the configuration file. User controls the indicators
passed to the training/prediction by prepending indicators with `'%-' + coin `
(see convention below). I.e. user should not prepend any supporting metrics
(e.g. bb_lowerband below) with % unless they explicitly want to pass that metric to the
model.
:param pair: pair to be used as informative
:param df: strategy dataframe which will receive merges from informatives
:param tf: timeframe of the dataframe which will modify the feature names
:param informative: the dataframe associated with the informative pair
:param coin: the name of the coin which will modify the feature names.
"""
coint = pair.split('/')[0]
if informative is None:
informative = self.dp.get_pair_dataframe(pair, tf)
# first loop is automatically duplicating indicators for time periods
for t in self.freqai_info["feature_parameters"]["indicator_periods_candles"]:
t = int(t)
informative[f"%-{coin}rsi-period_{t}"] = ta.RSI(informative, timeperiod=t)
informative[f"%-{coin}mfi-period_{t}"] = ta.MFI(informative, timeperiod=t)
informative[f"%-{coin}adx-period_{t}"] = ta.ADX(informative, window=t)
bollinger = qtpylib.bollinger_bands(
qtpylib.typical_price(informative), window=t, stds=2.2
)
informative[f"{coin}bb_lowerband-period_{t}"] = bollinger["lower"]
informative[f"{coin}bb_middleband-period_{t}"] = bollinger["mid"]
informative[f"{coin}bb_upperband-period_{t}"] = bollinger["upper"]
informative[f"%-{coin}bb_width-period_{t}"] = (
informative[f"{coin}bb_upperband-period_{t}"]
- informative[f"{coin}bb_lowerband-period_{t}"]
) / informative[f"{coin}bb_middleband-period_{t}"]
informative[f"%-{coin}close-bb_lower-period_{t}"] = (
informative["close"] / informative[f"{coin}bb_lowerband-period_{t}"]
)
informative[f"%-{coin}relative_volume-period_{t}"] = (
informative["volume"] / informative["volume"].rolling(t).mean()
)
indicators = [col for col in informative if col.startswith("%")]
# This loop duplicates and shifts all indicators to add a sense of recency to data
for n in range(self.freqai_info["feature_parameters"]["include_shifted_candles"] + 1):
if n == 0:
continue
informative_shift = informative[indicators].shift(n)
informative_shift = informative_shift.add_suffix("_shift-" + str(n))
informative = pd.concat((informative, informative_shift), axis=1)
df = merge_informative_pair(df, informative, self.config["timeframe"], tf, ffill=True)
skip_columns = [
(s + "_" + tf) for s in ["date", "open", "high", "low", "close", "volume"]
]
df = df.drop(columns=skip_columns)
# Add generalized indicators here (because in live, it will call this
# function to populate indicators during training). Notice how we ensure not to
# add them multiple times
if set_generalized_indicators:
df["%-day_of_week"] = (df["date"].dt.dayofweek + 1) / 7
df["%-hour_of_day"] = (df["date"].dt.hour + 1) / 25
# user adds targets here by prepending them with &- (see convention below)
# If user wishes to use multiple targets, a multioutput prediction model
# needs to be used such as templates/CatboostPredictionMultiModel.py
df["&-s_close"] = (
df["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ df["close"]
- 1
)
return df
```
The user of the present example does not wish to pass the `bb_lowerband` as a feature to the model,
and has therefore not prepended it with `%`. The user does, however, wish to pass `bb_width` to the
model for training/prediction and has therefore prepended it with `%`.
The `include_timeframes` from the example config above are the timeframes (`tf`) of each call to `populate_any_indicators()`
included metric for inclusion in the feature set. In the present case, the user is asking for the
`5m`, `15m`, and `4h` timeframes of the `rsi`, `mfi`, `roc`, and `bb_width` to be included in the feature set.
In addition, the user can ask for each of these features to be included from
informative pairs using the `include_corr_pairlist`. This means that the present feature
set will include all the features from `populate_any_indicators` on all the `include_timeframes` for each of
`ETH/USD`, `LINK/USD`, and `BNB/USD`.
`include_shifted_candles` is another user controlled parameter which indicates the number of previous
candles to include in the present feature set. In other words, `include_shifted_candles: 2`, tells
FreqAI to include the the past 2 candles for each of the features included in the dataset.
In total, the number of features the present user has created is:
length of `include_timeframes` * no. features in `populate_any_indicators()` * length of `include_corr_pairlist` * no. `include_shifted_candles` * length of `indicator_periods_candles`
$3 * 3 * 3 * 2 * 2 = 108$.
!!! Note
Features **must** be defined in `populate_any_indicators()`. Making features in `populate_indicators()`
will fail in live/dry mode. If the user wishes to add generalized features that are not associated with
a specific pair or timeframe, they should use the following structure inside `populate_any_indicators()`
(as exemplified in `freqtrade/templates/FreqaiExampleStrategy.py`:
```python
def populate_any_indicators(self, metadata, pair, df, tf, informative=None, coin="", set_generalized_indicators=False):
...
# Add generalized indicators here (because in live, it will call only this function to populate
# indicators for retraining). Notice how we ensure not to add them multiple times by associating
# these generalized indicators to the basepair/timeframe
if set_generalized_indicators:
df['%-day_of_week'] = (df["date"].dt.dayofweek + 1) / 7
df['%-hour_of_day'] = (df['date'].dt.hour + 1) / 25
# user adds targets here by prepending them with &- (see convention below)
# If user wishes to use multiple targets, a multioutput prediction model
# needs to be used such as templates/CatboostPredictionMultiModel.py
df["&-s_close"] = (
df["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ df["close"]
- 1
)
```
(Please see the example script located in `freqtrade/templates/FreqaiExampleStrategy.py` for a full example of `populate_any_indicators()`)
### Deciding the sliding training window and backtesting duration
Users define the backtesting timerange with the typical `--timerange` parameter in the user
configuration file. `train_period_days` is the duration of the sliding training window, while
`backtest_period_days` is the sliding backtesting window, both in number of days (`backtest_period_days` can be
a float to indicate sub daily retraining in live/dry mode). In the present example,
the user is asking FreqAI to use a training period of 30 days and backtest the subsequent 7 days.
This means that if the user sets `--timerange 20210501-20210701`,
FreqAI will train 8 separate models (because the full range comprises 8 weeks),
and then backtest the subsequent week associated with each of the 8 training
data set timerange months. Users can think of this as a "sliding window" which
emulates FreqAI retraining itself once per week in live using the previous
month of data.
In live, the required training data is automatically computed and downloaded. However, in backtesting
the user must manually enter the required number of `startup_candles` in the config. This value
is used to increase the available data to FreqAI and should be sufficient to enable all indicators
to be NaN free at the beginning of the first training timerange. This boils down to identifying the
highest timeframe (`4h` in present example) and the longest indicator period (25 in present example)
and adding this to the `train_period_days`. The units need to be in the base candle time frame:
`startup_candles` = ( 4 hours * 25 max period * 60 minutes/hour + 30 day train_period_days * 1440 minutes per day ) / 5 min (base time frame) = 1488.
!!! Note
In dry/live, this is all precomputed and handled automatically. Thus, `startup_candle` has no influence on dry/live.
!!! Note
Although fractional `backtest_period_days` is allowed, the user should be ware that the `--timerange` is divided by this value to determine the number of models that FreqAI will need to train in order to backtest the full range. For example, if the user wants to set a `--timerange` of 10 days, and asks for a `backtest_period_days` of 0.1, FreqAI will need to train 100 models per pair to complete the full backtest. This is why it is physically impossible to truly backtest FreqAI adaptive training. The best way to fully test a model is to run it dry and let it constantly train. In this case, backtesting would take the exact same amount of time as a dry run.
## Running FreqAI
### Backtesting
The FreqAI backtesting module can be executed with the following command:
```bash
freqtrade backtesting --strategy FreqaiExampleStrategy --config config_freqai.example.json --freqaimodel LightGBMRegressor --timerange 20210501-20210701
```
Backtesting mode requires the user to have the data pre-downloaded (unlike dry/live, where FreqAI automatically downloads the necessary data). The user should be careful to consider that the range of the downloaded data is more than the backtesting range. This is because FreqAI needs data prior to the desired backtesting range in order to train a model to be ready to make predictions on the first candle of the user set backtesting range. More details on how to calculate the data download timerange can be found [here](#deciding-the-sliding-training-window-and-backtesting-duration).
If this command has never been executed with the existing config file, then it will train a new model
for each pair, for each backtesting window within the bigger `--timerange`.
!!! Note "Model reuse"
Once the training is completed, the user can execute this again with the same config file and
FreqAI will find the trained models and load them instead of spending time training. This is useful
if the user wants to tweak (or even hyperopt) buy and sell criteria inside the strategy. IF the user
*wants* to retrain a new model with the same config file, then he/she should simply change the `identifier`.
This way, the user can return to using any model they wish by simply changing the `identifier`.
---
### Building a freqai strategy
The FreqAI strategy requires the user to include the following lines of code in the strategy:
```python
def informative_pairs(self):
whitelist_pairs = self.dp.current_whitelist()
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
informative_pairs = []
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
for pair in whitelist_pairs:
informative_pairs.append((pair, tf))
for pair in corr_pairs:
if pair in whitelist_pairs:
continue # avoid duplication
informative_pairs.append((pair, tf))
return informative_pairs
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# All indicators must be populated by populate_any_indicators() for live functionality
# to work correctly.
# the model will return all labels created by user in `populate_any_indicators`
# (& appended targets), an indication of whether or not the prediction should be accepted,
# the target mean/std values for each of the labels created by user in
# `populate_any_indicators()` for each training period.
dataframe = self.freqai.start(dataframe, metadata, self)
return dataframe
def populate_any_indicators(
self, pair, df, tf, informative=None, set_generalized_indicators=False
):
"""
Function designed to automatically generate, name and merge features
from user indicated timeframes in the configuration file. User controls the indicators
passed to the training/prediction by prepending indicators with `'%-' + coin `
(see convention below). I.e. user should not prepend any supporting metrics
(e.g. bb_lowerband below) with % unless they explicitly want to pass that metric to the
model.
:param pair: pair to be used as informative
:param df: strategy dataframe which will receive merges from informatives
:param tf: timeframe of the dataframe which will modify the feature names
:param informative: the dataframe associated with the informative pair
:param coin: the name of the coin which will modify the feature names.
"""
coin = pair.split('/')[0]
if informative is None:
informative = self.dp.get_pair_dataframe(pair, tf)
# first loop is automatically duplicating indicators for time periods
for t in self.freqai_info["feature_parameters"]["indicator_periods_candles"]:
t = int(t)
informative[f"%-{coin}rsi-period_{t}"] = ta.RSI(informative, timeperiod=t)
informative[f"%-{coin}mfi-period_{t}"] = ta.MFI(informative, timeperiod=t)
informative[f"%-{coin}adx-period_{t}"] = ta.ADX(informative, window=t)
indicators = [col for col in informative if col.startswith("%")]
# This loop duplicates and shifts all indicators to add a sense of recency to data
for n in range(self.freqai_info["feature_parameters"]["include_shifted_candles"] + 1):
if n == 0:
continue
informative_shift = informative[indicators].shift(n)
informative_shift = informative_shift.add_suffix("_shift-" + str(n))
informative = pd.concat((informative, informative_shift), axis=1)
df = merge_informative_pair(df, informative, self.config["timeframe"], tf, ffill=True)
skip_columns = [
(s + "_" + tf) for s in ["date", "open", "high", "low", "close", "volume"]
]
df = df.drop(columns=skip_columns)
# Add generalized indicators here (because in live, it will call this
# function to populate indicators during training). Notice how we ensure not to
# add them multiple times
if set_generalized_indicators:
# user adds targets here by prepending them with &- (see convention below)
# If user wishes to use multiple targets, a multioutput prediction model
# needs to be used such as templates/CatboostPredictionMultiModel.py
df["&-s_close"] = (
df["close"]
.shift(-self.freqai_info["feature_parameters"]["label_period_candles"])
.rolling(self.freqai_info["feature_parameters"]["label_period_candles"])
.mean()
/ df["close"]
- 1
)
return df
```
Notice how the `populate_any_indicators()` is where the user adds their own features and labels ([more information](#feature-engineering)). See a full example at `templates/FreqaiExampleStrategy.py`.
### Setting classifier targets
FreqAI includes a the `CatboostClassifier` via the flag `--freqaimodel CatboostClassifier`. Typically, the user would set the targets using strings:
```python
df['&s-up_or_down'] = np.where( df["close"].shift(-100) > df["close"], 'up', 'down')
```
### Running the model live
FreqAI can be run dry/live using the following command
```bash
freqtrade trade --strategy FreqaiExampleStrategy --config config_freqai.example.json --freqaimodel LightGBMRegressor
```
By default, FreqAI will not find any existing models and will start by training a new one
given the user configuration settings. Following training, it will use that model to make predictions on incoming candles until a new model is available. New models are typically generated as often as possible, with FreqAI managing an internal queue of the pairs to try and keep all models equally "young." FreqAI will always use the newest trained model to make predictions on incoming live data. If users do not want FreqAI to retrain new models as often as possible, they can set `live_retrain_hours` to tell FreqAI to wait at least that number of hours before retraining a new model. Additionally, users can set `expired_hours` to tell FreqAI to avoid making predictions on models aged over this number of hours.
If the user wishes to start dry/live from a backtested saved model, the user only needs to reuse
the same `identifier` parameter
```json
"freqai": {
"identifier": "example",
"live_retrain_hours": 1
}
```
In this case, although FreqAI will initiate with a
pre-trained model, it will still check to see how much time has elapsed since the model was trained,
and if a full `live_retrain_hours` has elapsed since the end of the loaded model, FreqAI will self retrain.
## Data analysis techniques
### Controlling the model learning process
Model training parameters are unique to the ML library used by the user. FreqAI allows users to set any parameter for any library using the `model_training_parameters` dictionary in the user configuration file. The example configuration files show some of the example parameters associated with `Catboost` and `LightGBM`, but users can add any parameters available in those libraries.
Data split parameters are defined in `data_split_parameters` which can be any parameters associated with `Sklearn`'s `train_test_split()` function. FreqAI includes some additional parameters such `weight_factor` which allows the user to weight more recent data more strongly
than past data via an exponential function:
$$ W_i = \exp(\frac{-i}{\alpha*n}) $$
where $W_i$ is the weight of data point $i$ in a total set of $n$ data points.
![weight-factor](assets/weights_factor.png)
`train_test_split()` has a parameters called `shuffle`, which users also have access to in FreqAI, that allows them to keep the data unshuffled. This is particularly useful to avoid biasing training with temporally auto-correlated data.
Finally, `label_period_candles` defines the offset used for the `labels`. In the present example,
the user is asking for `labels` that are 24 candles in the future.
### Removing outliers with the Dissimilarity Index
The Dissimilarity Index (DI) aims to quantify the uncertainty associated with each
prediction by the model. To do so, FreqAI measures the distance between each training
data point and all other training data points:
$$ d_{ab} = \sqrt{\sum_{j=1}^p(X_{a,j}-X_{b,j})^2} $$
where $d_{ab}$ is the distance between the normalized points $a$ and $b$. $p$
is the number of features i.e. the length of the vector $X$.
The characteristic distance, $\overline{d}$ for a set of training data points is simply the mean
of the average distances:
$$ \overline{d} = \sum_{a=1}^n(\sum_{b=1}^n(d_{ab}/n)/n) $$
$\overline{d}$ quantifies the spread of the training data, which is compared to
the distance between the new prediction feature vectors, $X_k$ and all the training
data:
$$ d_k = \arg \min d_{k,i} $$
which enables the estimation of a Dissimilarity Index:
$$ DI_k = d_k/\overline{d} $$
Equity and crypto markets suffer from a high level of non-patterned noise in the
form of outlier data points. The dissimilarity index allows predictions which
are outliers and not existent in the model feature space, to be thrown out due
to low levels of certainty. Activating the Dissimilarity Index can be achieved with:
```json
"freqai": {
"feature_parameters" : {
"DI_threshold": 1
}
}
```
The user can tweak the DI with `DI_threshold` to increase or decrease the extrapolation of the trained model.
### Reducing data dimensionality with Principal Component Analysis
Users can reduce the dimensionality of their features by activating the `principal_component_analysis`:
```json
"freqai": {
"feature_parameters" : {
"principal_component_analysis": true
}
}
```
Which will perform PCA on the features and reduce the dimensionality of the data so that the explained
variance of the data set is >= 0.999.
### Removing outliers using a Support Vector Machine (SVM)
The user can tell FreqAI to remove outlier data points from the training/test data sets by setting:
```json
"freqai": {
"feature_parameters" : {
"use_SVM_to_remove_outliers": true
}
}
```
FreqAI will train an SVM on the training data (or components if the user activated
`principal_component_analysis`) and remove any data point that it deems to be sitting beyond the feature space.
### Clustering the training data and removing outliers with DBSCAN
The user can configure FreqAI to use DBSCAN to cluster training data and remove outliers from the training data set. The user activates `use_DBSCAN_to_remove_outliers` to cluster training data for identification of outliers. Also used to detect incoming outliers for prediction data points.
```json
"freqai": {
"feature_parameters" : {
"use_DBSCAN_to_remove_outliers": true
}
}
```
### Stratifying the data
The user can stratify the training/testing data using:
```json
"freqai": {
"feature_parameters" : {
"stratify_training_data": 3
}
}
```
which will split the data chronologically so that every Xth data points is a testing data point. In the
present example, the user is asking for every third data point in the dataframe to be used for
testing, the other points are used for training.
## Setting up a follower
The user can define:
```json
"freqai": {
"follow_mode": true,
"identifier": "example"
}
```
to indicate to the bot that it should not train models, but instead should look for models trained
by a leader with the same `identifier`. In this example, the user has a leader bot with the
`identifier: "example"` already running or launching simultaneously as the present follower.
The follower will load models created by the leader and inference them to obtain predictions.
## Purging old model data
FreqAI stores new model files each time it retrains. These files become obsolete as new models
are trained and FreqAI adapts to the new market conditions. Users planning to leave FreqAI running
for extended periods of time with high frequency retraining should set `purge_old_models` in their
config:
```json
"freqai": {
"purge_old_models": true,
}
```
which will automatically purge all models older than the two most recently trained ones.
## Defining model expirations
During dry/live, FreqAI trains each pair sequentially (on separate threads/GPU from the main
Freqtrade bot). This means there is always an age discrepancy between models. If a user is training
on 50 pairs, and each pair requires 5 minutes to train, the oldest model will be over 4 hours old.
This may be undesirable if the characteristic time scale (read trade duration target) for a strategy
is much less than 4 hours. The user can decide to only make trade entries if the model is less than
a certain number of hours in age by setting the `expiration_hours` in the config file:
```json
"freqai": {
"expiration_hours": 0.5,
}
```
In the present example, the user will only allow predictions on models that are less than 1/2 hours
old.
## Choosing the calculation of the `target_roi`
As shown in `templates/FreqaiExampleStrategy.py`, the `target_roi` is based on two metrics computed
by FreqAI: `label_mean` and `label_std`. These are the statistics associated with the labels used
*during the most recent training*.
This allows the model to know what magnitude of a target to be expecting since it is directly stemming from the training data.
By default, FreqAI computes this based on training data and it assumes the labels are Gaussian distributed.
These are big assumptions that the user should consider when creating their labels. If the user wants to consider the population
of *historical predictions* for creating the dynamic target instead of the trained labels, the user
can do so by setting `fit_live_prediction_candles` to the number of historical prediction candles
the user wishes to use to generate target statistics.
```json
"freqai": {
"fit_live_prediction_candles": 300,
}
```
If the user sets this value, FreqAI will initially use the predictions from the training data set
and then subsequently begin introducing real prediction data as it is generated. FreqAI will save
this historical data to be reloaded if the user stops and restarts with the same `identifier`.
## Extra returns per train
Users may find that there are some important metrics that they'd like to return to the strategy at the end of each retrain.
Users can include these metrics by assigning them to `dk.data['extra_returns_per_train']['my_new_value'] = XYZ` inside their custom prediction
model class. FreqAI takes the `my_new_value` assigned in this dictionary and expands it to fit the return dataframe to the strategy.
The user can then use the value in the strategy with `dataframe['my_new_value']`. An example of how this is already used in FreqAI is
the `&*_mean` and `&*_std` values, which indicate the mean and standard deviation of that particular label during the most recent training.
Another example is shown below if the user wants to use live metrics from the trade database.
The user needs to set the standard dictionary in the config so FreqAI can return proper dataframe shapes:
```json
"freqai": {
"extra_returns_per_train": {"total_profit": 4}
}
```
These values will likely be overridden by the user prediction model, but in the case where the user model has yet to set them, or needs
a default initial value - this is the value that will be returned.
## Building an IFreqaiModel
FreqAI has multiple example prediction model based libraries such as `Catboost` regression (`freqai/prediction_models/CatboostRegressor.py`) and `LightGBM` regression.
However, users can customize and create their own prediction models using the `IFreqaiModel` class.
Users are encouraged to inherit `train()` and `predict()` to let them customize various aspects of their training procedures.
## Additional information
### Common pitfalls
FreqAI cannot be combined with `VolumePairlists` (or any pairlist filter that adds and removes pairs dynamically).
This is for performance reasons - FreqAI relies on making quick predictions/retrains. To do this effectively,
it needs to download all the training data at the beginning of a dry/live instance. FreqAI stores and appends
new candles automatically for future retrains. But this means that if new pairs arrive later in the dry run due
to a volume pairlist, it will not have the data ready. FreqAI does work, however, with the `ShufflePairlist`.
### Feature normalization
The feature set created by the user is automatically normalized to the training data only.
This includes all test data and unseen prediction data (dry/live/backtest).
### File structure
`user_data_dir/models/` contains all the data associated with the trainings and backtests.
This file structure is heavily controlled and read by the `FreqaiDataKitchen()`
and should therefore not be modified.
## Credits
FreqAI was developed by a group of individuals who all contributed specific skillsets to the project.
Conception and software development:
Robert Caulk @robcaulk
Theoretical brainstorming:
Elin Törnquist @thorntwig
Code review, software architecture brainstorming:
@xmatthias
Beta testing and bug reporting:
@bloodhunter4rc, Salah Lamkadem @ikonx, @ken11o2, @longyu, @paranoidandy, @smidelis, @smarm
Juha Nykänen @suikula, Wagner Costa @wagnercosta

View File

@@ -40,13 +40,15 @@ pip install -r requirements-hyperopt.txt
``` ```
usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH] [--userdir PATH] [-s NAME] [--strategy-path PATH]
[-i TIMEFRAME] [--timerange TIMERANGE] [--recursive-strategy-search] [-i TIMEFRAME]
[--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}] [--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT] [--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT] [--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[-p PAIRS [PAIRS ...]] [--hyperopt-path PATH] [-p PAIRS [PAIRS ...]] [--hyperopt-path PATH]
[--eps] [--dmmp] [--enable-protections] [--eps] [--dmmp] [--enable-protections]
[--dry-run-wallet DRY_RUN_WALLET] [-e INT] [--dry-run-wallet DRY_RUN_WALLET]
[--timeframe-detail TIMEFRAME_DETAIL] [-e INT]
[--spaces {all,buy,sell,roi,stoploss,trailing,protection,default} [{all,buy,sell,roi,stoploss,trailing,protection,default} ...]] [--spaces {all,buy,sell,roi,stoploss,trailing,protection,default} [{all,buy,sell,roi,stoploss,trailing,protection,default} ...]]
[--print-all] [--no-color] [--print-json] [-j JOBS] [--print-all] [--no-color] [--print-json] [-j JOBS]
[--random-state INT] [--min-trades INT] [--random-state INT] [--min-trades INT]
@@ -55,7 +57,7 @@ usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME -i TIMEFRAME, --timeframe TIMEFRAME
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`). Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
--timerange TIMERANGE --timerange TIMERANGE
Specify what timerange of data to use. Specify what timerange of data to use.
@@ -89,6 +91,9 @@ optional arguments:
--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET --dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET
Starting balance, used for backtesting / hyperopt and Starting balance, used for backtesting / hyperopt and
dry-runs. dry-runs.
--timeframe-detail TIMEFRAME_DETAIL
Specify detail timeframe for backtesting (`1m`, `5m`,
`30m`, `1h`, `1d`).
-e INT, --epochs INT Specify number of epochs (default: 100). -e INT, --epochs INT Specify number of epochs (default: 100).
--spaces {all,buy,sell,roi,stoploss,trailing,protection,default} [{all,buy,sell,roi,stoploss,trailing,protection,default} ...] --spaces {all,buy,sell,roi,stoploss,trailing,protection,default} [{all,buy,sell,roi,stoploss,trailing,protection,default} ...]
Specify which parameters to hyperopt. Space-separated Specify which parameters to hyperopt. Space-separated
@@ -116,7 +121,9 @@ optional arguments:
ShortTradeDurHyperOptLoss, OnlyProfitHyperOptLoss, ShortTradeDurHyperOptLoss, OnlyProfitHyperOptLoss,
SharpeHyperOptLoss, SharpeHyperOptLossDaily, SharpeHyperOptLoss, SharpeHyperOptLossDaily,
SortinoHyperOptLoss, SortinoHyperOptLossDaily, SortinoHyperOptLoss, SortinoHyperOptLossDaily,
CalmarHyperOptLoss, MaxDrawDownHyperOptLoss, ProfitDrawDownHyperOptLoss CalmarHyperOptLoss, MaxDrawDownHyperOptLoss,
MaxDrawDownRelativeHyperOptLoss,
ProfitDrawDownHyperOptLoss
--disable-param-export --disable-param-export
Disable automatic hyperopt parameter export. Disable automatic hyperopt parameter export.
--ignore-missing-spaces, --ignore-unparameterized-spaces --ignore-missing-spaces, --ignore-unparameterized-spaces
@@ -144,7 +151,9 @@ Strategy arguments:
Specify strategy class name which will be used by the Specify strategy class name which will be used by the
bot. bot.
--strategy-path PATH Specify additional strategy lookup path. --strategy-path PATH Specify additional strategy lookup path.
--recursive-strategy-search
Recursively search for a strategy in the strategies
folder.
``` ```
### Hyperopt checklist ### Hyperopt checklist
@@ -153,8 +162,8 @@ Checklist on all tasks / possibilities in hyperopt
Depending on the space you want to optimize, only some of the below are required: Depending on the space you want to optimize, only some of the below are required:
* define parameters with `space='buy'` - for buy signal optimization * define parameters with `space='buy'` - for entry signal optimization
* define parameters with `space='sell'` - for sell signal optimization * define parameters with `space='sell'` - for exit signal optimization
!!! Note !!! Note
`populate_indicators` needs to create all indicators any of the spaces may use, otherwise hyperopt will not work. `populate_indicators` needs to create all indicators any of the spaces may use, otherwise hyperopt will not work.
@@ -180,7 +189,7 @@ Hyperopt will first load your data into memory and will then run `populate_indic
Hyperopt will then spawn into different processes (number of processors, or `-j <n>`), and run backtesting over and over again, changing the parameters that are part of the `--spaces` defined. Hyperopt will then spawn into different processes (number of processors, or `-j <n>`), and run backtesting over and over again, changing the parameters that are part of the `--spaces` defined.
For every new set of parameters, freqtrade will run first `populate_buy_trend()` followed by `populate_sell_trend()`, and then run the regular backtesting process to simulate trades. For every new set of parameters, freqtrade will run first `populate_entry_trend()` followed by `populate_exit_trend()`, and then run the regular backtesting process to simulate trades.
After backtesting, the results are passed into the [loss function](#loss-functions), which will evaluate if this result was better or worse than previous results. After backtesting, the results are passed into the [loss function](#loss-functions), which will evaluate if this result was better or worse than previous results.
Based on the loss function result, hyperopt will determine the next set of parameters to try in the next round of backtesting. Based on the loss function result, hyperopt will determine the next set of parameters to try in the next round of backtesting.
@@ -190,7 +199,7 @@ Based on the loss function result, hyperopt will determine the next set of param
There are two places you need to change in your strategy file to add a new buy hyperopt for testing: There are two places you need to change in your strategy file to add a new buy hyperopt for testing:
* Define the parameters at the class level hyperopt shall be optimizing. * Define the parameters at the class level hyperopt shall be optimizing.
* Within `populate_buy_trend()` - use defined parameter values instead of raw constants. * Within `populate_entry_trend()` - use defined parameter values instead of raw constants.
There you have two different types of indicators: 1. `guards` and 2. `triggers`. There you have two different types of indicators: 1. `guards` and 2. `triggers`.
@@ -200,25 +209,25 @@ There you have two different types of indicators: 1. `guards` and 2. `triggers`.
!!! Hint "Guards and Triggers" !!! Hint "Guards and Triggers"
Technically, there is no difference between 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". 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). Sticking signals are signals that are active for multiple candles. This can lead into entering 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. Hyper-optimization will, for each epoch round, pick one trigger and possibly multiple guards.
#### Sell optimization #### Exit signal optimization
Similar to the buy-signal above, sell-signals can also be optimized. Similar to the entry-signal above, exit-signals can also be optimized.
Place the corresponding settings into the following methods Place the corresponding settings into the following methods
* Define the parameters at the class level hyperopt shall be optimizing, either naming them `sell_*`, or by explicitly defining `space='sell'`. * Define the parameters at the class level hyperopt shall be optimizing, either naming them `sell_*`, or by explicitly defining `space='sell'`.
* Within `populate_sell_trend()` - use defined parameter values instead of raw constants. * Within `populate_exit_trend()` - use defined parameter values instead of raw constants.
The configuration and rules are the same than for buy signals. The configuration and rules are the same than for buy signals.
## Solving a Mystery ## Solving a Mystery
Let's say you are curious: should you use MACD crossings or lower Bollinger Bands to trigger your buys. Let's say you are curious: should you use MACD crossings or lower Bollinger Bands to trigger your long entries.
And you also wonder should you use RSI or ADX to help with those buy decisions. And you also wonder should you use RSI or ADX to help with those decisions.
If you decide to use RSI or ADX, which values should I use for them? If you decide to use RSI or ADX, which values should I use for them?
So let's use hyperparameter optimization to solve this mystery. So let's use hyperparameter optimization to solve this mystery.
@@ -269,12 +278,13 @@ The last one we call `trigger` and use it to decide which buy trigger we want to
!!! Note "Parameter space assignment" !!! Note "Parameter space assignment"
Parameters must either be assigned to a variable named `buy_*` or `sell_*` - or contain `space='buy'` | `space='sell'` to be assigned to a space correctly. Parameters must either be assigned to a variable named `buy_*` or `sell_*` - or contain `space='buy'` | `space='sell'` to be assigned to a space correctly.
If no parameter is available for a space, you'll receive the error that no space was found when running hyperopt. If no parameter is available for a space, you'll receive the error that no space was found when running hyperopt.
Parameters with unclear space (e.g. `adx_period = IntParameter(4, 24, default=14)` - no explicit nor implicit space) will not be detected and will therefore be ignored.
So let's write the buy strategy using these values: So let's write the buy strategy using these values:
```python ```python
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = [] conditions = []
# GUARDS AND TRENDS # GUARDS AND TRENDS
if self.buy_adx_enabled.value: if self.buy_adx_enabled.value:
@@ -296,12 +306,12 @@ So let's write the buy strategy using these values:
if conditions: if conditions:
dataframe.loc[ dataframe.loc[
reduce(lambda x, y: x & y, conditions), reduce(lambda x, y: x & y, conditions),
'buy'] = 1 'enter_long'] = 1
return dataframe return dataframe
``` ```
Hyperopt will now call `populate_buy_trend()` many times (`epochs`) with different value combinations. Hyperopt will now call `populate_entry_trend()` many times (`epochs`) with different value combinations.
It will use the given historical data and simulate buys based on the buy signals generated with the above function. It will use the given historical data and simulate 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)). Based on the results, hyperopt will tell you which parameter combination produced the best results (based on the configured [loss function](#loss-functions)).
@@ -332,6 +342,7 @@ There are four parameter types each suited for different purposes.
## Optimizing an indicator parameter ## Optimizing an indicator parameter
Assuming you have a simple strategy in mind - a EMA cross strategy (2 Moving averages crossing) - and you'd like to find the ideal parameters for this strategy. Assuming you have a simple strategy in mind - a EMA cross strategy (2 Moving averages crossing) - and you'd like to find the ideal parameters for this strategy.
By default, we assume a stoploss of 5% - and a take-profit (`minimal_roi`) of 10% - which means freqtrade will sell the trade once 10% profit has been reached.
``` python ``` python
from pandas import DataFrame from pandas import DataFrame
@@ -346,6 +357,9 @@ import freqtrade.vendor.qtpylib.indicators as qtpylib
class MyAwesomeStrategy(IStrategy): class MyAwesomeStrategy(IStrategy):
stoploss = -0.05 stoploss = -0.05
timeframe = '15m' timeframe = '15m'
minimal_roi = {
"0": 0.10
},
# Define the parameter spaces # Define the parameter spaces
buy_ema_short = IntParameter(3, 50, default=5) buy_ema_short = IntParameter(3, 50, default=5)
buy_ema_long = IntParameter(15, 200, default=50) buy_ema_long = IntParameter(15, 200, default=50)
@@ -364,7 +378,7 @@ class MyAwesomeStrategy(IStrategy):
return dataframe return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = [] conditions = []
conditions.append(qtpylib.crossed_above( conditions.append(qtpylib.crossed_above(
dataframe[f'ema_short_{self.buy_ema_short.value}'], dataframe[f'ema_long_{self.buy_ema_long.value}'] dataframe[f'ema_short_{self.buy_ema_short.value}'], dataframe[f'ema_long_{self.buy_ema_long.value}']
@@ -376,11 +390,11 @@ class MyAwesomeStrategy(IStrategy):
if conditions: if conditions:
dataframe.loc[ dataframe.loc[
reduce(lambda x, y: x & y, conditions), reduce(lambda x, y: x & y, conditions),
'buy'] = 1 'enter_long'] = 1
return dataframe return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = [] conditions = []
conditions.append(qtpylib.crossed_above( conditions.append(qtpylib.crossed_above(
dataframe[f'ema_long_{self.buy_ema_long.value}'], dataframe[f'ema_short_{self.buy_ema_short.value}'] dataframe[f'ema_long_{self.buy_ema_long.value}'], dataframe[f'ema_short_{self.buy_ema_short.value}']
)) ))
@@ -391,7 +405,7 @@ class MyAwesomeStrategy(IStrategy):
if conditions: if conditions:
dataframe.loc[ dataframe.loc[
reduce(lambda x, y: x & y, conditions), reduce(lambda x, y: x & y, conditions),
'sell'] = 1 'exit_long'] = 1
return dataframe return dataframe
``` ```
@@ -401,7 +415,7 @@ Using `self.buy_ema_short.range` will return a range object containing all entri
In this case (`IntParameter(3, 50, default=5)`), the loop would run for all numbers between 3 and 50 (`[3, 4, 5, ... 49, 50]`). In this case (`IntParameter(3, 50, default=5)`), the loop would run for all numbers between 3 and 50 (`[3, 4, 5, ... 49, 50]`).
By using this in a loop, hyperopt will generate 48 new columns (`['buy_ema_3', 'buy_ema_4', ... , 'buy_ema_50']`). By using this in a loop, hyperopt will generate 48 new columns (`['buy_ema_3', 'buy_ema_4', ... , 'buy_ema_50']`).
Hyperopt itself will then use the selected value to create the buy and sell signals Hyperopt itself will then use the selected value to create the buy and sell signals.
While this strategy is most likely too simple to provide consistent profit, it should serve as an example how optimize indicator parameters. While this strategy is most likely too simple to provide consistent profit, it should serve as an example how optimize indicator parameters.
@@ -563,7 +577,8 @@ Currently, the following loss functions are builtin:
* `SharpeHyperOptLossDaily` - optimizes Sharpe Ratio calculated on **daily** trade returns relative to standard deviation. * `SharpeHyperOptLossDaily` - optimizes Sharpe Ratio calculated on **daily** trade returns relative to standard deviation.
* `SortinoHyperOptLoss` - optimizes Sortino Ratio calculated on trade returns relative to **downside** standard deviation. * `SortinoHyperOptLoss` - optimizes Sortino Ratio calculated on trade returns relative to **downside** standard deviation.
* `SortinoHyperOptLossDaily` - optimizes Sortino Ratio calculated on **daily** trade returns relative to **downside** standard deviation. * `SortinoHyperOptLossDaily` - optimizes Sortino Ratio calculated on **daily** trade returns relative to **downside** standard deviation.
* `MaxDrawDownHyperOptLoss` - Optimizes Maximum drawdown. * `MaxDrawDownHyperOptLoss` - Optimizes Maximum absolute drawdown.
* `MaxDrawDownRelativeHyperOptLoss` - Optimizes both maximum absolute drawdown while also adjusting for maximum relative drawdown.
* `CalmarHyperOptLoss` - Optimizes Calmar Ratio calculated on trade returns relative to max drawdown. * `CalmarHyperOptLoss` - Optimizes Calmar Ratio calculated on trade returns relative to max drawdown.
* `ProfitDrawDownHyperOptLoss` - Optimizes by max Profit & min Drawdown objective. `DRAWDOWN_MULT` variable within the hyperoptloss file can be adjusted to be stricter or more flexible on drawdown purposes. * `ProfitDrawDownHyperOptLoss` - Optimizes by max Profit & min Drawdown objective. `DRAWDOWN_MULT` variable within the hyperoptloss file can be adjusted to be stricter or more flexible on drawdown purposes.
@@ -677,7 +692,7 @@ class MyAwesomeStrategy(IStrategy):
!!! Note !!! Note
Values in the configuration file will overwrite Parameter-file level parameters - and both will overwrite parameters within the strategy. Values in the configuration file will overwrite Parameter-file level parameters - and both will overwrite parameters within the strategy.
The prevalence is therefore: config > parameter file > strategy The prevalence is therefore: config > parameter file > strategy `*_params` > parameter default
### Understand Hyperopt ROI results ### Understand Hyperopt ROI results
@@ -859,10 +874,28 @@ You can also enable position stacking in the configuration file by explicitly se
As hyperopt consumes a lot of memory (the complete data needs to be in memory once per parallel backtesting process), it's likely that you run into "out of memory" errors. As hyperopt consumes a lot of memory (the complete data needs to be in memory once per parallel backtesting process), it's likely that you run into "out of memory" errors.
To combat these, you have multiple options: To combat these, you have multiple options:
* reduce the amount of pairs * Reduce the amount of pairs.
* reduce the timerange used (`--timerange <timerange>`) * Reduce the timerange used (`--timerange <timerange>`).
* reduce the number of parallel processes (`-j <n>`) * Avoid using `--timeframe-detail` (this loads a lot of additional data into memory).
* Increase the memory of your machine * Reduce the number of parallel processes (`-j <n>`).
* Increase the memory of your machine.
## The objective has been evaluated at this point before.
If you see `The objective has been evaluated at this point before.` - then this is a sign that your space has been exhausted, or is close to that.
Basically all points in your space have been hit (or a local minima has been hit) - and hyperopt does no longer find points in the multi-dimensional space it did not try yet.
Freqtrade tries to counter the "local minima" problem by using new, randomized points in this case.
Example:
``` python
buy_ema_short = IntParameter(5, 20, default=10, space="buy", optimize=True)
# This is the only parameter in the buy space
```
The `buy_ema_short` space has 15 possible values (`5, 6, ... 19, 20`). If you now run hyperopt for the buy space, hyperopt will only have 15 values to try before running out of options.
Your epochs should therefore be aligned to the possible values - or you should be ready to interrupt a run if you norice a lot of `The objective has been evaluated at this point before.` warnings.
## Show details of Hyperopt results ## Show details of Hyperopt results

View File

@@ -44,7 +44,7 @@ It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklis
```json ```json
"pairlists": [ "pairlists": [
{"method": "StaticPairList"} {"method": "StaticPairList"}
], ],
``` ```
By default, only currently enabled pairs are allowed. By default, only currently enabled pairs are allowed.
@@ -160,17 +160,17 @@ This filter allows freqtrade to ignore pairs until they have been listed for at
Offsets an incoming pairlist by a given `offset` value. Offsets an incoming pairlist by a given `offset` value.
As an example it can be used in conjunction with `VolumeFilter` to remove the top X volume pairs. Or to split As an example it can be used in conjunction with `VolumeFilter` to remove the top X volume pairs. Or to split a larger pairlist on two bot instances.
a larger pairlist on two bot instances.
Example to remove the first 10 pairs from the pairlist: Example to remove the first 10 pairs from the pairlist, and takes the next 20 (taking items 10-30 of the initial list):
```json ```json
"pairlists": [ "pairlists": [
// ... // ...
{ {
"method": "OffsetFilter", "method": "OffsetFilter",
"offset": 10 "offset": 10,
"number_assets": 20
} }
], ],
``` ```
@@ -181,7 +181,7 @@ Example to remove the first 10 pairs from the pairlist:
`VolumeFilter`. `VolumeFilter`.
!!! Note !!! Note
An offset larger then the total length of the incoming pairlist will result in an empty pairlist. An offset larger than the total length of the incoming pairlist will result in an empty pairlist.
#### PerformanceFilter #### PerformanceFilter

View File

@@ -1,6 +1,6 @@
## Prices used for orders ## 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 for regular orders can be controlled via the parameter structures `entry_pricing` for trade entries and `exit_pricing` for trade exits.
Prices are always retrieved right before an order is placed, either by querying the exchange tickers or by using the orderbook data. Prices are always retrieved right before an order is placed, either by querying the exchange tickers or by using the orderbook data.
!!! Note !!! Note
@@ -9,20 +9,11 @@ Prices are always retrieved right before an order is placed, either by querying
!!! Warning "Using market orders" !!! Warning "Using market orders"
Please read the section [Market order pricing](#market-order-pricing) section when using market orders. Please read the section [Market order pricing](#market-order-pricing) section when using market orders.
### Buy price ### Entry price
#### Check depth of market #### Enter price side
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. The configuration setting `entry_pricing.price_side` defines the side of the orderbook the bot looks for when buying.
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. The following displays an orderbook.
@@ -38,30 +29,53 @@ The following displays an orderbook.
... ...
``` ```
If `bid_strategy.price_side` is set to `"bid"`, then the bot will use 99 as buying price. If `entry_pricing.price_side` is set to `"bid"`, then the bot will use 99 as entry price.
In line with that, if `bid_strategy.price_side` is set to `"ask"`, then the bot will use 101 as buying price. In line with that, if `entry_pricing.price_side` is set to `"ask"`, then the bot will use 101 as entry price.
Using `ask` price often guarantees quicker filled orders, but the bot can also end up paying more than what would have been necessary. Depending on the order direction (_long_/_short_), this will lead to different results. Therefore we recommend to use `"same"` or `"other"` for this configuration instead.
This would result in the following pricing matrix:
| direction | Order | setting | price | crosses spread |
|------ |--------|-----|-----|-----|
| long | buy | ask | 101 | yes |
| long | buy | bid | 99 | no |
| long | buy | same | 99 | no |
| long | buy | other | 101 | yes |
| short | sell | ask | 101 | no |
| short | sell | bid | 99 | yes |
| short | sell | same | 101 | no |
| short | sell | other | 99 | yes |
Using the other side of the orderbook 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. 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). Also, prices at the "other" 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 #### Entry 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 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. When entering a trade with the orderbook enabled (`entry_pricing.use_order_book=True`), Freqtrade fetches the `entry_pricing.order_book_top` entries from the orderbook and uses the entry specified as `entry_pricing.order_book_top` on the configured side (`entry_pricing.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 #### Entry price without Orderbook enabled
The following section uses `side` as the configured `bid_strategy.price_side`. The following section uses `side` as the configured `entry_pricing.price_side` (defaults to `"same"`).
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. When not using orderbook (`entry_pricing.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 based on `entry_pricing.price_last_balance`.
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. The `entry_pricing.price_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 #### Check depth of market
#### Sell price side When check depth of market is enabled (`entry_pricing.check_depth_of_market.enabled=True`), the entry signals are filtered based on the orderbook depth (sum of all amounts) for each orderbook side.
The configuration setting `ask_strategy.price_side` defines the side of the spread the bot looks for when selling. 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 `entry_pricing.check_depth_of_market.bids_to_ask_delta` parameter. The entry 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).
### Exit price
#### Exit price side
The configuration setting `exit_pricing.price_side` defines the side of the spread the bot looks for when exiting a trade.
The following displays an orderbook: The following displays an orderbook:
@@ -77,40 +91,54 @@ The following displays an orderbook:
... ...
``` ```
If `ask_strategy.price_side` is set to `"ask"`, then the bot will use 101 as selling price. If `exit_pricing.price_side` is set to `"ask"`, then the bot will use 101 as exiting price.
In line with that, if `ask_strategy.price_side` is set to `"bid"`, then the bot will use 99 as selling price. In line with that, if `exit_pricing.price_side` is set to `"bid"`, then the bot will use 99 as exiting price.
#### Sell price with Orderbook enabled Depending on the order direction (_long_/_short_), this will lead to different results. Therefore we recommend to use `"same"` or `"other"` for this configuration instead.
This would result in the following pricing matrix:
When selling with the orderbook enabled (`ask_strategy.use_order_book=True`), Freqtrade fetches the `ask_strategy.order_book_top` entries in the orderbook and uses the entry specified as `ask_strategy.order_book_top` from the configured side (`ask_strategy.price_side`) as selling price. | Direction | Order | setting | price | crosses spread |
|------ |--------|-----|-----|-----|
| long | sell | ask | 101 | no |
| long | sell | bid | 99 | yes |
| long | sell | same | 101 | no |
| long | sell | other | 99 | yes |
| short | buy | ask | 101 | yes |
| short | buy | bid | 99 | no |
| short | buy | same | 99 | no |
| short | buy | other | 101 | yes |
#### Exit price with Orderbook enabled
When exiting with the orderbook enabled (`exit_pricing.use_order_book=True`), Freqtrade fetches the `exit_pricing.order_book_top` entries in the orderbook and uses the entry specified as `exit_pricing.order_book_top` from the configured side (`exit_pricing.price_side`) as trade exit price.
1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on. 1 specifies the topmost entry in the orderbook, while 2 would use the 2nd entry in the orderbook, and so on.
#### Sell price without Orderbook enabled #### Exit 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. The following section uses `side` as the configured `exit_pricing.price_side` (defaults to `"ask"`).
When not using orderbook (`ask_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. When not using orderbook (`exit_pricing.use_order_book=False`), Freqtrade uses the best `side` price from the ticker if it's above the `last` traded price from the ticker. Otherwise (when the `side` price is below the `last` price), it calculates a rate between `side` and `last` price based on `exit_pricing.price_last_balance`.
The `ask_strategy.bid_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 `side` and last price. The `exit_pricing.price_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 `side` and last price.
### Market order pricing ### Market order pricing
When using market orders, prices should be configured to use the "correct" side of the orderbook to allow realistic pricing detection. 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 Assuming both entry and exits are using market orders, a configuration similar to the following must be used
``` jsonc ``` jsonc
"order_types": { "order_types": {
"buy": "market", "entry": "market",
"sell": "market" "exit": "market"
// ... // ...
}, },
"bid_strategy": { "entry_pricing": {
"price_side": "ask", "price_side": "other",
// ... // ...
}, },
"ask_strategy":{ "exit_pricing":{
"price_side": "bid", "price_side": "other",
// ... // ...
}, },
``` ```

View File

@@ -48,6 +48,10 @@ If `trade_limit` or more trades resulted in stoploss, trading will stop for `sto
This applies across all pairs, unless `only_per_pair` is set to true, which will then only look at one pair at a time. This applies across all pairs, unless `only_per_pair` is set to true, which will then only look at one pair at a time.
Similarly, this protection will by default look at all trades (long and short). For futures bots, setting `only_per_side` will make the bot only consider one side, and will then only lock this one side, allowing for example shorts to continue after a series of long stoplosses.
`required_profit` will determine the required relative profit (or loss) for stoplosses to consider. This should normally not be set and defaults to 0.0 - which means all losing stoplosses will be triggering a block.
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. 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.
``` python ``` python
@@ -59,7 +63,9 @@ def protections(self):
"lookback_period_candles": 24, "lookback_period_candles": 24,
"trade_limit": 4, "trade_limit": 4,
"stop_duration_candles": 4, "stop_duration_candles": 4,
"only_per_pair": False "required_profit": 0.0,
"only_per_pair": False,
"only_per_side": False
} }
] ]
``` ```
@@ -93,6 +99,8 @@ def protections(self):
`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. `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`). 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`).
For futures bots, setting `only_per_side` will make the bot only consider one side, and will then only lock this one side, allowing for example shorts to continue after a series of long losses.
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. 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.
``` python ``` python
@@ -104,7 +112,8 @@ def protections(self):
"lookback_period_candles": 6, "lookback_period_candles": 6,
"trade_limit": 2, "trade_limit": 2,
"stop_duration": 60, "stop_duration": 60,
"required_profit": 0.02 "required_profit": 0.02,
"only_per_pair": False,
} }
] ]
``` ```

View File

@@ -22,10 +22,6 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is
![freqtrade screenshot](assets/freqtrade-screenshot.png) ![freqtrade screenshot](assets/freqtrade-screenshot.png)
## Sponsored promotion
[![tokenbot-promo](assets/TokenBot-Freqtrade-banner.png)](https://tokenbot.com/?utm_source=github&utm_medium=freqtrade&utm_campaign=algodevs)
## Features ## Features
- Develop your Strategy: Write your strategy in python, using [pandas](https://pandas.pydata.org/). Example strategies to inspire you are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies). - Develop your Strategy: Write your strategy in python, using [pandas](https://pandas.pydata.org/). Example strategies to inspire you are available in the [strategy repository](https://github.com/freqtrade/freqtrade-strategies).
@@ -42,14 +38,23 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is
Please read the [exchange specific notes](exchanges.md) to learn about eventual, special configurations needed for each exchange. 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#binance-blacklist)) - [X] [Binance](https://www.binance.com/)
- [X] [Bittrex](https://bittrex.com/) - [X] [Bittrex](https://bittrex.com/)
- [X] [FTX](https://ftx.com) - [X] [FTX](https://ftx.com/#a=2258149)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Huobi](http://huobi.com/)
- [X] [Kraken](https://kraken.com/) - [X] [Kraken](https://kraken.com/)
- [X] [OKX](https://www.okx.com/) - [X] [OKX](https://okx.com/) (Former OKEX)
- [ ] [potentially many others through <img alt="ccxt" width="30px" src="assets/ccxt-logo.svg" />](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_ - [ ] [potentially many others through <img alt="ccxt" width="30px" src="assets/ccxt-logo.svg" />](https://github.com/ccxt/ccxt/). _(We cannot guarantee they will work)_
### Supported Futures Exchanges (experimental)
- [X] [Binance](https://www.binance.com/)
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [OKX](https://okx.com/).
Please make sure to read the [exchange specific notes](exchanges.md), as well as the [trading with leverage](leverage.md) documentation before diving in.
### Community tested ### Community tested
Exchanges confirmed working by the community: Exchanges confirmed working by the community:

View File

@@ -326,6 +326,16 @@ python3 -m pip install --upgrade pip
python3 -m pip install -e . python3 -m pip install -e .
``` ```
Patch conda libta-lib (Linux only)
```bash
# Ensure that the environment is active!
conda activate freqtrade-conda
cd build_helpers
bash install_ta-lib.sh ${CONDA_PREFIX} nosudo
```
### Congratulations ### Congratulations
[You are ready](#you-are-ready), and run the bot [You are ready](#you-are-ready), and run the bot

View File

@@ -9,4 +9,4 @@ window.MathJax = {
ignoreHtmlClass: ".*|", ignoreHtmlClass: ".*|",
processHtmlClass: "arithmatex" processHtmlClass: "arithmatex"
} }
}; };

136
docs/leverage.md Normal file
View File

@@ -0,0 +1,136 @@
# Trading with Leverage
!!! Warning "Beta feature"
This feature is still in it's testing phase. Should you notice something you think is wrong please let us know via Discord or via Github Issue.
!!! Note "Multiple bots on one account"
You can't run 2 bots on the same account with leverage. For leveraged / margin trading, freqtrade assumes it's the only user of the account, and all liquidation levels are calculated based on this assumption.
!!! Danger "Trading with leverage is very risky"
Do not trade with a leverage > 1 using a strategy that hasn't shown positive results in a live run using the spot market. Check the stoploss of your strategy. With a leverage of 2, a stoploss of 0.5 (50%) would be too low, and these trades would be liquidated before reaching that stoploss.
We do not assume any responsibility for eventual losses that occur from using this software or this mode.
Please only use advanced trading modes when you know how freqtrade (and your strategy) works.
Also, never risk more than what you can afford to lose.
Please read the [strategy migration guide](strategy_migration.md#strategy-migration-between-v2-and-v3) to migrate your strategy from a freqtrade v2 strategy, to v3 strategy that can short and trade futures.
## Shorting
Shorting is not possible when trading with [`trading_mode`](#understand-tradingmode) set to `spot`. To short trade, `trading_mode` must be set to `margin`(currently unavailable) or [`futures`](#futures), with [`margin_mode`](#margin-mode) set to `cross`(currently unavailable) or [`isolated`](#isolated-margin-mode)
For a strategy to short, the strategy class must set the class variable `can_short = True`
Please read [strategy customization](strategy-customization.md#entry-signal-rules) for instructions on how to set signals to enter and exit short trades.
## Understand `trading_mode`
The possible values are: `spot` (default), `margin`(*Currently unavailable*) or `futures`.
### Spot
Regular trading mode (low risk)
- Long trades only (No short trades).
- No leverage.
- No Liquidation.
- Profits gained/lost are equal to the change in value of the assets (minus trading fees).
### Leverage trading modes
With leverage, a trader borrows capital from the exchange. The capital must be re-payed fully to the exchange (potentially with interest), and the trader keeps any profits, or pays any losses, from any trades made using the borrowed capital.
Because the capital must always be re-payed, exchanges will **liquidate** (forcefully sell the traders assets) a trade made using borrowed capital when the total value of assets in the leverage account drops to a certain point (a point where the total value of losses is less than the value of the collateral that the trader actually owns in the leverage account), in order to ensure that the trader has enough capital to pay the borrowed assets back to the exchange. The exchange will also charge a **liquidation fee**, adding to the traders losses.
For this reason, **DO NOT TRADE WITH LEVERAGE IF YOU DON'T KNOW EXACTLY WHAT YOUR DOING. LEVERAGE TRADING IS HIGH RISK, AND CAN RESULT IN THE VALUE OF YOUR ASSETS DROPPING TO 0 VERY QUICKLY, WITH NO CHANCE OF INCREASING IN VALUE AGAIN.**
#### Margin (currently unavailable)
Trading occurs on the spot market, but the exchange lends currency to you in an amount equal to the chosen leverage. You pay the amount lent to you back to the exchange with interest, and your profits/losses are multiplied by the leverage specified.
#### Futures
Perpetual swaps (also known as Perpetual Futures) are contracts traded at a price that is closely tied to the underlying asset they are based off of (ex.). You are not trading the actual asset but instead are trading a derivative contract. Perpetual swap contracts can last indefinitely, in contrast to futures or option contracts.
In addition to the gains/losses from the change in price of the futures contract, traders also exchange _funding fees_, which are gains/losses worth an amount that is derived from the difference in price between the futures contract and the underlying asset. The difference in price between a futures contract and the underlying asset varies between exchanges.
To trade in futures markets, you'll have to set `trading_mode` to "futures".
You will also have to pick a "margin mode" (explanation below) - with freqtrade currently only supporting isolated margin.
``` json
"trading_mode": "futures",
"margin_mode": "isolated"
```
### Margin mode
On top of `trading_mode` - you will also have to configure your `margin_mode`.
While freqtrade currently only supports one margin mode, this will change, and by configuring it now you're all set for future updates.
The possible values are: `isolated`, or `cross`(*currently unavailable*).
#### Isolated margin mode
Each market(trading pair), keeps collateral in a separate account
``` json
"margin_mode": "isolated"
```
#### Cross margin mode (currently unavailable)
One account is used to share collateral between markets (trading pairs). Margin is taken from total account balance to avoid liquidation when needed.
``` json
"margin_mode": "cross"
```
## Set leverage to use
Different strategies and risk profiles will require different levels of leverage.
While you could configure one static leverage value - freqtrade offers you the flexibility to adjust this via [strategy leverage callback](strategy-callbacks.md#leverage-callback) - which allows you to use different leverages by pair, or based on some other factor benefitting your strategy result.
If not implemented, leverage defaults to 1x (no leverage).
!!! Warning
Higher leverage also equals higher risk - be sure you fully understand the implications of using leverage!
## Understand `liquidation_buffer`
*Defaults to `0.05`*
A ratio specifying how large of a safety net to place between the liquidation price and the stoploss to prevent a position from reaching the liquidation price.
This artificial liquidation price is calculated as:
`freqtrade_liquidation_price = liquidation_price ± (abs(open_rate - liquidation_price) * liquidation_buffer)`
- `±` = `+` for long trades
- `±` = `-` for short trades
Possible values are any floats between 0.0 and 0.99
**ex:** If a trade is entered at a price of 10 coin/USDT, and the liquidation price of this trade is 8 coin/USDT, then with `liquidation_buffer` set to `0.05` the minimum stoploss for this trade would be $8 + ((10 - 8) * 0.05) = 8 + 0.1 = 8.1$
!!! Danger "A `liquidation_buffer` of 0.0, or a low `liquidation_buffer` is likely to result in liquidations, and liquidation fees"
Currently Freqtrade is able to calculate liquidation prices, but does not calculate liquidation fees. Setting your `liquidation_buffer` to 0.0, or using a low `liquidation_buffer` could result in your positions being liquidated. Freqtrade does not track liquidation fees, so liquidations will result in inaccurate profit/loss results for your bot. If you use a low `liquidation_buffer`, it is recommended to use `stoploss_on_exchange` if your exchange supports this.
## Unavailable funding rates
For futures data, exchanges commonly provide the futures candles, the marks, and the funding rates. However, it is common that whilst candles and marks might be available, the funding rates are not. This can affect backtesting timeranges, i.e. you may only be able to test recent timeranges and not earlier, experiencing the `No data found. Terminating.` error. To get around this, add the `futures_funding_rate` config option as listed in [configuration.md](configuration.md), and it is recommended that you set this to `0`, unless you know a given specific funding rate for your pair, exchange and timerange. Setting this to anything other than `0` can have drastic effects on your profit calculations within strategy, e.g. within the `custom_exit`, `custom_stoploss`, etc functions.
!!! Warning "This will mean your backtests are inaccurate."
This will not overwrite funding rates that are available from the exchange, but bear in mind that setting a false funding rate will mean backtesting results will be inaccurate for historical timeranges where funding rates are not available.
### Developer
#### Margin mode
For shorts, the currency which pays the interest fee for the `borrowed` currency is purchased at the same time of the closing trade (This means that the amount purchased in short closing trades is greater than the amount sold in short opening trades).
For longs, the currency which pays the interest fee for the `borrowed` will already be owned by the user and does not need to be purchased. The interest is subtracted from the `close_value` of the trade.
All Fees are included in `current_profit` calculations during the trade.
#### Futures mode
Funding fees are either added or subtracted from the total amount of a trade

View File

@@ -14,7 +14,7 @@ pip install -U -r requirements-plot.txt
The `freqtrade plot-dataframe` subcommand shows an interactive graph with three subplots: The `freqtrade plot-dataframe` subcommand shows an interactive graph with three subplots:
* Main plot with candlestics and indicators following price (sma/ema) * Main plot with candlesticks and indicators following price (sma/ema)
* Volume bars * Volume bars
* Additional indicators as specified by `--indicators2` * Additional indicators as specified by `--indicators2`
@@ -65,7 +65,7 @@ optional arguments:
_today.json` _today.json`
--timerange TIMERANGE --timerange TIMERANGE
Specify what timerange of data to use. Specify what timerange of data to use.
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME -i TIMEFRAME, --timeframe TIMEFRAME
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`). Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
--no-trades Skip using trades from backtesting file and DB. --no-trades Skip using trades from backtesting file and DB.
@@ -96,7 +96,7 @@ Strategy arguments:
Example: Example:
``` bash ``` bash
freqtrade plot-dataframe -p BTC/ETH freqtrade plot-dataframe -p BTC/ETH --strategy AwesomeStrategy
``` ```
The `-p/--pairs` argument can be used to specify pairs you would like to plot. The `-p/--pairs` argument can be used to specify pairs you would like to plot.
@@ -107,9 +107,6 @@ The `-p/--pairs` argument can be used to specify pairs you would like to plot.
Specify custom indicators. Specify custom indicators.
Use `--indicators1` for the main plot and `--indicators2` for the subplot below (if values are in a different range than prices). Use `--indicators1` for the main plot and `--indicators2` for the subplot below (if values are in a different range than prices).
!!! Tip
You will almost certainly want to specify a custom strategy! This can be done by adding `-s Classname` / `--strategy ClassName` to the command.
``` bash ``` bash
freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --indicators1 sma ema --indicators2 macd freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --indicators1 sma ema --indicators2 macd
``` ```
@@ -330,7 +327,7 @@ optional arguments:
--trade-source {DB,file} --trade-source {DB,file}
Specify the source for trades (Can be DB or file Specify the source for trades (Can be DB or file
(backtest file)) Default: file (backtest file)) Default: file
-i TIMEFRAME, --timeframe TIMEFRAME, --ticker-interval TIMEFRAME -i TIMEFRAME, --timeframe TIMEFRAME
Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`). Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).
--auto-open Automatically open generated plot. --auto-open Automatically open generated plot.

View File

@@ -1,4 +1,6 @@
mkdocs==1.2.3 markdown==3.3.7
mkdocs-material==8.2.1 mkdocs==1.3.1
mdx_truly_sane_lists==1.2 mkdocs-material==8.4.0
pymdown-extensions==9.2 mdx_truly_sane_lists==1.3
pymdown-extensions==9.5
jinja2==3.1.2

View File

@@ -145,9 +145,10 @@ python3 scripts/rest_client.py --config rest_config.json <command> [optional par
| `locks` | Displays currently locked pairs. | `locks` | Displays currently locked pairs.
| `delete_lock <lock_id>` | Deletes (disables) the lock by id. | `delete_lock <lock_id>` | Deletes (disables) the lock by id.
| `profit` | Display a summary of your profit/loss from close trades and some stats about your performance. | `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`). | `forceexit <trade_id>` | Instantly exits the given trade (Ignoring `minimum_roi`).
| `forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`). | `forceexit all` | Instantly exits all open trades (Ignoring `minimum_roi`).
| `forcebuy <pair> [rate]` | Instantly buys the given pair. Rate is optional. (`forcebuy_enable` must be set to True) | `forceenter <pair> [rate]` | Instantly enters the given pair. Rate is optional. (`force_entry_enable` must be set to True)
| `forceenter <pair> <side> [rate]` | Instantly longs or shorts the given pair. Rate is optional. (`force_entry_enable` must be set to True)
| `performance` | Show performance of each finished trade grouped by pair. | `performance` | Show performance of each finished trade grouped by pair.
| `balance` | Show account balance per currency. | `balance` | Show account balance per currency.
| `daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7). | `daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7).
@@ -215,8 +216,15 @@ forcebuy
:param pair: Pair to buy (ETH/BTC) :param pair: Pair to buy (ETH/BTC)
:param price: Optional - price to buy :param price: Optional - price to buy
forcesell forceenter
Force-sell a trade. Force entering a trade
:param pair: Pair to buy (ETH/BTC)
:param side: 'long' or 'short'
:param price: Optional - price to buy
forceexit
Force-exit a trade.
:param tradeid: Id of the trade (can be received via status command) :param tradeid: Id of the trade (can be received via status command)
@@ -285,6 +293,9 @@ strategy
:param strategy: Strategy class name :param strategy: Strategy class name
sysinfo
Provides system information (CPU, RAM usage)
trade trade
Return specific trade Return specific trade

View File

@@ -104,16 +104,16 @@ To mitigate this, you can try to match the first order on the opposite orderbook
``` jsonc ``` jsonc
"order_types": { "order_types": {
"buy": "limit", "entry": "limit",
"sell": "limit" "exit": "limit"
// ... // ...
}, },
"bid_strategy": { "entry_pricing": {
"price_side": "ask", "price_side": "other",
// ... // ...
}, },
"ask_strategy":{ "exit_pricing":{
"price_side": "bid", "price_side": "other",
// ... // ...
}, },
``` ```

View File

@@ -49,14 +49,14 @@ sqlite3
SELECT * FROM trades; SELECT * FROM trades;
``` ```
## Fix trade still open after a manual sell on the exchange ## Fix trade still open after a manual exit on the exchange
!!! Warning !!! 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. Manually selling a pair on the exchange will not be detected by the bot and it will try to sell anyway. Whenever possible, /forceexit <tradeid> should be used to accomplish the same thing.
It is strongly advised to backup your database file before making any manual changes. It is strongly advised to backup your database file before making any manual changes.
!!! Note !!! 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 /forceexit, as force_exit orders are closed automatically by the bot on the next iteration.
```sql ```sql
UPDATE trades UPDATE trades
@@ -65,7 +65,7 @@ SET is_open=0,
close_rate=<close_rate>, close_rate=<close_rate>,
close_profit = close_rate / open_rate - 1, close_profit = close_rate / open_rate - 1,
close_profit_abs = (amount * <close_rate> * (1 - fee_close) - (amount * (open_rate * (1 - fee_open)))), close_profit_abs = (amount * <close_rate> * (1 - fee_close) - (amount * (open_rate * (1 - fee_open)))),
sell_reason=<sell_reason> exit_reason=<exit_reason>
WHERE id=<trade_ID_to_update>; WHERE id=<trade_ID_to_update>;
``` ```
@@ -78,7 +78,7 @@ SET is_open=0,
close_rate=0.19638016, close_rate=0.19638016,
close_profit=0.0496, close_profit=0.0496,
close_profit_abs = (amount * 0.19638016 * (1 - fee_close) - (amount * (open_rate * (1 - fee_open)))), close_profit_abs = (amount * 0.19638016 * (1 - fee_close) - (amount * (open_rate * (1 - fee_open)))),
sell_reason='force_sell' exit_reason='force_exit'
WHERE id=31; WHERE id=31;
``` ```
@@ -89,11 +89,12 @@ WHERE id=31;
If you'd still like to remove a trade from the database directly, you can use the below query. If you'd still like to remove a trade from the database directly, you can use the below query.
```sql !!! Danger
DELETE FROM trades WHERE id = <tradeid>; Some systems (Ubuntu) disable foreign keys in their sqlite3 packaging. When using sqlite - please ensure that foreign keys are on by running `PRAGMA foreign_keys = ON` before the above query.
```
```sql ```sql
DELETE FROM trades WHERE id = <tradeid>;
DELETE FROM trades WHERE id = 31; DELETE FROM trades WHERE id = 31;
``` ```
@@ -102,13 +103,20 @@ DELETE FROM trades WHERE id = 31;
## Use a different database system ## Use a different database system
Freqtrade is using SQLAlchemy, which supports multiple different database systems. As such, a multitude of database systems should be supported.
Freqtrade does not depend or install any additional database driver. Please refer to the [SQLAlchemy docs](https://docs.sqlalchemy.org/en/14/core/engines.html#database-urls) on installation instructions for the respective database systems.
The following systems have been tested and are known to work with freqtrade:
* sqlite (default)
* PostgreSQL)
* MariaDB
!!! Warning !!! Warning
By using one of the below database systems, you acknowledge that you know how to manage such a system. Freqtrade will not provide any support with setup or maintenance (or backups) of the below database systems. By using one of the below database systems, you acknowledge that you know how to manage such a system. The freqtrade team will not provide any support with setup or maintenance (or backups) of the below database systems.
### PostgreSQL ### PostgreSQL
Freqtrade supports PostgreSQL by using SQLAlchemy, which supports multiple different database systems.
Installation: Installation:
`pip install psycopg2-binary` `pip install psycopg2-binary`

View File

@@ -17,14 +17,14 @@ Those stoploss modes can be *on exchange* or *off exchange*.
These modes can be configured with these values: These modes can be configured with these values:
``` python ``` python
'emergencysell': 'market', 'emergency_exit': 'market',
'stoploss_on_exchange': False 'stoploss_on_exchange': False
'stoploss_on_exchange_interval': 60, 'stoploss_on_exchange_interval': 60,
'stoploss_on_exchange_limit_ratio': 0.99 'stoploss_on_exchange_limit_ratio': 0.99
``` ```
!!! Note !!! Note
Stoploss on exchange is only supported for Binance (stop-loss-limit), Kraken (stop-loss-market, stop-loss-limit) and FTX (stop limit and stop-market) as of now. Stoploss on exchange is only supported for Binance (stop-loss-limit), Huobi (stop-limit), Kraken (stop-loss-market, stop-loss-limit), FTX (stop limit and stop-market) Gateio (stop-limit), and Kucoin (stop-limit and stop-market) as of now.
<ins>Do not set too low/tight stoploss value if using stop loss on exchange!</ins> <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. If set to low/tight then you have greater risk of missing fill on the order and stoploss will not work.
@@ -52,30 +52,30 @@ The bot cannot do these every 5 seconds (at each iteration), otherwise it would
So this parameter will tell the bot how often it should update the stoploss order. The default value is 60 (1 minute). 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. This same logic will reapply a stoploss order on the exchange should you cancel it accidentally.
### forcesell ### force_exit
`forcesell` is an optional value, which defaults to the same value as `sell` and is used when sending a `/forcesell` command from Telegram or from the Rest API. `force_exit` is an optional value, which defaults to the same value as `exit` and is used when sending a `/forceexit` command from Telegram or from the Rest API.
### forcebuy ### force_entry
`forcebuy` is an optional value, which defaults to the same value as `buy` and is used when sending a `/forcebuy` command from Telegram or from the Rest API. `force_entry` is an optional value, which defaults to the same value as `entry` and is used when sending a `/forceentry` command from Telegram or from the Rest API.
### emergencysell ### emergency_exit
`emergencysell` is an optional value, which defaults to `market` and is used when creating stop loss on exchange orders fails. `emergency_exit` 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. The below is the default which is used if not changed in strategy or configuration file.
Example from strategy file: Example from strategy file:
``` python ``` python
order_types = { order_types = {
'buy': 'limit', "entry": "limit",
'sell': 'limit', "exit": "limit",
'emergencysell': 'market', "emergency_exit": "market",
'stoploss': 'market', "stoploss": "market",
'stoploss_on_exchange': True, "stoploss_on_exchange": True,
'stoploss_on_exchange_interval': 60, "stoploss_on_exchange_interval": 60,
'stoploss_on_exchange_limit_ratio': 0.99 "stoploss_on_exchange_limit_ratio": 0.99
} }
``` ```
@@ -130,7 +130,7 @@ In summary: The stoploss will be adjusted to be always be -10% of the highest ob
### Trailing stop loss, custom positive loss ### Trailing stop loss, custom positive loss
It is also possible to have a default stop loss, when you are in the red with your buy (buy - fee), but once you hit positive result the system will utilize a new stop loss, which can have a different value. You could also have a default stop loss when you are in the red with your buy (buy - fee), but once you hit a positive result (or an offset you define) the system will utilize a new stop loss, which can have a different value.
For example, your default stop loss is -10%, but once you have more than 0% profit (example 0.1%) a different trailing stoploss will be used. For example, your default stop loss is -10%, but once you have more than 0% profit (example 0.1%) a different trailing stoploss will be used.
!!! Note !!! Note
@@ -142,6 +142,8 @@ Both values require `trailing_stop` to be set to true and `trailing_stop_positiv
stoploss = -0.10 stoploss = -0.10
trailing_stop = True trailing_stop = True
trailing_stop_positive = 0.02 trailing_stop_positive = 0.02
trailing_stop_positive_offset = 0.0
trailing_only_offset_is_reached = False # Default - not necessary for this example
``` ```
For example, simplified math: For example, simplified math:
@@ -156,11 +158,31 @@ For example, simplified math:
The 0.02 would translate to a -2% stop loss. The 0.02 would translate to a -2% stop loss.
Before this, `stoploss` is used for the trailing stoploss. Before this, `stoploss` is used for the trailing stoploss.
!!! Tip "Use an offset to change your stoploss"
Use `trailing_stop_positive_offset` to ensure that your new trailing stoploss will be in profit by setting `trailing_stop_positive_offset` higher than `trailing_stop_positive`. Your first new stoploss value will then already have locked in profits.
Example with simplified math:
``` python
stoploss = -0.10
trailing_stop = True
trailing_stop_positive = 0.02
trailing_stop_positive_offset = 0.03
```
* the bot buys an asset at a price of 100$
* the stop loss is defined at -10%, so the stop loss would get triggered once the asset drops below 90$
* assuming the asset now increases to 102$
* the stoploss will now be at 91.8$ - 10% below the highest observed rate
* assuming the asset now increases to 103.5$ (above the offset configured)
* the stop loss will now be -2% of 103.5$ = 101.43$
* now the asset drops in value to 102\$, the stop loss will still be 101.43$ and would trigger once price breaks below 101.43$
### Trailing stop loss only once the trade has reached a certain offset ### Trailing stop loss only once the trade has reached a certain offset
It is also possible to use a static stoploss until the offset is reached, and then trail the trade to take profits once the market turns. You can also keep a static stoploss until the offset is reached, and then trail the trade to take profits once the market turns.
If `"trailing_only_offset_is_reached": true` then the trailing stoploss is only activated once the offset is reached. Until then, the stoploss remains at the configured `stoploss`. If `trailing_only_offset_is_reached = True` then the trailing stoploss is only activated once the offset is reached. Until then, the stoploss remains at the configured `stoploss`.
This option can be used with or without `trailing_stop_positive`, but uses `trailing_stop_positive_offset` as offset. This option can be used with or without `trailing_stop_positive`, but uses `trailing_stop_positive_offset` as offset.
``` python ``` python
@@ -191,6 +213,18 @@ For example, simplified math:
!!! Tip !!! 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. Make sure to have this value (`trailing_stop_positive_offset`) lower than minimal ROI, otherwise minimal ROI will apply first and sell the trade.
## Stoploss and Leverage
Stoploss should be thought of as "risk on this trade" - so a stoploss of 10% on a 100$ trade means you are willing to lose 10$ (10%) on this trade - which would trigger if the price moves 10% to the downside.
When using leverage, the same principle is applied - with stoploss defining the risk on the trade (the amount you are willing to lose).
Therefore, a stoploss of 10% on a 10x trade would trigger on a 1% price move.
If your stake amount (own capital) was 100$ - this trade would be 1000$ at 10x (after leverage).
If price moves 1% - you've lost 10$ of your own capital - therfore stoploss will trigger in this case.
Make sure to be aware of this, and avoid using too tight stoploss (at 10x leverage, 10% risk may be too little to allow the trade to "breath" a little).
## Changing stoploss on open trades ## Changing stoploss on open trades
A stoploss on an open trade can be changed by changing the value in the configuration or strategy and use the `/reload_config` command (alternatively, completely stopping and restarting the bot also works). A stoploss on an open trade can be changed by changing the value in the configuration or strategy and use the `/reload_config` command (alternatively, completely stopping and restarting the bot also works).

View File

@@ -49,7 +49,7 @@ from freqtrade.exchange import timeframe_to_prev_date
class AwesomeStrategy(IStrategy): class AwesomeStrategy(IStrategy):
def confirm_trade_exit(self, pair: str, trade: 'Trade', order_type: str, amount: float, def confirm_trade_exit(self, pair: str, trade: 'Trade', order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str, rate: float, time_in_force: str, exit_reason: str,
current_time: 'datetime', **kwargs) -> bool: current_time: 'datetime', **kwargs) -> bool:
# Obtain pair dataframe. # Obtain pair dataframe.
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
@@ -77,47 +77,47 @@ class AwesomeStrategy(IStrategy):
*** ***
## Buy Tag ## Enter Tag
When your strategy has multiple buy signals, you can name the signal that triggered. When your strategy has multiple buy signals, you can name the signal that triggered.
Then you can access you buy signal on `custom_sell` Then you can access you buy signal on `custom_exit`
```python ```python
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[ dataframe.loc[
( (
(dataframe['rsi'] < 35) & (dataframe['rsi'] < 35) &
(dataframe['volume'] > 0) (dataframe['volume'] > 0)
), ),
['buy', 'buy_tag']] = (1, 'buy_signal_rsi') ['enter_long', 'enter_tag']] = (1, 'buy_signal_rsi')
return dataframe return dataframe
def custom_sell(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, def custom_exit(self, pair: str, trade: Trade, current_time: datetime, current_rate: float,
current_profit: float, **kwargs): current_profit: float, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze() last_candle = dataframe.iloc[-1].squeeze()
if trade.buy_tag == 'buy_signal_rsi' and last_candle['rsi'] > 80: if trade.enter_tag == 'buy_signal_rsi' and last_candle['rsi'] > 80:
return 'sell_signal_rsi' return 'sell_signal_rsi'
return None return None
``` ```
!!! Note !!! Note
`buy_tag` is limited to 100 characters, remaining data will be truncated. `enter_tag` is limited to 100 characters, remaining data will be truncated.
## Exit tag ## Exit tag
Similar to [Buy Tagging](#buy-tag), you can also specify a sell tag. Similar to [Buy Tagging](#buy-tag), you can also specify a sell tag.
``` python ``` python
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[ dataframe.loc[
( (
(dataframe['rsi'] > 70) & (dataframe['rsi'] > 70) &
(dataframe['volume'] > 0) (dataframe['volume'] > 0)
), ),
['sell', 'exit_tag']] = (1, 'exit_rsi') ['exit_long', 'exit_tag']] = (1, 'exit_rsi')
return dataframe return dataframe
``` ```
@@ -125,7 +125,7 @@ def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame
The provided exit-tag is then used as sell-reason - and shown as such in backtest results. The provided exit-tag is then used as sell-reason - and shown as such in backtest results.
!!! Note !!! Note
`sell_reason` is limited to 100 characters, remaining data will be truncated. `exit_reason` is limited to 100 characters, remaining data will be truncated.
## Strategy version ## Strategy version
@@ -146,7 +146,7 @@ def version(self) -> str:
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: The strategies can be derived from other strategies. This avoids duplication of your custom strategy code. You can use this technique to override small parts of your main strategy, leaving the rest untouched:
``` python ``` python title="user_data/strategies/myawesomestrategy.py"
class MyAwesomeStrategy(IStrategy): class MyAwesomeStrategy(IStrategy):
... ...
stoploss = 0.13 stoploss = 0.13
@@ -155,6 +155,10 @@ class MyAwesomeStrategy(IStrategy):
# should be in any custom strategy... # should be in any custom strategy...
... ...
```
``` python title="user_data/strategies/MyAwesomeStrategy2.py"
from myawesomestrategy import MyAwesomeStrategy
class MyAwesomeStrategy2(MyAwesomeStrategy): class MyAwesomeStrategy2(MyAwesomeStrategy):
# Override something # Override something
stoploss = 0.08 stoploss = 0.08
@@ -163,16 +167,7 @@ class MyAwesomeStrategy2(MyAwesomeStrategy):
Both attributes and methods may be overridden, 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" While keeping the subclass in the same file is technically possible, it can lead to some problems with hyperopt parameter files, we therefore recommend to use separate strategy files, and import the parent strategy as shown above.
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 ## Embedding Strategies
@@ -229,3 +224,5 @@ for val in self.buy_ema_short.range:
# Append columns to existing dataframe # Append columns to existing dataframe
merged_frame = pd.concat(frames, axis=1) merged_frame = pd.concat(frames, axis=1)
``` ```
Freqtrade does however also counter this by running `dataframe.copy()` on the dataframe right after the `populate_indicators()` method - so performance implications of this should be low to non-existant.

View File

@@ -1,25 +1,54 @@
# Strategy Callbacks # Strategy Callbacks
While the main strategy functions (`populate_indicators()`, `populate_buy_trend()`, `populate_sell_trend()`) should be used in a vectorized way, and are only called [once during backtesting](bot-basics.md#backtesting-hyperopt-execution-logic), callbacks are called "whenever needed". While the main strategy functions (`populate_indicators()`, `populate_entry_trend()`, `populate_exit_trend()`) should be used in a vectorized way, and are only called [once during backtesting](bot-basics.md#backtesting-hyperopt-execution-logic), callbacks are called "whenever needed".
As such, you should avoid doing heavy calculations in callbacks to avoid delays during operations. As such, you should avoid doing heavy calculations in callbacks to avoid delays during operations.
Depending on the callback used, they may be called when entering / exiting a trade, or throughout the duration of a trade. Depending on the callback used, they may be called when entering / exiting a trade, or throughout the duration of a trade.
Currently available callbacks: Currently available callbacks:
* [`bot_start()`](#bot-start)
* [`bot_loop_start()`](#bot-loop-start) * [`bot_loop_start()`](#bot-loop-start)
* [`custom_stake_amount()`](#custom-stake-size) * [`custom_stake_amount()`](#stake-size-management)
* [`custom_sell()`](#custom-sell-signal) * [`custom_exit()`](#custom-exit-signal)
* [`custom_stoploss()`](#custom-stoploss) * [`custom_stoploss()`](#custom-stoploss)
* [`custom_entry_price()` and `custom_exit_price()`](#custom-order-price-rules) * [`custom_entry_price()` and `custom_exit_price()`](#custom-order-price-rules)
* [`check_buy_timeout()` and `check_sell_timeout()](#custom-order-timeout-rules) * [`check_entry_timeout()` and `check_exit_timeout()`](#custom-order-timeout-rules)
* [`confirm_trade_entry()`](#trade-entry-buy-order-confirmation) * [`confirm_trade_entry()`](#trade-entry-buy-order-confirmation)
* [`confirm_trade_exit()`](#trade-exit-sell-order-confirmation) * [`confirm_trade_exit()`](#trade-exit-sell-order-confirmation)
* [`adjust_trade_position()`](#adjust-trade-position) * [`adjust_trade_position()`](#adjust-trade-position)
* [`adjust_entry_price()`](#adjust-entry-price)
* [`leverage()`](#leverage-callback)
!!! Tip "Callback calling sequence" !!! Tip "Callback calling sequence"
You can find the callback calling sequence in [bot-basics](bot-basics.md#bot-execution-logic) You can find the callback calling sequence in [bot-basics](bot-basics.md#bot-execution-logic)
## Bot start
A simple callback which is called once when the strategy is loaded.
This can be used to perform actions that must only be performed once and runs after dataprovider and wallet are set
``` python
import requests
class AwesomeStrategy(IStrategy):
# ... populate_* methods
def bot_start(self, **kwargs) -> None:
"""
Called only once after bot instantiation.
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
"""
if self.config['runmode'].value in ('live', 'dry_run'):
# Assign this to the class by using self.*
# can then be used by populate_* methods
self.cust_remote_data = requests.get('https://some_remote_source.example.com')
```
During hyperopt, this runs only once at startup.
## Bot loop start ## Bot loop start
A simple callback which is called once at the start of every bot throttling iteration (roughly every 5 seconds, unless configured differently). A simple callback which is called once at the start of every bot throttling iteration (roughly every 5 seconds, unless configured differently).
@@ -46,15 +75,16 @@ class AwesomeStrategy(IStrategy):
``` ```
## Custom Stake size ### Stake size management
Called before entering a trade, makes it possible to manage your position size when placing a new trade. Called before entering a trade, makes it possible to manage your position size when placing a new trade.
```python ```python
class AwesomeStrategy(IStrategy): class AwesomeStrategy(IStrategy):
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
proposed_stake: float, min_stake: float, max_stake: float, proposed_stake: float, min_stake: Optional[float], max_stake: float,
entry_tag: Optional[str], **kwargs) -> float: leverage: float, entry_tag: Optional[str], side: str,
**kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe) dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
current_candle = dataframe.iloc[-1].squeeze() current_candle = dataframe.iloc[-1].squeeze()
@@ -79,24 +109,25 @@ Freqtrade will fall back to the `proposed_stake` value should your code raise an
!!! Tip !!! Tip
Returning `0` or `None` will prevent trades from being placed. Returning `0` or `None` will prevent trades from being placed.
## Custom sell signal ## Custom exit signal
Called for open trade every throttling iteration (roughly every 5 seconds) until a trade is closed. Called for open trade every throttling iteration (roughly every 5 seconds) until a trade is closed.
Allows to define custom sell signals, indicating that specified position should be sold. This is very useful when we need to customize sell conditions for each individual trade, or if you need trade data to make an exit decision. Allows to define custom exit signals, indicating that specified position should be sold. This is very useful when we need to customize exit conditions for each individual trade, or if you need trade data to make an exit decision.
For example you could implement a 1:2 risk-reward ROI with `custom_sell()`. For example you could implement a 1:2 risk-reward ROI with `custom_exit()`.
Using custom_sell() signals in place of stoploss though *is not recommended*. It is a inferior method to using `custom_stoploss()` in this regard - which also allows you to keep the stoploss on exchange. Using `custom_exit()` signals in place of stoploss though *is not recommended*. It is a inferior method to using `custom_stoploss()` in this regard - which also allows you to keep the stoploss on exchange.
!!! Note !!! Note
Returning a (none-empty) `string` or `True` from this method is equal to setting sell signal on a candle at specified time. This method is not called when sell signal is set already, or if sell signals are disabled (`use_sell_signal=False` or `sell_profit_only=True` while profit is below `sell_profit_offset`). `string` max length is 64 characters. Exceeding this limit will cause the message to be truncated to 64 characters. Returning a (none-empty) `string` or `True` from this method is equal to setting exit signal on a candle at specified time. This method is not called when exit signal is set already, or if exit signals are disabled (`use_exit_signal=False`). `string` max length is 64 characters. Exceeding this limit will cause the message to be truncated to 64 characters.
`custom_exit()` will ignore `exit_profit_only`, and will always be called unless `use_exit_signal=False`, even if there is a new enter signal.
An example of how we can use different indicators depending on the current profit and also sell trades that were open longer than one day: An example of how we can use different indicators depending on the current profit and also exit trades that were open longer than one day:
``` python ``` python
class AwesomeStrategy(IStrategy): class AwesomeStrategy(IStrategy):
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float, def custom_exit(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
current_profit: float, **kwargs): current_profit: float, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze() last_candle = dataframe.iloc[-1].squeeze()
@@ -120,10 +151,11 @@ See [Dataframe access](strategy-advanced.md#dataframe-access) for more informati
## Custom stoploss ## Custom stoploss
Called for open trade every throttling iteration (roughly every 5 seconds) until a trade is closed. Called for open trade every iteration (roughly every 5 seconds) until a trade is closed.
The usage of the custom stoploss method must be enabled by setting `use_custom_stoploss=True` on the strategy object. The usage of the custom stoploss method must be enabled by setting `use_custom_stoploss=True` on the strategy object.
The stoploss price can only ever move upwards - if the stoploss value returned from `custom_stoploss` would result in a lower stoploss price than was previously set, it will be ignored. The traditional `stoploss` value serves as an absolute lower level and will be instated as the initial stoploss (before this method is called for the first time for a trade). The stoploss price can only ever move upwards - if the stoploss value returned from `custom_stoploss` would result in a lower stoploss price than was previously set, it will be ignored. The traditional `stoploss` value serves as an absolute lower level and will be instated as the initial stoploss (before this method is called for the first time for a trade), and is still mandatory.
The method must return a stoploss value (float / number) as a percentage of the current price. The method must return a stoploss value (float / number) as a percentage of the current price.
E.g. If the `current_rate` is 200 USD, then returning `0.02` will set the stoploss price 2% lower, at 196 USD. E.g. If the `current_rate` is 200 USD, then returning `0.02` will set the stoploss price 2% lower, at 196 USD.
@@ -158,7 +190,7 @@ class AwesomeStrategy(IStrategy):
:param pair: Pair that's currently analyzed :param pair: Pair that's currently analyzed
:param trade: trade object. :param trade: trade object.
:param current_time: datetime object, containing the current datetime :param current_time: datetime object, containing the current datetime
:param current_rate: Rate, calculated based on pricing settings in ask_strategy. :param current_rate: Rate, calculated based on pricing settings in exit_pricing.
:param current_profit: Current profit (as ratio), calculated based on current_rate. :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. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return float: New stoploss value, relative to the current rate :return float: New stoploss value, relative to the current rate
@@ -283,11 +315,11 @@ class AwesomeStrategy(IStrategy):
# evaluate highest to lowest, so that highest possible stop is used # evaluate highest to lowest, so that highest possible stop is used
if current_profit > 0.40: if current_profit > 0.40:
return stoploss_from_open(0.25, current_profit) return stoploss_from_open(0.25, current_profit, is_short=trade.is_short)
elif current_profit > 0.25: elif current_profit > 0.25:
return stoploss_from_open(0.15, current_profit) return stoploss_from_open(0.15, current_profit, is_short=trade.is_short)
elif current_profit > 0.20: elif current_profit > 0.20:
return stoploss_from_open(0.07, current_profit) return stoploss_from_open(0.07, current_profit, is_short=trade.is_short)
# return maximum stoploss value, keeping current stoploss price unchanged # return maximum stoploss value, keeping current stoploss price unchanged
return 1 return 1
@@ -362,36 +394,36 @@ class AwesomeStrategy(IStrategy):
# ... populate_* methods # ... populate_* methods
def custom_entry_price(self, pair: str, current_time: datetime, proposed_rate: float, def custom_entry_price(self, pair: str, current_time: datetime, proposed_rate: float,
entry_tag: Optional[str], **kwargs) -> float: entry_tag: Optional[str], side: str, **kwargs) -> float:
dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=pair, dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=pair,
timeframe=self.timeframe) timeframe=self.timeframe)
new_entryprice = dataframe['bollinger_10_lowerband'].iat[-1] new_entryprice = dataframe['bollinger_10_lowerband'].iat[-1]
return new_entryprice return new_entryprice
def custom_exit_price(self, pair: str, trade: Trade, def custom_exit_price(self, pair: str, trade: Trade,
current_time: datetime, proposed_rate: float, current_time: datetime, proposed_rate: float,
current_profit: float, **kwargs) -> float: current_profit: float, exit_tag: Optional[str], **kwargs) -> float:
dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=pair, dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=pair,
timeframe=self.timeframe) timeframe=self.timeframe)
new_exitprice = dataframe['bollinger_10_upperband'].iat[-1] new_exitprice = dataframe['bollinger_10_upperband'].iat[-1]
return new_exitprice return new_exitprice
``` ```
!!! Warning !!! Warning
Modifying entry and exit prices will only work for limit orders. Depending on the price chosen, this can result in a lot of unfilled orders. By default the maximum allowed distance between the current price and the custom price is 2%, this value can be changed in config with the `custom_price_max_distance_ratio` parameter. Modifying entry and exit prices will only work for limit orders. Depending on the price chosen, this can result in a lot of unfilled orders. By default the maximum allowed distance between the current price and the custom price is 2%, this value can be changed in config with the `custom_price_max_distance_ratio` parameter.
**Example**: **Example**:
If the new_entryprice is 97, the proposed_rate is 100 and the `custom_price_max_distance_ratio` is set to 2%, The retained valid custom entry price will be 98, which is 2% below the current (proposed) rate. If the new_entryprice is 97, the proposed_rate is 100 and the `custom_price_max_distance_ratio` is set to 2%, The retained valid custom entry price will be 98, which is 2% below the current (proposed) rate.
!!! Warning "Backtesting" !!! Warning "Backtesting"
Custom prices are supported in backtesting (starting with 2021.12), and orders will fill if the price falls within the candle's low/high range. Custom prices are supported in backtesting (starting with 2021.12), and orders will fill if the price falls within the candle's low/high range.
Orders that don't fill immediately are subject to regular timeout handling, which happens once per (detail) candle. Orders that don't fill immediately are subject to regular timeout handling, which happens once per (detail) candle.
`custom_exit_price()` is only called for sells of type Sell_signal and Custom sell. All other sell-types will use regular backtesting prices. `custom_exit_price()` is only called for sells of type exit_signal and Custom exit. All other exit-types will use regular backtesting prices.
## Custom order timeout rules ## Custom order timeout rules
@@ -406,7 +438,7 @@ However, freqtrade also offers a custom callback for both order types, which all
### Custom order timeout example ### Custom order timeout example
Called for every open order until that order is either filled or cancelled. Called for every open order until that order is either filled or cancelled.
`check_buy_timeout()` is called for trade entries, while `check_sell_timeout()` is called for trade exit orders. `check_entry_timeout()` is called for trade entries, while `check_exit_timeout()` is called for trade exit orders.
A simple example, which applies different unfilled-timeouts depending on the price of the asset can be seen below. A simple example, which applies different unfilled-timeouts depending on the price of the asset can be seen below.
It applies a tight timeout for higher priced assets, while allowing more time to fill on cheap coins. It applies a tight timeout for higher priced assets, while allowing more time to fill on cheap coins.
@@ -415,7 +447,7 @@ The function must return either `True` (cancel order) or `False` (keep order ali
``` python ``` python
from datetime import datetime, timedelta from datetime import datetime, timedelta
from freqtrade.persistence import Trade from freqtrade.persistence import Trade, Order
class AwesomeStrategy(IStrategy): class AwesomeStrategy(IStrategy):
@@ -423,12 +455,12 @@ class AwesomeStrategy(IStrategy):
# Set unfilledtimeout to 25 hours, since the maximum timeout from below is 24 hours. # Set unfilledtimeout to 25 hours, since the maximum timeout from below is 24 hours.
unfilledtimeout = { unfilledtimeout = {
'buy': 60 * 25, 'entry': 60 * 25,
'sell': 60 * 25 'exit': 60 * 25
} }
def check_buy_timeout(self, pair: str, trade: 'Trade', order: dict, def check_entry_timeout(self, pair: str, trade: 'Trade', order: 'Order',
current_time: datetime, **kwargs) -> bool: current_time: datetime, **kwargs) -> bool:
if trade.open_rate > 100 and trade.open_date_utc < current_time - timedelta(minutes=5): if trade.open_rate > 100 and trade.open_date_utc < current_time - timedelta(minutes=5):
return True return True
elif trade.open_rate > 10 and trade.open_date_utc < current_time - timedelta(minutes=3): elif trade.open_rate > 10 and trade.open_date_utc < current_time - timedelta(minutes=3):
@@ -438,7 +470,7 @@ class AwesomeStrategy(IStrategy):
return False return False
def check_sell_timeout(self, pair: str, trade: Trade, order: dict, def check_exit_timeout(self, pair: str, trade: Trade, order: 'Order',
current_time: datetime, **kwargs) -> bool: current_time: datetime, **kwargs) -> bool:
if trade.open_rate > 100 and trade.open_date_utc < current_time - timedelta(minutes=5): if trade.open_rate > 100 and trade.open_date_utc < current_time - timedelta(minutes=5):
return True return True
@@ -456,7 +488,7 @@ class AwesomeStrategy(IStrategy):
``` python ``` python
from datetime import datetime from datetime import datetime
from freqtrade.persistence import Trade from freqtrade.persistence import Trade, Order
class AwesomeStrategy(IStrategy): class AwesomeStrategy(IStrategy):
@@ -464,26 +496,26 @@ class AwesomeStrategy(IStrategy):
# Set unfilledtimeout to 25 hours, since the maximum timeout from below is 24 hours. # Set unfilledtimeout to 25 hours, since the maximum timeout from below is 24 hours.
unfilledtimeout = { unfilledtimeout = {
'buy': 60 * 25, 'entry': 60 * 25,
'sell': 60 * 25 'exit': 60 * 25
} }
def check_buy_timeout(self, pair: str, trade: Trade, order: dict, def check_entry_timeout(self, pair: str, trade: 'Trade', order: 'Order',
current_time: datetime, **kwargs) -> bool: current_time: datetime, **kwargs) -> bool:
ob = self.dp.orderbook(pair, 1) ob = self.dp.orderbook(pair, 1)
current_price = ob['bids'][0][0] current_price = ob['bids'][0][0]
# Cancel buy order if price is more than 2% above the order. # Cancel buy order if price is more than 2% above the order.
if current_price > order['price'] * 1.02: if current_price > order.price * 1.02:
return True return True
return False return False
def check_sell_timeout(self, pair: str, trade: Trade, order: dict, def check_exit_timeout(self, pair: str, trade: 'Trade', order: 'Order',
current_time: datetime, **kwargs) -> bool: current_time: datetime, **kwargs) -> bool:
ob = self.dp.orderbook(pair, 1) ob = self.dp.orderbook(pair, 1)
current_price = ob['asks'][0][0] current_price = ob['asks'][0][0]
# Cancel sell order if price is more than 2% below the order. # Cancel sell order if price is more than 2% below the order.
if current_price < order['price'] * 0.98: if current_price < order.price * 0.98:
return True return True
return False return False
``` ```
@@ -505,10 +537,10 @@ class AwesomeStrategy(IStrategy):
# ... populate_* methods # ... populate_* methods
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, current_time: datetime, entry_tag: Optional[str], time_in_force: str, current_time: datetime, entry_tag: Optional[str],
**kwargs) -> bool: side: str, **kwargs) -> bool:
""" """
Called right before placing a buy order. Called right before placing a entry order.
Timing for this function is critical, so avoid doing heavy computations or Timing for this function is critical, so avoid doing heavy computations or
network requests in this method. network requests in this method.
@@ -516,12 +548,15 @@ class AwesomeStrategy(IStrategy):
When not implemented by a strategy, returns True (always confirming). When not implemented by a strategy, returns True (always confirming).
:param pair: Pair that's about to be bought. :param pair: Pair that's about to be bought/shorted.
:param order_type: Order type (as configured in order_types). usually limit or market. :param order_type: Order type (as configured in order_types). usually limit or market.
:param amount: Amount in target (quote) currency that's going to be traded. :param amount: Amount in target (base) currency that's going to be traded.
:param rate: Rate that's going to be used when using limit orders :param rate: Rate that's going to be used when using limit orders
or current rate for market orders.
:param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled).
:param current_time: datetime object, containing the current datetime :param current_time: datetime object, containing the current datetime
:param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
:param side: 'long' or 'short' - indicating the direction of the proposed trade
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return bool: When True is returned, then the buy-order is placed on the exchange. :return bool: When True is returned, then the buy-order is placed on the exchange.
False aborts the process False aborts the process
@@ -534,6 +569,14 @@ class AwesomeStrategy(IStrategy):
`confirm_trade_exit()` can be used to abort a trade exit (sell) at the latest second (maybe because the price is not what we expect). `confirm_trade_exit()` can be used to abort a trade exit (sell) at the latest second (maybe because the price is not what we expect).
`confirm_trade_exit()` may be called multiple times within one iteration for the same trade if different exit-reasons apply.
The exit-reasons (if applicable) will be in the following sequence:
* `exit_signal` / `custom_exit`
* `stop_loss`
* `roi`
* `trailing_stop_loss`
``` python ``` python
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
@@ -543,10 +586,10 @@ class AwesomeStrategy(IStrategy):
# ... populate_* methods # ... populate_* methods
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str, rate: float, time_in_force: str, exit_reason: str,
current_time: datetime, **kwargs) -> bool: current_time: datetime, **kwargs) -> bool:
""" """
Called right before placing a regular sell order. Called right before placing a regular exit order.
Timing for this function is critical, so avoid doing heavy computations or Timing for this function is critical, so avoid doing heavy computations or
network requests in this method. network requests in this method.
@@ -554,20 +597,22 @@ class AwesomeStrategy(IStrategy):
When not implemented by a strategy, returns True (always confirming). When not implemented by a strategy, returns True (always confirming).
:param pair: Pair that's about to be sold. :param pair: Pair for trade that's about to be exited.
:param trade: trade object.
:param order_type: Order type (as configured in order_types). usually limit or market. :param order_type: Order type (as configured in order_types). usually limit or market.
:param amount: Amount in quote currency. :param amount: Amount in base currency.
:param rate: Rate that's going to be used when using limit orders :param rate: Rate that's going to be used when using limit orders
or current rate for market orders.
:param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled). :param time_in_force: Time in force. Defaults to GTC (Good-til-cancelled).
:param sell_reason: Sell reason. :param exit_reason: Exit reason.
Can be any of ['roi', 'stop_loss', 'stoploss_on_exchange', 'trailing_stop_loss', Can be any of ['roi', 'stop_loss', 'stoploss_on_exchange', 'trailing_stop_loss',
'sell_signal', 'force_sell', 'emergency_sell'] 'exit_signal', 'force_exit', 'emergency_exit']
:param current_time: datetime object, containing the current datetime :param current_time: datetime object, containing the current datetime
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return bool: When True is returned, then the sell-order is placed on the exchange. :return bool: When True, then the exit-order is placed on the exchange.
False aborts the process False aborts the process
""" """
if sell_reason == 'force_sell' and trade.calc_profit_ratio(rate) < 0: if exit_reason == 'force_exit' and trade.calc_profit_ratio(rate) < 0:
# Reject force-sells with negative profit # Reject force-sells with negative profit
# This is just a sample, please adjust to your needs # This is just a sample, please adjust to your needs
# (this does not necessarily make sense, assuming you know when you're force-selling) # (this does not necessarily make sense, assuming you know when you're force-selling)
@@ -576,11 +621,15 @@ class AwesomeStrategy(IStrategy):
``` ```
!!! Warning
`confirm_trade_exit()` can prevent stoploss exits, causing significant losses as this would ignore stoploss exits.
`confirm_trade_exit()` will not be called for Liquidations - as liquidations are forced by the exchange, and therefore cannot be rejected.
## Adjust trade position ## Adjust trade position
The `position_adjustment_enable` strategy property enables the usage of `adjust_trade_position()` callback in the strategy. The `position_adjustment_enable` strategy property enables the usage of `adjust_trade_position()` callback in the strategy.
For performance reasons, it's disabled by default and freqtrade will show a warning message on startup if enabled. For performance reasons, it's disabled by default and freqtrade will show a warning message on startup if enabled.
`adjust_trade_position()` can be used to perform additional orders, for example to manage risk with DCA (Dollar Cost Averaging). `adjust_trade_position()` can be used to perform additional orders, for example to manage risk with DCA (Dollar Cost Averaging) or to increase or decrease positions.
`max_entry_position_adjustment` property is used to limit the number of additional buys per trade (on top of the first buy) that the bot can execute. By default, the value is -1 which means the bot have no limit on number of adjustment buys. `max_entry_position_adjustment` property is used to limit the number of additional buys per trade (on top of the first buy) that the bot can execute. By default, the value is -1 which means the bot have no limit on number of adjustment buys.
@@ -588,9 +637,14 @@ The strategy is expected to return a stake_amount (in stake currency) between `m
If there are not enough funds in the wallet (the return value is above `max_stake`) then the signal will be ignored. If there are not enough funds in the wallet (the return value is above `max_stake`) then the signal will be ignored.
Additional orders also result in additional fees and those orders don't count towards `max_open_trades`. Additional orders also result in additional fees and those orders don't count towards `max_open_trades`.
This callback is **not** called when there is an open order (either buy or sell) waiting for execution, or when you have reached the maximum amount of extra buys that you have set on `max_entry_position_adjustment`. This callback is **not** called when there is an open order (either buy or sell) waiting for execution.
`adjust_trade_position()` is called very frequently for the duration of a trade, so you must keep your implementation as performant as possible. `adjust_trade_position()` is called very frequently for the duration of a trade, so you must keep your implementation as performant as possible.
Additional Buys are ignored once you have reached the maximum amount of extra buys that you have set on `max_entry_position_adjustment`, but the callback is called anyway looking for partial exits.
Position adjustments will always be applied in the direction of the trade, so a positive value will always increase your position (negative values will decrease your position), no matter if it's a long or short trade. Modifications to leverage are not possible.
!!! Note "About stake size" !!! Note "About stake size"
Using fixed stake size means it will be the amount used for the first order, just like without position adjustment. Using fixed stake size means it will be the amount used for the first order, just like without position adjustment.
If you wish to buy additional orders with DCA, then make sure to leave enough funds in the wallet for that. If you wish to buy additional orders with DCA, then make sure to leave enough funds in the wallet for that.
@@ -598,57 +652,77 @@ This callback is **not** called when there is an open order (either buy or sell)
!!! Warning !!! Warning
Stoploss is still calculated from the initial opening price, not averaged price. Stoploss is still calculated from the initial opening price, not averaged price.
Regular stoploss rules still apply (cannot move down).
!!! Warning "/stopbuy"
While `/stopbuy` command stops the bot from entering new trades, the position adjustment feature will continue buying new orders on existing trades. While `/stopbuy` command stops the bot from entering new trades, the position adjustment feature will continue buying new orders on existing trades.
!!! Warning "Backtesting" !!! Warning "Backtesting"
During backtesting this callback is called for each candle in `timeframe` or `timeframe_detail`, so performance will be affected. During backtesting this callback is called for each candle in `timeframe` or `timeframe_detail`, so run-time performance will be affected.
``` python ``` python
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
class DigDeeperStrategy(IStrategy): class DigDeeperStrategy(IStrategy):
position_adjustment_enable = True position_adjustment_enable = True
# Attempts to handle large drops with DCA. High stoploss is required. # Attempts to handle large drops with DCA. High stoploss is required.
stoploss = -0.30 stoploss = -0.30
# ... populate_* methods # ... populate_* methods
# Example specific variables # Example specific variables
max_entry_position_adjustment = 3 max_entry_position_adjustment = 3
# This number is explained a bit further down # This number is explained a bit further down
max_dca_multiplier = 5.5 max_dca_multiplier = 5.5
# This is called when placing the initial order (opening trade) # This is called when placing the initial order (opening trade)
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
proposed_stake: float, min_stake: float, max_stake: float, proposed_stake: float, min_stake: Optional[float], max_stake: float,
entry_tag: Optional[str], **kwargs) -> float: leverage: float, entry_tag: Optional[str], side: str,
**kwargs) -> float:
# We need to leave most of the funds for possible further DCA orders # We need to leave most of the funds for possible further DCA orders
# This also applies to fixed stakes # This also applies to fixed stakes
return proposed_stake / self.max_dca_multiplier return proposed_stake / self.max_dca_multiplier
def adjust_trade_position(self, trade: Trade, current_time: datetime, def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, min_stake: float, current_rate: float, current_profit: float,
max_stake: float, **kwargs): min_stake: Optional[float], max_stake: float,
current_entry_rate: float, current_exit_rate: float,
current_entry_profit: float, current_exit_profit: float,
**kwargs) -> Optional[float]:
""" """
Custom trade adjustment logic, returning the stake amount that a trade should be increased. Custom trade adjustment logic, returning the stake amount that a trade should be
This means extra buy orders with additional fees. increased or decreased.
This means extra buy or sell orders with additional fees.
Only called when `position_adjustment_enable` is set to True.
For full documentation please go to https://www.freqtrade.io/en/latest/strategy-advanced/
When not implemented by a strategy, returns None
:param trade: trade object. :param trade: trade object.
:param current_time: datetime object, containing the current datetime :param current_time: datetime object, containing the current datetime
:param current_rate: Current buy rate. :param current_rate: Current buy rate.
:param current_profit: Current profit (as ratio), calculated based on current_rate. :param current_profit: Current profit (as ratio), calculated based on current_rate.
:param min_stake: Minimal stake size allowed by exchange. :param min_stake: Minimal stake size allowed by exchange (for both entries and exits)
:param max_stake: Balance available for trading. :param max_stake: Maximum stake allowed (either through balance, or by exchange limits).
:param current_entry_rate: Current rate using entry pricing.
:param current_exit_rate: Current rate using exit pricing.
:param current_entry_profit: Current profit using entry pricing.
:param current_exit_profit: Current profit using exit pricing.
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return float: Stake amount to adjust your trade :return float: Stake amount to adjust your trade,
Positive values to increase position, Negative values to decrease position.
Return None for no action.
""" """
if current_profit > 0.05 and trade.nr_of_successful_exits == 0:
# Take half of the profit at +5%
return -(trade.stake_amount / 2)
if current_profit > -0.05: if current_profit > -0.05:
return None return None
@@ -660,8 +734,8 @@ class DigDeeperStrategy(IStrategy):
if last_candle['close'] < previous_candle['close']: if last_candle['close'] < previous_candle['close']:
return None return None
filled_buys = trade.select_filled_orders('buy') filled_entries = trade.select_filled_orders(trade.entry_side)
count_of_buys = trade.nr_of_successful_buys count_of_entries = trade.nr_of_successful_entries
# Allow up to 3 additional increasingly larger buys (4 in total) # Allow up to 3 additional increasingly larger buys (4 in total)
# Initial buy is 1x # Initial buy is 1x
# If that falls to -5% profit, we buy 1.25x more, average profit should increase to roughly -2.2% # If that falls to -5% profit, we buy 1.25x more, average profit should increase to roughly -2.2%
@@ -672,9 +746,9 @@ class DigDeeperStrategy(IStrategy):
# Hope you have a deep wallet! # Hope you have a deep wallet!
try: try:
# This returns first order stake size # This returns first order stake size
stake_amount = filled_buys[0].cost stake_amount = filled_entries[0].cost
# This then calculates current safety order size # This then calculates current safety order size
stake_amount = stake_amount * (1 + (count_of_buys * 0.25)) stake_amount = stake_amount * (1 + (count_of_entries * 0.25))
return stake_amount return stake_amount
except Exception as exception: except Exception as exception:
return None return None
@@ -682,3 +756,117 @@ class DigDeeperStrategy(IStrategy):
return None return None
``` ```
### Position adjust calculations
* Entry rates are calculated using weighted averages.
* Exits will not influence the average entry rate.
* Partial exit relative profit is relative to the average entry price at this point.
* Final exit relative profit is calculated based on the total invested capital. (See example below)
??? example "Calculation example"
*This example assumes 0 fees for simplicity, and a long position on an imaginary coin.*
* Buy 100@8\$
* Buy 100@9\$ -> Avg price: 8.5\$
* Sell 100@10\$ -> Avg price: 8.5\$, realized profit 150\$, 17.65%
* Buy 150@11\$ -> Avg price: 10\$, realized profit 150\$, 17.65%
* Sell 100@12\$ -> Avg price: 10\$, total realized profit 350\$, 20%
* Sell 150@14\$ -> Avg price: 10\$, total realized profit 950\$, 40%
The total profit for this trade was 950$ on a 3350$ investment (`100@8$ + 100@9$ + 150@11$`). As such - the final relative profit is 28.35% (`950 / 3350`).
## Adjust Entry Price
The `adjust_entry_price()` callback may be used by strategy developer to refresh/replace limit orders upon arrival of new candles.
Be aware that `custom_entry_price()` is still the one dictating initial entry limit order price target at the time of entry trigger.
Orders can be cancelled out of this callback by returning `None`.
Returning `current_order_rate` will keep the order on the exchange "as is".
Returning any other price will cancel the existing order, and replace it with a new order.
The trade open-date (`trade.open_date_utc`) will remain at the time of the very first order placed.
Please make sure to be aware of this - and eventually adjust your logic in other callbacks to account for this, and use the date of the first filled order instead.
!!! Warning "Regular timeout"
Entry `unfilledtimeout` mechanism (as well as `check_entry_timeout()`) takes precedence over this.
Entry Orders that are cancelled via the above methods will not have this callback called. Be sure to update timeout values to match your expectations.
```python
from freqtrade.persistence import Trade
from datetime import timedelta
class AwesomeStrategy(IStrategy):
# ... populate_* methods
def adjust_entry_price(self, trade: Trade, order: Optional[Order], pair: str,
current_time: datetime, proposed_rate: float, current_order_rate: float,
entry_tag: Optional[str], side: str, **kwargs) -> float:
"""
Entry price re-adjustment logic, returning the user desired limit price.
This only executes when a order was already placed, still open (unfilled fully or partially)
and not timed out on subsequent candles after entry trigger.
When not implemented by a strategy, returns current_order_rate as default.
If current_order_rate is returned then the existing order is maintained.
If None is returned then order gets canceled but not replaced by a new one.
:param pair: Pair that's currently analyzed
:param trade: Trade object.
:param order: Order object
:param current_time: datetime object, containing the current datetime
:param proposed_rate: Rate, calculated based on pricing settings in entry_pricing.
:param current_order_rate: Rate of the existing order in place.
:param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
:param side: 'long' or 'short' - indicating the direction of the proposed trade
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return float: New entry price value if provided
"""
# Limit orders to use and follow SMA200 as price target for the first 10 minutes since entry trigger for BTC/USDT pair.
if pair == 'BTC/USDT' and entry_tag == 'long_sma200' and side == 'long' and (current_time - timedelta(minutes=10) > trade.open_date_utc:
# just cancel the order if it has been filled more than half of the amount
if order.filled > order.remaining:
return None
else:
dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
current_candle = dataframe.iloc[-1].squeeze()
# desired price
return current_candle['sma_200']
# default: maintain existing order
return current_order_rate
```
## Leverage Callback
When trading in markets that allow leverage, this method must return the desired Leverage (Defaults to 1 -> No leverage).
Assuming a capital of 500USDT, a trade with leverage=3 would result in a position with 500 x 3 = 1500 USDT.
Values that are above `max_leverage` will be adjusted to `max_leverage`.
For markets / exchanges that don't support leverage, this method is ignored.
``` python
class AwesomeStrategy(IStrategy):
def leverage(self, pair: str, current_time: datetime, current_rate: float,
proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], side: str,
**kwargs) -> float:
"""
Customize leverage for each new trade. This method is only called in futures mode.
:param pair: Pair that's currently analyzed
:param current_time: datetime object, containing the current datetime
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
:param proposed_leverage: A leverage proposed by the bot.
:param max_leverage: Max leverage allowed on this pair
:param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
:param side: 'long' or 'short' - indicating the direction of the proposed trade
:return: A leverage amount, which is between 1.0 and max_leverage.
"""
return 1.0
```
All profit calculations include leverage. Stoploss / ROI also include leverage in their calculation.
Defining a stoploss of 10% at 10x leverage would trigger the stoploss with a 1% move to the downside.

View File

@@ -26,8 +26,8 @@ This will create a new strategy file from a template, which will be located unde
A strategy file contains all the information needed to build a good strategy: A strategy file contains all the information needed to build a good strategy:
- Indicators - Indicators
- Buy strategy rules - Entry strategy rules
- Sell strategy rules - Exit strategy rules
- Minimal ROI recommended - Minimal ROI recommended
- Stoploss strongly recommended - Stoploss strongly recommended
@@ -35,7 +35,7 @@ The bot also include a sample strategy called `SampleStrategy` you can update: `
You can test it with the parameter: `--strategy SampleStrategy` You can test it with the parameter: `--strategy SampleStrategy`
Additionally, there is an attribute called `INTERFACE_VERSION`, which defines the version of the strategy interface the bot should use. Additionally, there is an attribute called `INTERFACE_VERSION`, which defines the version of the strategy interface the bot should use.
The current version is 2 - which is also the default when it's not set explicitly in the strategy. The current version is 3 - which is also the default when it's not set explicitly in the strategy.
Future versions will require this to be set. Future versions will require this to be set.
@@ -82,7 +82,7 @@ As a dataframe is a table, simple python comparisons like the following will not
``` python ``` python
if dataframe['rsi'] > 30: if dataframe['rsi'] > 30:
dataframe['buy'] = 1 dataframe['enter_long'] = 1
``` ```
The above section will fail with `The truth value of a Series is ambiguous. [...]`. The above section will fail with `The truth value of a Series is ambiguous. [...]`.
@@ -92,16 +92,16 @@ This must instead be written in a pandas-compatible way, so the operation is per
``` python ``` python
dataframe.loc[ dataframe.loc[
(dataframe['rsi'] > 30) (dataframe['rsi'] > 30)
, 'buy'] = 1 , 'enter_long'] = 1
``` ```
With this section, you have a new column in your dataframe, which has `1` assigned whenever RSI is above 30. With this section, you have a new column in your dataframe, which has `1` assigned whenever RSI is above 30.
### Customize Indicators ### Customize Indicators
Buy and sell strategies need indicators. You can add more indicators by extending the list contained in the method `populate_indicators()` from your strategy file. Buy and sell signals need indicators. You can add more indicators by extending the list contained in the method `populate_indicators()` from your strategy file.
You should only add the indicators used in either `populate_buy_trend()`, `populate_sell_trend()`, or to populate another indicator, otherwise performance may suffer. You should only add the indicators used in either `populate_entry_trend()`, `populate_exit_trend()`, or to populate another indicator, otherwise performance may suffer.
It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected. It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected.
@@ -199,18 +199,18 @@ If this data is available, indicators will be calculated with this extended time
!!! Note !!! Note
If data for the startup period is not available, then the timerange will be adjusted to account for this startup period - so Backtesting would start at 2019-01-01 08:30:00. If data for the startup period is not available, then the timerange will be adjusted to account for this startup period - so Backtesting would start at 2019-01-01 08:30:00.
### Buy signal rules ### Entry signal rules
Edit the method `populate_buy_trend()` in your strategy file to update your buy strategy. Edit the method `populate_entry_trend()` in your strategy file to update your entry strategy.
It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected. It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected.
This method will also define a new column, `"buy"`, which needs to contain 1 for buys, and 0 for "no action". This method will also define a new column, `"enter_long"` (`"enter_short"` for shorts), which needs to contain 1 for entries, and 0 for "no action". `enter_long` is a mandatory column that must be set even if the strategy is shorting only.
Sample from `user_data/strategies/sample_strategy.py`: Sample from `user_data/strategies/sample_strategy.py`:
```python ```python
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
""" """
Based on TA indicators, populates the buy signal for the given dataframe Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame populated with indicators :param dataframe: DataFrame populated with indicators
@@ -224,29 +224,58 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard (dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0 (dataframe['volume'] > 0) # Make sure Volume is not 0
), ),
'buy'] = 1 ['enter_long', 'enter_tag']] = (1, 'rsi_cross')
return dataframe return dataframe
``` ```
??? Note "Enter short trades"
Short-entries can be created by setting `enter_short` (corresponds to `enter_long` for long trades).
The `enter_tag` column remains identical.
Short-trades need to be supported by your exchange and market configuration!
Please make sure to set [`can_short`]() appropriately on your strategy if you intend to short.
```python
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30
(dataframe['tema'] <= dataframe['bb_middleband']) & # Guard
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['enter_long', 'enter_tag']] = (1, 'rsi_cross')
dataframe.loc[
(
(qtpylib.crossed_below(dataframe['rsi'], 70)) & # Signal: RSI crosses below 70
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['enter_short', 'enter_tag']] = (1, 'rsi_cross')
return dataframe
```
!!! Note !!! Note
Buying requires sellers to buy from - therefore volume needs to be > 0 (`dataframe['volume'] > 0`) to make sure that the bot does not buy/sell in no-activity periods. Buying requires sellers to buy from - therefore volume needs to be > 0 (`dataframe['volume'] > 0`) to make sure that the bot does not buy/sell in no-activity periods.
### Sell signal rules ### Exit signal rules
Edit the method `populate_sell_trend()` into your strategy file to update your sell strategy. Edit the method `populate_exit_trend()` into your strategy file to update your exit strategy.
Please note that the sell-signal is only used if `use_sell_signal` is set to true in the configuration. Please note that the exit-signal is only used if `use_exit_signal` is set to true in the configuration.
It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected. It's important to always return the dataframe without removing/modifying the columns `"open", "high", "low", "close", "volume"`, otherwise these fields would contain something unexpected.
This method will also define a new column, `"sell"`, which needs to contain 1 for sells, and 0 for "no action". This method will also define a new column, `"exit_long"` (`"exit_short"` for shorts), which needs to contain 1 for exits, and 0 for "no action".
Sample from `user_data/strategies/sample_strategy.py`: Sample from `user_data/strategies/sample_strategy.py`:
```python ```python
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
""" """
Based on TA indicators, populates the sell signal for the given dataframe Based on TA indicators, populates the exit signal for the given dataframe
:param dataframe: DataFrame populated with indicators :param dataframe: DataFrame populated with indicators
:param metadata: Additional information, like the currently traded pair :param metadata: Additional information, like the currently traded pair
:return: DataFrame with buy column :return: DataFrame with buy column
@@ -258,13 +287,39 @@ def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard (dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0 (dataframe['volume'] > 0) # Make sure Volume is not 0
), ),
'sell'] = 1 ['exit_long', 'exit_tag']] = (1, 'rsi_too_high')
return dataframe return dataframe
``` ```
??? Note "Exit short trades"
Short-exits can be created by setting `exit_short` (corresponds to `exit_long`).
The `exit_tag` column remains identical.
Short-trades need to be supported by your exchange and market configuration!
```python
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 70)) & # Signal: RSI crosses above 70
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['exit_long', 'exit_tag']] = (1, 'rsi_too_high')
dataframe.loc[
(
(qtpylib.crossed_below(dataframe['rsi'], 30)) & # Signal: RSI crosses below 30
(dataframe['tema'] < dataframe['bb_middleband']) & # Guard
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['exit_short', 'exit_tag']] = (1, 'rsi_too_low')
return dataframe
```
### Minimal ROI ### Minimal ROI
This dict defines the minimal Return On Investment (ROI) a trade should reach before selling, independent from the sell signal. This dict defines the minimal Return On Investment (ROI) a trade should reach before exiting, independent from the exit signal.
It is of the following format, with the dict key (left side of the colon) being the minutes passed since the trade opened, and the value (right side of the colon) being the percentage. It is of the following format, with the dict key (left side of the colon) being the minutes passed since the trade opened, and the value (right side of the colon) being the percentage.
@@ -279,10 +334,10 @@ minimal_roi = {
The above configuration would therefore mean: The above configuration would therefore mean:
- Sell whenever 4% profit was reached - Exit whenever 4% profit was reached
- Sell when 2% profit was reached (in effect after 20 minutes) - Exit when 2% profit was reached (in effect after 20 minutes)
- Sell when 1% profit was reached (in effect after 30 minutes) - Exit when 1% profit was reached (in effect after 30 minutes)
- Sell when trade is non-loosing (in effect after 40 minutes) - Exit when trade is non-loosing (in effect after 40 minutes)
The calculation does include fees. The calculation does include fees.
@@ -294,7 +349,7 @@ minimal_roi = {
} }
``` ```
While technically not completely disabled, this would sell once the trade reaches 10000% Profit. While technically not completely disabled, this would exit once the trade reaches 10000% Profit.
To use times based on candle duration (timeframe), the following snippet can be handy. To use times based on candle duration (timeframe), the following snippet can be handy.
This will allow you to change the timeframe for the strategy, and ROI times will still be set as candles (e.g. after 3 candles ...) This will allow you to change the timeframe for the strategy, and ROI times will still be set as candles (e.g. after 3 candles ...)
@@ -325,18 +380,24 @@ stoploss = -0.10
For the full documentation on stoploss features, look at the dedicated [stoploss page](stoploss.md). For the full documentation on stoploss features, look at the dedicated [stoploss page](stoploss.md).
### Timeframe (formerly ticker interval) ### Timeframe
This is the set of candles the bot should download and use for the analysis. This is the set of candles the bot should download and use for the analysis.
Common values are `"1m"`, `"5m"`, `"15m"`, `"1h"`, however all values supported by your exchange should work. Common values are `"1m"`, `"5m"`, `"15m"`, `"1h"`, however all values supported by your exchange should work.
Please note that the same buy/sell signals may work well with one timeframe, but not with the others. Please note that the same entry/exit signals may work well with one timeframe, but not with the others.
This setting is accessible within the strategy methods as the `self.timeframe` attribute. This setting is accessible within the strategy methods as the `self.timeframe` attribute.
### Can short
To use short signals in futures markets, you will have to let us know to do so by setting `can_short=True`.
Strategies which enable this will fail to load on spot markets.
Disabling of this will have short signals ignored (also in futures markets).
### Metadata dict ### Metadata dict
The metadata-dict (available for `populate_buy_trend`, `populate_sell_trend`, `populate_indicators`) contains additional information. The metadata-dict (available for `populate_entry_trend`, `populate_exit_trend`, `populate_indicators`) contains additional information.
Currently this is `pair`, which can be accessed using `metadata['pair']` - and will return a pair in the format `XRP/BTC`. Currently this is `pair`, which can be accessed using `metadata['pair']` - and will return a pair in the format `XRP/BTC`.
The Metadata-dict should not be modified and does not persist information across multiple calls. The Metadata-dict should not be modified and does not persist information across multiple calls.
@@ -382,6 +443,19 @@ A full sample can be found [in the DataProvider section](#complete-data-provider
It is however better to use resampling to longer timeframes whenever possible It is however better to use resampling to longer timeframes whenever possible
to avoid hammering the exchange with too many requests and risk being blocked. to avoid hammering the exchange with too many requests and risk being blocked.
??? Note "Alternative candle types"
Informative_pairs can also provide a 3rd tuple element defining the candle type explicitly.
Availability of alternative candle-types will depend on the trading-mode and the exchange. Details about this can be found in the exchange documentation.
``` python
def informative_pairs(self):
return [
("ETH/USDT", "5m", ""), # Uses default candletype, depends on trading_mode
("ETH/USDT", "5m", "spot"), # Forces usage of spot candles
("BTC/TUSD", "15m", "futures"), # Uses futures candles
("BTC/TUSD", "15m", "mark"), # Uses mark candles
]
```
*** ***
### Informative pairs decorator (`@informative()`) ### Informative pairs decorator (`@informative()`)
@@ -395,6 +469,8 @@ for more information.
``` python ``` python
def informative(timeframe: str, asset: str = '', def informative(timeframe: str, asset: str = '',
fmt: Optional[Union[str, Callable[[KwArg(str)], str]]] = None, fmt: Optional[Union[str, Callable[[KwArg(str)], str]]] = None,
*,
candle_type: Optional[CandleType] = None,
ffill: bool = True) -> Callable[[PopulateIndicators], PopulateIndicators]: ffill: bool = True) -> Callable[[PopulateIndicators], PopulateIndicators]:
""" """
A decorator for populate_indicators_Nn(self, dataframe, metadata), allowing these functions to A decorator for populate_indicators_Nn(self, dataframe, metadata), allowing these functions to
@@ -423,6 +499,7 @@ for more information.
* {column} - name of dataframe column. * {column} - name of dataframe column.
* {timeframe} - timeframe of informative dataframe. * {timeframe} - timeframe of informative dataframe.
:param ffill: ffill dataframe after merging informative pair. :param ffill: ffill dataframe after merging informative pair.
:param candle_type: '', mark, index, premiumIndex, or funding_rate
""" """
``` ```
@@ -451,7 +528,7 @@ for more information.
# Define BTC/STAKE informative pair. Available in populate_indicators and other methods as # Define BTC/STAKE informative pair. Available in populate_indicators and other methods as
# 'btc_rsi_1h'. Current stake currency should be specified as {stake} format variable # 'btc_rsi_1h'. Current stake currency should be specified as {stake} format variable
# instead of hardcoding actual stake currency. Available in populate_indicators and other # instead of hard-coding actual stake currency. Available in populate_indicators and other
# methods as 'btc_usdt_rsi_1h' (when stake currency is USDT). # methods as 'btc_usdt_rsi_1h' (when stake currency is USDT).
@informative('1h', 'BTC/{stake}') @informative('1h', 'BTC/{stake}')
def populate_indicators_btc_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_indicators_btc_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
@@ -490,7 +567,7 @@ for more information.
Use string formatting when accessing informative dataframes of other pairs. This will allow easily changing stake currency in config without having to adjust strategy code. Use string formatting when accessing informative dataframes of other pairs. This will allow easily changing stake currency in config without having to adjust strategy code.
``` python ``` python
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
stake = self.config['stake_currency'] stake = self.config['stake_currency']
dataframe.loc[ dataframe.loc[
( (
@@ -498,7 +575,7 @@ for more information.
& &
(dataframe['volume'] > 0) (dataframe['volume'] > 0)
), ),
['buy', 'buy_tag']] = (1, 'buy_signal_rsi') ['enter_long', 'enter_tag']] = (1, 'buy_signal_rsi')
return dataframe return dataframe
``` ```
@@ -510,7 +587,6 @@ for more information.
will overwrite previously defined method and not produce any errors due to limitations of Python programming language. In such cases you will find that indicators will overwrite previously defined method and not produce any errors due to limitations of Python programming language. In such cases you will find that indicators
created in earlier-defined methods are not available in the dataframe. Carefully review method names and make sure they are unique! created in earlier-defined methods are not available in the dataframe. Carefully review method names and make sure they are unique!
## Additional data (DataProvider) ## Additional data (DataProvider)
The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy. The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy.
@@ -541,9 +617,8 @@ Please always check the mode of operation to select the correct method to get da
### *available_pairs* ### *available_pairs*
``` python ``` python
if self.dp: for pair, timeframe in self.dp.available_pairs:
for pair, timeframe in self.dp.available_pairs: print(f"available {pair}, {timeframe}")
print(f"available {pair}, {timeframe}")
``` ```
### *current_whitelist()* ### *current_whitelist()*
@@ -554,7 +629,7 @@ The strategy might look something like this:
*Scan through the top 10 pairs by volume using the `VolumePairList` every 5 minutes and use a 14 day RSI to buy and sell.* *Scan through the top 10 pairs by volume using the `VolumePairList` every 5 minutes and use a 14 day RSI to buy and sell.*
Due to the limited available data, it's very difficult to resample `5m` candles into daily candles for use in a 14 day RSI. Most exchanges limit us to just 500 candles which effectively gives us around 1.74 daily candles. We need 14 days at least! Due to the limited available data, it's very difficult to resample `5m` candles into daily candles for use in a 14 day RSI. Most exchanges limit us to just 500-1000 candles which effectively gives us around 1.74 daily candles. We need 14 days at least!
Since we can't resample the data we will have to use an informative pair; and since the whitelist will be dynamic we don't know which pair(s) to use. Since we can't resample the data we will have to use an informative pair; and since the whitelist will be dynamic we don't know which pair(s) to use.
@@ -570,14 +645,16 @@ This is where calling `self.dp.current_whitelist()` comes in handy.
return informative_pairs return informative_pairs
``` ```
??? Note "Plotting with current_whitelist"
Current whitelist is not supported for `plot-dataframe`, as this command is usually used by providing an explicit pairlist - and would therefore make the return values of this method misleading.
### *get_pair_dataframe(pair, timeframe)* ### *get_pair_dataframe(pair, timeframe)*
``` python ``` python
# fetch live / historical candle (OHLCV) data for the first informative pair # fetch live / historical candle (OHLCV) data for the first informative pair
if self.dp: inf_pair, inf_timeframe = self.informative_pairs()[0]
inf_pair, inf_timeframe = self.informative_pairs()[0] informative = self.dp.get_pair_dataframe(pair=inf_pair,
informative = self.dp.get_pair_dataframe(pair=inf_pair, timeframe=inf_timeframe)
timeframe=inf_timeframe)
``` ```
!!! Warning "Warning about backtesting" !!! Warning "Warning about backtesting"
@@ -592,10 +669,9 @@ It can also be used in specific callbacks to get the signal that caused the acti
``` python ``` python
# fetch current dataframe # fetch current dataframe
if self.dp: if self.dp.runmode.value in ('live', 'dry_run'):
if self.dp.runmode.value in ('live', 'dry_run'): dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=metadata['pair'],
dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=metadata['pair'], timeframe=self.timeframe)
timeframe=self.timeframe)
``` ```
!!! Note "No data available" !!! Note "No data available"
@@ -605,11 +681,10 @@ if self.dp:
### *orderbook(pair, maximum)* ### *orderbook(pair, maximum)*
``` python ``` python
if self.dp: if self.dp.runmode.value in ('live', 'dry_run'):
if self.dp.runmode.value in ('live', 'dry_run'): ob = self.dp.orderbook(metadata['pair'], 1)
ob = self.dp.orderbook(metadata['pair'], 1) dataframe['best_bid'] = ob['bids'][0][0]
dataframe['best_bid'] = ob['bids'][0][0] dataframe['best_ask'] = ob['asks'][0][0]
dataframe['best_ask'] = ob['asks'][0][0]
``` ```
The orderbook structure is aligned with the order structure from [ccxt](https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure), so the result will look as follows: The orderbook structure is aligned with the order structure from [ccxt](https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure), so the result will look as follows:
@@ -638,12 +713,11 @@ Therefore, using `ob['bids'][0][0]` as demonstrated above will result in using t
### *ticker(pair)* ### *ticker(pair)*
``` python ``` python
if self.dp: if self.dp.runmode.value in ('live', 'dry_run'):
if self.dp.runmode.value in ('live', 'dry_run'): ticker = self.dp.ticker(metadata['pair'])
ticker = self.dp.ticker(metadata['pair']) dataframe['last_price'] = ticker['last']
dataframe['last_price'] = ticker['last'] dataframe['volume24h'] = ticker['quoteVolume']
dataframe['volume24h'] = ticker['quoteVolume'] dataframe['vwap'] = ticker['vwap']
dataframe['vwap'] = ticker['vwap']
``` ```
!!! Warning !!! Warning
@@ -653,7 +727,24 @@ if self.dp:
data returned from the exchange and add appropriate error handling / defaults. data returned from the exchange and add appropriate error handling / defaults.
!!! Warning "Warning about backtesting" !!! Warning "Warning about backtesting"
This method will always return up-to-date values - so usage during backtesting / hyperopt will lead to wrong results. This method will always return up-to-date values - so usage during backtesting / hyperopt without runmode checks will lead to wrong results.
### Send Notification
The dataprovider `.send_msg()` function allows you to send custom notifications from your strategy.
Identical notifications will only be sent once per candle, unless the 2nd argument (`always_send`) is set to True.
``` python
self.dp.send_msg(f"{metadata['pair']} just got hot!")
# Force send this notification, avoid caching (Please read warning below!)
self.dp.send_msg(f"{metadata['pair']} just got hot!", always_send=True)
```
Notifications will only be sent in trading modes (Live/Dry-run) - so this method can be called without conditions for backtesting.
!!! Warning "Spamming"
You can spam yourself pretty good by setting `always_send=True` in this method. Use this with great care and only in conditions you know will not happen throughout a candle to avoid a message every 5 seconds.
### Complete Data-provider sample ### Complete Data-provider sample
@@ -706,7 +797,7 @@ class SampleStrategy(IStrategy):
return dataframe return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[ dataframe.loc[
( (
@@ -714,7 +805,7 @@ class SampleStrategy(IStrategy):
(dataframe['rsi_1d'] < 30) & # Ensure daily RSI is < 30 (dataframe['rsi_1d'] < 30) & # Ensure daily RSI is < 30
(dataframe['volume'] > 0) # Ensure this candle had volume (important for backtesting) (dataframe['volume'] > 0) # Ensure this candle had volume (important for backtesting)
), ),
'buy'] = 1 ['enter_long', 'enter_tag']] = (1, 'rsi_cross')
``` ```
@@ -791,7 +882,7 @@ Stoploss values returned from `custom_stoploss` must specify a percentage relati
Say the open price was $100, and `current_price` is $121 (`current_profit` will be `0.21`). Say the open price was $100, and `current_price` is $121 (`current_profit` will be `0.21`).
If we want a stop price at 7% above the open price we can call `stoploss_from_open(0.07, current_profit)` which will return `0.1157024793`. 11.57% below $121 is $107, which is the same as 7% above $100. If we want a stop price at 7% above the open price we can call `stoploss_from_open(0.07, current_profit, False)` which will return `0.1157024793`. 11.57% below $121 is $107, which is the same as 7% above $100.
``` python ``` python
@@ -811,7 +902,7 @@ Stoploss values returned from `custom_stoploss` must specify a percentage relati
# once the profit has risen above 10%, keep the stoploss at 7% above the open price # once the profit has risen above 10%, keep the stoploss at 7% above the open price
if current_profit > 0.10: if current_profit > 0.10:
return stoploss_from_open(0.07, current_profit) return stoploss_from_open(0.07, current_profit, is_short=trade.is_short)
return 1 return 1
@@ -822,7 +913,7 @@ Stoploss values returned from `custom_stoploss` must specify a percentage relati
!!! Note !!! Note
Providing invalid input to `stoploss_from_open()` may produce "CustomStoploss function did not return valid stoploss" warnings. Providing invalid input to `stoploss_from_open()` may produce "CustomStoploss function did not return valid stoploss" warnings.
This may happen if `current_profit` parameter is below specified `open_relative_stop`. Such situations may arise when closing trade This may happen if `current_profit` parameter is below specified `open_relative_stop`. Such situations may arise when closing trade
is blocked by `confirm_trade_exit()` method. Warnings can be solved by never blocking stop loss sells by checking `sell_reason` in is blocked by `confirm_trade_exit()` method. Warnings can be solved by never blocking stop loss sells by checking `exit_reason` in
`confirm_trade_exit()`, or by using `return stoploss_from_open(...) or 1` idiom, which will request to not change stop loss when `confirm_trade_exit()`, or by using `return stoploss_from_open(...) or 1` idiom, which will request to not change stop loss when
`current_profit < open_relative_stop`. `current_profit < open_relative_stop`.
@@ -832,7 +923,7 @@ In some situations it may be confusing to deal with stops relative to current ra
??? Example "Returning a stoploss using absolute price from the custom stoploss function" ??? Example "Returning a stoploss using absolute price from the custom stoploss function"
If we want to trail a stop price at 2xATR below current proce we can call `stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate)`. If we want to trail a stop price at 2xATR below current price we can call `stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short)`.
``` python ``` python
@@ -852,7 +943,7 @@ In some situations it may be confusing to deal with stops relative to current ra
current_rate: float, current_profit: float, **kwargs) -> float: current_rate: float, current_profit: float, **kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
candle = dataframe.iloc[-1].squeeze() candle = dataframe.iloc[-1].squeeze()
return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate) return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short)
``` ```
@@ -920,7 +1011,7 @@ if self.config['runmode'].value in ('live', 'dry_run'):
Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of 0.015). Sample return value: ETH/BTC had 5 trades, with a total profit of 1.5% (ratio of 0.015).
``` json ``` json
{'pair': "ETH/BTC", 'profit': 0.015, 'count': 5} {"pair": "ETH/BTC", "profit": 0.015, "count": 5}
``` ```
!!! Warning !!! Warning
@@ -974,16 +1065,16 @@ if self.config['runmode'].value in ('live', 'dry_run'):
## Print created dataframe ## Print created dataframe
To inspect the created dataframe, you can issue a print-statement in either `populate_buy_trend()` or `populate_sell_trend()`. To inspect the created dataframe, you can issue a print-statement in either `populate_entry_trend()` or `populate_exit_trend()`.
You may also want to print the pair so it's clear what data is currently shown. You may also want to print the pair so it's clear what data is currently shown.
``` python ``` python
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[ dataframe.loc[
( (
#>> whatever condition<<< #>> whatever condition<<<
), ),
'buy'] = 1 ['enter_long', 'enter_tag']] = (1, 'somestring')
# Print the Analyzed pair # Print the Analyzed pair
print(f"result for {metadata['pair']}") print(f"result for {metadata['pair']}")
@@ -1012,7 +1103,12 @@ The following lists some common patterns which should be avoided to prevent frus
### Colliding signals ### Colliding signals
When buy and sell signals collide (both `'buy'` and `'sell'` are 1), freqtrade will do nothing and ignore the entry (buy) signal. This will avoid trades that buy, and sell immediately. Obviously, this can potentially lead to missed entries. When conflicting signals collide (e.g. both `'enter_long'` and `'exit_long'` are 1), freqtrade will do nothing and ignore the entry signal. This will avoid trades that enter, and exit immediately. Obviously, this can potentially lead to missed entries.
The following rules apply, and entry signals will be ignored if more than one of the 3 signals is set:
- `enter_long` -> `exit_long`, `enter_short`
- `enter_short` -> `exit_short`, `enter_long`
## Further strategy ideas ## Further strategy ideas

View File

@@ -14,7 +14,7 @@ from freqtrade.configuration import Configuration
# Initialize empty configuration object # Initialize empty configuration object
config = Configuration.from_files([]) config = Configuration.from_files([])
# Optionally, use existing configuration file # Optionally (recommended), use existing configuration file
# config = Configuration.from_files(["config.json"]) # config = Configuration.from_files(["config.json"])
# Define some constants # Define some constants
@@ -22,7 +22,7 @@ config["timeframe"] = "5m"
# Name of the strategy class # Name of the strategy class
config["strategy"] = "SampleStrategy" config["strategy"] = "SampleStrategy"
# Location of the data # Location of the data
data_location = Path(config['user_data_dir'], 'data', 'binance') data_location = config['datadir']
# Pair to analyze - Only use one pair here # Pair to analyze - Only use one pair here
pair = "BTC/USDT" pair = "BTC/USDT"
``` ```
@@ -31,11 +31,13 @@ pair = "BTC/USDT"
```python ```python
# Load data using values set above # Load data using values set above
from freqtrade.data.history import load_pair_history from freqtrade.data.history import load_pair_history
from freqtrade.enums import CandleType
candles = load_pair_history(datadir=data_location, candles = load_pair_history(datadir=data_location,
timeframe=config["timeframe"], timeframe=config["timeframe"],
pair=pair, pair=pair,
data_format = "hdf5", data_format = "hdf5",
candle_type=CandleType.SPOT,
) )
# Confirm success # Confirm success
@@ -73,7 +75,7 @@ df.tail()
```python ```python
# Report results # Report results
print(f"Generated {df['buy'].sum()} buy signals") print(f"Generated {df['enter_long'].sum()} entry signals")
data = df.set_index('date', drop=False) data = df.set_index('date', drop=False)
data.tail() data.tail()
``` ```
@@ -129,7 +131,7 @@ print(stats['strategy_comparison'])
trades = load_backtest_data(backtest_dir) trades = load_backtest_data(backtest_dir)
# Show value-counts per pair # Show value-counts per pair
trades.groupby("pair")["sell_reason"].value_counts() trades.groupby("pair")["exit_reason"].value_counts()
``` ```
## Plotting daily profit / equity line ## Plotting daily profit / equity line
@@ -182,7 +184,7 @@ from freqtrade.data.btanalysis import load_trades_from_db
trades = load_trades_from_db("sqlite:///tradesv3.sqlite") trades = load_trades_from_db("sqlite:///tradesv3.sqlite")
# Display results # Display results
trades.groupby("pair")["sell_reason"].value_counts() trades.groupby("pair")["exit_reason"].value_counts()
``` ```
## Analyze the loaded trades for trade parallelism ## Analyze the loaded trades for trade parallelism
@@ -244,7 +246,7 @@ import plotly.figure_factory as ff
hist_data = [trades.profit_ratio] hist_data = [trades.profit_ratio]
group_labels = ['profit_ratio'] # name of the dataset group_labels = ['profit_ratio'] # name of the dataset
fig = ff.create_distplot(hist_data, group_labels,bin_size=0.01) fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)
fig.show() fig.show()
``` ```

471
docs/strategy_migration.md Normal file
View File

@@ -0,0 +1,471 @@
# Strategy Migration between V2 and V3
To support new markets and trade-types (namely short trades / trades with leverage), some things had to change in the interface.
If you intend on using markets other than spot markets, please migrate your strategy to the new format.
We have put a great effort into keeping compatibility with existing strategies, so if you just want to continue using freqtrade in __spot markets__, there should be no changes necessary for now.
You can use the quick summary as checklist. Please refer to the detailed sections below for full migration details.
## Quick summary / migration checklist
Note : `forcesell`, `forcebuy`, `emergencysell` are changed to `force_exit`, `force_enter`, `emergency_exit` respectively.
* Strategy methods:
* [`populate_buy_trend()` -> `populate_entry_trend()`](#populate_buy_trend)
* [`populate_sell_trend()` -> `populate_exit_trend()`](#populate_sell_trend)
* [`custom_sell()` -> `custom_exit()`](#custom_sell)
* [`check_buy_timeout()` -> `check_entry_timeout()`](#custom_entry_timeout)
* [`check_sell_timeout()` -> `check_exit_timeout()`](#custom_entry_timeout)
* New `side` argument to callbacks without trade object
* [`custom_stake_amount`](#custom_stake_amount)
* [`confirm_trade_entry`](#confirm_trade_entry)
* [`custom_entry_price`](#custom_entry_price)
* [Changed argument name in `confirm_trade_exit`](#confirm_trade_exit)
* Dataframe columns:
* [`buy` -> `enter_long`](#populate_buy_trend)
* [`sell` -> `exit_long`](#populate_sell_trend)
* [`buy_tag` -> `enter_tag` (used for both long and short trades)](#populate_buy_trend)
* [New column `enter_short` and corresponding new column `exit_short`](#populate_sell_trend)
* trade-object now has the following new properties:
* `is_short`
* `entry_side`
* `exit_side`
* `trade_direction`
* renamed: `sell_reason` -> `exit_reason`
* [Renamed `trade.nr_of_successful_buys` to `trade.nr_of_successful_entries` (mostly relevant for `adjust_trade_position()`)](#adjust-trade-position-changes)
* Introduced new [`leverage` callback](strategy-callbacks.md#leverage-callback).
* Informative pairs can now pass a 3rd element in the Tuple, defining the candle type.
* `@informative` decorator now takes an optional `candle_type` argument.
* [helper methods](#helper-methods) `stoploss_from_open` and `stoploss_from_absolute` now take `is_short` as additional argument.
* `INTERFACE_VERSION` should be set to 3.
* [Strategy/Configuration settings](#strategyconfiguration-settings).
* `order_time_in_force` buy -> entry, sell -> exit.
* `order_types` buy -> entry, sell -> exit.
* `unfilledtimeout` buy -> entry, sell -> exit.
* Terminology changes
* Sell reasons changed to reflect the new naming of "exit" instead of sells. Be careful in your strategy if you're using `exit_reason` checks and eventually update your strategy.
* `sell_signal` -> `exit_signal`
* `custom_sell` -> `custom_exit`
* `force_sell` -> `force_exit`
* `emergency_sell` -> `emergency_exit`
* Webhook terminology changed from "sell" to "exit", and from "buy" to entry
* `webhookbuy` -> `webhookentry`
* `webhookbuyfill` -> `webhookentryfill`
* `webhookbuycancel` -> `webhookentrycancel`
* `webhooksell` -> `webhookexit`
* `webhooksellfill` -> `webhookexitfill`
* `webhooksellcancel` -> `webhookexitcancel`
* Telegram notification settings
* `buy` -> `entry`
* `buy_fill` -> `entry_fill`
* `buy_cancel` -> `entry_cancel`
* `sell` -> `exit`
* `sell_fill` -> `exit_fill`
* `sell_cancel` -> `exit_cancel`
* Strategy/config settings:
* `use_sell_signal` -> `use_exit_signal`
* `sell_profit_only` -> `exit_profit_only`
* `sell_profit_offset` -> `exit_profit_offset`
* `ignore_roi_if_buy_signal` -> `ignore_roi_if_entry_signal`
* `forcebuy_enable` -> `force_entry_enable`
## Extensive explanation
### `populate_buy_trend`
In `populate_buy_trend()` - you will want to change the columns you assign from `'buy`' to `'enter_long'`, as well as the method name from `populate_buy_trend` to `populate_entry_trend`.
```python hl_lines="1 9"
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30
(dataframe['tema'] <= dataframe['bb_middleband']) & # Guard
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['buy', 'buy_tag']] = (1, 'rsi_cross')
return dataframe
```
After:
```python hl_lines="1 9"
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30
(dataframe['tema'] <= dataframe['bb_middleband']) & # Guard
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['enter_long', 'enter_tag']] = (1, 'rsi_cross')
return dataframe
```
Please refer to the [Strategy documentation](strategy-customization.md#entry-signal-rules) on how to enter and exit short trades.
### `populate_sell_trend`
Similar to `populate_buy_trend`, `populate_sell_trend()` will be renamed to `populate_exit_trend()`.
We'll also change the column from `'sell'` to `'exit_long'`.
``` python hl_lines="1 9"
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 70)) & # Signal: RSI crosses above 70
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['sell', 'exit_tag']] = (1, 'some_exit_tag')
return dataframe
```
After
``` python hl_lines="1 9"
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 70)) & # Signal: RSI crosses above 70
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
['exit_long', 'exit_tag']] = (1, 'some_exit_tag')
return dataframe
```
Please refer to the [Strategy documentation](strategy-customization.md#exit-signal-rules) on how to enter and exit short trades.
### `custom_sell`
`custom_sell` has been renamed to `custom_exit`.
It's now also being called for every iteration, independent of current profit and `exit_profit_only` settings.
``` python hl_lines="2"
class AwesomeStrategy(IStrategy):
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
current_profit: float, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
# ...
```
``` python hl_lines="2"
class AwesomeStrategy(IStrategy):
def custom_exit(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
current_profit: float, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
# ...
```
### `custom_entry_timeout`
`check_buy_timeout()` has been renamed to `check_entry_timeout()`, and `check_sell_timeout()` has been renamed to `check_exit_timeout()`.
``` python hl_lines="2 6"
class AwesomeStrategy(IStrategy):
def check_buy_timeout(self, pair: str, trade: 'Trade', order: dict,
current_time: datetime, **kwargs) -> bool:
return False
def check_sell_timeout(self, pair: str, trade: 'Trade', order: dict,
current_time: datetime, **kwargs) -> bool:
return False
```
``` python hl_lines="2 6"
class AwesomeStrategy(IStrategy):
def check_entry_timeout(self, pair: str, trade: 'Trade', order: 'Order',
current_time: datetime, **kwargs) -> bool:
return False
def check_exit_timeout(self, pair: str, trade: 'Trade', order: 'Order',
current_time: datetime, **kwargs) -> bool:
return False
```
### `custom_stake_amount`
New string argument `side` - which can be either `"long"` or `"short"`.
``` python hl_lines="4"
class AwesomeStrategy(IStrategy):
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
proposed_stake: float, min_stake: Optional[float], max_stake: float,
entry_tag: Optional[str], **kwargs) -> float:
# ...
return proposed_stake
```
``` python hl_lines="4"
class AwesomeStrategy(IStrategy):
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
proposed_stake: float, min_stake: Optional[float], max_stake: float,
entry_tag: Optional[str], side: str, **kwargs) -> float:
# ...
return proposed_stake
```
### `confirm_trade_entry`
New string argument `side` - which can be either `"long"` or `"short"`.
``` python hl_lines="4"
class AwesomeStrategy(IStrategy):
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, current_time: datetime, entry_tag: Optional[str],
**kwargs) -> bool:
return True
```
After:
``` python hl_lines="4"
class AwesomeStrategy(IStrategy):
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, current_time: datetime, entry_tag: Optional[str],
side: str, **kwargs) -> bool:
return True
```
### `confirm_trade_exit`
Changed argument `sell_reason` to `exit_reason`.
For compatibility, `sell_reason` will still be provided for a limited time.
``` python hl_lines="3"
class AwesomeStrategy(IStrategy):
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str,
current_time: datetime, **kwargs) -> bool:
return True
```
After:
``` python hl_lines="3"
class AwesomeStrategy(IStrategy):
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, exit_reason: str,
current_time: datetime, **kwargs) -> bool:
return True
```
### `custom_entry_price`
New string argument `side` - which can be either `"long"` or `"short"`.
``` python hl_lines="3"
class AwesomeStrategy(IStrategy):
def custom_entry_price(self, pair: str, current_time: datetime, proposed_rate: float,
entry_tag: Optional[str], **kwargs) -> float:
return proposed_rate
```
After:
``` python hl_lines="3"
class AwesomeStrategy(IStrategy):
def custom_entry_price(self, pair: str, current_time: datetime, proposed_rate: float,
entry_tag: Optional[str], side: str, **kwargs) -> float:
return proposed_rate
```
### Adjust trade position changes
While adjust-trade-position itself did not change, you should no longer use `trade.nr_of_successful_buys` - and instead use `trade.nr_of_successful_entries`, which will also include short entries.
### Helper methods
Added argument "is_short" to `stoploss_from_open` and `stoploss_from_absolute`.
This should be given the value of `trade.is_short`.
``` python hl_lines="5 7"
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# once the profit has risen above 10%, keep the stoploss at 7% above the open price
if current_profit > 0.10:
return stoploss_from_open(0.07, current_profit)
return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate)
return 1
```
After:
``` python hl_lines="5 7"
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
# once the profit has risen above 10%, keep the stoploss at 7% above the open price
if current_profit > 0.10:
return stoploss_from_open(0.07, current_profit, is_short=trade.is_short)
return stoploss_from_absolute(current_rate - (candle['atr'] * 2), current_rate, is_short=trade.is_short)
```
### Strategy/Configuration settings
#### `order_time_in_force`
`order_time_in_force` attributes changed from `"buy"` to `"entry"` and `"sell"` to `"exit"`.
``` python
order_time_in_force: Dict = {
"buy": "gtc",
"sell": "gtc",
}
```
After:
``` python hl_lines="2 3"
order_time_in_force: Dict = {
"entry": "gtc",
"exit": "gtc",
}
```
#### `order_types`
`order_types` have changed all wordings from `buy` to `entry` - and `sell` to `exit`.
And two words are joined with `_`.
``` python hl_lines="2-6"
order_types = {
"buy": "limit",
"sell": "limit",
"emergencysell": "market",
"forcesell": "market",
"forcebuy": "market",
"stoploss": "market",
"stoploss_on_exchange": false,
"stoploss_on_exchange_interval": 60
}
```
After:
``` python hl_lines="2-6"
order_types = {
"entry": "limit",
"exit": "limit",
"emergency_exit": "market",
"force_exit": "market",
"force_entry": "market",
"stoploss": "market",
"stoploss_on_exchange": false,
"stoploss_on_exchange_interval": 60
}
```
#### Strategy level settings
* `use_sell_signal` -> `use_exit_signal`
* `sell_profit_only` -> `exit_profit_only`
* `sell_profit_offset` -> `exit_profit_offset`
* `ignore_roi_if_buy_signal` -> `ignore_roi_if_entry_signal`
``` python hl_lines="2-5"
# These values can be overridden in the config.
use_sell_signal = True
sell_profit_only = True
sell_profit_offset: 0.01
ignore_roi_if_buy_signal = False
```
After:
``` python hl_lines="2-5"
# These values can be overridden in the config.
use_exit_signal = True
exit_profit_only = True
exit_profit_offset: 0.01
ignore_roi_if_entry_signal = False
```
#### `unfilledtimeout`
`unfilledtimeout` have changed all wordings from `buy` to `entry` - and `sell` to `exit`.
``` python hl_lines="2-3"
unfilledtimeout = {
"buy": 10,
"sell": 10,
"exit_timeout_count": 0,
"unit": "minutes"
}
```
After:
``` python hl_lines="2-3"
unfilledtimeout = {
"entry": 10,
"exit": 10,
"exit_timeout_count": 0,
"unit": "minutes"
}
```
#### `order pricing`
Order pricing changed in 2 ways. `bid_strategy` was renamed to `entry_pricing` and `ask_strategy` was renamed to `exit_pricing`.
The attributes `ask_last_balance` -> `price_last_balance` and `bid_last_balance` -> `price_last_balance` were renamed as well.
Also, price-side can now be defined as `ask`, `bid`, `same` or `other`.
Please refer to the [pricing documentation](configuration.md#prices-used-for-orders) for more information.
``` json hl_lines="2-3 6 12-13 16"
{
"bid_strategy": {
"price_side": "bid",
"use_order_book": true,
"order_book_top": 1,
"ask_last_balance": 0.0,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"ask_strategy":{
"price_side": "ask",
"use_order_book": true,
"order_book_top": 1,
"bid_last_balance": 0.0
}
}
```
after:
``` json hl_lines="2-3 6 12-13 16"
{
"entry_pricing": {
"price_side": "same",
"use_order_book": true,
"order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"exit_pricing":{
"price_side": "same",
"use_order_book": true,
"order_book_top": 1,
"price_last_balance": 0.0
}
}
```

View File

@@ -81,34 +81,37 @@ Example configuration showing the different settings:
"status": "silent", "status": "silent",
"warning": "on", "warning": "on",
"startup": "off", "startup": "off",
"buy": "silent", "entry": "silent",
"sell": { "exit": {
"roi": "silent", "roi": "silent",
"emergency_sell": "on", "emergency_exit": "on",
"force_sell": "on", "force_exit": "on",
"sell_signal": "silent", "exit_signal": "silent",
"trailing_stop_loss": "on", "trailing_stop_loss": "on",
"stop_loss": "on", "stop_loss": "on",
"stoploss_on_exchange": "on", "stoploss_on_exchange": "on",
"custom_sell": "silent" "custom_exit": "silent"
}, },
"buy_cancel": "silent", "entry_cancel": "silent",
"sell_cancel": "on", "exit_cancel": "on",
"buy_fill": "off", "entry_fill": "off",
"sell_fill": "off", "exit_fill": "off",
"protection_trigger": "off", "protection_trigger": "off",
"protection_trigger_global": "on" "protection_trigger_global": "on",
"strategy_msg": "off",
"show_candle": "off"
}, },
"reload": true, "reload": true,
"balance_dust_level": 0.01 "balance_dust_level": 0.01
}, },
``` ```
`buy` notifications are sent when the order is placed, while `buy_fill` notifications are sent when the order is filled on the exchange. `entry` notifications are sent when the order is placed, while `entry_fill` notifications are sent when the order is filled on the exchange.
`sell` notifications are sent when the order is placed, while `sell_fill` notifications are sent when the order is filled on the exchange. `exit` notifications are sent when the order is placed, while `exit_fill` notifications are sent when the order is filled on the exchange.
`*_fill` notifications are off by default and must be explicitly enabled. `*_fill` notifications are off by default and must be explicitly enabled.
`protection_trigger` notifications are sent when a protection triggers and `protection_trigger_global` notifications trigger when global protections are triggered. `protection_trigger` notifications are sent when a protection triggers and `protection_trigger_global` notifications trigger when global protections are triggered.
`strategy_msg` - Receive notifications from the strategy, sent via `self.dp.send_msg()` from the strategy [more details](strategy-customization.md#send-notification).
`show_candle` - show candle values as part of entry/exit messages. Only possible values are `"ohlc"` or `"off"`.
`balance_dust_level` will define what the `/balance` command takes as "dust" - Currencies with a balance below this will be shown. `balance_dust_level` will define what the `/balance` command takes as "dust" - Currencies with a balance below this will be shown.
`reload` allows you to disable reload-buttons on selected messages. `reload` allows you to disable reload-buttons on selected messages.
@@ -171,16 +174,20 @@ official commands. You can ask at any moment for help with `/help`.
| `/locks` | Show currently locked pairs. | `/locks` | Show currently locked pairs.
| `/unlock <pair or lock_id>` | Remove the lock for this pair (or for this lock id). | `/unlock <pair or lock_id>` | Remove the lock for this pair (or for this lock id).
| `/profit [<n>]` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default) | `/profit [<n>]` | Display a summary of your profit/loss from close trades and some stats about your performance, over the last n days (all trades by default)
| `/forcesell <trade_id>` | Instantly sells the given trade (Ignoring `minimum_roi`). | `/forceexit <trade_id> | /fx <tradeid>` | Instantly exits the given trade (Ignoring `minimum_roi`).
| `/forcesell all` | Instantly sells all open trades (Ignoring `minimum_roi`). | `/forceexit all | /fx all` | Instantly exits all open trades (Ignoring `minimum_roi`).
| `/forcebuy <pair> [rate]` | Instantly buys the given pair. Rate is optional and only applies to limit orders. (`forcebuy_enable` must be set to True) | `/fx` | alias for `/forceexit`
| `/forcelong <pair> [rate]` | Instantly buys the given pair. Rate is optional and only applies to limit orders. (`force_entry_enable` must be set to True)
| `/forceshort <pair> [rate]` | Instantly shorts the given pair. Rate is optional and only applies to limit orders. This will only work on non-spot markets. (`force_entry_enable` must be set to True)
| `/performance` | Show performance of each finished trade grouped by pair | `/performance` | Show performance of each finished trade grouped by pair
| `/balance` | Show account balance per currency | `/balance` | Show account balance per currency
| `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7) | `/daily <n>` | Shows profit or loss per day, over the last n days (n defaults to 7)
| `/weekly <n>` | Shows profit or loss per week, over the last n weeks (n defaults to 8) | `/weekly <n>` | Shows profit or loss per week, over the last n weeks (n defaults to 8)
| `/monthly <n>` | Shows profit or loss per month, over the last n months (n defaults to 6) | `/monthly <n>` | Shows profit or loss per month, over the last n months (n defaults to 6)
| `/stats` | Shows Wins / losses by Sell reason as well as Avg. holding durations for buys and sells | `/stats` | Shows Wins / losses by Exit reason as well as Avg. holding durations for buys and sells
| `/whitelist` | Show the current whitelist | `/exits` | Shows Wins / losses by Exit reason as well as Avg. holding durations for buys and sells
| `/entries` | Shows Wins / losses by Exit reason as well as Avg. holding durations for buys and sells
| `/whitelist [sorted] [baseonly]` | Show the current whitelist. Optionally display in alphabetical order and/or with just the base currency of each pairing.
| `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist. | `/blacklist [pair]` | Show the current blacklist, or adds a pair to the blacklist.
| `/edge` | Show validated pairs by Edge if it is enabled. | `/edge` | Show validated pairs by Edge if it is enabled.
| `/help` | Show help message | `/help` | Show help message
@@ -216,11 +223,14 @@ Once all positions are sold, run `/stop` to completely stop the bot.
### /status ### /status
For each open trade, the bot will send you the following message. For each open trade, the bot will send you the following message.
Enter Tag is configurable via Strategy.
> **Trade ID:** `123` `(since 1 days ago)` > **Trade ID:** `123` `(since 1 days ago)`
> **Current Pair:** CVC/BTC > **Current Pair:** CVC/BTC
> **Open Since:** `1 days ago` > **Direction:** Long
> **Leverage:** 1.0
> **Amount:** `26.64180098` > **Amount:** `26.64180098`
> **Enter Tag:** Awesome Long Signal
> **Open Rate:** `0.00007489` > **Open Rate:** `0.00007489`
> **Current Rate:** `0.00007489` > **Current Rate:** `0.00007489`
> **Current Profit:** `12.95%` > **Current Profit:** `12.95%`
@@ -231,10 +241,10 @@ For each open trade, the bot will send you the following message.
Return the status of all open trades in a table format. Return the status of all open trades in a table format.
``` ```
ID Pair Since Profit ID L/S Pair Since Profit
---- -------- ------- -------- ---- -------- ------- --------
67 SC/BTC 1 d 13.33% 67 L SC/BTC 1 d 13.33%
123 CVC/BTC 1 h 12.95% 123 S CVC/BTC 1 h 12.95%
``` ```
### /count ### /count
@@ -263,26 +273,38 @@ Return a summary of your profit/loss and performance.
> **Latest Trade opened:** `2 minutes ago` > **Latest Trade opened:** `2 minutes ago`
> **Avg. Duration:** `2:33:45` > **Avg. Duration:** `2:33:45`
> **Best Performing:** `PAY/BTC: 50.23%` > **Best Performing:** `PAY/BTC: 50.23%`
> **Trading volume:** `0.5 BTC`
> **Profit factor:** `1.04`
> **Max Drawdown:** `9.23% (0.01255 BTC)`
The relative profit of `1.2%` is the average profit per trade. The relative profit of `1.2%` is the average profit per trade.
The relative profit of `15.2 Σ%` is be based on the starting capital - so in this case, the starting capital was `0.00485701 * 1.152 = 0.00738 BTC`. The relative profit of `15.2 Σ%` is be based on the starting capital - so in this case, the starting capital was `0.00485701 * 1.152 = 0.00738 BTC`.
Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits. Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits.
Profit Factor is calculated as gross profits / gross losses - and should serve as an overall metric for the strategy.
Max drawdown corresponds to the backtesting metric `Absolute Drawdown (Account)` - calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`.
### /forcesell <trade_id> ### /forceexit <trade_id>
> **BITTREX:** Selling BTC/LTC with limit `0.01650000 (profit: ~-4.07%, -0.00008168)` > **BINANCE:** Exiting BTC/LTC with limit `0.01650000 (profit: ~-4.07%, -0.00008168)`
### /forcebuy <pair> [rate] !!! Tip
You can get a list of all open trades by calling `/forceexit` without parameter, which will show a list of buttons to simply exit a trade.
This command has an alias in `/fx` - which has the same capabilities, but is faster to type in "emergency" situations.
> **BITTREX:** Buying ETH/BTC with limit `0.03400000` (`1.000000 ETH`, `225.290 USD`) ### /forcelong <pair> [rate] | /forceshort <pair> [rate]
Omitting the pair will open a query asking for the pair to buy (based on the current whitelist). `/forcebuy <pair> [rate]` is also supported for longs but should be considered deprecated.
> **BINANCE:** Long ETH/BTC with limit `0.03400000` (`1.000000 ETH`, `225.290 USD`)
Omitting the pair will open a query asking for the pair to trade (based on the current whitelist).
Trades created through `/forcelong` will have the buy-tag of `force_entry`.
![Telegram force-buy screenshot](assets/telegram_forcebuy.png) ![Telegram force-buy screenshot](assets/telegram_forcebuy.png)
Note that for this to work, `forcebuy_enable` needs to be set to true. Note that for this to work, `force_entry_enable` needs to be set to true.
[More details](configuration.md#understand-forcebuy_enable) [More details](configuration.md#understand-force_entry_enable)
### /performance ### /performance
@@ -315,11 +337,11 @@ Per default `/daily` will return the 7 last days. The example below if for `/dai
> **Daily Profit over the last 3 days:** > **Daily Profit over the last 3 days:**
``` ```
Day Profit BTC Profit USD Day (count) USDT USD Profit %
---------- -------------- ------------ -------------- ------------ ---------- ----------
2018-01-03 0.00224175 BTC 29,142 USD 2022-06-11 (1) -0.746 USDT -0.75 USD -0.08%
2018-01-02 0.00033131 BTC 4,307 USD 2022-06-10 (0) 0 USDT 0.00 USD 0.00%
2018-01-01 0.00269130 BTC 34.986 USD 2022-06-09 (5) 20 USDT 20.10 USD 5.00%
``` ```
### /weekly <n> ### /weekly <n>
@@ -329,11 +351,11 @@ from Monday. The example below if for `/weekly 3`:
> **Weekly Profit over the last 3 weeks (starting from Monday):** > **Weekly Profit over the last 3 weeks (starting from Monday):**
``` ```
Monday Profit BTC Profit USD Monday (count) Profit BTC Profit USD Profit %
---------- -------------- ------------ ------------- -------------- ------------ ----------
2018-01-03 0.00224175 BTC 29,142 USD 2018-01-03 (5) 0.00224175 BTC 29,142 USD 4.98%
2017-12-27 0.00033131 BTC 4,307 USD 2017-12-27 (1) 0.00033131 BTC 4,307 USD 0.00%
2017-12-20 0.00269130 BTC 34.986 USD 2017-12-20 (4) 0.00269130 BTC 34.986 USD 5.12%
``` ```
### /monthly <n> ### /monthly <n>
@@ -343,11 +365,11 @@ if for `/monthly 3`:
> **Monthly Profit over the last 3 months:** > **Monthly Profit over the last 3 months:**
``` ```
Month Profit BTC Profit USD Month (count) Profit BTC Profit USD Profit %
---------- -------------- ------------ ------------- -------------- ------------ ----------
2018-01 0.00224175 BTC 29,142 USD 2018-01 (20) 0.00224175 BTC 29,142 USD 4.98%
2017-12 0.00033131 BTC 4,307 USD 2017-12 (5) 0.00033131 BTC 4,307 USD 0.00%
2017-11 0.00269130 BTC 34.986 USD 2017-11 (10) 0.00269130 BTC 34.986 USD 5.10%
``` ```
### /whitelist ### /whitelist

View File

@@ -2,6 +2,10 @@
To update your freqtrade installation, please use one of the below methods, corresponding to your installation method. To update your freqtrade installation, please use one of the below methods, corresponding to your installation method.
!!! Note "Tracking changes"
Breaking changes / changed behavior will be documented in the changelog that is posted alongside every release.
For the develop branch, please follow PR's to avoid being surprised by changes.
## docker-compose ## docker-compose
!!! Note "Legacy installations using the `master` image" !!! Note "Legacy installations using the `master` image"
@@ -28,4 +32,8 @@ Please ensure that you're also updating dependencies - otherwise things might br
``` bash ``` bash
git pull git pull
pip install -U -r requirements.txt pip install -U -r requirements.txt
pip install -e .
# Ensure freqUI is at the latest version
freqtrade install-ui
``` ```

View File

@@ -119,6 +119,7 @@ This subcommand is useful for finding problems in your environment with loading
usage: freqtrade list-strategies [-h] [-v] [--logfile FILE] [-V] [-c PATH] usage: freqtrade list-strategies [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-d PATH] [--userdir PATH]
[--strategy-path PATH] [-1] [--no-color] [--strategy-path PATH] [-1] [--no-color]
[--recursive-strategy-search]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@@ -126,6 +127,9 @@ optional arguments:
-1, --one-column Print output in one column. -1, --one-column Print output in one column.
--no-color Disable colorization of hyperopt results. May be --no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file. useful if you are redirecting output to a file.
--recursive-strategy-search
Recursively search for a strategy in the strategies
folder.
Common arguments: Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages). -v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
@@ -134,9 +138,10 @@ Common arguments:
details. details.
-V, --version show program's version number and exit -V, --version show program's version number and exit
-c PATH, --config PATH -c PATH, --config PATH
Specify configuration file (default: `config.json`). Specify configuration file (default:
Multiple --config options may be used. Can be set to `userdir/config.json` or `config.json` whichever
`-` to read config from stdin. exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
-d PATH, --datadir PATH -d PATH, --datadir PATH
Path to directory with historical backtesting data. Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH --userdir PATH, --user-data-dir PATH
@@ -439,14 +444,15 @@ usage: freqtrade list-markets [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv] [--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]] [--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a]
[-a] [--trading-mode {spot,margin,futures}]
usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH] usage: freqtrade list-pairs [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--exchange EXCHANGE] [-d PATH] [--userdir PATH] [--exchange EXCHANGE]
[--print-list] [--print-json] [-1] [--print-csv] [--print-list] [--print-json] [-1] [--print-csv]
[--base BASE_CURRENCY [BASE_CURRENCY ...]] [--base BASE_CURRENCY [BASE_CURRENCY ...]]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [-a]
[--trading-mode {spot,margin,futures}]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@@ -463,6 +469,8 @@ optional arguments:
Specify quote currency(-ies). Space-separated list. Specify quote currency(-ies). Space-separated list.
-a, --all Print all pairs or market symbols. By default only -a, --all Print all pairs or market symbols. By default only
active ones are shown. active ones are shown.
--trading-mode {spot,margin,futures}
Select Trading mode
Common arguments: Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages). -v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
@@ -517,20 +525,25 @@ Requires a configuration with specified `pairlists` attribute.
Can be used to generate static pairlists to be used during backtesting / hyperopt. Can be used to generate static pairlists to be used during backtesting / hyperopt.
``` ```
usage: freqtrade test-pairlist [-h] [-c PATH] usage: freqtrade test-pairlist [-h] [-v] [-c PATH]
[--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]] [--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]]
[-1] [--print-json] [-1] [--print-json] [--exchange EXCHANGE]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
-c PATH, --config PATH -c PATH, --config PATH
Specify configuration file (default: `config.json`). Specify configuration file (default:
Multiple --config options may be used. Can be set to `userdir/config.json` or `config.json` whichever
`-` to read config from stdin. exists). Multiple --config options may be used. Can be
set to `-` to read config from stdin.
--quote QUOTE_CURRENCY [QUOTE_CURRENCY ...] --quote QUOTE_CURRENCY [QUOTE_CURRENCY ...]
Specify quote currency(-ies). Space-separated list. Specify quote currency(-ies). Space-separated list.
-1, --one-column Print output in one column. -1, --one-column Print output in one column.
--print-json Print list of pairs or market symbols in JSON format. --print-json Print list of pairs or market symbols in JSON format.
--exchange EXCHANGE Exchange name (default: `bittrex`). Only valid if no
config is provided.
``` ```
### Examples ### Examples
@@ -541,6 +554,27 @@ Show whitelist when using a [dynamic pairlist](plugins.md#pairlists).
freqtrade test-pairlist --config config.json --quote USDT BTC freqtrade test-pairlist --config config.json --quote USDT BTC
``` ```
## Convert database
`freqtrade convert-db` can be used to convert your database from one system to another (sqlite -> postgres, postgres -> other postgres), migrating all trades, orders and Pairlocks.
Please refer to the [SQL cheatsheet](sql_cheatsheet.md#use-a-different-database-system) to learn about requirements for different database systems.
```
usage: freqtrade convert-db [-h] [--db-url PATH] [--db-url-from PATH]
optional arguments:
-h, --help show this help message and exit
--db-url PATH Override trades database URL, this is useful in custom
deployments (default: `sqlite:///tradesv3.sqlite` for
Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for
Dry Run).
--db-url-from PATH Source db url to use when migrating a database.
```
!!! Warning
Please ensure to only use this on an empty target database. Freqtrade will perform a regular migration, but may fail if entries already existed.
## Webserver mode ## Webserver mode
!!! Warning "Experimental" !!! Warning "Experimental"
@@ -577,6 +611,26 @@ Common arguments:
``` ```
### Webserver mode - docker
You can also use webserver mode via docker.
Starting a one-off container requires the configuration of the port explicitly, as ports are not exposed by default.
You can use `docker-compose run --rm -p 127.0.0.1:8080:8080 freqtrade webserver` to start a one-off container that'll be removed once you stop it. This assumes that port 8080 is still available and no other bot is running on that port.
Alternatively, you can reconfigure the docker-compose file to have the command updated:
``` yml
command: >
webserver
--config /freqtrade/user_data/config.json
```
You can now use `docker-compose up` to start the webserver.
This assumes that the configuration has a webserver enabled and configured for docker (listening port = `0.0.0.0`).
!!! Tip
Don't forget to reset the command back to the trade command if you want to start a live or dry-run bot.
## Show previous Backtest results ## Show previous Backtest results
Allows you to show previous backtest results. Allows you to show previous backtest results.
@@ -617,6 +671,61 @@ Common arguments:
``` ```
## Detailed backtest analysis
Advanced backtest result analysis.
More details in the [Backtesting analysis](advanced-backtesting.md#analyze-the-buyentry-and-sellexit-tags) Section.
```
usage: freqtrade backtesting-analysis [-h] [-v] [--logfile FILE] [-V]
[-c PATH] [-d PATH] [--userdir PATH]
[--export-filename PATH]
[--analysis-groups {0,1,2,3,4} [{0,1,2,3,4} ...]]
[--enter-reason-list ENTER_REASON_LIST [ENTER_REASON_LIST ...]]
[--exit-reason-list EXIT_REASON_LIST [EXIT_REASON_LIST ...]]
[--indicator-list INDICATOR_LIST [INDICATOR_LIST ...]]
optional arguments:
-h, --help show this help message and exit
--export-filename PATH, --backtest-filename PATH
Use this filename for backtest results.Requires
`--export` to be set as well. Example: `--export-filen
ame=user_data/backtest_results/backtest_today.json`
--analysis-groups {0,1,2,3,4} [{0,1,2,3,4} ...]
grouping output - 0: simple wins/losses by enter tag,
1: by enter_tag, 2: by enter_tag and exit_tag, 3: by
pair and enter_tag, 4: by pair, enter_ and exit_tag
(this can get quite large)
--enter-reason-list ENTER_REASON_LIST [ENTER_REASON_LIST ...]
Comma separated list of entry signals to analyse.
Default: all. e.g. 'entry_tag_a,entry_tag_b'
--exit-reason-list EXIT_REASON_LIST [EXIT_REASON_LIST ...]
Comma separated list of exit signals to analyse.
Default: all. e.g.
'exit_tag_a,roi,stop_loss,trailing_stop_loss'
--indicator-list INDICATOR_LIST [INDICATOR_LIST ...]
Comma separated list of indicators to analyse. e.g.
'close,rsi,bb_lowerband,profit_abs'
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.
```
## List Hyperopt results ## List Hyperopt results
You can list the hyperoptimization epochs the Hyperopt module evaluated previously with the `hyperopt-list` sub-command. You can list the hyperoptimization epochs the Hyperopt module evaluated previously with the `hyperopt-list` sub-command.

View File

@@ -10,33 +10,33 @@ Sample configuration (tested using IFTTT).
"webhook": { "webhook": {
"enabled": true, "enabled": true,
"url": "https://maker.ifttt.com/trigger/<YOUREVENT>/with/key/<YOURKEY>/", "url": "https://maker.ifttt.com/trigger/<YOUREVENT>/with/key/<YOURKEY>/",
"webhookbuy": { "webhookentry": {
"value1": "Buying {pair}", "value1": "Buying {pair}",
"value2": "limit {limit:8f}", "value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}" "value3": "{stake_amount:8f} {stake_currency}"
}, },
"webhookbuycancel": { "webhookentrycancel": {
"value1": "Cancelling Open Buy Order for {pair}", "value1": "Cancelling Open Buy Order for {pair}",
"value2": "limit {limit:8f}", "value2": "limit {limit:8f}",
"value3": "{stake_amount:8f} {stake_currency}" "value3": "{stake_amount:8f} {stake_currency}"
}, },
"webhookbuyfill": { "webhookentryfill": {
"value1": "Buy Order for {pair} filled", "value1": "Buy Order for {pair} filled",
"value2": "at {open_rate:8f}", "value2": "at {open_rate:8f}",
"value3": "" "value3": ""
}, },
"webhooksell": { "webhookexit": {
"value1": "Selling {pair}", "value1": "Exiting {pair}",
"value2": "limit {limit:8f}", "value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})" "value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
}, },
"webhooksellcancel": { "webhookexitcancel": {
"value1": "Cancelling Open Sell Order for {pair}", "value1": "Cancelling Open Exit Order for {pair}",
"value2": "limit {limit:8f}", "value2": "limit {limit:8f}",
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})" "value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
}, },
"webhooksellfill": { "webhookexitfill": {
"value1": "Sell Order for {pair} filled", "value1": "Exit Order for {pair} filled",
"value2": "at {close_rate:8f}.", "value2": "at {close_rate:8f}.",
"value3": "" "value3": ""
}, },
@@ -96,14 +96,16 @@ Optional parameters are available to enable automatic retries for webhook messag
Different payloads can be configured for different events. Not all fields are necessary, but you should configure at least one of the dicts, otherwise the webhook will never be called. Different payloads can be configured for different events. Not all fields are necessary, but you should configure at least one of the dicts, otherwise the webhook will never be called.
### Webhookbuy ### Webhookentry
The fields in `webhook.webhookbuy` are filled when the bot executes a buy. Parameters are filled using string.format. The fields in `webhook.webhookentry` are filled when the bot executes a long/short. Parameters are filled using string.format.
Possible parameters are: Possible parameters are:
* `trade_id` * `trade_id`
* `exchange` * `exchange`
* `pair` * `pair`
* `direction`
* `leverage`
* ~~`limit` # Deprecated - should no longer be used.~~ * ~~`limit` # Deprecated - should no longer be used.~~
* `open_rate` * `open_rate`
* `amount` * `amount`
@@ -114,16 +116,18 @@ Possible parameters are:
* `fiat_currency` * `fiat_currency`
* `order_type` * `order_type`
* `current_rate` * `current_rate`
* `buy_tag` * `enter_tag`
### Webhookbuycancel ### Webhookentrycancel
The fields in `webhook.webhookbuycancel` are filled when the bot cancels a buy order. Parameters are filled using string.format. The fields in `webhook.webhookentrycancel` are filled when the bot cancels a long/short order. Parameters are filled using string.format.
Possible parameters are: Possible parameters are:
* `trade_id` * `trade_id`
* `exchange` * `exchange`
* `pair` * `pair`
* `direction`
* `leverage`
* `limit` * `limit`
* `amount` * `amount`
* `open_date` * `open_date`
@@ -133,16 +137,18 @@ Possible parameters are:
* `fiat_currency` * `fiat_currency`
* `order_type` * `order_type`
* `current_rate` * `current_rate`
* `buy_tag` * `enter_tag`
### Webhookbuyfill ### Webhookentryfill
The fields in `webhook.webhookbuyfill` are filled when the bot filled a buy order. Parameters are filled using string.format. The fields in `webhook.webhookentryfill` are filled when the bot filled a long/short order. Parameters are filled using string.format.
Possible parameters are: Possible parameters are:
* `trade_id` * `trade_id`
* `exchange` * `exchange`
* `pair` * `pair`
* `direction`
* `leverage`
* `open_rate` * `open_rate`
* `amount` * `amount`
* `open_date` * `open_date`
@@ -152,16 +158,18 @@ Possible parameters are:
* `fiat_currency` * `fiat_currency`
* `order_type` * `order_type`
* `current_rate` * `current_rate`
* `buy_tag` * `enter_tag`
### Webhooksell ### Webhookexit
The fields in `webhook.webhooksell` are filled when the bot sells a trade. Parameters are filled using string.format. The fields in `webhook.webhookexit` are filled when the bot exits a trade. Parameters are filled using string.format.
Possible parameters are: Possible parameters are:
* `trade_id` * `trade_id`
* `exchange` * `exchange`
* `pair` * `pair`
* `direction`
* `leverage`
* `gain` * `gain`
* `limit` * `limit`
* `amount` * `amount`
@@ -171,19 +179,21 @@ Possible parameters are:
* `stake_currency` * `stake_currency`
* `base_currency` * `base_currency`
* `fiat_currency` * `fiat_currency`
* `sell_reason` * `exit_reason`
* `order_type` * `order_type`
* `open_date` * `open_date`
* `close_date` * `close_date`
### Webhooksellfill ### Webhookexitfill
The fields in `webhook.webhooksellfill` are filled when the bot fills a sell order (closes a Trae). Parameters are filled using string.format. The fields in `webhook.webhookexitfill` are filled when the bot fills a exit order (closes a Trade). Parameters are filled using string.format.
Possible parameters are: Possible parameters are:
* `trade_id` * `trade_id`
* `exchange` * `exchange`
* `pair` * `pair`
* `direction`
* `leverage`
* `gain` * `gain`
* `close_rate` * `close_rate`
* `amount` * `amount`
@@ -194,19 +204,21 @@ Possible parameters are:
* `stake_currency` * `stake_currency`
* `base_currency` * `base_currency`
* `fiat_currency` * `fiat_currency`
* `sell_reason` * `exit_reason`
* `order_type` * `order_type`
* `open_date` * `open_date`
* `close_date` * `close_date`
### Webhooksellcancel ### Webhookexitcancel
The fields in `webhook.webhooksellcancel` are filled when the bot cancels a sell order. Parameters are filled using string.format. The fields in `webhook.webhookexitcancel` are filled when the bot cancels a exit order. Parameters are filled using string.format.
Possible parameters are: Possible parameters are:
* `trade_id` * `trade_id`
* `exchange` * `exchange`
* `pair` * `pair`
* `direction`
* `leverage`
* `gain` * `gain`
* `limit` * `limit`
* `amount` * `amount`
@@ -217,7 +229,7 @@ Possible parameters are:
* `stake_currency` * `stake_currency`
* `base_currency` * `base_currency`
* `fiat_currency` * `fiat_currency`
* `sell_reason` * `exit_reason`
* `order_type` * `order_type`
* `open_date` * `open_date`
* `close_date` * `close_date`
@@ -227,3 +239,52 @@ Possible parameters are:
The fields in `webhook.webhookstatus` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format. The fields in `webhook.webhookstatus` are used for regular status messages (Started / Stopped / ...). Parameters are filled using string.format.
The only possible value here is `{status}`. The only possible value here is `{status}`.
## Discord
A special form of webhooks is available for discord.
You can configure this as follows:
```json
"discord": {
"enabled": true,
"webhook_url": "https://discord.com/api/webhooks/<Your webhook URL ...>",
"exit_fill": [
{"Trade ID": "{trade_id}"},
{"Exchange": "{exchange}"},
{"Pair": "{pair}"},
{"Direction": "{direction}"},
{"Open rate": "{open_rate}"},
{"Close rate": "{close_rate}"},
{"Amount": "{amount}"},
{"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"},
{"Close date": "{close_date:%Y-%m-%d %H:%M:%S}"},
{"Profit": "{profit_amount} {stake_currency}"},
{"Profitability": "{profit_ratio:.2%}"},
{"Enter tag": "{enter_tag}"},
{"Exit Reason": "{exit_reason}"},
{"Strategy": "{strategy}"},
{"Timeframe": "{timeframe}"},
],
"entry_fill": [
{"Trade ID": "{trade_id}"},
{"Exchange": "{exchange}"},
{"Pair": "{pair}"},
{"Direction": "{direction}"},
{"Open rate": "{open_rate}"},
{"Amount": "{amount}"},
{"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"},
{"Enter tag": "{enter_tag}"},
{"Strategy": "{strategy} {timeframe}"},
]
}
```
The above represents the default (`exit_fill` and `entry_fill` are optional and will default to the above configuration) - modifications are obviously possible.
Available fields correspond to the fields for webhooks and are documented in the corresponding webhook sections.
The notifications will look as follows by default.
![discord-notification](assets/discord_notification.png)

View File

@@ -9,6 +9,7 @@ dependencies:
- pandas - pandas
- pip - pip
- py-find-1st
- aiohttp - aiohttp
- SQLAlchemy - SQLAlchemy
- python-telegram-bot - python-telegram-bot
@@ -30,7 +31,9 @@ dependencies:
- colorama - colorama
- questionary - questionary
- prompt-toolkit - prompt-toolkit
- schedule
- python-dateutil - python-dateutil
- joblib
# ============================ # ============================
@@ -53,7 +56,6 @@ dependencies:
- scikit-learn - scikit-learn
- filelock - filelock
- scikit-optimize - scikit-optimize
- joblib
- progressbar2 - progressbar2
# ============================ # ============================
# 4/4 req plot # 4/4 req plot
@@ -63,7 +65,7 @@ dependencies:
- pip: - pip:
- pycoingecko - pycoingecko
- py_find_1st # - py_find_1st
- tables - tables
- pytest-random-order - pytest-random-order
- ccxt - ccxt

View File

@@ -11,4 +11,3 @@ Restart=on-failure
[Install] [Install]
WantedBy=default.target WantedBy=default.target

View File

@@ -27,4 +27,3 @@ WatchdogSec=20
[Install] [Install]
WantedBy=default.target WantedBy=default.target

View File

@@ -1,27 +1,14 @@
""" Freqtrade bot """ """ Freqtrade bot """
__version__ = '2022.2.2' __version__ = '2022.8.dev'
if __version__ == 'develop':
if 'dev' in __version__:
try: try:
import subprocess import subprocess
__version__ = 'develop-' + subprocess.check_output( __version__ = __version__ + '-' + subprocess.check_output(
['git', 'log', '--format="%h"', '-n 1'], ['git', 'log', '--format="%h"', '-n 1'],
stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"') stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"')
# from datetime import datetime
# last_release = subprocess.check_output(
# ['git', 'tag']
# ).decode('utf-8').split()[-1].split(".")
# # Releases are in the format "2020.1" - we increment the latest version for dev.
# prefix = f"{last_release[0]}.{int(last_release[1]) + 1}"
# dev_version = int(datetime.now().timestamp() // 1000)
# __version__ = f"{prefix}.dev{dev_version}"
# subprocess.check_output(
# ['git', 'log', '--format="%h"', '-n 1'],
# stderr=subprocess.DEVNULL).decode("utf-8").rstrip().strip('"')
except Exception: # pragma: no cover except Exception: # pragma: no cover
# git not available, ignore # git not available, ignore
try: try:

View File

@@ -6,10 +6,12 @@ Contains all start-commands, subcommands and CLI Interface creation.
Note: Be careful with file-scoped imports in these subfiles. Note: Be careful with file-scoped imports in these subfiles.
as they are parsed on startup, nothing containing optional modules should be loaded. as they are parsed on startup, nothing containing optional modules should be loaded.
""" """
from freqtrade.commands.analyze_commands import start_analysis_entries_exits
from freqtrade.commands.arguments import Arguments from freqtrade.commands.arguments import Arguments
from freqtrade.commands.build_config_commands import start_new_config from freqtrade.commands.build_config_commands import start_new_config
from freqtrade.commands.data_commands import (start_convert_data, start_convert_trades, from freqtrade.commands.data_commands import (start_convert_data, start_convert_trades,
start_download_data, start_list_data) start_download_data, start_list_data)
from freqtrade.commands.db_commands import start_convert_db
from freqtrade.commands.deploy_commands import (start_create_userdir, start_install_ui, from freqtrade.commands.deploy_commands import (start_create_userdir, start_install_ui,
start_new_strategy) start_new_strategy)
from freqtrade.commands.hyperopt_commands import start_hyperopt_list, start_hyperopt_show from freqtrade.commands.hyperopt_commands import start_hyperopt_list, start_hyperopt_show

View File

@@ -0,0 +1,69 @@
import logging
from pathlib import Path
from typing import Any, Dict
from freqtrade.configuration import setup_utils_configuration
from freqtrade.enums import RunMode
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
def setup_analyze_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for the entry/exit reason analysis module
:param args: Cli args from Arguments()
:param method: Bot running mode
:return: Configuration
"""
config = setup_utils_configuration(args, method)
no_unlimited_runmodes = {
RunMode.BACKTEST: 'backtesting',
}
if method in no_unlimited_runmodes.keys():
from freqtrade.data.btanalysis import get_latest_backtest_filename
if 'exportfilename' in config:
if config['exportfilename'].is_dir():
btfile = Path(get_latest_backtest_filename(config['exportfilename']))
signals_file = f"{config['exportfilename']}/{btfile.stem}_signals.pkl"
else:
if config['exportfilename'].exists():
btfile = Path(config['exportfilename'])
signals_file = f"{btfile.parent}/{btfile.stem}_signals.pkl"
else:
raise OperationalException(f"{config['exportfilename']} does not exist.")
else:
raise OperationalException('exportfilename not in config.')
if (not Path(signals_file).exists()):
raise OperationalException(
(f"Cannot find latest backtest signals file: {signals_file}."
"Run backtesting with `--export signals`.")
)
return config
def start_analysis_entries_exits(args: Dict[str, Any]) -> None:
"""
Start analysis script
:param args: Cli args from Arguments()
:return: None
"""
from freqtrade.data.entryexitanalysis import process_entry_exit_reasons
# Initialize configuration
config = setup_analyze_configuration(args, RunMode.BACKTEST)
logger.info('Starting freqtrade in analysis mode')
process_entry_exit_reasons(config['exportfilename'],
config['exchange']['pair_whitelist'],
config['analysis_groups'],
config['enter_reason_list'],
config['exit_reason_list'],
config['indicator_list']
)

View File

@@ -12,7 +12,8 @@ from freqtrade.constants import DEFAULT_CONFIG
ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"] ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"]
ARGS_STRATEGY = ["strategy", "strategy_path"] ARGS_STRATEGY = ["strategy", "strategy_path", "recursive_strategy_search", "freqaimodel",
"freqaimodel_path"]
ARGS_TRADE = ["db_url", "sd_notify", "dry_run", "dry_run_wallet", "fee"] ARGS_TRADE = ["db_url", "sd_notify", "dry_run", "dry_run_wallet", "fee"]
@@ -28,7 +29,7 @@ ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_pos
ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
"position_stacking", "use_max_market_positions", "position_stacking", "use_max_market_positions",
"enable_protections", "dry_run_wallet", "enable_protections", "dry_run_wallet", "timeframe_detail",
"epochs", "spaces", "print_all", "epochs", "spaces", "print_all",
"print_colorized", "print_json", "hyperopt_jobs", "print_colorized", "print_json", "hyperopt_jobs",
"hyperopt_random_state", "hyperopt_min_trades", "hyperopt_random_state", "hyperopt_min_trades",
@@ -37,7 +38,8 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"] ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column", "print_colorized"] ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column", "print_colorized",
"recursive_strategy_search"]
ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column", "print_colorized"] ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column", "print_colorized"]
@@ -48,10 +50,11 @@ ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"]
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"] ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
ARGS_LIST_PAIRS = ["exchange", "print_list", "list_pairs_print_json", "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"] "print_csv", "base_currencies", "quote_currencies", "list_pairs_all",
"trading_mode"]
ARGS_TEST_PAIRLIST = ["verbosity", "config", "quote_currencies", "print_one_column", ARGS_TEST_PAIRLIST = ["verbosity", "config", "quote_currencies", "print_one_column",
"list_pairs_print_json"] "list_pairs_print_json", "exchange"]
ARGS_CREATE_USERDIR = ["user_data_dir", "reset"] ARGS_CREATE_USERDIR = ["user_data_dir", "reset"]
@@ -60,15 +63,18 @@ ARGS_BUILD_CONFIG = ["config"]
ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"] ARGS_BUILD_STRATEGY = ["user_data_dir", "strategy", "template"]
ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to", "erase"] ARGS_CONVERT_DATA = ["pairs", "format_from", "format_to", "erase"]
ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes"]
ARGS_CONVERT_DATA_OHLCV = ARGS_CONVERT_DATA + ["timeframes", "exchange", "trading_mode",
"candle_types"]
ARGS_CONVERT_TRADES = ["pairs", "timeframes", "exchange", "dataformat_ohlcv", "dataformat_trades"] ARGS_CONVERT_TRADES = ["pairs", "timeframes", "exchange", "dataformat_ohlcv", "dataformat_trades"]
ARGS_LIST_DATA = ["exchange", "dataformat_ohlcv", "pairs"] ARGS_LIST_DATA = ["exchange", "dataformat_ohlcv", "pairs", "trading_mode"]
ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "new_pairs_days", "include_inactive", ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "new_pairs_days", "include_inactive",
"timerange", "download_trades", "exchange", "timeframes", "timerange", "download_trades", "exchange", "timeframes",
"erase", "dataformat_ohlcv", "dataformat_trades"] "erase", "dataformat_ohlcv", "dataformat_trades", "trading_mode",
"prepend_data"]
ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit",
"db_url", "trade_source", "export", "exportfilename", "db_url", "trade_source", "export", "exportfilename",
@@ -77,7 +83,9 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit",
ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url",
"trade_source", "timeframe", "plot_auto_open", ] "trade_source", "timeframe", "plot_auto_open", ]
ARGS_INSTALL_UI = ["erase_ui_only", 'ui_version'] ARGS_CONVERT_DB = ["db_url", "db_url_from"]
ARGS_INSTALL_UI = ["erase_ui_only", "ui_version"]
ARGS_SHOW_TRADES = ["db_url", "trade_ids", "print_json"] ARGS_SHOW_TRADES = ["db_url", "trade_ids", "print_json"]
@@ -94,6 +102,9 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop
"print_json", "hyperoptexportfilename", "hyperopt_show_no_header", "print_json", "hyperoptexportfilename", "hyperopt_show_no_header",
"disableparamexport", "backtest_breakdown"] "disableparamexport", "backtest_breakdown"]
ARGS_ANALYZE_ENTRIES_EXITS = ["exportfilename", "analysis_groups", "enter_reason_list",
"exit_reason_list", "indicator_list"]
NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes", NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes",
"list-markets", "list-pairs", "list-strategies", "list-data", "list-markets", "list-pairs", "list-strategies", "list-data",
"hyperopt-list", "hyperopt-show", "backtest-filter", "hyperopt-list", "hyperopt-show", "backtest-filter",
@@ -175,8 +186,9 @@ class Arguments:
self.parser = argparse.ArgumentParser(description='Free, open source crypto trading bot') self.parser = argparse.ArgumentParser(description='Free, open source crypto trading bot')
self._build_args(optionlist=['version'], parser=self.parser) self._build_args(optionlist=['version'], parser=self.parser)
from freqtrade.commands import (start_backtesting, start_backtesting_show, from freqtrade.commands import (start_analysis_entries_exits, start_backtesting,
start_convert_data, start_convert_trades, start_backtesting_show, start_convert_data,
start_convert_db, start_convert_trades,
start_create_userdir, start_download_data, start_edge, start_create_userdir, start_download_data, start_edge,
start_hyperopt, start_hyperopt_list, start_hyperopt_show, start_hyperopt, start_hyperopt_list, start_hyperopt_show,
start_install_ui, start_list_data, start_list_exchanges, start_install_ui, start_list_data, start_list_exchanges,
@@ -276,6 +288,13 @@ class Arguments:
backtesting_show_cmd.set_defaults(func=start_backtesting_show) backtesting_show_cmd.set_defaults(func=start_backtesting_show)
self._build_args(optionlist=ARGS_BACKTEST_SHOW, parser=backtesting_show_cmd) self._build_args(optionlist=ARGS_BACKTEST_SHOW, parser=backtesting_show_cmd)
# Add backtesting analysis subcommand
analysis_cmd = subparsers.add_parser('backtesting-analysis',
help='Backtest Analysis module.',
parents=[_common_parser])
analysis_cmd.set_defaults(func=start_analysis_entries_exits)
self._build_args(optionlist=ARGS_ANALYZE_ENTRIES_EXITS, parser=analysis_cmd)
# Add edge subcommand # Add edge subcommand
edge_cmd = subparsers.add_parser('edge', help='Edge module.', edge_cmd = subparsers.add_parser('edge', help='Edge module.',
parents=[_common_parser, _strategy_parser]) parents=[_common_parser, _strategy_parser])
@@ -369,6 +388,14 @@ class Arguments:
test_pairlist_cmd.set_defaults(func=start_test_pairlist) test_pairlist_cmd.set_defaults(func=start_test_pairlist)
self._build_args(optionlist=ARGS_TEST_PAIRLIST, parser=test_pairlist_cmd) self._build_args(optionlist=ARGS_TEST_PAIRLIST, parser=test_pairlist_cmd)
# Add db-convert subcommand
convert_db = subparsers.add_parser(
"convert-db",
help="Migrate database to different system",
)
convert_db.set_defaults(func=start_convert_db)
self._build_args(optionlist=ARGS_CONVERT_DB, parser=convert_db)
# Add install-ui subcommand # Add install-ui subcommand
install_ui_cmd = subparsers.add_parser( install_ui_cmd = subparsers.add_parser(
'install-ui', 'install-ui',

View File

@@ -67,7 +67,7 @@ def ask_user_config() -> Dict[str, Any]:
"type": "text", "type": "text",
"name": "stake_amount", "name": "stake_amount",
"message": f"Please insert your stake amount (Number or '{UNLIMITED_STAKE_AMOUNT}'):", "message": f"Please insert your stake amount (Number or '{UNLIMITED_STAKE_AMOUNT}'):",
"default": "100", "default": "unlimited",
"validate": lambda val: val == UNLIMITED_STAKE_AMOUNT or validate_is_float(val), "validate": lambda val: val == UNLIMITED_STAKE_AMOUNT or validate_is_float(val),
"filter": lambda val: '"' + UNLIMITED_STAKE_AMOUNT + '"' "filter": lambda val: '"' + UNLIMITED_STAKE_AMOUNT + '"'
if val == UNLIMITED_STAKE_AMOUNT if val == UNLIMITED_STAKE_AMOUNT
@@ -104,19 +104,28 @@ def ask_user_config() -> Dict[str, Any]:
"type": "select", "type": "select",
"name": "exchange_name", "name": "exchange_name",
"message": "Select exchange", "message": "Select exchange",
"choices": [ "choices": lambda x: [
"binance", "binance",
"binanceus", "binanceus",
"bittrex", "bittrex",
"kraken",
"ftx", "ftx",
"kucoin",
"gateio", "gateio",
"huobi",
"kraken",
"kucoin",
"okx", "okx",
Separator(), Separator("------------------"),
"other", "other",
], ],
}, },
{
"type": "confirm",
"name": "trading_mode",
"message": "Do you want to trade Perpetual Swaps (perpetual futures)?",
"default": False,
"filter": lambda val: 'futures' if val else 'spot',
"when": lambda x: x["exchange_name"] in ['binance', 'gateio', 'okx'],
},
{ {
"type": "autocomplete", "type": "autocomplete",
"name": "exchange_name", "name": "exchange_name",
@@ -155,7 +164,7 @@ def ask_user_config() -> Dict[str, Any]:
"when": lambda x: x['telegram'] "when": lambda x: x['telegram']
}, },
{ {
"type": "text", "type": "password",
"name": "telegram_chat_id", "name": "telegram_chat_id",
"message": "Insert Telegram chat id", "message": "Insert Telegram chat id",
"when": lambda x: x['telegram'] "when": lambda x: x['telegram']
@@ -182,7 +191,7 @@ def ask_user_config() -> Dict[str, Any]:
"when": lambda x: x['api_server'] "when": lambda x: x['api_server']
}, },
{ {
"type": "text", "type": "password",
"name": "api_server_password", "name": "api_server_password",
"message": "Insert api-server password", "message": "Insert api-server password",
"when": lambda x: x['api_server'] "when": lambda x: x['api_server']
@@ -193,7 +202,13 @@ def ask_user_config() -> Dict[str, Any]:
if not answers: if not answers:
# Interrupted questionary sessions return an empty dict. # Interrupted questionary sessions return an empty dict.
raise OperationalException("User interrupted interactive questions.") raise OperationalException("User interrupted interactive questions.")
# Ensure default is set for non-futures exchanges
answers['trading_mode'] = answers.get('trading_mode', "spot")
answers['margin_mode'] = (
'isolated'
if answers.get('trading_mode') == 'futures'
else ''
)
# Force JWT token to be a random string # Force JWT token to be a random string
answers['api_server_jwt_key'] = secrets.token_hex() answers['api_server_jwt_key'] = secrets.token_hex()

View File

@@ -5,6 +5,7 @@ from argparse import SUPPRESS, ArgumentTypeError
from freqtrade import __version__, constants from freqtrade import __version__, constants
from freqtrade.constants import HYPEROPT_LOSS_BUILTIN from freqtrade.constants import HYPEROPT_LOSS_BUILTIN
from freqtrade.enums import CandleType
def check_int_positive(value: str) -> int: def check_int_positive(value: str) -> int:
@@ -82,6 +83,11 @@ AVAILABLE_CLI_OPTIONS = {
help='Reset sample files to their original state.', help='Reset sample files to their original state.',
action='store_true', action='store_true',
), ),
"recursive_strategy_search": Arg(
'--recursive-strategy-search',
help='Recursively search for a strategy in the strategies folder.',
action='store_true',
),
# Main options # Main options
"strategy": Arg( "strategy": Arg(
'-s', '--strategy', '-s', '--strategy',
@@ -100,6 +106,11 @@ AVAILABLE_CLI_OPTIONS = {
f'`{constants.DEFAULT_DB_DRYRUN_URL}` for Dry Run).', f'`{constants.DEFAULT_DB_DRYRUN_URL}` for Dry Run).',
metavar='PATH', metavar='PATH',
), ),
"db_url_from": Arg(
'--db-url-from',
help='Source db url to use when migrating a database.',
metavar='PATH',
),
"sd_notify": Arg( "sd_notify": Arg(
'--sd-notify', '--sd-notify',
help='Notify systemd service manager.', help='Notify systemd service manager.',
@@ -117,7 +128,7 @@ AVAILABLE_CLI_OPTIONS = {
), ),
# Optimize common # Optimize common
"timeframe": Arg( "timeframe": Arg(
'-i', '--timeframe', '--ticker-interval', '-i', '--timeframe',
help='Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).', help='Specify timeframe (`1m`, `5m`, `30m`, `1h`, `1d`).',
), ),
"timerange": Arg( "timerange": Arg(
@@ -169,7 +180,7 @@ AVAILABLE_CLI_OPTIONS = {
"strategy_list": Arg( "strategy_list": Arg(
'--strategy-list', '--strategy-list',
help='Provide a space-separated list of strategies to backtest. ' help='Provide a space-separated list of strategies to backtest. '
'Please note that ticker-interval needs to be set either in config ' 'Please note that timeframe needs to be set either in config '
'or via command line. When using this together with `--export trades`, ' 'or via command line. When using this together with `--export trades`, '
'the strategy-name is injected into the filename ' 'the strategy-name is injected into the filename '
'(so `backtest-data.json` becomes `backtest-data-SampleStrategy.json`', '(so `backtest-data.json` becomes `backtest-data-SampleStrategy.json`',
@@ -179,7 +190,6 @@ AVAILABLE_CLI_OPTIONS = {
'--export', '--export',
help='Export backtest results (default: trades).', help='Export backtest results (default: trades).',
choices=constants.EXPORT_OPTIONS, choices=constants.EXPORT_OPTIONS,
), ),
"exportfilename": Arg( "exportfilename": Arg(
"--export-filename", "--export-filename",
@@ -356,6 +366,17 @@ AVAILABLE_CLI_OPTIONS = {
nargs='+', nargs='+',
metavar='BASE_CURRENCY', metavar='BASE_CURRENCY',
), ),
"trading_mode": Arg(
'--trading-mode',
help='Select Trading mode',
choices=constants.TRADING_MODES,
),
"candle_types": Arg(
'--candle-types',
help='Select candle type to use',
choices=[c.value for c in CandleType],
nargs='+',
),
# Script options # Script options
"pairs": Arg( "pairs": Arg(
'-p', '--pairs', '-p', '--pairs',
@@ -427,6 +448,11 @@ AVAILABLE_CLI_OPTIONS = {
default=['1m', '5m'], default=['1m', '5m'],
nargs='+', nargs='+',
), ),
"prepend_data": Arg(
'--prepend',
help='Allow data prepending.',
action='store_true',
),
"erase": Arg( "erase": Arg(
'--erase', '--erase',
help='Clean all existing data for the selected exchange/pairs/timeframes.', help='Clean all existing data for the selected exchange/pairs/timeframes.',
@@ -588,4 +614,47 @@ AVAILABLE_CLI_OPTIONS = {
"that do not contain any parameters."), "that do not contain any parameters."),
action="store_true", action="store_true",
), ),
"analysis_groups": Arg(
"--analysis-groups",
help=("grouping output - "
"0: simple wins/losses by enter tag, "
"1: by enter_tag, "
"2: by enter_tag and exit_tag, "
"3: by pair and enter_tag, "
"4: by pair, enter_ and exit_tag (this can get quite large)"),
nargs='+',
default=['0', '1', '2'],
choices=['0', '1', '2', '3', '4'],
),
"enter_reason_list": Arg(
"--enter-reason-list",
help=("Comma separated list of entry signals to analyse. Default: all. "
"e.g. 'entry_tag_a,entry_tag_b'"),
nargs='+',
default=['all'],
),
"exit_reason_list": Arg(
"--exit-reason-list",
help=("Comma separated list of exit signals to analyse. Default: all. "
"e.g. 'exit_tag_a,roi,stop_loss,trailing_stop_loss'"),
nargs='+',
default=['all'],
),
"indicator_list": Arg(
"--indicator-list",
help=("Comma separated list of indicators to analyse. "
"e.g. 'close,rsi,bb_lowerband,profit_abs'"),
nargs='+',
default=[],
),
"freqaimodel": Arg(
'--freqaimodel',
help='Specify a custom freqaimodels.',
metavar='NAME',
),
"freqaimodel_path": Arg(
'--freqaimodel-path',
help='Specify additional lookup path for freqaimodels.',
metavar='PATH',
),
} }

View File

@@ -8,11 +8,11 @@ from freqtrade.configuration import TimeRange, setup_utils_configuration
from freqtrade.data.converter import convert_ohlcv_format, convert_trades_format 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.history import (convert_trades_to_ohlcv, refresh_backtest_ohlcv_data,
refresh_backtest_trades_data) refresh_backtest_trades_data)
from freqtrade.enums import RunMode from freqtrade.enums import CandleType, RunMode, TradingMode
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.exchange import timeframe_to_minutes from freqtrade.exchange import timeframe_to_minutes
from freqtrade.exchange.exchange import market_is_active from freqtrade.exchange.exchange import market_is_active
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist, expand_pairlist
from freqtrade.resolvers import ExchangeResolver from freqtrade.resolvers import ExchangeResolver
@@ -50,7 +50,8 @@ def start_download_data(args: Dict[str, Any]) -> None:
exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False)
markets = [p for p, m in exchange.markets.items() if market_is_active(m) markets = [p for p, m in exchange.markets.items() if market_is_active(m)
or config.get('include_inactive')] or config.get('include_inactive')]
expanded_pairs = expand_pairlist(config['pairs'], markets)
expanded_pairs = dynamic_expand_pairlist(config, markets)
# Manual validations of relevant settings # Manual validations of relevant settings
if not config['exchange'].get('skip_pair_validation', False): if not config['exchange'].get('skip_pair_validation', False):
@@ -64,6 +65,8 @@ def start_download_data(args: Dict[str, Any]) -> None:
try: try:
if config.get('download_trades'): if config.get('download_trades'):
if config.get('trading_mode') == 'futures':
raise OperationalException("Trade download not supported for futures.")
pairs_not_available = refresh_backtest_trades_data( pairs_not_available = refresh_backtest_trades_data(
exchange, pairs=expanded_pairs, datadir=config['datadir'], exchange, pairs=expanded_pairs, datadir=config['datadir'],
timerange=timerange, new_pairs_days=config['new_pairs_days'], timerange=timerange, new_pairs_days=config['new_pairs_days'],
@@ -77,11 +80,20 @@ def start_download_data(args: Dict[str, Any]) -> None:
data_format_trades=config['dataformat_trades'], data_format_trades=config['dataformat_trades'],
) )
else: else:
if not exchange._ft_has.get('ohlcv_has_history', True):
raise OperationalException(
f"Historic klines not available for {exchange.name}. "
"Please use `--dl-trades` instead for this exchange "
"(will unfortunately take a long time)."
)
pairs_not_available = refresh_backtest_ohlcv_data( pairs_not_available = refresh_backtest_ohlcv_data(
exchange, pairs=expanded_pairs, timeframes=config['timeframes'], exchange, pairs=expanded_pairs, timeframes=config['timeframes'],
datadir=config['datadir'], timerange=timerange, datadir=config['datadir'], timerange=timerange,
new_pairs_days=config['new_pairs_days'], new_pairs_days=config['new_pairs_days'],
erase=bool(config.get('erase')), data_format=config['dataformat_ohlcv']) erase=bool(config.get('erase')), data_format=config['dataformat_ohlcv'],
trading_mode=config.get('trading_mode', 'spot'),
prepend=config.get('prepend_data', False)
)
except KeyboardInterrupt: except KeyboardInterrupt:
sys.exit("SIGINT received, aborting ...") sys.exit("SIGINT received, aborting ...")
@@ -133,9 +145,11 @@ def start_convert_data(args: Dict[str, Any], ohlcv: bool = True) -> None:
""" """
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if ohlcv: if ohlcv:
convert_ohlcv_format(config, candle_types = [CandleType.from_string(ct) for ct in config.get('candle_types', ['spot'])]
convert_from=args['format_from'], convert_to=args['format_to'], for candle_type in candle_types:
erase=args['erase']) convert_ohlcv_format(config,
convert_from=args['format_from'], convert_to=args['format_to'],
erase=args['erase'], candle_type=candle_type)
else: else:
convert_trades_format(config, convert_trades_format(config,
convert_from=args['format_from'], convert_to=args['format_to'], convert_from=args['format_from'], convert_to=args['format_to'],
@@ -154,17 +168,26 @@ def start_list_data(args: Dict[str, Any]) -> None:
from freqtrade.data.history.idatahandler import get_datahandler from freqtrade.data.history.idatahandler import get_datahandler
dhc = get_datahandler(config['datadir'], config['dataformat_ohlcv']) dhc = get_datahandler(config['datadir'], config['dataformat_ohlcv'])
paircombs = dhc.ohlcv_get_available_data(config['datadir']) paircombs = dhc.ohlcv_get_available_data(
config['datadir'],
config.get('trading_mode', TradingMode.SPOT)
)
if args['pairs']: if args['pairs']:
paircombs = [comb for comb in paircombs if comb[0] in args['pairs']] paircombs = [comb for comb in paircombs if comb[0] in args['pairs']]
print(f"Found {len(paircombs)} pair / timeframe combinations.") print(f"Found {len(paircombs)} pair / timeframe combinations.")
groupedpair = defaultdict(list) groupedpair = defaultdict(list)
for pair, timeframe in sorted(paircombs, key=lambda x: (x[0], timeframe_to_minutes(x[1]))): for pair, timeframe, candle_type in sorted(
groupedpair[pair].append(timeframe) paircombs,
key=lambda x: (x[0], timeframe_to_minutes(x[1]), x[2])
):
groupedpair[(pair, candle_type)].append(timeframe)
if groupedpair: if groupedpair:
print(tabulate([(pair, ', '.join(timeframes)) for pair, timeframes in groupedpair.items()], print(tabulate([
headers=("Pair", "Timeframe"), (pair, ', '.join(timeframes), candle_type)
tablefmt='psql', stralign='right')) for (pair, candle_type), timeframes in groupedpair.items()
],
headers=("Pair", "Timeframe", "Type"),
tablefmt='psql', stralign='right'))

View File

@@ -0,0 +1,55 @@
import logging
from typing import Any, Dict
from sqlalchemy import func
from freqtrade.configuration.config_setup import setup_utils_configuration
from freqtrade.enums.runmode import RunMode
logger = logging.getLogger(__name__)
def start_convert_db(args: Dict[str, Any]) -> None:
from sqlalchemy.orm import make_transient
from freqtrade.persistence import Order, Trade, init_db
from freqtrade.persistence.migrations import set_sequence_ids
from freqtrade.persistence.pairlock import PairLock
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
init_db(config['db_url'])
session_target = Trade._session
init_db(config['db_url_from'])
logger.info("Starting db migration.")
trade_count = 0
pairlock_count = 0
for trade in Trade.get_trades():
trade_count += 1
make_transient(trade)
for o in trade.orders:
make_transient(o)
session_target.add(trade)
session_target.commit()
for pairlock in PairLock.query:
pairlock_count += 1
make_transient(pairlock)
session_target.add(pairlock)
session_target.commit()
# Update sequences
max_trade_id = session_target.query(func.max(Trade.id)).scalar()
max_order_id = session_target.query(func.max(Order.id)).scalar()
max_pairlock_id = session_target.query(func.max(PairLock.id)).scalar()
set_sequence_ids(session_target.get_bind(),
trade_id=max_trade_id,
order_id=max_order_id,
pairlock_id=max_pairlock_id)
logger.info(f"Migrated {trade_count} Trades, and {pairlock_count} Pairlocks.")

View File

@@ -24,7 +24,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None:
print_colorized = config.get('print_colorized', False) print_colorized = config.get('print_colorized', False)
print_json = config.get('print_json', False) print_json = config.get('print_json', False)
export_csv = config.get('export_csv', None) export_csv = config.get('export_csv')
no_details = config.get('hyperopt_list_no_details', False) no_details = config.get('hyperopt_list_no_details', False)
no_header = False no_header = False

View File

@@ -41,7 +41,7 @@ def start_list_exchanges(args: Dict[str, Any]) -> None:
print(tabulate(exchanges, headers=['Exchange name', 'Valid', 'reason'])) print(tabulate(exchanges, headers=['Exchange name', 'Valid', 'reason']))
def _print_objs_tabular(objs: List, print_colorized: bool) -> None: def _print_objs_tabular(objs: List, print_colorized: bool, base_dir: Path) -> None:
if print_colorized: if print_colorized:
colorama_init(autoreset=True) colorama_init(autoreset=True)
red = Fore.RED red = Fore.RED
@@ -55,7 +55,7 @@ def _print_objs_tabular(objs: List, print_colorized: bool) -> None:
names = [s['name'] for s in objs] names = [s['name'] for s in objs]
objs_to_print = [{ objs_to_print = [{
'name': s['name'] if s['name'] else "--", 'name': s['name'] if s['name'] else "--",
'location': s['location'].name, 'location': s['location'].relative_to(base_dir),
'status': (red + "LOAD FAILED" + reset if s['class'] is None 'status': (red + "LOAD FAILED" + reset if s['class'] is None
else "OK" if names.count(s['name']) == 1 else "OK" if names.count(s['name']) == 1
else yellow + "DUPLICATE NAME" + reset) else yellow + "DUPLICATE NAME" + reset)
@@ -77,7 +77,8 @@ def start_list_strategies(args: Dict[str, Any]) -> None:
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES)) directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES))
strategy_objs = StrategyResolver.search_all_objects(directory, not args['print_one_column']) strategy_objs = StrategyResolver.search_all_objects(
directory, not args['print_one_column'], config.get('recursive_strategy_search', False))
# Sort alphabetically # Sort alphabetically
strategy_objs = sorted(strategy_objs, key=lambda x: x['name']) strategy_objs = sorted(strategy_objs, key=lambda x: x['name'])
for obj in strategy_objs: for obj in strategy_objs:
@@ -89,7 +90,7 @@ def start_list_strategies(args: Dict[str, Any]) -> None:
if args['print_one_column']: if args['print_one_column']:
print('\n'.join([s['name'] for s in strategy_objs])) print('\n'.join([s['name'] for s in strategy_objs]))
else: else:
_print_objs_tabular(strategy_objs, config.get('print_colorized', False)) _print_objs_tabular(strategy_objs, config.get('print_colorized', False), directory)
def start_list_timeframes(args: Dict[str, Any]) -> None: def start_list_timeframes(args: Dict[str, Any]) -> None:
@@ -131,7 +132,7 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None:
try: try:
pairs = exchange.get_markets(base_currencies=base_currencies, pairs = exchange.get_markets(base_currencies=base_currencies,
quote_currencies=quote_currencies, quote_currencies=quote_currencies,
pairs_only=pairs_only, tradable_only=pairs_only,
active_only=active_only) active_only=active_only)
# Sort the pairs/markets by symbol # Sort the pairs/markets by symbol
pairs = dict(sorted(pairs.items())) pairs = dict(sorted(pairs.items()))
@@ -151,15 +152,19 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None:
if quote_currencies else "")) if quote_currencies else ""))
headers = ["Id", "Symbol", "Base", "Quote", "Active", headers = ["Id", "Symbol", "Base", "Quote", "Active",
*(['Is pair'] if not pairs_only else [])] "Spot", "Margin", "Future", "Leverage"]
tabular_data = [] tabular_data = [{
for _, v in pairs.items(): 'Id': v['id'],
tabular_data.append({'Id': v['id'], 'Symbol': v['symbol'], 'Symbol': v['symbol'],
'Base': v['base'], 'Quote': v['quote'], 'Base': v['base'],
'Active': market_is_active(v), 'Quote': v['quote'],
**({'Is pair': exchange.market_is_tradable(v)} 'Active': market_is_active(v),
if not pairs_only else {})}) 'Spot': 'Spot' if exchange.market_is_spot(v) else '',
'Margin': 'Margin' if exchange.market_is_margin(v) else '',
'Future': 'Future' if exchange.market_is_future(v) else '',
'Leverage': exchange.get_max_leverage(v['symbol'], 20)
} for _, v in pairs.items()]
if (args.get('print_one_column', False) or if (args.get('print_one_column', False) or
args.get('list_pairs_print_json', False) or args.get('list_pairs_print_json', False) or
@@ -207,7 +212,7 @@ def start_show_trades(args: Dict[str, Any]) -> None:
raise OperationalException("--db-url is required for this command.") raise OperationalException("--db-url is required for this command.")
logger.info(f'Using DB: "{parse_db_uri_for_logging(config["db_url"])}"') logger.info(f'Using DB: "{parse_db_uri_for_logging(config["db_url"])}"')
init_db(config['db_url'], clean_open_orders=False) init_db(config['db_url'])
tfilter = [] tfilter = []
if config.get('trade_ids'): if config.get('trade_ids'):

View File

@@ -25,12 +25,16 @@ def setup_optimize_configuration(args: Dict[str, Any], method: RunMode) -> Dict[
RunMode.HYPEROPT: 'hyperoptimization', RunMode.HYPEROPT: 'hyperoptimization',
} }
if method in no_unlimited_runmodes.keys(): if method in no_unlimited_runmodes.keys():
wallet_size = config['dry_run_wallet'] * config['tradable_balance_ratio']
# tradable_balance_ratio
if (config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT if (config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT
and config['stake_amount'] > config['dry_run_wallet']): and config['stake_amount'] > wallet_size):
wallet = round_coin_value(config['dry_run_wallet'], config['stake_currency']) wallet = round_coin_value(wallet_size, config['stake_currency'])
stake = round_coin_value(config['stake_amount'], config['stake_currency']) stake = round_coin_value(config['stake_amount'], config['stake_currency'])
raise OperationalException(f"Starting balance ({wallet}) " raise OperationalException(
f"is smaller than stake_amount {stake}.") f"Starting balance ({wallet}) is smaller than stake_amount {stake}. "
f"Wallet is calculated as `dry_run_wallet * tradable_balance_ratio`."
)
return config return config

View File

@@ -4,5 +4,4 @@ from freqtrade.configuration.check_exchange import check_exchange
from freqtrade.configuration.config_setup import setup_utils_configuration from freqtrade.configuration.config_setup import setup_utils_configuration
from freqtrade.configuration.config_validation import validate_config_consistency from freqtrade.configuration.config_validation import validate_config_consistency
from freqtrade.configuration.configuration import Configuration from freqtrade.configuration.configuration import Configuration
from freqtrade.configuration.PeriodicCache import PeriodicCache
from freqtrade.configuration.timerange import TimeRange from freqtrade.configuration.timerange import TimeRange

View File

@@ -27,7 +27,7 @@ def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool:
return True return True
logger.info("Checking exchange...") logger.info("Checking exchange...")
exchange = config.get('exchange', {}).get('name').lower() exchange = config.get('exchange', {}).get('name', '').lower()
if not exchange: if not exchange:
raise OperationalException( raise OperationalException(
f'This command requires a configured exchange. You should either use ' f'This command requires a configured exchange. You should either use '

View File

@@ -22,6 +22,6 @@ def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str
# Ensure these modes are using Dry-run # Ensure these modes are using Dry-run
config['dry_run'] = True config['dry_run'] = True
validate_config_consistency(config) validate_config_consistency(config, preliminary=True)
return config return config

View File

@@ -6,7 +6,8 @@ from jsonschema import Draft4Validator, validators
from jsonschema.exceptions import ValidationError, best_match from jsonschema.exceptions import ValidationError, best_match
from freqtrade import constants from freqtrade import constants
from freqtrade.enums import RunMode from freqtrade.configuration.deprecated_settings import process_deprecated_setting
from freqtrade.enums import RunMode, TradingMode
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
@@ -38,7 +39,7 @@ def _extend_validator(validator_class):
FreqtradeValidator = _extend_validator(Draft4Validator) FreqtradeValidator = _extend_validator(Draft4Validator)
def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]: def validate_config_schema(conf: Dict[str, Any], preliminary: bool = False) -> Dict[str, Any]:
""" """
Validate the configuration follow the Config Schema Validate the configuration follow the Config Schema
:param conf: Config in JSON format :param conf: Config in JSON format
@@ -48,7 +49,10 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]:
if conf.get('runmode', RunMode.OTHER) in (RunMode.DRY_RUN, RunMode.LIVE): if conf.get('runmode', RunMode.OTHER) in (RunMode.DRY_RUN, RunMode.LIVE):
conf_schema['required'] = constants.SCHEMA_TRADE_REQUIRED conf_schema['required'] = constants.SCHEMA_TRADE_REQUIRED
elif conf.get('runmode', RunMode.OTHER) in (RunMode.BACKTEST, RunMode.HYPEROPT): elif conf.get('runmode', RunMode.OTHER) in (RunMode.BACKTEST, RunMode.HYPEROPT):
conf_schema['required'] = constants.SCHEMA_BACKTEST_REQUIRED if preliminary:
conf_schema['required'] = constants.SCHEMA_BACKTEST_REQUIRED
else:
conf_schema['required'] = constants.SCHEMA_BACKTEST_REQUIRED_FINAL
else: else:
conf_schema['required'] = constants.SCHEMA_MINIMAL_REQUIRED conf_schema['required'] = constants.SCHEMA_MINIMAL_REQUIRED
try: try:
@@ -63,7 +67,7 @@ def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]:
) )
def validate_config_consistency(conf: Dict[str, Any]) -> None: def validate_config_consistency(conf: Dict[str, Any], preliminary: bool = False) -> None:
""" """
Validate the configuration consistency. Validate the configuration consistency.
Should be ran after loading both configuration and strategy, Should be ran after loading both configuration and strategy,
@@ -80,10 +84,11 @@ def validate_config_consistency(conf: Dict[str, Any]) -> None:
_validate_protections(conf) _validate_protections(conf)
_validate_unlimited_amount(conf) _validate_unlimited_amount(conf)
_validate_ask_orderbook(conf) _validate_ask_orderbook(conf)
validate_migrated_strategy_settings(conf)
# validate configuration before returning # validate configuration before returning
logger.info('Validating configuration ...') logger.info('Validating configuration ...')
validate_config_schema(conf) validate_config_schema(conf, preliminary=preliminary)
def _validate_unlimited_amount(conf: Dict[str, Any]) -> None: def _validate_unlimited_amount(conf: Dict[str, Any]) -> None:
@@ -92,8 +97,8 @@ def _validate_unlimited_amount(conf: Dict[str, Any]) -> None:
:raise: OperationalException if config validation failed :raise: OperationalException if config validation failed
""" """
if (not conf.get('edge', {}).get('enabled') if (not conf.get('edge', {}).get('enabled')
and conf.get('max_open_trades') == float('inf') and conf.get('max_open_trades') == float('inf')
and conf.get('stake_amount') == constants.UNLIMITED_STAKE_AMOUNT): and conf.get('stake_amount') == constants.UNLIMITED_STAKE_AMOUNT):
raise OperationalException("`max_open_trades` and `stake_amount` cannot both be unlimited.") raise OperationalException("`max_open_trades` and `stake_amount` cannot both be unlimited.")
@@ -101,13 +106,15 @@ def _validate_price_config(conf: Dict[str, Any]) -> None:
""" """
When using market orders, price sides must be using the "other" side of the price When using market orders, price sides must be using the "other" side of the price
""" """
if (conf.get('order_types', {}).get('buy') == 'market' # TODO: The below could be an enforced setting when using market orders
and conf.get('bid_strategy', {}).get('price_side') != 'ask'): if (conf.get('order_types', {}).get('entry') == 'market'
raise OperationalException('Market buy orders require bid_strategy.price_side = "ask".') and conf.get('entry_pricing', {}).get('price_side') not in ('ask', 'other')):
raise OperationalException(
'Market entry orders require entry_pricing.price_side = "other".')
if (conf.get('order_types', {}).get('sell') == 'market' if (conf.get('order_types', {}).get('exit') == 'market'
and conf.get('ask_strategy', {}).get('price_side') != 'bid'): and conf.get('exit_pricing', {}).get('price_side') not in ('bid', 'other')):
raise OperationalException('Market sell orders require ask_strategy.price_side = "bid".') raise OperationalException('Market exit orders require exit_pricing.price_side = "other".')
def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None: def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None:
@@ -150,9 +157,9 @@ def _validate_edge(conf: Dict[str, Any]) -> None:
if not conf.get('edge', {}).get('enabled'): if not conf.get('edge', {}).get('enabled'):
return return
if not conf.get('use_sell_signal', True): if not conf.get('use_exit_signal', True):
raise OperationalException( raise OperationalException(
"Edge requires `use_sell_signal` to be True, otherwise no sells will happen." "Edge requires `use_exit_signal` to be True, otherwise no sells will happen."
) )
@@ -190,13 +197,13 @@ def _validate_protections(conf: Dict[str, Any]) -> None:
def _validate_ask_orderbook(conf: Dict[str, Any]) -> None: def _validate_ask_orderbook(conf: Dict[str, Any]) -> None:
ask_strategy = conf.get('ask_strategy', {}) ask_strategy = conf.get('exit_pricing', {})
ob_min = ask_strategy.get('order_book_min') ob_min = ask_strategy.get('order_book_min')
ob_max = ask_strategy.get('order_book_max') ob_max = ask_strategy.get('order_book_max')
if ob_min is not None and ob_max is not None and ask_strategy.get('use_order_book'): if ob_min is not None and ob_max is not None and ask_strategy.get('use_order_book'):
if ob_min != ob_max: if ob_min != ob_max:
raise OperationalException( raise OperationalException(
"Using order_book_max != order_book_min in ask_strategy is no longer supported." "Using order_book_max != order_book_min in exit_pricing is no longer supported."
"Please pick one value and use `order_book_top` in the future." "Please pick one value and use `order_book_top` in the future."
) )
else: else:
@@ -205,5 +212,121 @@ def _validate_ask_orderbook(conf: Dict[str, Any]) -> None:
logger.warning( logger.warning(
"DEPRECATED: " "DEPRECATED: "
"Please use `order_book_top` instead of `order_book_min` and `order_book_max` " "Please use `order_book_top` instead of `order_book_min` and `order_book_max` "
"for your `ask_strategy` configuration." "for your `exit_pricing` configuration."
) )
def validate_migrated_strategy_settings(conf: Dict[str, Any]) -> None:
_validate_time_in_force(conf)
_validate_order_types(conf)
_validate_unfilledtimeout(conf)
_validate_pricing_rules(conf)
_strategy_settings(conf)
def _validate_time_in_force(conf: Dict[str, Any]) -> None:
time_in_force = conf.get('order_time_in_force', {})
if 'buy' in time_in_force or 'sell' in time_in_force:
if conf.get('trading_mode', TradingMode.SPOT) != TradingMode.SPOT:
raise OperationalException(
"Please migrate your time_in_force settings to use 'entry' and 'exit'.")
else:
logger.warning(
"DEPRECATED: Using 'buy' and 'sell' for time_in_force is deprecated."
"Please migrate your time_in_force settings to use 'entry' and 'exit'."
)
process_deprecated_setting(
conf, 'order_time_in_force', 'buy', 'order_time_in_force', 'entry')
process_deprecated_setting(
conf, 'order_time_in_force', 'sell', 'order_time_in_force', 'exit')
def _validate_order_types(conf: Dict[str, Any]) -> None:
order_types = conf.get('order_types', {})
old_order_types = ['buy', 'sell', 'emergencysell', 'forcebuy',
'forcesell', 'emergencyexit', 'forceexit', 'forceentry']
if any(x in order_types for x in old_order_types):
if conf.get('trading_mode', TradingMode.SPOT) != TradingMode.SPOT:
raise OperationalException(
"Please migrate your order_types settings to use the new wording.")
else:
logger.warning(
"DEPRECATED: Using 'buy' and 'sell' for order_types is deprecated."
"Please migrate your order_types settings to use 'entry' and 'exit' wording."
)
for o, n in [
('buy', 'entry'),
('sell', 'exit'),
('emergencysell', 'emergency_exit'),
('forcesell', 'force_exit'),
('forcebuy', 'force_entry'),
('emergencyexit', 'emergency_exit'),
('forceexit', 'force_exit'),
('forceentry', 'force_entry'),
]:
process_deprecated_setting(conf, 'order_types', o, 'order_types', n)
def _validate_unfilledtimeout(conf: Dict[str, Any]) -> None:
unfilledtimeout = conf.get('unfilledtimeout', {})
if any(x in unfilledtimeout for x in ['buy', 'sell']):
if conf.get('trading_mode', TradingMode.SPOT) != TradingMode.SPOT:
raise OperationalException(
"Please migrate your unfilledtimeout settings to use the new wording.")
else:
logger.warning(
"DEPRECATED: Using 'buy' and 'sell' for unfilledtimeout is deprecated."
"Please migrate your unfilledtimeout settings to use 'entry' and 'exit' wording."
)
for o, n in [
('buy', 'entry'),
('sell', 'exit'),
]:
process_deprecated_setting(conf, 'unfilledtimeout', o, 'unfilledtimeout', n)
def _validate_pricing_rules(conf: Dict[str, Any]) -> None:
if conf.get('ask_strategy') or conf.get('bid_strategy'):
if conf.get('trading_mode', TradingMode.SPOT) != TradingMode.SPOT:
raise OperationalException(
"Please migrate your pricing settings to use the new wording.")
else:
logger.warning(
"DEPRECATED: Using 'ask_strategy' and 'bid_strategy' is deprecated."
"Please migrate your settings to use 'entry_pricing' and 'exit_pricing'."
)
conf['entry_pricing'] = {}
for obj in list(conf.get('bid_strategy', {}).keys()):
if obj == 'ask_last_balance':
process_deprecated_setting(conf, 'bid_strategy', obj,
'entry_pricing', 'price_last_balance')
else:
process_deprecated_setting(conf, 'bid_strategy', obj, 'entry_pricing', obj)
del conf['bid_strategy']
conf['exit_pricing'] = {}
for obj in list(conf.get('ask_strategy', {}).keys()):
if obj == 'bid_last_balance':
process_deprecated_setting(conf, 'ask_strategy', obj,
'exit_pricing', 'price_last_balance')
else:
process_deprecated_setting(conf, 'ask_strategy', obj, 'exit_pricing', obj)
del conf['ask_strategy']
def _strategy_settings(conf: Dict[str, Any]) -> None:
process_deprecated_setting(conf, None, 'use_sell_signal', None, 'use_exit_signal')
process_deprecated_setting(conf, None, 'sell_profit_only', None, 'exit_profit_only')
process_deprecated_setting(conf, None, 'sell_profit_offset', None, 'exit_profit_offset')
process_deprecated_setting(conf, None, 'ignore_roi_if_buy_signal',
None, 'ignore_roi_if_entry_signal')

View File

@@ -12,8 +12,8 @@ from freqtrade.configuration.check_exchange import check_exchange
from freqtrade.configuration.deprecated_settings import process_temporary_deprecated_settings 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.environment_vars import enironment_vars_to_dict from freqtrade.configuration.environment_vars import enironment_vars_to_dict
from freqtrade.configuration.load_config import load_config_file, load_file from freqtrade.configuration.load_config import load_file, load_from_files
from freqtrade.enums import NON_UTIL_MODES, TRADING_MODES, RunMode from freqtrade.enums import NON_UTIL_MODES, TRADING_MODES, CandleType, RunMode, TradingMode
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.loggers import setup_logging from freqtrade.loggers import setup_logging
from freqtrade.misc import deep_merge_dicts, parse_db_uri_for_logging from freqtrade.misc import deep_merge_dicts, parse_db_uri_for_logging
@@ -55,47 +55,28 @@ class Configuration:
:param files: List of file paths :param files: List of file paths
:return: configuration dictionary :return: configuration dictionary
""" """
# Keep this method as staticmethod, so it can be used from interactive environments
c = Configuration({'config': files}, RunMode.OTHER) c = Configuration({'config': files}, RunMode.OTHER)
return c.get_config() return c.get_config()
def load_from_files(self, files: List[str]) -> Dict[str, Any]:
# Keep this method as staticmethod, so it can be used from interactive environments
config: Dict[str, Any] = {}
if not files:
return deepcopy(constants.MINIMAL_CONFIG)
# We expect here a list of config filenames
for path in files:
logger.info(f'Using config: {path} ...')
# Merge config options, overwriting old values
config = deep_merge_dicts(load_config_file(path), config)
# Load environment variables
env_data = enironment_vars_to_dict()
config = deep_merge_dicts(env_data, config)
config['config_files'] = files
# Normalize config
if 'internals' not in config:
config['internals'] = {}
if 'ask_strategy' not in config:
config['ask_strategy'] = {}
if 'pairlists' not in config:
config['pairlists'] = []
return config
def load_config(self) -> Dict[str, Any]: def load_config(self) -> Dict[str, Any]:
""" """
Extract information for sys.argv and load the bot configuration Extract information for sys.argv and load the bot configuration
:return: Configuration dictionary :return: Configuration dictionary
""" """
# Load all configs # Load all configs
config: Dict[str, Any] = self.load_from_files(self.args.get("config", [])) config: Dict[str, Any] = load_from_files(self.args.get("config", []))
# Load environment variables
env_data = enironment_vars_to_dict()
config = deep_merge_dicts(env_data, config)
# Normalize config
if 'internals' not in config:
config['internals'] = {}
if 'pairlists' not in config:
config['pairlists'] = []
# Keep a copy of the original configuration file # Keep a copy of the original configuration file
config['original_config'] = deepcopy(config) config['original_config'] = deepcopy(config)
@@ -114,6 +95,10 @@ class Configuration:
self._process_data_options(config) self._process_data_options(config)
self._process_analyze_options(config)
self._process_freqai_options(config)
# Check if the exchange set by the user is supported # Check if the exchange set by the user is supported
check_exchange(config, config.get('experimental', {}).get('block_bad_exchanges', True)) check_exchange(config, config.get('experimental', {}).get('block_bad_exchanges', True))
@@ -146,7 +131,7 @@ class Configuration:
# Default to in-memory db for dry_run if not specified # Default to in-memory db for dry_run if not specified
config['db_url'] = constants.DEFAULT_DB_DRYRUN_URL config['db_url'] = constants.DEFAULT_DB_DRYRUN_URL
else: else:
if not config.get('db_url', None): if not config.get('db_url'):
config['db_url'] = constants.DEFAULT_DB_PROD_URL config['db_url'] = constants.DEFAULT_DB_PROD_URL
logger.info('Dry run is disabled') logger.info('Dry run is disabled')
@@ -166,8 +151,11 @@ class Configuration:
config.update({'db_url': self.args['db_url']}) config.update({'db_url': self.args['db_url']})
logger.info('Parameter --db-url detected ...') logger.info('Parameter --db-url detected ...')
if config.get('forcebuy_enable', False): self._args_to_config(config, argname='db_url_from',
logger.warning('`forcebuy` RPC message enabled.') logstring='Parameter --db-url-from detected ...')
if config.get('force_entry_enable', False):
logger.warning('`force_entry_enable` RPC message enabled.')
# Support for sd_notify # Support for sd_notify
if 'sd_notify' in self.args and self.args['sd_notify']: if 'sd_notify' in self.args and self.args['sd_notify']:
@@ -196,7 +184,7 @@ class Configuration:
config['user_data_dir'] = create_userdata_dir(config['user_data_dir'], create_dir=False) config['user_data_dir'] = create_userdata_dir(config['user_data_dir'], create_dir=False)
logger.info('Using user-data directory: %s ...', config['user_data_dir']) logger.info('Using user-data directory: %s ...', config['user_data_dir'])
config.update({'datadir': create_datadir(config, self.args.get('datadir', None))}) config.update({'datadir': create_datadir(config, self.args.get('datadir'))})
logger.info('Using data directory: %s ...', config.get('datadir')) logger.info('Using data directory: %s ...', config.get('datadir'))
if self.args.get('exportfilename'): if self.args.get('exportfilename'):
@@ -235,7 +223,7 @@ class Configuration:
if config.get('max_open_trades') == -1: if config.get('max_open_trades') == -1:
config['max_open_trades'] = float('inf') config['max_open_trades'] = float('inf')
if self.args.get('stake_amount', None): if self.args.get('stake_amount'):
# Convert explicitly to float to support CLI argument for both unlimited and value # Convert explicitly to float to support CLI argument for both unlimited and value
try: try:
self.args['stake_amount'] = float(self.args['stake_amount']) self.args['stake_amount'] = float(self.args['stake_amount'])
@@ -267,6 +255,12 @@ class Configuration:
self._args_to_config(config, argname='strategy_list', self._args_to_config(config, argname='strategy_list',
logstring='Using strategy list of {} strategies', logfun=len) logstring='Using strategy list of {} strategies', logfun=len)
self._args_to_config(
config,
argname='recursive_strategy_search',
logstring='Recursively searching for a strategy in the strategies folder.',
)
self._args_to_config(config, argname='timeframe', self._args_to_config(config, argname='timeframe',
logstring='Overriding timeframe with Command line argument') logstring='Overriding timeframe with Command line argument')
@@ -406,6 +400,8 @@ class Configuration:
self._args_to_config(config, argname='trade_source', self._args_to_config(config, argname='trade_source',
logstring='Using trades from: {}') logstring='Using trades from: {}')
self._args_to_config(config, argname='prepend_data',
logstring='Prepend detected. Allowing data prepending.')
self._args_to_config(config, argname='erase', self._args_to_config(config, argname='erase',
logstring='Erase detected. Deleting existing data.') logstring='Erase detected. Deleting existing data.')
@@ -433,6 +429,26 @@ class Configuration:
def _process_data_options(self, config: Dict[str, Any]) -> None: def _process_data_options(self, config: Dict[str, Any]) -> None:
self._args_to_config(config, argname='new_pairs_days', self._args_to_config(config, argname='new_pairs_days',
logstring='Detected --new-pairs-days: {}') logstring='Detected --new-pairs-days: {}')
self._args_to_config(config, argname='trading_mode',
logstring='Detected --trading-mode: {}')
config['candle_type_def'] = CandleType.get_default(
config.get('trading_mode', 'spot') or 'spot')
config['trading_mode'] = TradingMode(config.get('trading_mode', 'spot') or 'spot')
self._args_to_config(config, argname='candle_types',
logstring='Detected --candle-types: {}')
def _process_analyze_options(self, config: Dict[str, Any]) -> None:
self._args_to_config(config, argname='analysis_groups',
logstring='Analysis reason groups: {}')
self._args_to_config(config, argname='enter_reason_list',
logstring='Analysis enter tag list: {}')
self._args_to_config(config, argname='exit_reason_list',
logstring='Analysis exit tag list: {}')
self._args_to_config(config, argname='indicator_list',
logstring='Analysis indicator list: {}')
def _process_runmode(self, config: Dict[str, Any]) -> None: def _process_runmode(self, config: Dict[str, Any]) -> None:
@@ -447,6 +463,16 @@ class Configuration:
config.update({'runmode': self.runmode}) config.update({'runmode': self.runmode})
def _process_freqai_options(self, config: Dict[str, Any]) -> None:
self._args_to_config(config, argname='freqaimodel',
logstring='Using freqaimodel class name: {}')
self._args_to_config(config, argname='freqaimodel_path',
logstring='Using freqaimodel path: {}')
return
def _args_to_config(self, config: Dict[str, Any], argname: str, def _args_to_config(self, config: Dict[str, Any], argname: str,
logstring: str, logfun: Optional[Callable] = None, logstring: str, logfun: Optional[Callable] = None,
deprecated_msg: Optional[str] = None) -> None: deprecated_msg: Optional[str] = None) -> None:
@@ -460,7 +486,7 @@ class Configuration:
configuration instead of the content) configuration instead of the content)
""" """
if (argname in self.args and self.args[argname] is not None if (argname in self.args and self.args[argname] is not None
and self.args[argname] is not False): and self.args[argname] is not False):
config.update({argname: self.args[argname]}) config.update({argname: self.args[argname]})
if logfun: if logfun:
@@ -491,7 +517,8 @@ class Configuration:
if not pairs_file.exists(): if not pairs_file.exists():
raise OperationalException(f'No pairs file found with path "{pairs_file}".') raise OperationalException(f'No pairs file found with path "{pairs_file}".')
config['pairs'] = load_file(pairs_file) config['pairs'] = load_file(pairs_file)
config['pairs'].sort() if isinstance(config['pairs'], list):
config['pairs'].sort()
return return
if 'config' in self.args and self.args['config']: if 'config' in self.args and self.args['config']:
@@ -502,5 +529,5 @@ class Configuration:
pairs_file = config['datadir'] / 'pairs.json' pairs_file = config['datadir'] / 'pairs.json'
if pairs_file.exists(): if pairs_file.exists():
config['pairs'] = load_file(pairs_file) config['pairs'] = load_file(pairs_file)
if 'pairs' in config: if 'pairs' in config and isinstance(config['pairs'], list):
config['pairs'].sort() config['pairs'].sort()

View File

@@ -12,14 +12,15 @@ logger = logging.getLogger(__name__)
def check_conflicting_settings(config: Dict[str, Any], def check_conflicting_settings(config: Dict[str, Any],
section_old: str, name_old: str, section_old: Optional[str], name_old: str,
section_new: Optional[str], name_new: str) -> None: section_new: Optional[str], name_new: str) -> None:
section_new_config = config.get(section_new, {}) if section_new else config section_new_config = config.get(section_new, {}) if section_new else config
section_old_config = config.get(section_old, {}) section_old_config = config.get(section_old, {}) if section_old else config
if name_new in section_new_config and name_old in section_old_config: if name_new in section_new_config and name_old in section_old_config:
new_name = f"{section_new}.{name_new}" if section_new else f"{name_new}" new_name = f"{section_new}.{name_new}" if section_new else f"{name_new}"
old_name = f"{section_old}.{name_old}" if section_old else f"{name_old}"
raise OperationalException( raise OperationalException(
f"Conflicting settings `{new_name}` and `{section_old}.{name_old}` " f"Conflicting settings `{new_name}` and `{old_name}` "
"(DEPRECATED) detected in the configuration file. " "(DEPRECATED) detected in the configuration file. "
"This deprecated setting will be removed in the next versions of Freqtrade. " "This deprecated setting will be removed in the next versions of Freqtrade. "
f"Please delete it from your configuration and use the `{new_name}` " f"Please delete it from your configuration and use the `{new_name}` "
@@ -47,23 +48,25 @@ def process_removed_setting(config: Dict[str, Any],
def process_deprecated_setting(config: Dict[str, Any], def process_deprecated_setting(config: Dict[str, Any],
section_old: str, name_old: str, section_old: Optional[str], name_old: str,
section_new: Optional[str], name_new: str section_new: Optional[str], name_new: str
) -> None: ) -> None:
check_conflicting_settings(config, section_old, name_old, section_new, name_new) check_conflicting_settings(config, section_old, name_old, section_new, name_new)
section_old_config = config.get(section_old, {}) section_old_config = config.get(section_old, {}) if section_old else config
if name_old in section_old_config: if name_old in section_old_config:
section_1 = f"{section_old}.{name_old}" if section_old else f"{name_old}"
section_2 = f"{section_new}.{name_new}" if section_new else f"{name_new}" section_2 = f"{section_new}.{name_new}" if section_new else f"{name_new}"
logger.warning( logger.warning(
"DEPRECATED: " "DEPRECATED: "
f"The `{section_old}.{name_old}` setting is deprecated and " f"The `{section_1}` setting is deprecated and "
"will be removed in the next versions of Freqtrade. " "will be removed in the next versions of Freqtrade. "
f"Please use the `{section_2}` setting in your configuration instead." f"Please use the `{section_2}` setting in your configuration instead."
) )
section_new_config = config.get(section_new, {}) if section_new else config section_new_config = config.get(section_new, {}) if section_new else config
section_new_config[name_new] = section_old_config[name_old] section_new_config[name_new] = section_old_config[name_old]
del section_old_config[name_old]
def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None: def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
@@ -71,25 +74,51 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
# Kept for future deprecated / moved settings # Kept for future deprecated / moved settings
# check_conflicting_settings(config, 'ask_strategy', 'use_sell_signal', # check_conflicting_settings(config, 'ask_strategy', 'use_sell_signal',
# 'experimental', 'use_sell_signal') # 'experimental', 'use_sell_signal')
process_deprecated_setting(config, 'ask_strategy', 'use_sell_signal',
None, 'use_sell_signal')
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_only',
None, 'sell_profit_only')
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_offset',
None, 'sell_profit_offset')
process_deprecated_setting(config, 'ask_strategy', 'ignore_roi_if_buy_signal',
None, 'ignore_roi_if_buy_signal')
process_deprecated_setting(config, 'ask_strategy', 'ignore_buying_expired_candle_after', process_deprecated_setting(config, 'ask_strategy', 'ignore_buying_expired_candle_after',
None, 'ignore_buying_expired_candle_after') None, 'ignore_buying_expired_candle_after')
# Legacy way - having them in experimental ... process_deprecated_setting(config, None, 'forcebuy_enable', None, 'force_entry_enable')
process_removed_setting(config, 'experimental', 'use_sell_signal',
None, 'use_sell_signal')
process_removed_setting(config, 'experimental', 'sell_profit_only',
None, 'sell_profit_only')
process_removed_setting(config, 'experimental', 'ignore_roi_if_buy_signal',
None, 'ignore_roi_if_buy_signal')
# New settings
if config.get('telegram'):
process_deprecated_setting(config['telegram'], 'notification_settings', 'sell',
'notification_settings', 'exit')
process_deprecated_setting(config['telegram'], 'notification_settings', 'sell_fill',
'notification_settings', 'exit_fill')
process_deprecated_setting(config['telegram'], 'notification_settings', 'sell_cancel',
'notification_settings', 'exit_cancel')
process_deprecated_setting(config['telegram'], 'notification_settings', 'buy',
'notification_settings', 'entry')
process_deprecated_setting(config['telegram'], 'notification_settings', 'buy_fill',
'notification_settings', 'entry_fill')
process_deprecated_setting(config['telegram'], 'notification_settings', 'buy_cancel',
'notification_settings', 'entry_cancel')
if config.get('webhook'):
process_deprecated_setting(config, 'webhook', 'webhookbuy', 'webhook', 'webhookentry')
process_deprecated_setting(config, 'webhook', 'webhookbuycancel',
'webhook', 'webhookentrycancel')
process_deprecated_setting(config, 'webhook', 'webhookbuyfill',
'webhook', 'webhookentryfill')
process_deprecated_setting(config, 'webhook', 'webhooksell', 'webhook', 'webhookexit')
process_deprecated_setting(config, 'webhook', 'webhooksellcancel',
'webhook', 'webhookexitcancel')
process_deprecated_setting(config, 'webhook', 'webhooksellfill',
'webhook', 'webhookexitfill')
# Legacy way - having them in experimental ...
process_removed_setting(config, 'experimental', 'use_sell_signal', None, 'use_exit_signal')
process_removed_setting(config, 'experimental', 'sell_profit_only', None, 'exit_profit_only')
process_removed_setting(config, 'experimental', 'ignore_roi_if_buy_signal',
None, 'ignore_roi_if_entry_signal')
process_removed_setting(config, 'ask_strategy', 'use_sell_signal', None, 'use_exit_signal')
process_removed_setting(config, 'ask_strategy', 'sell_profit_only', None, 'exit_profit_only')
process_removed_setting(config, 'ask_strategy', 'sell_profit_offset',
None, 'exit_profit_offset')
process_removed_setting(config, 'ask_strategy', 'ignore_roi_if_buy_signal',
None, 'ignore_roi_if_entry_signal')
if (config.get('edge', {}).get('enabled', False) if (config.get('edge', {}).get('enabled', False)
and 'capital_available_percentage' in config.get('edge', {})): and 'capital_available_percentage' in config.get('edge', {})):
raise OperationalException( raise OperationalException(
@@ -100,16 +129,11 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
"from the edge configuration." "from the edge configuration."
) )
if 'ticker_interval' in config: if 'ticker_interval' in config:
logger.warning(
"DEPRECATED: " raise OperationalException(
"DEPRECATED: 'ticker_interval' detected. "
"Please use 'timeframe' instead of 'ticker_interval." "Please use 'timeframe' instead of 'ticker_interval."
) )
if 'timeframe' in config:
raise OperationalException(
"Both 'timeframe' and 'ticker_interval' detected."
"Please remove 'ticker_interval' from your configuration to continue operating."
)
config['timeframe'] = config['ticker_interval']
if 'protections' in config: if 'protections' in config:
logger.warning("DEPRECATED: Setting 'protections' in the configuration is deprecated.") logger.warning("DEPRECATED: Setting 'protections' in the configuration is deprecated.")

View File

@@ -15,7 +15,7 @@ def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> Pat
folder = Path(datadir) if datadir else Path(f"{config['user_data_dir']}/data") folder = Path(datadir) if datadir else Path(f"{config['user_data_dir']}/data")
if not datadir: if not datadir:
# set datadir # set datadir
exchange_name = config.get('exchange', {}).get('name').lower() exchange_name = config.get('exchange', {}).get('name', '').lower()
folder = folder.joinpath(exchange_name) folder = folder.joinpath(exchange_name)
if not folder.is_dir(): if not folder.is_dir():

View File

@@ -4,12 +4,15 @@ This module contain functions to load the configuration file
import logging import logging
import re import re
import sys import sys
from copy import deepcopy
from pathlib import Path from pathlib import Path
from typing import Any, Dict from typing import Any, Dict, List
import rapidjson import rapidjson
from freqtrade.constants import MINIMAL_CONFIG
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import deep_merge_dicts
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -28,7 +31,7 @@ def log_config_error_range(path: str, errmsg: str) -> str:
offset = int(offsetlist[0]) offset = int(offsetlist[0])
text = Path(path).read_text() text = Path(path).read_text()
# Fetch an offset of 80 characters around the error line # Fetch an offset of 80 characters around the error line
subtext = text[offset-min(80, offset):offset+80] subtext = text[offset - min(80, offset):offset + 80]
segments = subtext.split('\n') segments = subtext.split('\n')
if len(segments) > 3: if len(segments) > 3:
# Remove first and last lines, to avoid odd truncations # Remove first and last lines, to avoid odd truncations
@@ -70,3 +73,43 @@ def load_config_file(path: str) -> Dict[str, Any]:
) )
return config return config
def load_from_files(files: List[str], base_path: Path = None, level: int = 0) -> Dict[str, Any]:
"""
Recursively load configuration files if specified.
Sub-files are assumed to be relative to the initial config.
"""
config: Dict[str, Any] = {}
if level > 5:
raise OperationalException("Config loop detected.")
if not files:
return deepcopy(MINIMAL_CONFIG)
files_loaded = []
# We expect here a list of config filenames
for filename in files:
logger.info(f'Using config: {filename} ...')
if filename == '-':
# Immediately load stdin and return
return load_config_file(filename)
file = Path(filename)
if base_path:
# Prepend basepath to allow for relative assignments
file = base_path / file
config_tmp = load_config_file(str(file))
if 'add_config_files' in config_tmp:
config_sub = load_from_files(
config_tmp['add_config_files'], file.resolve().parent, level + 1)
files_loaded.extend(config_sub.get('config_files', []))
config_tmp = deep_merge_dicts(config_tmp, config_sub)
files_loaded.insert(0, str(file))
# Merge config options, overwriting prior values
config = deep_merge_dicts(config_tmp, config)
config['config_files'] = files_loaded
return config

View File

@@ -3,7 +3,9 @@
""" """
bot constants bot constants
""" """
from typing import List, Tuple from typing import List, Literal, Tuple
from freqtrade.enums import CandleType
DEFAULT_CONFIG = 'config.json' DEFAULT_CONFIG = 'config.json'
@@ -12,21 +14,22 @@ PROCESS_THROTTLE_SECS = 5 # sec
HYPEROPT_EPOCH = 100 # epochs HYPEROPT_EPOCH = 100 # epochs
RETRY_TIMEOUT = 30 # sec RETRY_TIMEOUT = 30 # sec
TIMEOUT_UNITS = ['minutes', 'seconds'] TIMEOUT_UNITS = ['minutes', 'seconds']
EXPORT_OPTIONS = ['none', 'trades'] EXPORT_OPTIONS = ['none', 'trades', 'signals']
DEFAULT_DB_PROD_URL = 'sqlite:///tradesv3.sqlite' DEFAULT_DB_PROD_URL = 'sqlite:///tradesv3.sqlite'
DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite' DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite'
UNLIMITED_STAKE_AMOUNT = 'unlimited' UNLIMITED_STAKE_AMOUNT = 'unlimited'
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05 DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
REQUIRED_ORDERTIF = ['buy', 'sell'] REQUIRED_ORDERTIF = ['entry', 'exit']
REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange'] REQUIRED_ORDERTYPES = ['entry', 'exit', 'stoploss', 'stoploss_on_exchange']
ORDERBOOK_SIDES = ['ask', 'bid'] PRICING_SIDES = ['ask', 'bid', 'same', 'other']
ORDERTYPE_POSSIBILITIES = ['limit', 'market'] ORDERTYPE_POSSIBILITIES = ['limit', 'market']
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc'] ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
HYPEROPT_LOSS_BUILTIN = ['ShortTradeDurHyperOptLoss', 'OnlyProfitHyperOptLoss', HYPEROPT_LOSS_BUILTIN = ['ShortTradeDurHyperOptLoss', 'OnlyProfitHyperOptLoss',
'SharpeHyperOptLoss', 'SharpeHyperOptLossDaily', 'SharpeHyperOptLoss', 'SharpeHyperOptLossDaily',
'SortinoHyperOptLoss', 'SortinoHyperOptLossDaily', 'SortinoHyperOptLoss', 'SortinoHyperOptLossDaily',
'CalmarHyperOptLoss', 'CalmarHyperOptLoss',
'MaxDrawDownHyperOptLoss', 'ProfitDrawDownHyperOptLoss'] 'MaxDrawDownHyperOptLoss', 'MaxDrawDownRelativeHyperOptLoss',
'ProfitDrawDownHyperOptLoss']
AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList', AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList',
'AgeFilter', 'OffsetFilter', 'PerformanceFilter', 'AgeFilter', 'OffsetFilter', 'PerformanceFilter',
'PrecisionFilter', 'PriceFilter', 'RangeStabilityFilter', 'PrecisionFilter', 'PriceFilter', 'RangeStabilityFilter',
@@ -43,6 +46,8 @@ DEFAULT_DATAFRAME_COLUMNS = ['date', 'open', 'high', 'low', 'close', 'volume']
# Don't modify sequence of DEFAULT_TRADES_COLUMNS # Don't modify sequence of DEFAULT_TRADES_COLUMNS
# it has wide consequences for stored trades files # it has wide consequences for stored trades files
DEFAULT_TRADES_COLUMNS = ['timestamp', 'id', 'type', 'side', 'price', 'amount', 'cost'] DEFAULT_TRADES_COLUMNS = ['timestamp', 'id', 'type', 'side', 'price', 'amount', 'cost']
TRADING_MODES = ['spot', 'margin', 'futures']
MARGIN_MODES = ['cross', 'isolated', '']
LAST_BT_RESULT_FN = '.last_result.json' LAST_BT_RESULT_FN = '.last_result.json'
FTHYPT_FILEVERSION = 'fthypt_fileversion' FTHYPT_FILEVERSION = 'fthypt_fileversion'
@@ -50,6 +55,7 @@ FTHYPT_FILEVERSION = 'fthypt_fileversion'
USERPATH_HYPEROPTS = 'hyperopts' USERPATH_HYPEROPTS = 'hyperopts'
USERPATH_STRATEGIES = 'strategies' USERPATH_STRATEGIES = 'strategies'
USERPATH_NOTEBOOKS = 'notebooks' USERPATH_NOTEBOOKS = 'notebooks'
USERPATH_FREQAIMODELS = 'freqaimodels'
TELEGRAM_SETTING_OPTIONS = ['on', 'off', 'silent'] TELEGRAM_SETTING_OPTIONS = ['on', 'off', 'silent']
WEBHOOK_FORMAT_OPTIONS = ['form', 'json', 'raw'] WEBHOOK_FORMAT_OPTIONS = ['form', 'json', 'raw']
@@ -82,20 +88,19 @@ SUPPORTED_FIAT = [
"AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK",
"EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY", "EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY",
"KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN", "KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN",
"RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR", "USD", "RUB", "UAH", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR",
"BTC", "ETH", "XRP", "LTC", "BCH" "USD", "BTC", "ETH", "XRP", "LTC", "BCH"
] ]
MINIMAL_CONFIG = { MINIMAL_CONFIG = {
'stake_currency': '', "stake_currency": "",
'dry_run': True, "dry_run": True,
'exchange': { "exchange": {
'name': '', "name": "",
'key': '', "key": "",
'secret': '', "secret": "",
'pair_whitelist': [], "pair_whitelist": [],
'ccxt_async_config': { "ccxt_async_config": {
'enableRateLimit': True,
} }
} }
} }
@@ -140,16 +145,19 @@ CONF_SCHEMA = {
'minProperties': 1 'minProperties': 1
}, },
'amount_reserve_percent': {'type': 'number', 'minimum': 0.0, 'maximum': 0.5}, 'amount_reserve_percent': {'type': 'number', 'minimum': 0.0, 'maximum': 0.5},
'stoploss': {'type': 'number', 'maximum': 0, 'exclusiveMaximum': True}, 'stoploss': {'type': 'number', 'maximum': 0, 'exclusiveMaximum': True, 'minimum': -1},
'trailing_stop': {'type': 'boolean'}, 'trailing_stop': {'type': 'boolean'},
'trailing_stop_positive': {'type': 'number', 'minimum': 0, 'maximum': 1}, 'trailing_stop_positive': {'type': 'number', 'minimum': 0, 'maximum': 1},
'trailing_stop_positive_offset': {'type': 'number', 'minimum': 0, 'maximum': 1}, 'trailing_stop_positive_offset': {'type': 'number', 'minimum': 0, 'maximum': 1},
'trailing_only_offset_is_reached': {'type': 'boolean'}, 'trailing_only_offset_is_reached': {'type': 'boolean'},
'use_sell_signal': {'type': 'boolean'}, 'use_exit_signal': {'type': 'boolean'},
'sell_profit_only': {'type': 'boolean'}, 'exit_profit_only': {'type': 'boolean'},
'sell_profit_offset': {'type': 'number'}, 'exit_profit_offset': {'type': 'number'},
'ignore_roi_if_buy_signal': {'type': 'boolean'}, 'ignore_roi_if_entry_signal': {'type': 'boolean'},
'ignore_buying_expired_candle_after': {'type': 'number'}, 'ignore_buying_expired_candle_after': {'type': 'number'},
'trading_mode': {'type': 'string', 'enum': TRADING_MODES},
'margin_mode': {'type': 'string', 'enum': MARGIN_MODES},
'liquidation_buffer': {'type': 'number', 'minimum': 0.0, 'maximum': 0.99},
'backtest_breakdown': { 'backtest_breakdown': {
'type': 'array', 'type': 'array',
'items': {'type': 'string', 'enum': BACKTEST_BREAKDOWNS} 'items': {'type': 'string', 'enum': BACKTEST_BREAKDOWNS}
@@ -158,22 +166,22 @@ CONF_SCHEMA = {
'unfilledtimeout': { 'unfilledtimeout': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'buy': {'type': 'number', 'minimum': 1}, 'entry': {'type': 'number', 'minimum': 1},
'sell': {'type': 'number', 'minimum': 1}, 'exit': {'type': 'number', 'minimum': 1},
'exit_timeout_count': {'type': 'number', 'minimum': 0, 'default': 0}, 'exit_timeout_count': {'type': 'number', 'minimum': 0, 'default': 0},
'unit': {'type': 'string', 'enum': TIMEOUT_UNITS, 'default': 'minutes'} 'unit': {'type': 'string', 'enum': TIMEOUT_UNITS, 'default': 'minutes'}
} }
}, },
'bid_strategy': { 'entry_pricing': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'ask_last_balance': { 'price_last_balance': {
'type': 'number', 'type': 'number',
'minimum': 0, 'minimum': 0,
'maximum': 1, 'maximum': 1,
'exclusiveMaximum': False, 'exclusiveMaximum': False,
}, },
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'bid'}, 'price_side': {'type': 'string', 'enum': PRICING_SIDES, 'default': 'same'},
'use_order_book': {'type': 'boolean'}, 'use_order_book': {'type': 'boolean'},
'order_book_top': {'type': 'integer', 'minimum': 1, 'maximum': 50, }, 'order_book_top': {'type': 'integer', 'minimum': 1, 'maximum': 50, },
'check_depth_of_market': { 'check_depth_of_market': {
@@ -186,11 +194,11 @@ CONF_SCHEMA = {
}, },
'required': ['price_side'] 'required': ['price_side']
}, },
'ask_strategy': { 'exit_pricing': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'ask'}, 'price_side': {'type': 'string', 'enum': PRICING_SIDES, 'default': 'same'},
'bid_last_balance': { 'price_last_balance': {
'type': 'number', 'type': 'number',
'minimum': 0, 'minimum': 0,
'maximum': 1, 'maximum': 1,
@@ -207,11 +215,11 @@ CONF_SCHEMA = {
'order_types': { 'order_types': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'buy': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES}, 'entry': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
'sell': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES}, 'exit': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
'forcesell': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES}, 'force_exit': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
'forcebuy': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES}, 'force_entry': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
'emergencysell': { 'emergency_exit': {
'type': 'string', 'type': 'string',
'enum': ORDERTYPE_POSSIBILITIES, 'enum': ORDERTYPE_POSSIBILITIES,
'default': 'market'}, 'default': 'market'},
@@ -221,18 +229,19 @@ CONF_SCHEMA = {
'stoploss_on_exchange_limit_ratio': {'type': 'number', 'minimum': 0.0, 'stoploss_on_exchange_limit_ratio': {'type': 'number', 'minimum': 0.0,
'maximum': 1.0} 'maximum': 1.0}
}, },
'required': ['buy', 'sell', 'stoploss', 'stoploss_on_exchange'] 'required': ['entry', 'exit', 'stoploss', 'stoploss_on_exchange']
}, },
'order_time_in_force': { 'order_time_in_force': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'buy': {'type': 'string', 'enum': ORDERTIF_POSSIBILITIES}, 'entry': {'type': 'string', 'enum': ORDERTIF_POSSIBILITIES},
'sell': {'type': 'string', 'enum': ORDERTIF_POSSIBILITIES} 'exit': {'type': 'string', 'enum': ORDERTIF_POSSIBILITIES}
}, },
'required': ['buy', 'sell'] 'required': REQUIRED_ORDERTIF
}, },
'exchange': {'$ref': '#/definitions/exchange'}, 'exchange': {'$ref': '#/definitions/exchange'},
'edge': {'$ref': '#/definitions/edge'}, 'edge': {'$ref': '#/definitions/edge'},
'freqai': {'$ref': '#/definitions/freqai'},
'experimental': { 'experimental': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
@@ -278,34 +287,42 @@ CONF_SCHEMA = {
'status': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS}, 'status': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'warning': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS}, 'warning': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'startup': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS}, 'startup': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'buy': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS}, 'entry': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'buy_cancel': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS}, 'entry_cancel': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'buy_fill': {'type': 'string', 'entry_fill': {'type': 'string',
'enum': TELEGRAM_SETTING_OPTIONS, 'enum': TELEGRAM_SETTING_OPTIONS,
'default': 'off' 'default': 'off'
}, },
'sell': { 'exit': {
'type': ['string', 'object'], 'type': ['string', 'object'],
'additionalProperties': { 'additionalProperties': {
'type': 'string', 'type': 'string',
'enum': TELEGRAM_SETTING_OPTIONS 'enum': TELEGRAM_SETTING_OPTIONS
} }
}, },
'sell_cancel': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS}, 'exit_cancel': {'type': 'string', 'enum': TELEGRAM_SETTING_OPTIONS},
'sell_fill': { 'exit_fill': {
'type': 'string', 'type': 'string',
'enum': TELEGRAM_SETTING_OPTIONS, 'enum': TELEGRAM_SETTING_OPTIONS,
'default': 'off' 'default': 'on'
}, },
'protection_trigger': { 'protection_trigger': {
'type': 'string', 'type': 'string',
'enum': TELEGRAM_SETTING_OPTIONS, 'enum': TELEGRAM_SETTING_OPTIONS,
'default': 'off' 'default': 'on'
}, },
'protection_trigger_global': { 'protection_trigger_global': {
'type': 'string', 'type': 'string',
'enum': TELEGRAM_SETTING_OPTIONS, 'enum': TELEGRAM_SETTING_OPTIONS,
}, },
'show_candle': {
'type': 'string',
'enum': ['off', 'ohlc'],
},
'strategy_msg': {
'type': 'string',
'enum': TELEGRAM_SETTING_OPTIONS,
},
} }
}, },
'reload': {'type': 'boolean'}, 'reload': {'type': 'boolean'},
@@ -320,15 +337,56 @@ CONF_SCHEMA = {
'format': {'type': 'string', 'enum': WEBHOOK_FORMAT_OPTIONS, 'default': 'form'}, 'format': {'type': 'string', 'enum': WEBHOOK_FORMAT_OPTIONS, 'default': 'form'},
'retries': {'type': 'integer', 'minimum': 0}, 'retries': {'type': 'integer', 'minimum': 0},
'retry_delay': {'type': 'number', 'minimum': 0}, 'retry_delay': {'type': 'number', 'minimum': 0},
'webhookbuy': {'type': 'object'}, 'webhookentry': {'type': 'object'},
'webhookbuycancel': {'type': 'object'}, 'webhookentrycancel': {'type': 'object'},
'webhookbuyfill': {'type': 'object'}, 'webhookentryfill': {'type': 'object'},
'webhooksell': {'type': 'object'}, 'webhookexit': {'type': 'object'},
'webhooksellcancel': {'type': 'object'}, 'webhookexitcancel': {'type': 'object'},
'webhooksellfill': {'type': 'object'}, 'webhookexitfill': {'type': 'object'},
'webhookstatus': {'type': 'object'}, 'webhookstatus': {'type': 'object'},
}, },
}, },
'discord': {
'type': 'object',
'properties': {
'enabled': {'type': 'boolean'},
'webhook_url': {'type': 'string'},
"exit_fill": {
'type': 'array', 'items': {'type': 'object'},
'default': [
{"Trade ID": "{trade_id}"},
{"Exchange": "{exchange}"},
{"Pair": "{pair}"},
{"Direction": "{direction}"},
{"Open rate": "{open_rate}"},
{"Close rate": "{close_rate}"},
{"Amount": "{amount}"},
{"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"},
{"Close date": "{close_date:%Y-%m-%d %H:%M:%S}"},
{"Profit": "{profit_amount} {stake_currency}"},
{"Profitability": "{profit_ratio:.2%}"},
{"Enter tag": "{enter_tag}"},
{"Exit Reason": "{exit_reason}"},
{"Strategy": "{strategy}"},
{"Timeframe": "{timeframe}"},
]
},
"entry_fill": {
'type': 'array', 'items': {'type': 'object'},
'default': [
{"Trade ID": "{trade_id}"},
{"Exchange": "{exchange}"},
{"Pair": "{pair}"},
{"Direction": "{direction}"},
{"Open rate": "{open_rate}"},
{"Amount": "{amount}"},
{"Open date": "{open_date:%Y-%m-%d %H:%M:%S}"},
{"Enter tag": "{enter_tag}"},
{"Strategy": "{strategy} {timeframe}"},
]
},
}
},
'api_server': { 'api_server': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
@@ -351,7 +409,7 @@ CONF_SCHEMA = {
'export': {'type': 'string', 'enum': EXPORT_OPTIONS, 'default': 'trades'}, 'export': {'type': 'string', 'enum': EXPORT_OPTIONS, 'default': 'trades'},
'disableparamexport': {'type': 'boolean'}, 'disableparamexport': {'type': 'boolean'},
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']}, 'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
'forcebuy_enable': {'type': 'boolean'}, 'force_entry_enable': {'type': 'boolean'},
'disable_dataframe_checks': {'type': 'boolean'}, 'disable_dataframe_checks': {'type': 'boolean'},
'internals': { 'internals': {
'type': 'object', 'type': 'object',
@@ -424,7 +482,60 @@ CONF_SCHEMA = {
'remove_pumps': {'type': 'boolean'} 'remove_pumps': {'type': 'boolean'}
}, },
'required': ['process_throttle_secs', 'allowed_risk'] 'required': ['process_throttle_secs', 'allowed_risk']
} },
"freqai": {
"type": "object",
"properties": {
"enabled": {"type": "boolean", "default": False},
"keras": {"type": "boolean", "default": False},
"conv_width": {"type": "integer", "default": 2},
"train_period_days": {"type": "integer", "default": 0},
"backtest_period_days": {"type": "number", "default": 7},
"identifier": {"type": "string", "default": "example"},
"feature_parameters": {
"type": "object",
"properties": {
"include_corr_pairlist": {"type": "array"},
"include_timeframes": {"type": "array"},
"label_period_candles": {"type": "integer"},
"include_shifted_candles": {"type": "integer", "default": 0},
"DI_threshold": {"type": "number", "default": 0},
"weight_factor": {"type": "number", "default": 0},
"principal_component_analysis": {"type": "boolean", "default": False},
"use_SVM_to_remove_outliers": {"type": "boolean", "default": False},
"svm_params": {"type": "object",
"properties": {
"shuffle": {"type": "boolean", "default": False},
"nu": {"type": "number", "default": 0.1}
},
}
},
"required": ["include_timeframes", "include_corr_pairlist", ]
},
"data_split_parameters": {
"type": "object",
"properties": {
"test_size": {"type": "number"},
"random_state": {"type": "integer"},
},
},
"model_training_parameters": {
"type": "object",
"properties": {
"n_estimators": {"type": "integer", "default": 1000}
},
},
},
"required": [
"enabled",
"train_period_days",
"backtest_period_days",
"identifier",
"feature_parameters",
"data_split_parameters",
"model_training_parameters"
]
},
}, },
} }
@@ -438,9 +549,8 @@ SCHEMA_TRADE_REQUIRED = [
'last_stake_amount_min_ratio', 'last_stake_amount_min_ratio',
'dry_run', 'dry_run',
'dry_run_wallet', 'dry_run_wallet',
'ask_strategy', 'exit_pricing',
'bid_strategy', 'entry_pricing',
'unfilledtimeout',
'stoploss', 'stoploss',
'minimal_roi', 'minimal_roi',
'internals', 'internals',
@@ -456,7 +566,10 @@ SCHEMA_BACKTEST_REQUIRED = [
'dry_run_wallet', 'dry_run_wallet',
'dataformat_ohlcv', 'dataformat_ohlcv',
'dataformat_trades', 'dataformat_trades',
'unfilledtimeout', ]
SCHEMA_BACKTEST_REQUIRED_FINAL = SCHEMA_BACKTEST_REQUIRED + [
'stoploss',
'minimal_roi',
] ]
SCHEMA_MINIMAL_REQUIRED = [ SCHEMA_MINIMAL_REQUIRED = [
@@ -473,12 +586,19 @@ CANCEL_REASON = {
"FULLY_CANCELLED": "fully cancelled", "FULLY_CANCELLED": "fully cancelled",
"ALL_CANCELLED": "cancelled (all unfilled and partially filled open orders cancelled)", "ALL_CANCELLED": "cancelled (all unfilled and partially filled open orders cancelled)",
"CANCELLED_ON_EXCHANGE": "cancelled on exchange", "CANCELLED_ON_EXCHANGE": "cancelled on exchange",
"FORCE_SELL": "forcesold", "FORCE_EXIT": "forcesold",
"REPLACE": "cancelled to be replaced by new limit order",
"USER_CANCEL": "user requested order cancel"
} }
# List of pairs with their timeframes # List of pairs with their timeframes
PairWithTimeframe = Tuple[str, str] PairWithTimeframe = Tuple[str, str, CandleType]
ListPairsWithTimeframes = List[PairWithTimeframe] ListPairsWithTimeframes = List[PairWithTimeframe]
# Type for trades list # Type for trades list
TradeList = List[List] TradeList = List[List]
LongShort = Literal['long', 'short']
EntryExit = Literal['entry', 'exit']
BuySell = Literal['buy', 'sell']
MakerTaker = Literal['maker', 'taker']

View File

@@ -5,14 +5,15 @@ import logging
from copy import copy from copy import copy
from datetime import datetime, timezone from datetime import datetime, timezone
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple, Union from typing import Any, Dict, List, Optional, Union
import numpy as np import numpy as np
import pandas as pd import pandas as pd
from freqtrade.constants import LAST_BT_RESULT_FN from freqtrade.constants import LAST_BT_RESULT_FN
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import get_backtest_metadata_filename, json_load from freqtrade.misc import json_load
from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename
from freqtrade.persistence import LocalTrade, Trade, init_db from freqtrade.persistence import LocalTrade, Trade, init_db
@@ -22,9 +23,11 @@ logger = logging.getLogger(__name__)
BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date', BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date',
'open_rate', 'close_rate', 'open_rate', 'close_rate',
'fee_open', 'fee_close', 'trade_duration', 'fee_open', 'fee_close', 'trade_duration',
'profit_ratio', 'profit_abs', 'sell_reason', 'profit_ratio', 'profit_abs', 'exit_reason',
'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs', 'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs',
'stop_loss_ratio', 'min_rate', 'max_rate', 'is_open', 'buy_tag'] 'stop_loss_ratio', 'min_rate', 'max_rate', 'is_open', 'enter_tag',
'is_short', 'open_timestamp', 'close_timestamp', 'orders'
]
def get_latest_optimize_filename(directory: Union[Path, str], variant: str) -> str: def get_latest_optimize_filename(directory: Union[Path, str], variant: str) -> str:
@@ -147,7 +150,14 @@ def load_backtest_stats(filename: Union[Path, str]) -> Dict[str, Any]:
return data return data
def _load_and_merge_backtest_result(strategy_name: str, filename: Path, results: Dict[str, Any]): def load_and_merge_backtest_result(strategy_name: str, filename: Path, results: Dict[str, Any]):
"""
Load one strategy from multi-strategy result
and merge it with results
:param strategy_name: Name of the strategy contained in the result
:param filename: Backtest-result-filename to load
:param results: dict to merge the result to.
"""
bt_data = load_backtest_stats(filename) bt_data = load_backtest_stats(filename)
for k in ('metadata', 'strategy'): for k in ('metadata', 'strategy'):
results[k][strategy_name] = bt_data[k][strategy_name] results[k][strategy_name] = bt_data[k][strategy_name]
@@ -158,6 +168,30 @@ def _load_and_merge_backtest_result(strategy_name: str, filename: Path, results:
break break
def _get_backtest_files(dirname: Path) -> List[Path]:
return list(reversed(sorted(dirname.glob('backtest-result-*-[0-9][0-9].json'))))
def get_backtest_resultlist(dirname: Path):
"""
Get list of backtest results read from metadata files
"""
results = []
for filename in _get_backtest_files(dirname):
metadata = load_backtest_metadata(filename)
if not metadata:
continue
for s, v in metadata.items():
results.append({
'filename': filename.name,
'strategy': s,
'run_id': v['run_id'],
'backtest_start_time': v['backtest_start_time'],
})
return results
def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, str], def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, str],
min_backtest_date: datetime = None) -> Dict[str, Any]: min_backtest_date: datetime = None) -> Dict[str, Any]:
""" """
@@ -177,7 +211,7 @@ def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, s
} }
# Weird glob expression here avoids including .meta.json files. # Weird glob expression here avoids including .meta.json files.
for filename in reversed(sorted(dirname.glob('backtest-result-*-[0-9][0-9].json'))): for filename in _get_backtest_files(dirname):
metadata = load_backtest_metadata(filename) metadata = load_backtest_metadata(filename)
if not metadata: if not metadata:
# Files are sorted from newest to oldest. When file without metadata is encountered it # Files are sorted from newest to oldest. When file without metadata is encountered it
@@ -191,14 +225,7 @@ def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, s
continue continue
if min_backtest_date is not None: if min_backtest_date is not None:
try: backtest_date = strategy_metadata['backtest_start_time']
backtest_date = strategy_metadata['backtest_start_time']
except KeyError:
# TODO: this can be removed starting from feb 2022
# The metadata-file without start_time was only available in develop
# and was never included in an official release.
# Older metadata format without backtest time, too old to consider.
return results
backtest_date = datetime.fromtimestamp(backtest_date, tz=timezone.utc) backtest_date = datetime.fromtimestamp(backtest_date, tz=timezone.utc)
if backtest_date < min_backtest_date: if backtest_date < min_backtest_date:
# Do not use a cached result for this strategy as first result is too old. # Do not use a cached result for this strategy as first result is too old.
@@ -207,7 +234,7 @@ def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, s
if strategy_metadata['run_id'] == run_id: if strategy_metadata['run_id'] == run_id:
del run_ids[strategy_name] del run_ids[strategy_name]
_load_and_merge_backtest_result(strategy_name, filename, results) load_and_merge_backtest_result(strategy_name, filename, results)
if len(run_ids) == 0: if len(run_ids) == 0:
break break
@@ -250,6 +277,15 @@ def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = Non
utc=True, utc=True,
infer_datetime_format=True infer_datetime_format=True
) )
# Compatibility support for pre short Columns
if 'is_short' not in df.columns:
df['is_short'] = 0
if 'enter_tag' not in df.columns:
df['enter_tag'] = df['buy_tag']
df = df.drop(['buy_tag'], axis=1)
if 'orders' not in df.columns:
df.loc[:, 'orders'] = None
else: else:
# old format - only with lists. # old format - only with lists.
raise OperationalException( raise OperationalException(
@@ -303,7 +339,7 @@ def trade_list_to_dataframe(trades: List[LocalTrade]) -> pd.DataFrame:
:param trades: List of trade objects :param trades: List of trade objects
:return: Dataframe with BT_DATA_COLUMNS :return: Dataframe with BT_DATA_COLUMNS
""" """
df = pd.DataFrame.from_records([t.to_json() for t in trades], columns=BT_DATA_COLUMNS) df = pd.DataFrame.from_records([t.to_json(True) for t in trades], columns=BT_DATA_COLUMNS)
if len(df) > 0: if len(df) > 0:
df.loc[:, 'close_date'] = pd.to_datetime(df['close_date'], utc=True) 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[:, 'open_date'] = pd.to_datetime(df['open_date'], utc=True)
@@ -319,7 +355,7 @@ def load_trades_from_db(db_url: str, strategy: Optional[str] = None) -> pd.DataF
Can also serve as protection to load the correct result. Can also serve as protection to load the correct result.
:return: Dataframe containing Trades :return: Dataframe containing Trades
""" """
init_db(db_url, clean_open_orders=False) init_db(db_url)
filters = [] filters = []
if strategy: if strategy:
@@ -366,157 +402,3 @@ def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame,
trades = trades.loc[(trades['open_date'] >= trades_start) & trades = trades.loc[(trades['open_date'] >= trades_start) &
(trades['close_date'] <= trades_stop)] (trades['close_date'] <= trades_stop)]
return trades return trades
def calculate_market_change(data: Dict[str, pd.DataFrame], column: str = "close") -> float:
"""
Calculate market change based on "column".
Calculation is done by taking the first non-null and the last non-null element of each column
and calculating the pctchange as "(last - first) / first".
Then the results per pair are combined as mean.
:param data: Dict of Dataframes, dict key should be pair.
:param column: Column in the original dataframes to use
:return:
"""
tmp_means = []
for pair, df in data.items():
start = df[column].dropna().iloc[0]
end = df[column].dropna().iloc[-1]
tmp_means.append((end - start) / start)
return float(np.mean(tmp_means))
def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame],
column: str = "close") -> pd.DataFrame:
"""
Combine multiple dataframes "column"
:param data: Dict of Dataframes, dict key should be pair.
:param column: Column in the original dataframes to use
:return: DataFrame with the column renamed to the dict key, and a column
named mean, containing the mean of all pairs.
:raise: ValueError if no data is provided.
"""
df_comb = pd.concat([data[pair].set_index('date').rename(
{column: pair}, axis=1)[pair] for pair in data], axis=1)
df_comb['mean'] = df_comb.mean(axis=1)
return df_comb
def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
timeframe: str) -> pd.DataFrame:
"""
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_abs)
:param col_name: Column name that will be assigned the results
:param timeframe: Timeframe used during the operations
:return: Returns df with one additional column, col_name, containing the cumulative profit.
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
from freqtrade.exchange import timeframe_to_minutes
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_abs']].sum()
df.loc[:, col_name] = _trades_sum['profit_abs'].cumsum()
# Set first value to 0
df.loc[df.iloc[0].name, col_name] = 0
# FFill to get continuous
df[col_name] = df[col_name].ffill()
return df
def _calc_drawdown_series(profit_results: pd.DataFrame, *, date_col: str, value_col: str
) -> pd.DataFrame:
max_drawdown_df = pd.DataFrame()
max_drawdown_df['cumulative'] = profit_results[value_col].cumsum()
max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax()
max_drawdown_df['drawdown'] = max_drawdown_df['cumulative'] - max_drawdown_df['high_value']
max_drawdown_df['date'] = profit_results.loc[:, date_col]
return max_drawdown_df
def calculate_underwater(trades: pd.DataFrame, *, date_col: str = 'close_date',
value_col: str = 'profit_ratio'
):
"""
Calculate max drawdown and the corresponding close dates
: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_ratio')
:return: Tuple (float, highdate, lowdate, highvalue, lowvalue) with absolute max drawdown,
high and low time and high and low value.
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
profit_results = trades.sort_values(date_col).reset_index(drop=True)
max_drawdown_df = _calc_drawdown_series(profit_results, date_col=date_col, value_col=value_col)
return max_drawdown_df
def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_date',
value_col: str = 'profit_abs', starting_balance: float = 0
) -> Tuple[float, pd.Timestamp, pd.Timestamp, float, float, float]:
"""
Calculate max drawdown and the corresponding close dates
: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_abs')
:param starting_balance: Portfolio starting balance - properly calculate relative drawdown.
:return: Tuple (float, highdate, lowdate, highvalue, lowvalue, relative_drawdown)
with absolute max drawdown, high and low time and high and low value,
and the relative account drawdown
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
profit_results = trades.sort_values(date_col).reset_index(drop=True)
max_drawdown_df = _calc_drawdown_series(profit_results, date_col=date_col, value_col=value_col)
idxmin = max_drawdown_df['drawdown'].idxmin()
if idxmin == 0:
raise ValueError("No losing trade, therefore no drawdown.")
high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col]
low_date = profit_results.loc[idxmin, date_col]
high_val = max_drawdown_df.loc[max_drawdown_df.iloc[:idxmin]
['high_value'].idxmax(), 'cumulative']
low_val = max_drawdown_df.loc[idxmin, 'cumulative']
max_drawdown_rel = 0.0
if high_val + starting_balance != 0:
max_drawdown_rel = (high_val - low_val) / (high_val + starting_balance)
return (
abs(min(max_drawdown_df['drawdown'])),
high_date,
low_date,
high_val,
low_val,
max_drawdown_rel
)
def calculate_csum(trades: pd.DataFrame, starting_balance: float = 0) -> 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)
:param starting_balance: Add starting balance to results, to show the wallets high / low points
: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() + starting_balance
csum_max = csum_df['sum'].max() + starting_balance
return csum_min, csum_max

View File

@@ -11,6 +11,7 @@ import pandas as pd
from pandas import DataFrame, to_datetime from pandas import DataFrame, to_datetime
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList
from freqtrade.enums import CandleType
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -261,13 +262,20 @@ def convert_trades_format(config: Dict[str, Any], convert_from: str, convert_to:
src.trades_purge(pair=pair) src.trades_purge(pair=pair)
def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to: str, erase: bool): def convert_ohlcv_format(
config: Dict[str, Any],
convert_from: str,
convert_to: str,
erase: bool,
candle_type: CandleType
):
""" """
Convert OHLCV from one format to another Convert OHLCV from one format to another
:param config: Config dictionary :param config: Config dictionary
:param convert_from: Source format :param convert_from: Source format
:param convert_to: Target format :param convert_to: Target format
:param erase: Erase source data (does not apply if source and target format are identical) :param erase: Erase source data (does not apply if source and target format are identical)
:param candle_type: Any of the enum CandleType (must match trading mode!)
""" """
from freqtrade.data.history.idatahandler import get_datahandler from freqtrade.data.history.idatahandler import get_datahandler
src = get_datahandler(config['datadir'], convert_from) src = get_datahandler(config['datadir'], convert_from)
@@ -279,8 +287,11 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to:
config['pairs'] = [] config['pairs'] = []
# Check timeframes or fall back to timeframe. # Check timeframes or fall back to timeframe.
for timeframe in timeframes: for timeframe in timeframes:
config['pairs'].extend(src.ohlcv_get_pairs(config['datadir'], config['pairs'].extend(src.ohlcv_get_pairs(
timeframe)) config['datadir'],
timeframe,
candle_type=candle_type
))
logger.info(f"Converting candle (OHLCV) data for {config['pairs']}") logger.info(f"Converting candle (OHLCV) data for {config['pairs']}")
for timeframe in timeframes: for timeframe in timeframes:
@@ -289,10 +300,16 @@ def convert_ohlcv_format(config: Dict[str, Any], convert_from: str, convert_to:
timerange=None, timerange=None,
fill_missing=False, fill_missing=False,
drop_incomplete=False, drop_incomplete=False,
startup_candles=0) startup_candles=0,
logger.info(f"Converting {len(data)} candles for {pair}") candle_type=candle_type)
logger.info(f"Converting {len(data)} {candle_type} candles for {pair}")
if len(data) > 0: if len(data) > 0:
trg.ohlcv_store(pair=pair, timeframe=timeframe, data=data) trg.ohlcv_store(
pair=pair,
timeframe=timeframe,
data=data,
candle_type=candle_type
)
if erase and convert_from != convert_to: if erase and convert_from != convert_to:
logger.info(f"Deleting source data for {pair} / {timeframe}") logger.info(f"Deleting source data for {pair} / {timeframe}")
src.ohlcv_purge(pair=pair, timeframe=timeframe) src.ohlcv_purge(pair=pair, timeframe=timeframe, candle_type=candle_type)

View File

@@ -5,6 +5,7 @@ including ticker and orderbook data, live and historical candle (OHLCV) data
Common Interface for bot and strategy to access data. Common Interface for bot and strategy to access data.
""" """
import logging import logging
from collections import deque
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
@@ -13,9 +14,10 @@ from pandas import DataFrame
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.constants import ListPairsWithTimeframes, PairWithTimeframe from freqtrade.constants import ListPairsWithTimeframes, PairWithTimeframe
from freqtrade.data.history import load_pair_history from freqtrade.data.history import load_pair_history
from freqtrade.enums import RunMode from freqtrade.enums import CandleType, RunMode
from freqtrade.exceptions import ExchangeError, OperationalException from freqtrade.exceptions import ExchangeError, OperationalException
from freqtrade.exchange import Exchange, timeframe_to_seconds from freqtrade.exchange import Exchange, timeframe_to_seconds
from freqtrade.util import PeriodicCache
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -33,6 +35,10 @@ class DataProvider:
self.__cached_pairs: Dict[PairWithTimeframe, Tuple[DataFrame, datetime]] = {} self.__cached_pairs: Dict[PairWithTimeframe, Tuple[DataFrame, datetime]] = {}
self.__slice_index: Optional[int] = None self.__slice_index: Optional[int] = None
self.__cached_pairs_backtesting: Dict[PairWithTimeframe, DataFrame] = {} self.__cached_pairs_backtesting: Dict[PairWithTimeframe, DataFrame] = {}
self._msg_queue: deque = deque()
self.__msg_cache = PeriodicCache(
maxsize=1000, ttl=timeframe_to_seconds(self._config.get('timeframe', '1h')))
def _set_dataframe_max_index(self, limit_index: int): def _set_dataframe_max_index(self, limit_index: int):
""" """
@@ -41,7 +47,13 @@ class DataProvider:
""" """
self.__slice_index = limit_index self.__slice_index = limit_index
def _set_cached_df(self, pair: str, timeframe: str, dataframe: DataFrame) -> None: def _set_cached_df(
self,
pair: str,
timeframe: str,
dataframe: DataFrame,
candle_type: CandleType
) -> None:
""" """
Store cached Dataframe. Store cached Dataframe.
Using private method as this should never be used by a user Using private method as this should never be used by a user
@@ -49,8 +61,10 @@ class DataProvider:
:param pair: pair to get the data for :param pair: pair to get the data for
:param timeframe: Timeframe to get data for :param timeframe: Timeframe to get data for
:param dataframe: analyzed dataframe :param dataframe: analyzed dataframe
:param candle_type: Any of the enum CandleType (must match trading mode!)
""" """
self.__cached_pairs[(pair, timeframe)] = (dataframe, datetime.now(timezone.utc)) self.__cached_pairs[(pair, timeframe, candle_type)] = (
dataframe, datetime.now(timezone.utc))
def add_pairlisthandler(self, pairlists) -> None: def add_pairlisthandler(self, pairlists) -> None:
""" """
@@ -58,13 +72,21 @@ class DataProvider:
""" """
self._pairlists = pairlists self._pairlists = pairlists
def historic_ohlcv(self, pair: str, timeframe: str = None) -> DataFrame: def historic_ohlcv(
self,
pair: str,
timeframe: str = None,
candle_type: str = ''
) -> DataFrame:
""" """
Get stored historical candle (OHLCV) data Get stored historical candle (OHLCV) data
:param pair: pair to get the data for :param pair: pair to get the data for
:param timeframe: timeframe to get data for :param timeframe: timeframe to get data for
:param candle_type: '', mark, index, premiumIndex, or funding_rate
""" """
saved_pair = (pair, str(timeframe)) _candle_type = CandleType.from_string(
candle_type) if candle_type != '' else self._config['candle_type_def']
saved_pair = (pair, str(timeframe), _candle_type)
if saved_pair not in self.__cached_pairs_backtesting: if saved_pair not in self.__cached_pairs_backtesting:
timerange = TimeRange.parse_timerange(None if self._config.get( timerange = TimeRange.parse_timerange(None if self._config.get(
'timerange') is None else str(self._config.get('timerange'))) 'timerange') is None else str(self._config.get('timerange')))
@@ -77,26 +99,36 @@ class DataProvider:
timeframe=timeframe or self._config['timeframe'], timeframe=timeframe or self._config['timeframe'],
datadir=self._config['datadir'], datadir=self._config['datadir'],
timerange=timerange, timerange=timerange,
data_format=self._config.get('dataformat_ohlcv', 'json') data_format=self._config.get('dataformat_ohlcv', 'json'),
candle_type=_candle_type,
) )
return self.__cached_pairs_backtesting[saved_pair].copy() return self.__cached_pairs_backtesting[saved_pair].copy()
def get_pair_dataframe(self, pair: str, timeframe: str = None) -> DataFrame: def get_pair_dataframe(
self,
pair: str,
timeframe: str = None,
candle_type: str = ''
) -> DataFrame:
""" """
Return pair candle (OHLCV) data, either live or cached historical -- depending Return pair candle (OHLCV) data, either live or cached historical -- depending
on the runmode. on the runmode.
Only combinations in the pairlist or which have been specified as informative pairs
will be available.
:param pair: pair to get the data for :param pair: pair to get the data for
:param timeframe: timeframe to get data for :param timeframe: timeframe to get data for
:return: Dataframe for this pair :return: Dataframe for this pair
:param candle_type: '', mark, index, premiumIndex, or funding_rate
""" """
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE): if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
# Get live OHLCV data. # Get live OHLCV data.
data = self.ohlcv(pair=pair, timeframe=timeframe) data = self.ohlcv(pair=pair, timeframe=timeframe, candle_type=candle_type)
else: else:
# Get historical OHLCV data (cached on disk). # Get historical OHLCV data (cached on disk).
data = self.historic_ohlcv(pair=pair, timeframe=timeframe) data = self.historic_ohlcv(pair=pair, timeframe=timeframe, candle_type=candle_type)
if len(data) == 0: if len(data) == 0:
logger.warning(f"No data found for ({pair}, {timeframe}).") logger.warning(f"No data found for ({pair}, {timeframe}, {candle_type}).")
return data return data
def get_analyzed_dataframe(self, pair: str, timeframe: str) -> Tuple[DataFrame, datetime]: def get_analyzed_dataframe(self, pair: str, timeframe: str) -> Tuple[DataFrame, datetime]:
@@ -109,7 +141,7 @@ class DataProvider:
combination. combination.
Returns empty dataframe and Epoch 0 (1970-01-01) if no dataframe was cached. Returns empty dataframe and Epoch 0 (1970-01-01) if no dataframe was cached.
""" """
pair_key = (pair, timeframe) pair_key = (pair, timeframe, self._config.get('candle_type_def', CandleType.SPOT))
if pair_key in self.__cached_pairs: if pair_key in self.__cached_pairs:
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE): if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
df, date = self.__cached_pairs[pair_key] df, date = self.__cached_pairs[pair_key]
@@ -177,20 +209,31 @@ class DataProvider:
raise OperationalException(NO_EXCHANGE_EXCEPTION) raise OperationalException(NO_EXCHANGE_EXCEPTION)
return list(self._exchange._klines.keys()) return list(self._exchange._klines.keys())
def ohlcv(self, pair: str, timeframe: str = None, copy: bool = True) -> DataFrame: def ohlcv(
self,
pair: str,
timeframe: str = None,
copy: bool = True,
candle_type: str = ''
) -> DataFrame:
""" """
Get candle (OHLCV) data for the given pair as DataFrame Get candle (OHLCV) data for the given pair as DataFrame
Please use the `available_pairs` method to verify which pairs are currently cached. Please use the `available_pairs` method to verify which pairs are currently cached.
:param pair: pair to get the data for :param pair: pair to get the data for
:param timeframe: Timeframe to get data for :param timeframe: Timeframe to get data for
:param candle_type: '', mark, index, premiumIndex, or funding_rate
:param copy: copy dataframe before returning if True. :param copy: copy dataframe before returning if True.
Use False only for read-only operations (where the dataframe is not modified) Use False only for read-only operations (where the dataframe is not modified)
""" """
if self._exchange is None: if self._exchange is None:
raise OperationalException(NO_EXCHANGE_EXCEPTION) raise OperationalException(NO_EXCHANGE_EXCEPTION)
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE): if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
return self._exchange.klines((pair, timeframe or self._config['timeframe']), _candle_type = CandleType.from_string(
copy=copy) candle_type) if candle_type != '' else self._config['candle_type_def']
return self._exchange.klines(
(pair, timeframe or self._config['timeframe'], _candle_type),
copy=copy
)
else: else:
return DataFrame() return DataFrame()
@@ -228,3 +271,20 @@ class DataProvider:
if self._exchange is None: if self._exchange is None:
raise OperationalException(NO_EXCHANGE_EXCEPTION) raise OperationalException(NO_EXCHANGE_EXCEPTION)
return self._exchange.fetch_l2_order_book(pair, maximum) return self._exchange.fetch_l2_order_book(pair, maximum)
def send_msg(self, message: str, *, always_send: bool = False) -> None:
"""
Send custom RPC Notifications from your bot.
Will not send any bot in modes other than Dry-run or Live.
:param message: Message to be sent. Must be below 4096.
:param always_send: If False, will send the message only once per candle, and surpress
identical messages.
Careful as this can end up spaming your chat.
Defaults to False
"""
if self.runmode not in (RunMode.DRY_RUN, RunMode.LIVE):
return
if always_send or message not in self.__msg_cache:
self._msg_queue.append(message)
self.__msg_cache[message] = True

View File

@@ -0,0 +1,227 @@
import logging
from pathlib import Path
from typing import List, Optional
import joblib
import pandas as pd
from tabulate import tabulate
from freqtrade.data.btanalysis import (get_latest_backtest_filename, load_backtest_data,
load_backtest_stats)
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
def _load_signal_candles(backtest_dir: Path):
if backtest_dir.is_dir():
scpf = Path(backtest_dir,
Path(get_latest_backtest_filename(backtest_dir)).stem + "_signals.pkl"
)
else:
scpf = Path(backtest_dir.parent / f"{backtest_dir.stem}_signals.pkl")
try:
scp = open(scpf, "rb")
signal_candles = joblib.load(scp)
logger.info(f"Loaded signal candles: {str(scpf)}")
except Exception as e:
logger.error("Cannot load signal candles from pickled results: ", e)
return signal_candles
def _process_candles_and_indicators(pairlist, strategy_name, trades, signal_candles):
analysed_trades_dict = {}
analysed_trades_dict[strategy_name] = {}
try:
logger.info(f"Processing {strategy_name} : {len(pairlist)} pairs")
for pair in pairlist:
if pair in signal_candles[strategy_name]:
analysed_trades_dict[strategy_name][pair] = _analyze_candles_and_indicators(
pair,
trades,
signal_candles[strategy_name][pair])
except Exception as e:
print(f"Cannot process entry/exit reasons for {strategy_name}: ", e)
return analysed_trades_dict
def _analyze_candles_and_indicators(pair, trades, signal_candles):
buyf = signal_candles
if len(buyf) > 0:
buyf = buyf.set_index('date', drop=False)
trades_red = trades.loc[trades['pair'] == pair].copy()
trades_inds = pd.DataFrame()
if trades_red.shape[0] > 0 and buyf.shape[0] > 0:
for t, v in trades_red.open_date.items():
allinds = buyf.loc[(buyf['date'] < v)]
if allinds.shape[0] > 0:
tmp_inds = allinds.iloc[[-1]]
trades_red.loc[t, 'signal_date'] = tmp_inds['date'].values[0]
trades_red.loc[t, 'enter_reason'] = trades_red.loc[t, 'enter_tag']
tmp_inds.index.rename('signal_date', inplace=True)
trades_inds = pd.concat([trades_inds, tmp_inds])
if 'signal_date' in trades_red:
trades_red['signal_date'] = pd.to_datetime(trades_red['signal_date'], utc=True)
trades_red.set_index('signal_date', inplace=True)
try:
trades_red = pd.merge(trades_red, trades_inds, on='signal_date', how='outer')
except Exception as e:
raise e
return trades_red
else:
return pd.DataFrame()
def _do_group_table_output(bigdf, glist):
for g in glist:
# 0: summary wins/losses grouped by enter tag
if g == "0":
group_mask = ['enter_reason']
wins = bigdf.loc[bigdf['profit_abs'] >= 0] \
.groupby(group_mask) \
.agg({'profit_abs': ['sum']})
wins.columns = ['profit_abs_wins']
loss = bigdf.loc[bigdf['profit_abs'] < 0] \
.groupby(group_mask) \
.agg({'profit_abs': ['sum']})
loss.columns = ['profit_abs_loss']
new = bigdf.groupby(group_mask).agg({'profit_abs': [
'count',
lambda x: sum(x > 0),
lambda x: sum(x <= 0)]})
new = pd.concat([new, wins, loss], axis=1).fillna(0)
new['profit_tot'] = new['profit_abs_wins'] - abs(new['profit_abs_loss'])
new['wl_ratio_pct'] = (new.iloc[:, 1] / new.iloc[:, 0] * 100).fillna(0)
new['avg_win'] = (new['profit_abs_wins'] / new.iloc[:, 1]).fillna(0)
new['avg_loss'] = (new['profit_abs_loss'] / new.iloc[:, 2]).fillna(0)
new.columns = ['total_num_buys', 'wins', 'losses', 'profit_abs_wins', 'profit_abs_loss',
'profit_tot', 'wl_ratio_pct', 'avg_win', 'avg_loss']
sortcols = ['total_num_buys']
_print_table(new, sortcols, show_index=True)
else:
agg_mask = {'profit_abs': ['count', 'sum', 'median', 'mean'],
'profit_ratio': ['sum', 'median', 'mean']}
agg_cols = ['num_buys', 'profit_abs_sum', 'profit_abs_median',
'profit_abs_mean', 'median_profit_pct', 'mean_profit_pct',
'total_profit_pct']
sortcols = ['profit_abs_sum', 'enter_reason']
# 1: profit summaries grouped by enter_tag
if g == "1":
group_mask = ['enter_reason']
# 2: profit summaries grouped by enter_tag and exit_tag
if g == "2":
group_mask = ['enter_reason', 'exit_reason']
# 3: profit summaries grouped by pair and enter_tag
if g == "3":
group_mask = ['pair', 'enter_reason']
# 4: profit summaries grouped by pair, enter_ and exit_tag (this can get quite large)
if g == "4":
group_mask = ['pair', 'enter_reason', 'exit_reason']
if group_mask:
new = bigdf.groupby(group_mask).agg(agg_mask).reset_index()
new.columns = group_mask + agg_cols
new['median_profit_pct'] = new['median_profit_pct'] * 100
new['mean_profit_pct'] = new['mean_profit_pct'] * 100
new['total_profit_pct'] = new['total_profit_pct'] * 100
_print_table(new, sortcols)
else:
logger.warning("Invalid group mask specified.")
def _print_results(analysed_trades, stratname, analysis_groups,
enter_reason_list, exit_reason_list,
indicator_list, columns=None):
if columns is None:
columns = ['pair', 'open_date', 'close_date', 'profit_abs', 'enter_reason', 'exit_reason']
bigdf = pd.DataFrame()
for pair, trades in analysed_trades[stratname].items():
bigdf = pd.concat([bigdf, trades], ignore_index=True)
if bigdf.shape[0] > 0 and ('enter_reason' in bigdf.columns):
if analysis_groups:
_do_group_table_output(bigdf, analysis_groups)
if enter_reason_list and "all" not in enter_reason_list:
bigdf = bigdf.loc[(bigdf['enter_reason'].isin(enter_reason_list))]
if exit_reason_list and "all" not in exit_reason_list:
bigdf = bigdf.loc[(bigdf['exit_reason'].isin(exit_reason_list))]
if "all" in indicator_list:
print(bigdf)
elif indicator_list is not None:
available_inds = []
for ind in indicator_list:
if ind in bigdf:
available_inds.append(ind)
ilist = ["pair", "enter_reason", "exit_reason"] + available_inds
_print_table(bigdf[ilist], sortcols=['exit_reason'], show_index=False)
else:
print("\\_ No trades to show")
def _print_table(df, sortcols=None, show_index=False):
if (sortcols is not None):
data = df.sort_values(sortcols)
else:
data = df
print(
tabulate(
data,
headers='keys',
tablefmt='psql',
showindex=show_index
)
)
def process_entry_exit_reasons(backtest_dir: Path,
pairlist: List[str],
analysis_groups: Optional[List[str]] = ["0", "1", "2"],
enter_reason_list: Optional[List[str]] = ["all"],
exit_reason_list: Optional[List[str]] = ["all"],
indicator_list: Optional[List[str]] = []):
try:
backtest_stats = load_backtest_stats(backtest_dir)
for strategy_name, results in backtest_stats['strategy'].items():
trades = load_backtest_data(backtest_dir, strategy_name)
if not trades.empty:
signal_candles = _load_signal_candles(backtest_dir)
analysed_trades_dict = _process_candles_and_indicators(pairlist, strategy_name,
trades, signal_candles)
_print_results(analysed_trades_dict,
strategy_name,
analysis_groups,
enter_reason_list,
exit_reason_list,
indicator_list)
except ValueError as e:
raise OperationalException(e) from e

View File

@@ -7,8 +7,8 @@ import numpy as np
import pandas as pd import pandas as pd
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.constants import (DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, DEFAULT_TRADES_COLUMNS, TradeList
ListPairsWithTimeframes, TradeList) from freqtrade.enums import CandleType
from .idatahandler import IDataHandler from .idatahandler import IDataHandler
@@ -21,44 +21,40 @@ class HDF5DataHandler(IDataHandler):
_columns = DEFAULT_DATAFRAME_COLUMNS _columns = DEFAULT_DATAFRAME_COLUMNS
@classmethod @classmethod
def ohlcv_get_available_data(cls, datadir: Path) -> ListPairsWithTimeframes: def ohlcv_get_pairs(cls, datadir: Path, timeframe: str, candle_type: CandleType) -> List[str]:
"""
Returns a list of all pairs with ohlcv data available in this datadir
:param datadir: Directory to search for ohlcv files
:return: List of Tuples of (pair, timeframe)
"""
_tmp = [re.search(r'^([a-zA-Z_]+)\-(\d+\S+)(?=.h5)', p.name)
for p in datadir.glob("*.h5")]
return [(match[1].replace('_', '/'), match[2]) for match in _tmp
if match and len(match.groups()) > 1]
@classmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]:
""" """
Returns a list of all pairs with ohlcv data available in this datadir Returns a list of all pairs with ohlcv data available in this datadir
for the specified timeframe for the specified timeframe
:param datadir: Directory to search for ohlcv files :param datadir: Directory to search for ohlcv files
:param timeframe: Timeframe to search pairs for :param timeframe: Timeframe to search pairs for
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: List of Pairs :return: List of Pairs
""" """
candle = ""
if candle_type != CandleType.SPOT:
datadir = datadir.joinpath('futures')
candle = f"-{candle_type}"
_tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.h5)', p.name) _tmp = [re.search(r'^(\S+)(?=\-' + timeframe + candle + '.h5)', p.name)
for p in datadir.glob(f"*{timeframe}.h5")] for p in datadir.glob(f"*{timeframe}{candle}.h5")]
# Check if regex found something and only return these results # Check if regex found something and only return these results
return [match[0].replace('_', '/') for match in _tmp if match] return [cls.rebuild_pair_from_filename(match[0]) for match in _tmp if match]
def ohlcv_store(self, pair: str, timeframe: str, data: pd.DataFrame) -> None: def ohlcv_store(
self, pair: str, timeframe: str, data: pd.DataFrame, candle_type: CandleType) -> None:
""" """
Store data in hdf5 file. Store data in hdf5 file.
:param pair: Pair - used to generate filename :param pair: Pair - used to generate filename
:param timeframe: Timeframe - used to generate filename :param timeframe: Timeframe - used to generate filename
:param data: Dataframe containing OHLCV data :param data: Dataframe containing OHLCV data
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: None :return: None
""" """
key = self._pair_ohlcv_key(pair, timeframe) key = self._pair_ohlcv_key(pair, timeframe)
_data = data.copy() _data = data.copy()
filename = self._pair_data_filename(self._datadir, pair, timeframe) filename = self._pair_data_filename(self._datadir, pair, timeframe, candle_type)
self.create_dir_if_needed(filename)
_data.loc[:, self._columns].to_hdf( _data.loc[:, self._columns].to_hdf(
filename, key, mode='a', complevel=9, complib='blosc', filename, key, mode='a', complevel=9, complib='blosc',
@@ -66,7 +62,8 @@ class HDF5DataHandler(IDataHandler):
) )
def _ohlcv_load(self, pair: str, timeframe: str, def _ohlcv_load(self, pair: str, timeframe: str,
timerange: Optional[TimeRange] = None) -> pd.DataFrame: timerange: Optional[TimeRange], candle_type: CandleType
) -> pd.DataFrame:
""" """
Internal method used to load data for one pair from disk. Internal method used to load data for one pair from disk.
Implements the loading and conversion to a Pandas dataframe. Implements the loading and conversion to a Pandas dataframe.
@@ -76,13 +73,23 @@ class HDF5DataHandler(IDataHandler):
:param timerange: Limit data to be loaded to this timerange. :param timerange: Limit data to be loaded to this timerange.
Optionally implemented by subclasses to avoid loading Optionally implemented by subclasses to avoid loading
all data where possible. all data where possible.
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: DataFrame with ohlcv data, or empty DataFrame :return: DataFrame with ohlcv data, or empty DataFrame
""" """
key = self._pair_ohlcv_key(pair, timeframe) key = self._pair_ohlcv_key(pair, timeframe)
filename = self._pair_data_filename(self._datadir, pair, timeframe) filename = self._pair_data_filename(
self._datadir,
pair,
timeframe,
candle_type=candle_type
)
if not filename.exists(): if not filename.exists():
return pd.DataFrame(columns=self._columns) # Fallback mode for 1M files
filename = self._pair_data_filename(
self._datadir, pair, timeframe, candle_type=candle_type, no_timeframe_modify=True)
if not filename.exists():
return pd.DataFrame(columns=self._columns)
where = [] where = []
if timerange: if timerange:
if timerange.starttype == 'date': if timerange.starttype == 'date':
@@ -98,12 +105,19 @@ class HDF5DataHandler(IDataHandler):
'low': 'float', 'close': 'float', 'volume': 'float'}) 'low': 'float', 'close': 'float', 'volume': 'float'})
return pairdata return pairdata
def ohlcv_append(self, pair: str, timeframe: str, data: pd.DataFrame) -> None: def ohlcv_append(
self,
pair: str,
timeframe: str,
data: pd.DataFrame,
candle_type: CandleType
) -> None:
""" """
Append data to existing data structures Append data to existing data structures
:param pair: Pair :param pair: Pair
:param timeframe: Timeframe this ohlcv data is for :param timeframe: Timeframe this ohlcv data is for
:param data: Data to append. :param data: Data to append.
:param candle_type: Any of the enum CandleType (must match trading mode!)
""" """
raise NotImplementedError() raise NotImplementedError()
@@ -117,7 +131,7 @@ class HDF5DataHandler(IDataHandler):
_tmp = [re.search(r'^(\S+)(?=\-trades.h5)', p.name) _tmp = [re.search(r'^(\S+)(?=\-trades.h5)', p.name)
for p in datadir.glob("*trades.h5")] for p in datadir.glob("*trades.h5")]
# Check if regex found something and only return these results to avoid exceptions. # Check if regex found something and only return these results to avoid exceptions.
return [match[0].replace('_', '/') for match in _tmp if match] return [cls.rebuild_pair_from_filename(match[0]) for match in _tmp if match]
def trades_store(self, pair: str, data: TradeList) -> None: def trades_store(self, pair: str, data: TradeList) -> None:
""" """
@@ -172,7 +186,9 @@ class HDF5DataHandler(IDataHandler):
@classmethod @classmethod
def _pair_ohlcv_key(cls, pair: str, timeframe: str) -> str: def _pair_ohlcv_key(cls, pair: str, timeframe: str) -> str:
return f"{pair}/ohlcv/tf_{timeframe}" # Escape futures pairs to avoid warnings
pair_esc = pair.replace(':', '_')
return f"{pair_esc}/ohlcv/tf_{timeframe}"
@classmethod @classmethod
def _pair_trades_key(cls, pair: str) -> str: def _pair_trades_key(cls, pair: str) -> str:

View File

@@ -12,6 +12,7 @@ from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
from freqtrade.data.converter import (clean_ohlcv_dataframe, ohlcv_to_dataframe, from freqtrade.data.converter import (clean_ohlcv_dataframe, ohlcv_to_dataframe,
trades_remove_duplicates, trades_to_ohlcv) trades_remove_duplicates, trades_to_ohlcv)
from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler
from freqtrade.enums import CandleType
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.misc import format_ms_time from freqtrade.misc import format_ms_time
@@ -29,6 +30,7 @@ def load_pair_history(pair: str,
startup_candles: int = 0, startup_candles: int = 0,
data_format: str = None, data_format: str = None,
data_handler: IDataHandler = None, data_handler: IDataHandler = None,
candle_type: CandleType = CandleType.SPOT
) -> DataFrame: ) -> DataFrame:
""" """
Load cached ohlcv history for the given pair. Load cached ohlcv history for the given pair.
@@ -43,6 +45,7 @@ def load_pair_history(pair: str,
:param startup_candles: Additional candles to load at the start of the period :param startup_candles: Additional candles to load at the start of the period
:param data_handler: Initialized data-handler to use. :param data_handler: Initialized data-handler to use.
Will be initialized from data_format if not set Will be initialized from data_format if not set
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: DataFrame with ohlcv data, or empty DataFrame :return: DataFrame with ohlcv data, or empty DataFrame
""" """
data_handler = get_datahandler(datadir, data_format, data_handler) data_handler = get_datahandler(datadir, data_format, data_handler)
@@ -53,6 +56,7 @@ def load_pair_history(pair: str,
fill_missing=fill_up_missing, fill_missing=fill_up_missing,
drop_incomplete=drop_incomplete, drop_incomplete=drop_incomplete,
startup_candles=startup_candles, startup_candles=startup_candles,
candle_type=candle_type,
) )
@@ -64,6 +68,8 @@ def load_data(datadir: Path,
startup_candles: int = 0, startup_candles: int = 0,
fail_without_data: bool = False, fail_without_data: bool = False,
data_format: str = 'json', data_format: str = 'json',
candle_type: CandleType = CandleType.SPOT,
user_futures_funding_rate: int = None,
) -> Dict[str, DataFrame]: ) -> Dict[str, DataFrame]:
""" """
Load ohlcv history data for a list of pairs. Load ohlcv history data for a list of pairs.
@@ -76,6 +82,7 @@ def load_data(datadir: Path,
:param startup_candles: Additional candles to load at the start of the period :param startup_candles: Additional candles to load at the start of the period
:param fail_without_data: Raise OperationalException if no data is found. :param fail_without_data: Raise OperationalException if no data is found.
:param data_format: Data format which should be used. Defaults to json :param data_format: Data format which should be used. Defaults to json
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: dict(<pair>:<Dataframe>) :return: dict(<pair>:<Dataframe>)
""" """
result: Dict[str, DataFrame] = {} result: Dict[str, DataFrame] = {}
@@ -89,22 +96,29 @@ def load_data(datadir: Path,
datadir=datadir, timerange=timerange, datadir=datadir, timerange=timerange,
fill_up_missing=fill_up_missing, fill_up_missing=fill_up_missing,
startup_candles=startup_candles, startup_candles=startup_candles,
data_handler=data_handler data_handler=data_handler,
candle_type=candle_type,
) )
if not hist.empty: if not hist.empty:
result[pair] = hist result[pair] = hist
else:
if candle_type is CandleType.FUNDING_RATE and user_futures_funding_rate is not None:
logger.warn(f"{pair} using user specified [{user_futures_funding_rate}]")
elif candle_type not in (CandleType.SPOT, CandleType.FUTURES):
result[pair] = DataFrame(columns=["date", "open", "close", "high", "low", "volume"])
if fail_without_data and not result: if fail_without_data and not result:
raise OperationalException("No data found. Terminating.") raise OperationalException("No data found. Terminating.")
return result return result
def refresh_data(datadir: Path, def refresh_data(*, datadir: Path,
timeframe: str, timeframe: str,
pairs: List[str], pairs: List[str],
exchange: Exchange, exchange: Exchange,
data_format: str = None, data_format: str = None,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
candle_type: CandleType,
) -> None: ) -> None:
""" """
Refresh ohlcv history data for a list of pairs. Refresh ohlcv history data for a list of pairs.
@@ -115,17 +129,25 @@ def refresh_data(datadir: Path,
:param exchange: Exchange object :param exchange: Exchange object
:param data_format: dataformat to use :param data_format: dataformat to use
:param timerange: Limit data to be loaded to this timerange :param timerange: Limit data to be loaded to this timerange
:param candle_type: Any of the enum CandleType (must match trading mode!)
""" """
data_handler = get_datahandler(datadir, data_format) data_handler = get_datahandler(datadir, data_format)
for idx, pair in enumerate(pairs): for idx, pair in enumerate(pairs):
process = f'{idx}/{len(pairs)}' process = f'{idx}/{len(pairs)}'
_download_pair_history(pair=pair, process=process, _download_pair_history(pair=pair, process=process,
timeframe=timeframe, datadir=datadir, timeframe=timeframe, datadir=datadir,
timerange=timerange, exchange=exchange, data_handler=data_handler) timerange=timerange, exchange=exchange, data_handler=data_handler,
candle_type=candle_type)
def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optional[TimeRange], def _load_cached_data_for_updating(
data_handler: IDataHandler) -> Tuple[DataFrame, Optional[int]]: pair: str,
timeframe: str,
timerange: Optional[TimeRange],
data_handler: IDataHandler,
candle_type: CandleType,
prepend: bool = False,
) -> Tuple[DataFrame, Optional[int], Optional[int]]:
""" """
Load cached data to download more data. Load cached data to download more data.
If timerange is passed in, checks whether data from an before the stored data will be If timerange is passed in, checks whether data from an before the stored data will be
@@ -135,23 +157,30 @@ def _load_cached_data_for_updating(pair: str, timeframe: str, timerange: Optiona
Note: Only used by download_pair_history(). Note: Only used by download_pair_history().
""" """
start = None start = None
end = None
if timerange: if timerange:
if timerange.starttype == 'date': if timerange.starttype == 'date':
start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc)
if timerange.stoptype == 'date':
end = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc)
# Intentionally don't pass timerange in - since we need to load the full dataset. # Intentionally don't pass timerange in - since we need to load the full dataset.
data = data_handler.ohlcv_load(pair, timeframe=timeframe, data = data_handler.ohlcv_load(pair, timeframe=timeframe,
timerange=None, fill_missing=False, timerange=None, fill_missing=False,
drop_incomplete=True, warn_no_data=False) drop_incomplete=True, warn_no_data=False,
candle_type=candle_type)
if not data.empty: if not data.empty:
if start and start < data.iloc[0]['date']: if not prepend and start and start < data.iloc[0]['date']:
# Earlier data than existing data requested, redownload all # Earlier data than existing data requested, redownload all
data = DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS) data = DataFrame(columns=DEFAULT_DATAFRAME_COLUMNS)
else: else:
start = data.iloc[-1]['date'] if prepend:
end = data.iloc[0]['date']
else:
start = data.iloc[-1]['date']
start_ms = int(start.timestamp() * 1000) if start else None start_ms = int(start.timestamp() * 1000) if start else None
return data, start_ms end_ms = int(end.timestamp() * 1000) if end else None
return data, start_ms, end_ms
def _download_pair_history(pair: str, *, def _download_pair_history(pair: str, *,
@@ -161,31 +190,42 @@ def _download_pair_history(pair: str, *,
process: str = '', process: str = '',
new_pairs_days: int = 30, new_pairs_days: int = 30,
data_handler: IDataHandler = None, data_handler: IDataHandler = None,
timerange: Optional[TimeRange] = None) -> bool: timerange: Optional[TimeRange] = None,
candle_type: CandleType,
erase: bool = False,
prepend: bool = False,
) -> bool:
""" """
Download latest candles from the exchange for the pair and timeframe passed in parameters Download latest candles from the exchange for the pair and timeframe passed in parameters
The data is downloaded starting from the last correct data that The data is downloaded starting from the last correct data that
exists in a cache. If timerange starts earlier than the data in the cache, exists in a cache. If timerange starts earlier than the data in the cache,
the full data will be redownloaded the full data will be redownloaded
Based on @Rybolov work: https://github.com/rybolov/freqtrade-data
:param pair: pair to download :param pair: pair to download
:param timeframe: Timeframe (e.g "5m") :param timeframe: Timeframe (e.g "5m")
:param timerange: range of time to download :param timerange: range of time to download
:param candle_type: Any of the enum CandleType (must match trading mode!)
:param erase: Erase existing data
:return: bool with success state :return: bool with success state
""" """
data_handler = get_datahandler(datadir, data_handler=data_handler) data_handler = get_datahandler(datadir, data_handler=data_handler)
try: try:
logger.info( if erase:
f'Download history data for pair: "{pair}" ({process}), timeframe: {timeframe} ' if data_handler.ohlcv_purge(pair, timeframe, candle_type=candle_type):
f'and store in {datadir}.' logger.info(f'Deleting existing data for pair {pair}, {timeframe}, {candle_type}.')
)
# data, since_ms = _load_cached_data_for_updating_old(datadir, pair, timeframe, timerange) data, since_ms, until_ms = _load_cached_data_for_updating(
data, since_ms = _load_cached_data_for_updating(pair, timeframe, timerange, pair, timeframe, timerange,
data_handler=data_handler) data_handler=data_handler,
candle_type=candle_type,
prepend=prepend)
logger.info(f'({process}) - Download history data for "{pair}", {timeframe}, '
f'{candle_type} and store in {datadir}. '
f'From {format_ms_time(since_ms) if since_ms else "start"} to '
f'{format_ms_time(until_ms) if until_ms else "now"}'
)
logger.debug("Current Start: %s", logger.debug("Current Start: %s",
f"{data.iloc[0]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None') f"{data.iloc[0]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None')
@@ -198,7 +238,9 @@ def _download_pair_history(pair: str, *,
since_ms=since_ms if since_ms else since_ms=since_ms if since_ms else
arrow.utcnow().shift( arrow.utcnow().shift(
days=-new_pairs_days).int_timestamp * 1000, days=-new_pairs_days).int_timestamp * 1000,
is_new_pair=data.empty is_new_pair=data.empty,
candle_type=candle_type,
until_ms=until_ms if until_ms else None
) )
# TODO: Maybe move parsing to exchange class (?) # TODO: Maybe move parsing to exchange class (?)
new_dataframe = ohlcv_to_dataframe(new_data, timeframe, pair, new_dataframe = ohlcv_to_dataframe(new_data, timeframe, pair,
@@ -216,7 +258,7 @@ def _download_pair_history(pair: str, *,
logger.debug("New End: %s", logger.debug("New End: %s",
f"{data.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None') f"{data.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}" if not data.empty else 'None')
data_handler.ohlcv_store(pair, timeframe, data=data) data_handler.ohlcv_store(pair, timeframe, data=data, candle_type=candle_type)
return True return True
except Exception: except Exception:
@@ -227,9 +269,12 @@ def _download_pair_history(pair: str, *,
def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes: List[str], def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes: List[str],
datadir: Path, timerange: Optional[TimeRange] = None, datadir: Path, trading_mode: str,
timerange: Optional[TimeRange] = None,
new_pairs_days: int = 30, erase: bool = False, new_pairs_days: int = 30, erase: bool = False,
data_format: str = None) -> List[str]: data_format: str = None,
prepend: bool = False,
) -> List[str]:
""" """
Refresh stored ohlcv data for backtesting and hyperopt operations. Refresh stored ohlcv data for backtesting and hyperopt operations.
Used by freqtrade download-data subcommand. Used by freqtrade download-data subcommand.
@@ -237,6 +282,8 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes
""" """
pairs_not_available = [] pairs_not_available = []
data_handler = get_datahandler(datadir, data_format) data_handler = get_datahandler(datadir, data_format)
candle_type = CandleType.get_default(trading_mode)
process = ''
for idx, pair in enumerate(pairs, start=1): for idx, pair in enumerate(pairs, start=1):
if pair not in exchange.markets: if pair not in exchange.markets:
pairs_not_available.append(pair) pairs_not_available.append(pair)
@@ -244,17 +291,29 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes
continue continue
for timeframe in timeframes: for timeframe in timeframes:
if erase:
if data_handler.ohlcv_purge(pair, timeframe):
logger.info(
f'Deleting existing data for pair {pair}, interval {timeframe}.')
logger.info(f'Downloading pair {pair}, interval {timeframe}.') logger.info(f'Downloading pair {pair}, interval {timeframe}.')
process = f'{idx}/{len(pairs)}' process = f'{idx}/{len(pairs)}'
_download_pair_history(pair=pair, process=process, _download_pair_history(pair=pair, process=process,
datadir=datadir, exchange=exchange, datadir=datadir, exchange=exchange,
timerange=timerange, data_handler=data_handler, timerange=timerange, data_handler=data_handler,
timeframe=str(timeframe), new_pairs_days=new_pairs_days) timeframe=str(timeframe), new_pairs_days=new_pairs_days,
candle_type=candle_type,
erase=erase, prepend=prepend)
if trading_mode == 'futures':
# Predefined candletype (and timeframe) depending on exchange
# Downloads what is necessary to backtest based on futures data.
tf_mark = exchange._ft_has['mark_ohlcv_timeframe']
fr_candle_type = CandleType.from_string(exchange._ft_has['mark_ohlcv_price'])
# All exchanges need FundingRate for futures trading.
# The timeframe is aligned to the mark-price timeframe.
for funding_candle_type in (CandleType.FUNDING_RATE, fr_candle_type):
_download_pair_history(pair=pair, process=process,
datadir=datadir, exchange=exchange,
timerange=timerange, data_handler=data_handler,
timeframe=str(tf_mark), new_pairs_days=new_pairs_days,
candle_type=funding_candle_type,
erase=erase, prepend=prepend)
return pairs_not_available return pairs_not_available
@@ -271,8 +330,9 @@ def _download_trades_history(exchange: Exchange,
try: try:
until = None until = None
if (timerange and timerange.starttype == 'date'): if timerange:
since = timerange.startts * 1000 if timerange.starttype == 'date':
since = timerange.startts * 1000
if timerange.stoptype == 'date': if timerange.stoptype == 'date':
until = timerange.stopts * 1000 until = timerange.stopts * 1000
else: else:
@@ -353,10 +413,16 @@ def refresh_backtest_trades_data(exchange: Exchange, pairs: List[str], datadir:
return pairs_not_available return pairs_not_available
def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str], def convert_trades_to_ohlcv(
datadir: Path, timerange: TimeRange, erase: bool = False, pairs: List[str],
data_format_ohlcv: str = 'json', timeframes: List[str],
data_format_trades: str = 'jsongz') -> None: datadir: Path,
timerange: TimeRange,
erase: bool = False,
data_format_ohlcv: str = 'json',
data_format_trades: str = 'jsongz',
candle_type: CandleType = CandleType.SPOT
) -> None:
""" """
Convert stored trades data to ohlcv data Convert stored trades data to ohlcv data
""" """
@@ -367,12 +433,12 @@ def convert_trades_to_ohlcv(pairs: List[str], timeframes: List[str],
trades = data_handler_trades.trades_load(pair) trades = data_handler_trades.trades_load(pair)
for timeframe in timeframes: for timeframe in timeframes:
if erase: if erase:
if data_handler_ohlcv.ohlcv_purge(pair, timeframe): if data_handler_ohlcv.ohlcv_purge(pair, timeframe, candle_type=candle_type):
logger.info(f'Deleting existing data for pair {pair}, interval {timeframe}.') logger.info(f'Deleting existing data for pair {pair}, interval {timeframe}.')
try: try:
ohlcv = trades_to_ohlcv(trades, timeframe) ohlcv = trades_to_ohlcv(trades, timeframe)
# Store ohlcv # Store ohlcv
data_handler_ohlcv.ohlcv_store(pair, timeframe, data=ohlcv) data_handler_ohlcv.ohlcv_store(pair, timeframe, data=ohlcv, candle_type=candle_type)
except ValueError: except ValueError:
logger.exception(f'Could not convert {pair} to OHLCV.') logger.exception(f'Could not convert {pair} to OHLCV.')

View File

@@ -4,7 +4,8 @@ It's subclasses handle and storing data from disk.
""" """
import logging import logging
from abc import ABC, abstractclassmethod, abstractmethod import re
from abc import ABC, abstractmethod
from copy import deepcopy from copy import deepcopy
from datetime import datetime, timezone from datetime import datetime, timezone
from pathlib import Path from pathlib import Path
@@ -16,6 +17,7 @@ from freqtrade import misc
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.constants import ListPairsWithTimeframes, TradeList from freqtrade.constants import ListPairsWithTimeframes, TradeList
from freqtrade.data.converter import clean_ohlcv_dataframe, trades_remove_duplicates, trim_dataframe from freqtrade.data.converter import clean_ohlcv_dataframe, trades_remove_duplicates, trim_dataframe
from freqtrade.enums import CandleType, TradingMode
from freqtrade.exchange import timeframe_to_seconds from freqtrade.exchange import timeframe_to_seconds
@@ -24,6 +26,8 @@ logger = logging.getLogger(__name__)
class IDataHandler(ABC): class IDataHandler(ABC):
_OHLCV_REGEX = r'^([a-zA-Z_-]+)\-(\d+[a-zA-Z]{1,2})\-?([a-zA-Z_]*)?(?=\.)'
def __init__(self, datadir: Path) -> None: def __init__(self, datadir: Path) -> None:
self._datadir = datadir self._datadir = datadir
@@ -34,37 +38,55 @@ class IDataHandler(ABC):
""" """
raise NotImplementedError() raise NotImplementedError()
@abstractclassmethod @classmethod
def ohlcv_get_available_data(cls, datadir: Path) -> ListPairsWithTimeframes: def ohlcv_get_available_data(
cls, datadir: Path, trading_mode: TradingMode) -> ListPairsWithTimeframes:
""" """
Returns a list of all pairs with ohlcv data available in this datadir Returns a list of all pairs with ohlcv data available in this datadir
:param datadir: Directory to search for ohlcv files :param datadir: Directory to search for ohlcv files
:return: List of Tuples of (pair, timeframe) :param trading_mode: trading-mode to be used
:return: List of Tuples of (pair, timeframe, CandleType)
""" """
if trading_mode == TradingMode.FUTURES:
datadir = datadir.joinpath('futures')
_tmp = [
re.search(
cls._OHLCV_REGEX, p.name
) for p in datadir.glob(f"*.{cls._get_file_extension()}")]
return [
(
cls.rebuild_pair_from_filename(match[1]),
cls.rebuild_timeframe_from_filename(match[2]),
CandleType.from_string(match[3])
) for match in _tmp if match and len(match.groups()) > 1]
@abstractclassmethod @classmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]: @abstractmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str, candle_type: CandleType) -> List[str]:
""" """
Returns a list of all pairs with ohlcv data available in this datadir Returns a list of all pairs with ohlcv data available in this datadir
for the specified timeframe for the specified timeframe
:param datadir: Directory to search for ohlcv files :param datadir: Directory to search for ohlcv files
:param timeframe: Timeframe to search pairs for :param timeframe: Timeframe to search pairs for
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: List of Pairs :return: List of Pairs
""" """
@abstractmethod @abstractmethod
def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None: def ohlcv_store(
self, pair: str, timeframe: str, data: DataFrame, candle_type: CandleType) -> None:
""" """
Store ohlcv data. Store ohlcv data.
:param pair: Pair - used to generate filename :param pair: Pair - used to generate filename
:param timeframe: Timeframe - used to generate filename :param timeframe: Timeframe - used to generate filename
:param data: Dataframe containing OHLCV data :param data: Dataframe containing OHLCV data
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: None :return: None
""" """
@abstractmethod @abstractmethod
def _ohlcv_load(self, pair: str, timeframe: str, def _ohlcv_load(self, pair: str, timeframe: str, timerange: Optional[TimeRange],
timerange: Optional[TimeRange] = None, candle_type: CandleType
) -> DataFrame: ) -> DataFrame:
""" """
Internal method used to load data for one pair from disk. Internal method used to load data for one pair from disk.
@@ -75,32 +97,42 @@ class IDataHandler(ABC):
:param timerange: Limit data to be loaded to this timerange. :param timerange: Limit data to be loaded to this timerange.
Optionally implemented by subclasses to avoid loading Optionally implemented by subclasses to avoid loading
all data where possible. all data where possible.
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: DataFrame with ohlcv data, or empty DataFrame :return: DataFrame with ohlcv data, or empty DataFrame
""" """
def ohlcv_purge(self, pair: str, timeframe: str) -> bool: def ohlcv_purge(self, pair: str, timeframe: str, candle_type: CandleType) -> bool:
""" """
Remove data for this pair Remove data for this pair
:param pair: Delete data for this pair. :param pair: Delete data for this pair.
:param timeframe: Timeframe (e.g. "5m") :param timeframe: Timeframe (e.g. "5m")
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: True when deleted, false if file did not exist. :return: True when deleted, false if file did not exist.
""" """
filename = self._pair_data_filename(self._datadir, pair, timeframe) filename = self._pair_data_filename(self._datadir, pair, timeframe, candle_type)
if filename.exists(): if filename.exists():
filename.unlink() filename.unlink()
return True return True
return False return False
@abstractmethod @abstractmethod
def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None: def ohlcv_append(
self,
pair: str,
timeframe: str,
data: DataFrame,
candle_type: CandleType
) -> None:
""" """
Append data to existing data structures Append data to existing data structures
:param pair: Pair :param pair: Pair
:param timeframe: Timeframe this ohlcv data is for :param timeframe: Timeframe this ohlcv data is for
:param data: Data to append. :param data: Data to append.
:param candle_type: Any of the enum CandleType (must match trading mode!)
""" """
@abstractclassmethod @classmethod
@abstractmethod
def trades_get_pairs(cls, datadir: Path) -> List[str]: def trades_get_pairs(cls, datadir: Path) -> List[str]:
""" """
Returns a list of all pairs for which trade data is available in this Returns a list of all pairs for which trade data is available in this
@@ -158,9 +190,33 @@ class IDataHandler(ABC):
return trades_remove_duplicates(self._trades_load(pair, timerange=timerange)) return trades_remove_duplicates(self._trades_load(pair, timerange=timerange))
@classmethod @classmethod
def _pair_data_filename(cls, datadir: Path, pair: str, timeframe: str) -> Path: def create_dir_if_needed(cls, datadir: Path):
"""
Creates datadir if necessary
should only create directories for "futures" mode at the moment.
"""
if not datadir.parent.is_dir():
datadir.parent.mkdir()
@classmethod
def _pair_data_filename(
cls,
datadir: Path,
pair: str,
timeframe: str,
candle_type: CandleType,
no_timeframe_modify: bool = False
) -> Path:
pair_s = misc.pair_to_filename(pair) pair_s = misc.pair_to_filename(pair)
filename = datadir.joinpath(f'{pair_s}-{timeframe}.{cls._get_file_extension()}') candle = ""
if not no_timeframe_modify:
timeframe = cls.timeframe_to_file(timeframe)
if candle_type != CandleType.SPOT:
datadir = datadir.joinpath('futures')
candle = f"-{candle_type}"
filename = datadir.joinpath(
f'{pair_s}-{timeframe}{candle}.{cls._get_file_extension()}')
return filename return filename
@classmethod @classmethod
@@ -169,12 +225,35 @@ class IDataHandler(ABC):
filename = datadir.joinpath(f'{pair_s}-trades.{cls._get_file_extension()}') filename = datadir.joinpath(f'{pair_s}-trades.{cls._get_file_extension()}')
return filename return filename
@staticmethod
def timeframe_to_file(timeframe: str):
return timeframe.replace('M', 'Mo')
@staticmethod
def rebuild_timeframe_from_filename(timeframe: str) -> str:
"""
converts timeframe from disk to file
Replaces mo with M (to avoid problems on case-insensitive filesystems)
"""
return re.sub('1mo', '1M', timeframe, flags=re.IGNORECASE)
@staticmethod
def rebuild_pair_from_filename(pair: str) -> str:
"""
Rebuild pair name from filename
Assumes a asset name of max. 7 length to also support BTC-PERP and BTC-PERP:USD names.
"""
res = re.sub(r'^(([A-Za-z]{1,10})|^([A-Za-z\-]{1,6}))(_)', r'\g<1>/', pair, 1)
res = re.sub('_', ':', res, 1)
return res
def ohlcv_load(self, pair, timeframe: str, def ohlcv_load(self, pair, timeframe: str,
candle_type: CandleType,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange] = None,
fill_missing: bool = True, fill_missing: bool = True,
drop_incomplete: bool = True, drop_incomplete: bool = True,
startup_candles: int = 0, startup_candles: int = 0,
warn_no_data: bool = True warn_no_data: bool = True,
) -> DataFrame: ) -> DataFrame:
""" """
Load cached candle (OHLCV) data for the given pair. Load cached candle (OHLCV) data for the given pair.
@@ -186,6 +265,7 @@ class IDataHandler(ABC):
:param drop_incomplete: Drop last candle assuming it may be incomplete. :param drop_incomplete: Drop last candle assuming it may be incomplete.
:param startup_candles: Additional candles to load at the start of the period :param startup_candles: Additional candles to load at the start of the period
:param warn_no_data: Log a warning message when no data is found :param warn_no_data: Log a warning message when no data is found
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: DataFrame with ohlcv data, or empty DataFrame :return: DataFrame with ohlcv data, or empty DataFrame
""" """
# Fix startup period # Fix startup period
@@ -193,17 +273,21 @@ class IDataHandler(ABC):
if startup_candles > 0 and timerange_startup: if startup_candles > 0 and timerange_startup:
timerange_startup.subtract_start(timeframe_to_seconds(timeframe) * startup_candles) timerange_startup.subtract_start(timeframe_to_seconds(timeframe) * startup_candles)
pairdf = self._ohlcv_load(pair, timeframe, pairdf = self._ohlcv_load(
timerange=timerange_startup) pair,
if self._check_empty_df(pairdf, pair, timeframe, warn_no_data): timeframe,
timerange=timerange_startup,
candle_type=candle_type
)
if self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data):
return pairdf return pairdf
else: else:
enddate = pairdf.iloc[-1]['date'] enddate = pairdf.iloc[-1]['date']
if timerange_startup: if timerange_startup:
self._validate_pairdata(pair, pairdf, timeframe, timerange_startup) self._validate_pairdata(pair, pairdf, timeframe, candle_type, timerange_startup)
pairdf = trim_dataframe(pairdf, timerange_startup) pairdf = trim_dataframe(pairdf, timerange_startup)
if self._check_empty_df(pairdf, pair, timeframe, warn_no_data): if self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data):
return pairdf return pairdf
# incomplete candles should only be dropped if we didn't trim the end beforehand. # incomplete candles should only be dropped if we didn't trim the end beforehand.
@@ -212,23 +296,25 @@ class IDataHandler(ABC):
fill_missing=fill_missing, fill_missing=fill_missing,
drop_incomplete=(drop_incomplete and drop_incomplete=(drop_incomplete and
enddate == pairdf.iloc[-1]['date'])) enddate == pairdf.iloc[-1]['date']))
self._check_empty_df(pairdf, pair, timeframe, warn_no_data) self._check_empty_df(pairdf, pair, timeframe, candle_type, warn_no_data)
return pairdf return pairdf
def _check_empty_df(self, pairdf: DataFrame, pair: str, timeframe: str, warn_no_data: bool): def _check_empty_df(self, pairdf: DataFrame, pair: str, timeframe: str,
candle_type: CandleType, warn_no_data: bool):
""" """
Warn on empty dataframe Warn on empty dataframe
""" """
if pairdf.empty: if pairdf.empty:
if warn_no_data: if warn_no_data:
logger.warning( logger.warning(
f'No history data for pair: "{pair}", timeframe: {timeframe}. ' f"No history for {pair}, {candle_type}, {timeframe} found. "
'Use `freqtrade download-data` to download the data' "Use `freqtrade download-data` to download the data"
) )
return True return True
return False return False
def _validate_pairdata(self, pair, pairdata: DataFrame, timeframe: str, timerange: TimeRange): def _validate_pairdata(self, pair, pairdata: DataFrame, timeframe: str,
candle_type: CandleType, timerange: TimeRange):
""" """
Validates pairdata for missing data at start end end and logs warnings. Validates pairdata for missing data at start end end and logs warnings.
:param pairdata: Dataframe to validate :param pairdata: Dataframe to validate
@@ -238,12 +324,12 @@ class IDataHandler(ABC):
if timerange.starttype == 'date': if timerange.starttype == 'date':
start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc) start = datetime.fromtimestamp(timerange.startts, tz=timezone.utc)
if pairdata.iloc[0]['date'] > start: if pairdata.iloc[0]['date'] > start:
logger.warning(f"Missing data at start for pair {pair} at {timeframe}, " logger.warning(f"{pair}, {candle_type}, {timeframe}, "
f"data starts at {pairdata.iloc[0]['date']:%Y-%m-%d %H:%M:%S}") f"data starts at {pairdata.iloc[0]['date']:%Y-%m-%d %H:%M:%S}")
if timerange.stoptype == 'date': if timerange.stoptype == 'date':
stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc) stop = datetime.fromtimestamp(timerange.stopts, tz=timezone.utc)
if pairdata.iloc[-1]['date'] < stop: if pairdata.iloc[-1]['date'] < stop:
logger.warning(f"Missing data at end for pair {pair} at {timeframe}, " logger.warning(f"{pair}, {candle_type}, {timeframe}, "
f"data ends at {pairdata.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}") f"data ends at {pairdata.iloc[-1]['date']:%Y-%m-%d %H:%M:%S}")

View File

@@ -8,8 +8,9 @@ from pandas import DataFrame, read_json, to_datetime
from freqtrade import misc from freqtrade import misc
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, ListPairsWithTimeframes, TradeList from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS, TradeList
from freqtrade.data.converter import trades_dict_to_list from freqtrade.data.converter import trades_dict_to_list
from freqtrade.enums import CandleType
from .idatahandler import IDataHandler from .idatahandler import IDataHandler
@@ -23,33 +24,27 @@ class JsonDataHandler(IDataHandler):
_columns = DEFAULT_DATAFRAME_COLUMNS _columns = DEFAULT_DATAFRAME_COLUMNS
@classmethod @classmethod
def ohlcv_get_available_data(cls, datadir: Path) -> ListPairsWithTimeframes: def ohlcv_get_pairs(cls, datadir: Path, timeframe: str, candle_type: CandleType) -> List[str]:
"""
Returns a list of all pairs with ohlcv data available in this datadir
:param datadir: Directory to search for ohlcv files
:return: List of Tuples of (pair, timeframe)
"""
_tmp = [re.search(r'^([a-zA-Z_]+)\-(\d+\S+)(?=.json)', p.name)
for p in datadir.glob(f"*.{cls._get_file_extension()}")]
return [(match[1].replace('_', '/'), match[2]) for match in _tmp
if match and len(match.groups()) > 1]
@classmethod
def ohlcv_get_pairs(cls, datadir: Path, timeframe: str) -> List[str]:
""" """
Returns a list of all pairs with ohlcv data available in this datadir Returns a list of all pairs with ohlcv data available in this datadir
for the specified timeframe for the specified timeframe
:param datadir: Directory to search for ohlcv files :param datadir: Directory to search for ohlcv files
:param timeframe: Timeframe to search pairs for :param timeframe: Timeframe to search pairs for
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: List of Pairs :return: List of Pairs
""" """
candle = ""
if candle_type != CandleType.SPOT:
datadir = datadir.joinpath('futures')
candle = f"-{candle_type}"
_tmp = [re.search(r'^(\S+)(?=\-' + timeframe + '.json)', p.name) _tmp = [re.search(r'^(\S+)(?=\-' + timeframe + candle + '.json)', p.name)
for p in datadir.glob(f"*{timeframe}.{cls._get_file_extension()}")] for p in datadir.glob(f"*{timeframe}{candle}.{cls._get_file_extension()}")]
# Check if regex found something and only return these results # Check if regex found something and only return these results
return [match[0].replace('_', '/') for match in _tmp if match] return [cls.rebuild_pair_from_filename(match[0]) for match in _tmp if match]
def ohlcv_store(self, pair: str, timeframe: str, data: DataFrame) -> None: def ohlcv_store(
self, pair: str, timeframe: str, data: DataFrame, candle_type: CandleType) -> None:
""" """
Store data in json format "values". Store data in json format "values".
format looks as follows: format looks as follows:
@@ -57,9 +52,11 @@ class JsonDataHandler(IDataHandler):
:param pair: Pair - used to generate filename :param pair: Pair - used to generate filename
:param timeframe: Timeframe - used to generate filename :param timeframe: Timeframe - used to generate filename
:param data: Dataframe containing OHLCV data :param data: Dataframe containing OHLCV data
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: None :return: None
""" """
filename = self._pair_data_filename(self._datadir, pair, timeframe) filename = self._pair_data_filename(self._datadir, pair, timeframe, candle_type)
self.create_dir_if_needed(filename)
_data = data.copy() _data = data.copy()
# Convert date to int # Convert date to int
_data['date'] = _data['date'].view(np.int64) // 1000 // 1000 _data['date'] = _data['date'].view(np.int64) // 1000 // 1000
@@ -70,7 +67,7 @@ class JsonDataHandler(IDataHandler):
compression='gzip' if self._use_zip else None) compression='gzip' if self._use_zip else None)
def _ohlcv_load(self, pair: str, timeframe: str, def _ohlcv_load(self, pair: str, timeframe: str,
timerange: Optional[TimeRange] = None, timerange: Optional[TimeRange], candle_type: CandleType
) -> DataFrame: ) -> DataFrame:
""" """
Internal method used to load data for one pair from disk. Internal method used to load data for one pair from disk.
@@ -81,11 +78,17 @@ class JsonDataHandler(IDataHandler):
:param timerange: Limit data to be loaded to this timerange. :param timerange: Limit data to be loaded to this timerange.
Optionally implemented by subclasses to avoid loading Optionally implemented by subclasses to avoid loading
all data where possible. all data where possible.
:param candle_type: Any of the enum CandleType (must match trading mode!)
:return: DataFrame with ohlcv data, or empty DataFrame :return: DataFrame with ohlcv data, or empty DataFrame
""" """
filename = self._pair_data_filename(self._datadir, pair, timeframe) filename = self._pair_data_filename(
self._datadir, pair, timeframe, candle_type=candle_type)
if not filename.exists(): if not filename.exists():
return DataFrame(columns=self._columns) # Fallback mode for 1M files
filename = self._pair_data_filename(
self._datadir, pair, timeframe, candle_type=candle_type, no_timeframe_modify=True)
if not filename.exists():
return DataFrame(columns=self._columns)
try: try:
pairdata = read_json(filename, orient='values') pairdata = read_json(filename, orient='values')
pairdata.columns = self._columns pairdata.columns = self._columns
@@ -100,25 +103,19 @@ class JsonDataHandler(IDataHandler):
infer_datetime_format=True) infer_datetime_format=True)
return pairdata return pairdata
def ohlcv_purge(self, pair: str, timeframe: str) -> bool: def ohlcv_append(
""" self,
Remove data for this pair pair: str,
:param pair: Delete data for this pair. timeframe: str,
:param timeframe: Timeframe (e.g. "5m") data: DataFrame,
:return: True when deleted, false if file did not exist. candle_type: CandleType
""" ) -> None:
filename = self._pair_data_filename(self._datadir, pair, timeframe)
if filename.exists():
filename.unlink()
return True
return False
def ohlcv_append(self, pair: str, timeframe: str, data: DataFrame) -> None:
""" """
Append data to existing data structures Append data to existing data structures
:param pair: Pair :param pair: Pair
:param timeframe: Timeframe this ohlcv data is for :param timeframe: Timeframe this ohlcv data is for
:param data: Data to append. :param data: Data to append.
:param candle_type: Any of the enum CandleType (must match trading mode!)
""" """
raise NotImplementedError() raise NotImplementedError()
@@ -132,7 +129,7 @@ class JsonDataHandler(IDataHandler):
_tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name) _tmp = [re.search(r'^(\S+)(?=\-trades.json)', p.name)
for p in datadir.glob(f"*trades.{cls._get_file_extension()}")] for p in datadir.glob(f"*trades.{cls._get_file_extension()}")]
# Check if regex found something and only return these results to avoid exceptions. # Check if regex found something and only return these results to avoid exceptions.
return [match[0].replace('_', '/') for match in _tmp if match] return [cls.rebuild_pair_from_filename(match[0]) for match in _tmp if match]
def trades_store(self, pair: str, data: TradeList) -> None: def trades_store(self, pair: str, data: TradeList) -> None:
""" """

192
freqtrade/data/metrics.py Normal file
View File

@@ -0,0 +1,192 @@
import logging
from typing import Dict, Tuple
import numpy as np
import pandas as pd
logger = logging.getLogger(__name__)
def calculate_market_change(data: Dict[str, pd.DataFrame], column: str = "close") -> float:
"""
Calculate market change based on "column".
Calculation is done by taking the first non-null and the last non-null element of each column
and calculating the pctchange as "(last - first) / first".
Then the results per pair are combined as mean.
:param data: Dict of Dataframes, dict key should be pair.
:param column: Column in the original dataframes to use
:return:
"""
tmp_means = []
for pair, df in data.items():
start = df[column].dropna().iloc[0]
end = df[column].dropna().iloc[-1]
tmp_means.append((end - start) / start)
return float(np.mean(tmp_means))
def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame],
column: str = "close") -> pd.DataFrame:
"""
Combine multiple dataframes "column"
:param data: Dict of Dataframes, dict key should be pair.
:param column: Column in the original dataframes to use
:return: DataFrame with the column renamed to the dict key, and a column
named mean, containing the mean of all pairs.
:raise: ValueError if no data is provided.
"""
df_comb = pd.concat([data[pair].set_index('date').rename(
{column: pair}, axis=1)[pair] for pair in data], axis=1)
df_comb['mean'] = df_comb.mean(axis=1)
return df_comb
def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
timeframe: str) -> pd.DataFrame:
"""
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_abs)
:param col_name: Column name that will be assigned the results
:param timeframe: Timeframe used during the operations
:return: Returns df with one additional column, col_name, containing the cumulative profit.
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
from freqtrade.exchange import timeframe_to_minutes
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_abs']].sum()
df.loc[:, col_name] = _trades_sum['profit_abs'].cumsum()
# Set first value to 0
df.loc[df.iloc[0].name, col_name] = 0
# FFill to get continuous
df[col_name] = df[col_name].ffill()
return df
def _calc_drawdown_series(profit_results: pd.DataFrame, *, date_col: str, value_col: str,
starting_balance: float) -> pd.DataFrame:
max_drawdown_df = pd.DataFrame()
max_drawdown_df['cumulative'] = profit_results[value_col].cumsum()
max_drawdown_df['high_value'] = max_drawdown_df['cumulative'].cummax()
max_drawdown_df['drawdown'] = max_drawdown_df['cumulative'] - max_drawdown_df['high_value']
max_drawdown_df['date'] = profit_results.loc[:, date_col]
if starting_balance:
cumulative_balance = starting_balance + max_drawdown_df['cumulative']
max_balance = starting_balance + max_drawdown_df['high_value']
max_drawdown_df['drawdown_relative'] = ((max_balance - cumulative_balance) / max_balance)
else:
# NOTE: This is not completely accurate,
# but might good enough if starting_balance is not available
max_drawdown_df['drawdown_relative'] = (
(max_drawdown_df['high_value'] - max_drawdown_df['cumulative'])
/ max_drawdown_df['high_value'])
return max_drawdown_df
def calculate_underwater(trades: pd.DataFrame, *, date_col: str = 'close_date',
value_col: str = 'profit_ratio', starting_balance: float = 0.0
):
"""
Calculate max drawdown and the corresponding close dates
: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_ratio')
:return: Tuple (float, highdate, lowdate, highvalue, lowvalue) with absolute max drawdown,
high and low time and high and low value.
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
profit_results = trades.sort_values(date_col).reset_index(drop=True)
max_drawdown_df = _calc_drawdown_series(
profit_results,
date_col=date_col,
value_col=value_col,
starting_balance=starting_balance)
return max_drawdown_df
def calculate_max_drawdown(trades: pd.DataFrame, *, date_col: str = 'close_date',
value_col: str = 'profit_abs', starting_balance: float = 0,
relative: bool = False
) -> Tuple[float, pd.Timestamp, pd.Timestamp, float, float, float]:
"""
Calculate max drawdown and the corresponding close dates
: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_abs')
:param starting_balance: Portfolio starting balance - properly calculate relative drawdown.
:return: Tuple (float, highdate, lowdate, highvalue, lowvalue, relative_drawdown)
with absolute max drawdown, high and low time and high and low value,
and the relative account drawdown
:raise: ValueError if trade-dataframe was found empty.
"""
if len(trades) == 0:
raise ValueError("Trade dataframe empty.")
profit_results = trades.sort_values(date_col).reset_index(drop=True)
max_drawdown_df = _calc_drawdown_series(
profit_results,
date_col=date_col,
value_col=value_col,
starting_balance=starting_balance
)
idxmin = max_drawdown_df['drawdown_relative'].idxmax() if relative \
else max_drawdown_df['drawdown'].idxmin()
if idxmin == 0:
raise ValueError("No losing trade, therefore no drawdown.")
high_date = profit_results.loc[max_drawdown_df.iloc[:idxmin]['high_value'].idxmax(), date_col]
low_date = profit_results.loc[idxmin, date_col]
high_val = max_drawdown_df.loc[max_drawdown_df.iloc[:idxmin]
['high_value'].idxmax(), 'cumulative']
low_val = max_drawdown_df.loc[idxmin, 'cumulative']
max_drawdown_rel = max_drawdown_df.loc[idxmin, 'drawdown_relative']
return (
abs(max_drawdown_df.loc[idxmin, 'drawdown']),
high_date,
low_date,
high_val,
low_val,
max_drawdown_rel
)
def calculate_csum(trades: pd.DataFrame, starting_balance: float = 0) -> 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)
:param starting_balance: Add starting balance to results, to show the wallets high / low points
: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() + starting_balance
csum_max = csum_df['sum'].max() + starting_balance
return csum_min, csum_max
def calculate_cagr(days_passed: int, starting_balance: float, final_balance: float) -> float:
"""
Calculate CAGR
:param days_passed: Days passed between start and ending balance
:param starting_balance: Starting balance
:param final_balance: Final balance to calculate CAGR against
:return: CAGR
"""
return (final_balance / starting_balance) ** (1 / (days_passed / 365)) - 1

View File

@@ -13,7 +13,7 @@ from pandas import DataFrame
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.constants import DATETIME_PRINT_FORMAT, UNLIMITED_STAKE_AMOUNT from freqtrade.constants import DATETIME_PRINT_FORMAT, UNLIMITED_STAKE_AMOUNT
from freqtrade.data.history import get_timerange, load_data, refresh_data from freqtrade.data.history import get_timerange, load_data, refresh_data
from freqtrade.enums import RunMode, SellType from freqtrade.enums import CandleType, ExitType, RunMode
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.exchange.exchange import timeframe_to_seconds from freqtrade.exchange.exchange import timeframe_to_seconds
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
@@ -116,11 +116,12 @@ class Edge:
timeframe=self.strategy.timeframe, timeframe=self.strategy.timeframe,
timerange=timerange_startup, timerange=timerange_startup,
data_format=self.config.get('dataformat_ohlcv', 'json'), data_format=self.config.get('dataformat_ohlcv', 'json'),
candle_type=self.config.get('candle_type_def', CandleType.SPOT),
) )
# Download informative pairs too # Download informative pairs too
res = defaultdict(list) res = defaultdict(list)
for p, t in self.strategy.gather_informative_pairs(): for pair, timeframe, _ in self.strategy.gather_informative_pairs():
res[t].append(p) res[timeframe].append(pair)
for timeframe, inf_pairs in res.items(): for timeframe, inf_pairs in res.items():
timerange_startup = deepcopy(self._timerange) timerange_startup = deepcopy(self._timerange)
timerange_startup.subtract_start(timeframe_to_seconds( timerange_startup.subtract_start(timeframe_to_seconds(
@@ -132,6 +133,7 @@ class Edge:
timeframe=timeframe, timeframe=timeframe,
timerange=timerange_startup, timerange=timerange_startup,
data_format=self.config.get('dataformat_ohlcv', 'json'), data_format=self.config.get('dataformat_ohlcv', 'json'),
candle_type=self.config.get('candle_type_def', CandleType.SPOT),
) )
data = load_data( data = load_data(
@@ -141,6 +143,7 @@ class Edge:
timerange=self._timerange, timerange=self._timerange,
startup_candles=self.strategy.startup_candle_count, startup_candles=self.strategy.startup_candle_count,
data_format=self.config.get('dataformat_ohlcv', 'json'), data_format=self.config.get('dataformat_ohlcv', 'json'),
candle_type=self.config.get('candle_type_def', CandleType.SPOT),
) )
if not data: if not data:
@@ -159,7 +162,9 @@ class Edge:
logger.info(f'Measuring data from {min_date.strftime(DATETIME_PRINT_FORMAT)} ' logger.info(f'Measuring data from {min_date.strftime(DATETIME_PRINT_FORMAT)} '
f'up to {max_date.strftime(DATETIME_PRINT_FORMAT)} ' f'up to {max_date.strftime(DATETIME_PRINT_FORMAT)} '
f'({(max_date - min_date).days} days)..') f'({(max_date - min_date).days} days)..')
headers = ['date', 'buy', 'open', 'close', 'sell', 'high', 'low'] # TODO: Should edge support shorts? needs to be investigated further
# * (add enter_short exit_short)
headers = ['date', 'open', 'high', 'low', 'close', 'enter_long', 'exit_long']
trades: list = [] trades: list = []
for pair, pair_data in preprocessed.items(): for pair, pair_data in preprocessed.items():
@@ -167,8 +172,13 @@ class Edge:
pair_data = pair_data.sort_values(by=['date']) pair_data = pair_data.sort_values(by=['date'])
pair_data = pair_data.reset_index(drop=True) pair_data = pair_data.reset_index(drop=True)
df_analyzed = self.strategy.advise_sell( df_analyzed = self.strategy.advise_exit(
self.strategy.advise_buy(pair_data, {'pair': pair}), {'pair': pair})[headers].copy() dataframe=self.strategy.advise_entry(
dataframe=pair_data,
metadata={'pair': pair}
),
metadata={'pair': pair}
)[headers].copy()
trades += self._find_trades_for_stoploss_range(df_analyzed, pair, self._stoploss_range) trades += self._find_trades_for_stoploss_range(df_analyzed, pair, self._stoploss_range)
@@ -219,9 +229,11 @@ class Edge:
""" """
final = [] final = []
for pair, info in self._cached_pairs.items(): for pair, info in self._cached_pairs.items():
if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \ if (
info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)) and \ info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2))
pair in pairs: and info.winrate > float(self.edge_config.get('minimum_winrate', 0.60))
and pair in pairs
):
final.append(pair) final.append(pair)
if self._final_pairs != final: if self._final_pairs != final:
@@ -246,8 +258,8 @@ class Edge:
""" """
final = [] final = []
for pair, info in self._cached_pairs.items(): for pair, info in self._cached_pairs.items():
if info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and \ if (info.expectancy > float(self.edge_config.get('minimum_expectancy', 0.2)) and
info.winrate > float(self.edge_config.get('minimum_winrate', 0.60)): info.winrate > float(self.edge_config.get('minimum_winrate', 0.60))):
final.append({ final.append({
'Pair': pair, 'Pair': pair,
'Winrate': info.winrate, 'Winrate': info.winrate,
@@ -382,8 +394,8 @@ class Edge:
return final return final
def _find_trades_for_stoploss_range(self, df, pair, stoploss_range): def _find_trades_for_stoploss_range(self, df, pair, stoploss_range):
buy_column = df['buy'].values buy_column = df['enter_long'].values
sell_column = df['sell'].values sell_column = df['exit_long'].values
date_column = df['date'].values date_column = df['date'].values
ohlc_columns = df[['open', 'high', 'low', 'close']].values ohlc_columns = df[['open', 'high', 'low', 'close']].values
@@ -448,7 +460,7 @@ class Edge:
if stop_index <= sell_index: if stop_index <= sell_index:
exit_index = open_trade_index + stop_index exit_index = open_trade_index + stop_index
exit_type = SellType.STOP_LOSS exit_type = ExitType.STOP_LOSS
exit_price = stop_price exit_price = stop_price
elif stop_index > sell_index: elif stop_index > sell_index:
# If exit is SELL then we exit at the next candle # If exit is SELL then we exit at the next candle
@@ -458,7 +470,7 @@ class Edge:
if len(ohlc_columns) - 1 < exit_index: if len(ohlc_columns) - 1 < exit_index:
break break
exit_type = SellType.SELL_SIGNAL exit_type = ExitType.EXIT_SIGNAL
exit_price = ohlc_columns[exit_index, 0] exit_price = ohlc_columns[exit_index, 0]
trade = {'pair': pair, trade = {'pair': pair,

View File

@@ -1,8 +1,12 @@
# flake8: noqa: F401 # flake8: noqa: F401
from freqtrade.enums.backteststate import BacktestState from freqtrade.enums.backteststate import BacktestState
from freqtrade.enums.candletype import CandleType
from freqtrade.enums.exitchecktuple import ExitCheckTuple
from freqtrade.enums.exittype import ExitType
from freqtrade.enums.marginmode import MarginMode
from freqtrade.enums.ordertypevalue import OrderTypeValues from freqtrade.enums.ordertypevalue import OrderTypeValues
from freqtrade.enums.rpcmessagetype import RPCMessageType from freqtrade.enums.rpcmessagetype import RPCMessageType
from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode
from freqtrade.enums.selltype import SellType from freqtrade.enums.signaltype import SignalDirection, SignalTagType, SignalType
from freqtrade.enums.signaltype import SignalTagType, SignalType
from freqtrade.enums.state import State from freqtrade.enums.state import State
from freqtrade.enums.tradingmode import TradingMode

View File

@@ -0,0 +1,27 @@
from enum import Enum
class CandleType(str, Enum):
"""Enum to distinguish candle types"""
SPOT = "spot"
FUTURES = "futures"
MARK = "mark"
INDEX = "index"
PREMIUMINDEX = "premiumIndex"
# TODO: Could take up less memory if these weren't a CandleType
FUNDING_RATE = "funding_rate"
# BORROW_RATE = "borrow_rate" # * unimplemented
@staticmethod
def from_string(value: str) -> 'CandleType':
if not value:
# Default to spot
return CandleType.SPOT
return CandleType(value)
@staticmethod
def get_default(trading_mode: str) -> 'CandleType':
if trading_mode == 'futures':
return CandleType.FUTURES
return CandleType.SPOT

View File

@@ -0,0 +1,23 @@
from freqtrade.enums.exittype import ExitType
class ExitCheckTuple:
"""
NamedTuple for Exit type + reason
"""
exit_type: ExitType
exit_reason: str = ''
def __init__(self, exit_type: ExitType, exit_reason: str = ''):
self.exit_type = exit_type
self.exit_reason = exit_reason or exit_type.value
@property
def exit_flag(self):
return self.exit_type != ExitType.NONE
def __eq__(self, other):
return self.exit_type == other.exit_type and self.exit_reason == other.exit_reason
def __repr__(self):
return f"ExitCheckTuple({self.exit_type}, {self.exit_reason})"

View File

@@ -1,18 +1,20 @@
from enum import Enum from enum import Enum
class SellType(Enum): class ExitType(Enum):
""" """
Enum to distinguish between sell reasons Enum to distinguish between exit reasons
""" """
ROI = "roi" ROI = "roi"
STOP_LOSS = "stop_loss" STOP_LOSS = "stop_loss"
STOPLOSS_ON_EXCHANGE = "stoploss_on_exchange" STOPLOSS_ON_EXCHANGE = "stoploss_on_exchange"
TRAILING_STOP_LOSS = "trailing_stop_loss" TRAILING_STOP_LOSS = "trailing_stop_loss"
SELL_SIGNAL = "sell_signal" LIQUIDATION = "liquidation"
FORCE_SELL = "force_sell" EXIT_SIGNAL = "exit_signal"
EMERGENCY_SELL = "emergency_sell" FORCE_EXIT = "force_exit"
CUSTOM_SELL = "custom_sell" EMERGENCY_EXIT = "emergency_exit"
CUSTOM_EXIT = "custom_exit"
PARTIAL_EXIT = "partial_exit"
NONE = "" NONE = ""
def __str__(self): def __str__(self):

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