mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-12-16 04:41:15 +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]
|
||||
[--targeted-trade-amount INT]
|
||||
[--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME]
|
||||
[--allow-limit-orders]
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
@@ -79,6 +80,8 @@ options:
|
||||
--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME
|
||||
Use this csv-filename to store lookahead-analysis-
|
||||
results
|
||||
--allow-limit-orders Allow limit orders in lookahead analysis (could cause
|
||||
false positives in lookahead analysis results).
|
||||
|
||||
Common arguments:
|
||||
-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).
|
||||
- `--stake-amount` is forced to be a static 10000 (10k).
|
||||
- `--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.
|
||||
|
||||
@@ -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.
|
||||
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.
|
||||
- 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
|
||||
will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased.
|
||||
**These are not biased and can safely be ignored.**
|
||||
|
||||
@@ -260,7 +260,12 @@ ARGS_LOOKAHEAD_ANALYSIS = [
|
||||
a
|
||||
for a in ARGS_BACKTEST
|
||||
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"]
|
||||
|
||||
|
||||
@@ -806,6 +806,14 @@ AVAILABLE_CLI_OPTIONS = {
|
||||
help="Specify startup candles to be checked (`199`, `499`, `999`, `1999`).",
|
||||
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",
|
||||
help="Show secrets in the output.",
|
||||
|
||||
@@ -147,6 +147,17 @@ class LookaheadAnalysisSubFunctions:
|
||||
"Protections were enabled. "
|
||||
"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"]:
|
||||
# this combo doesn't make any sense.
|
||||
raise OperationalException(
|
||||
|
||||
@@ -123,7 +123,7 @@ def test_lookahead_helper_no_strategy_defined(lookahead_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()
|
||||
text_table_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
@@ -131,13 +131,22 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None:
|
||||
initialize_single_lookahead_analysis=single_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 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()
|
||||
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(
|
||||
"indicators, expected_caption_text",
|
||||
|
||||
Reference in New Issue
Block a user