mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-12-15 20:31:43 +00:00
Merge pull request #12229 from freqtrade/lookahead_analysis_12168
Lookahead analysis - fix false positives
This commit is contained in:
@@ -21,6 +21,7 @@ usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE]
|
|||||||
[--minimum-trade-amount INT]
|
[--minimum-trade-amount INT]
|
||||||
[--targeted-trade-amount INT]
|
[--targeted-trade-amount INT]
|
||||||
[--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME]
|
[--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME]
|
||||||
|
[--allow-limit-orders]
|
||||||
|
|
||||||
options:
|
options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
@@ -79,6 +80,8 @@ options:
|
|||||||
--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME
|
--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME
|
||||||
Use this csv-filename to store lookahead-analysis-
|
Use this csv-filename to store lookahead-analysis-
|
||||||
results
|
results
|
||||||
|
--allow-limit-orders Allow limit orders in lookahead analysis (could cause
|
||||||
|
false positives in lookahead analysis results).
|
||||||
|
|
||||||
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).
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ This is done by not looking at the strategy code itself, but at changed indicato
|
|||||||
- `--dry-run-wallet` is forced to be basically infinite (1 billion).
|
- `--dry-run-wallet` is forced to be basically infinite (1 billion).
|
||||||
- `--stake-amount` is forced to be a static 10000 (10k).
|
- `--stake-amount` is forced to be a static 10000 (10k).
|
||||||
- `--enable-protections` is forced to be off.
|
- `--enable-protections` is forced to be off.
|
||||||
|
- `order_types` are forced to be "market" (late entries) unless `--lookahead-allow-limit-orders` is set.
|
||||||
|
|
||||||
These are set to avoid users accidentally generating false positives.
|
These are set to avoid users accidentally generating false positives.
|
||||||
|
|
||||||
@@ -99,6 +100,9 @@ This would lead to a false-negative, i.e. the strategy will be reported as non-b
|
|||||||
Please don't use any options like enabling position stacking as this will distort the number of checked signals.
|
Please don't use any options like enabling position stacking as this will distort the number of checked signals.
|
||||||
If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` slots,
|
If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` slots,
|
||||||
and that you have enough capital in the backtest wallet configuration.
|
and that you have enough capital in the backtest wallet configuration.
|
||||||
|
- limit orders in combination with `custom_entry_price()` and `custom_exit_price()` callbacks can cause late / delayed entries and exists, causing false positives.
|
||||||
|
To avoid this - market orders are forced for this command. This implicitly means that `custom_entry_price()` and `custom_exit_price()` callbacks are not called.
|
||||||
|
Using `--lookahead-allow-limit-orders` will skip the override and use your configured order types - however has shown to eventually produce false positives.
|
||||||
- In the results table, the `biased_indicators` column
|
- In the results table, the `biased_indicators` column
|
||||||
will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased.
|
will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased.
|
||||||
**These are not biased and can safely be ignored.**
|
**These are not biased and can safely be ignored.**
|
||||||
|
|||||||
@@ -260,7 +260,12 @@ ARGS_LOOKAHEAD_ANALYSIS = [
|
|||||||
a
|
a
|
||||||
for a in ARGS_BACKTEST
|
for a in ARGS_BACKTEST
|
||||||
if a not in ("position_stacking", "backtest_cache", "backtest_breakdown", "backtest_notes")
|
if a not in ("position_stacking", "backtest_cache", "backtest_breakdown", "backtest_notes")
|
||||||
] + ["minimum_trade_amount", "targeted_trade_amount", "lookahead_analysis_exportfilename"]
|
] + [
|
||||||
|
"minimum_trade_amount",
|
||||||
|
"targeted_trade_amount",
|
||||||
|
"lookahead_analysis_exportfilename",
|
||||||
|
"lookahead_allow_limit_orders",
|
||||||
|
]
|
||||||
|
|
||||||
ARGS_RECURSIVE_ANALYSIS = ["timeframe", "timerange", "dataformat_ohlcv", "pairs", "startup_candle"]
|
ARGS_RECURSIVE_ANALYSIS = ["timeframe", "timerange", "dataformat_ohlcv", "pairs", "startup_candle"]
|
||||||
|
|
||||||
|
|||||||
@@ -806,6 +806,14 @@ AVAILABLE_CLI_OPTIONS = {
|
|||||||
help="Specify startup candles to be checked (`199`, `499`, `999`, `1999`).",
|
help="Specify startup candles to be checked (`199`, `499`, `999`, `1999`).",
|
||||||
nargs="+",
|
nargs="+",
|
||||||
),
|
),
|
||||||
|
"lookahead_allow_limit_orders": Arg(
|
||||||
|
"--allow-limit-orders",
|
||||||
|
help=(
|
||||||
|
"Allow limit orders in lookahead analysis (could cause false positives "
|
||||||
|
"in lookahead analysis results)."
|
||||||
|
),
|
||||||
|
action="store_true",
|
||||||
|
),
|
||||||
"show_sensitive": Arg(
|
"show_sensitive": Arg(
|
||||||
"--show-sensitive",
|
"--show-sensitive",
|
||||||
help="Show secrets in the output.",
|
help="Show secrets in the output.",
|
||||||
|
|||||||
@@ -147,6 +147,17 @@ class LookaheadAnalysisSubFunctions:
|
|||||||
"Protections were enabled. "
|
"Protections were enabled. "
|
||||||
"Disabling protections now since they can produce false positives."
|
"Disabling protections now since they can produce false positives."
|
||||||
)
|
)
|
||||||
|
if not config.get("lookahead_allow_limit_orders", False):
|
||||||
|
logger.info("Forced order_types to market orders.")
|
||||||
|
config["order_types"] = {
|
||||||
|
"entry": "market",
|
||||||
|
"exit": "market",
|
||||||
|
"stoploss": "market",
|
||||||
|
"stoploss_on_exchange": False,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
logger.info("Using configured order_types, skipping order_types override.")
|
||||||
|
|
||||||
if config["targeted_trade_amount"] < config["minimum_trade_amount"]:
|
if config["targeted_trade_amount"] < config["minimum_trade_amount"]:
|
||||||
# this combo doesn't make any sense.
|
# this combo doesn't make any sense.
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ def test_lookahead_helper_no_strategy_defined(lookahead_conf):
|
|||||||
LookaheadAnalysisSubFunctions.start(conf)
|
LookaheadAnalysisSubFunctions.start(conf)
|
||||||
|
|
||||||
|
|
||||||
def test_lookahead_helper_start(lookahead_conf, mocker) -> None:
|
def test_lookahead_helper_start(lookahead_conf, mocker, caplog) -> None:
|
||||||
single_mock = MagicMock()
|
single_mock = MagicMock()
|
||||||
text_table_mock = MagicMock()
|
text_table_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@@ -131,13 +131,22 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None:
|
|||||||
initialize_single_lookahead_analysis=single_mock,
|
initialize_single_lookahead_analysis=single_mock,
|
||||||
text_table_lookahead_analysis_instances=text_table_mock,
|
text_table_lookahead_analysis_instances=text_table_mock,
|
||||||
)
|
)
|
||||||
LookaheadAnalysisSubFunctions.start(lookahead_conf)
|
LookaheadAnalysisSubFunctions.start(deepcopy(lookahead_conf))
|
||||||
assert single_mock.call_count == 1
|
assert single_mock.call_count == 1
|
||||||
assert text_table_mock.call_count == 1
|
assert text_table_mock.call_count == 1
|
||||||
|
assert log_has_re("Forced order_types to market orders.", caplog)
|
||||||
|
assert single_mock.call_args_list[0][0][0]["order_types"]["entry"] == "market"
|
||||||
|
|
||||||
single_mock.reset_mock()
|
single_mock.reset_mock()
|
||||||
text_table_mock.reset_mock()
|
text_table_mock.reset_mock()
|
||||||
|
|
||||||
|
lookahead_conf["lookahead_allow_limit_orders"] = True
|
||||||
|
LookaheadAnalysisSubFunctions.start(lookahead_conf)
|
||||||
|
assert single_mock.call_count == 1
|
||||||
|
assert text_table_mock.call_count == 1
|
||||||
|
assert log_has_re("Using configured order_types, skipping order_types override.", caplog)
|
||||||
|
assert "order_types" not in single_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"indicators, expected_caption_text",
|
"indicators, expected_caption_text",
|
||||||
|
|||||||
Reference in New Issue
Block a user