Skip to content

Commit 54bebea

Browse files
authored
Merge pull request freqtrade#12229 from freqtrade/lookahead_analysis_12168
Lookahead analysis - fix false positives
2 parents 3a17c2b + b35172a commit 54bebea

File tree

6 files changed

+43
-3
lines changed

6 files changed

+43
-3
lines changed

docs/commands/lookahead-analysis.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE]
2121
[--minimum-trade-amount INT]
2222
[--targeted-trade-amount INT]
2323
[--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME]
24+
[--allow-limit-orders]
2425
2526
options:
2627
-h, --help show this help message and exit
@@ -79,6 +80,8 @@ options:
7980
--lookahead-analysis-exportfilename LOOKAHEAD_ANALYSIS_EXPORTFILENAME
8081
Use this csv-filename to store lookahead-analysis-
8182
results
83+
--allow-limit-orders Allow limit orders in lookahead analysis (could cause
84+
false positives in lookahead analysis results).
8285
8386
Common arguments:
8487
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).

docs/lookahead-analysis.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This is done by not looking at the strategy code itself, but at changed indicato
2222
- `--dry-run-wallet` is forced to be basically infinite (1 billion).
2323
- `--stake-amount` is forced to be a static 10000 (10k).
2424
- `--enable-protections` is forced to be off.
25+
- `order_types` are forced to be "market" (late entries) unless `--lookahead-allow-limit-orders` is set.
2526

2627
These are set to avoid users accidentally generating false positives.
2728

@@ -99,6 +100,9 @@ This would lead to a false-negative, i.e. the strategy will be reported as non-b
99100
Please don't use any options like enabling position stacking as this will distort the number of checked signals.
100101
If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` slots,
101102
and that you have enough capital in the backtest wallet configuration.
103+
- limit orders in combination with `custom_entry_price()` and `custom_exit_price()` callbacks can cause late / delayed entries and exists, causing false positives.
104+
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.
105+
Using `--lookahead-allow-limit-orders` will skip the override and use your configured order types - however has shown to eventually produce false positives.
102106
- In the results table, the `biased_indicators` column
103107
will falsely flag FreqAI target indicators defined in `set_freqai_targets()` as biased.
104108
**These are not biased and can safely be ignored.**

freqtrade/commands/arguments.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,12 @@
260260
a
261261
for a in ARGS_BACKTEST
262262
if a not in ("position_stacking", "backtest_cache", "backtest_breakdown", "backtest_notes")
263-
] + ["minimum_trade_amount", "targeted_trade_amount", "lookahead_analysis_exportfilename"]
263+
] + [
264+
"minimum_trade_amount",
265+
"targeted_trade_amount",
266+
"lookahead_analysis_exportfilename",
267+
"lookahead_allow_limit_orders",
268+
]
264269

265270
ARGS_RECURSIVE_ANALYSIS = ["timeframe", "timerange", "dataformat_ohlcv", "pairs", "startup_candle"]
266271

freqtrade/commands/cli_options.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,14 @@ def __init__(self, *args, **kwargs):
806806
help="Specify startup candles to be checked (`199`, `499`, `999`, `1999`).",
807807
nargs="+",
808808
),
809+
"lookahead_allow_limit_orders": Arg(
810+
"--allow-limit-orders",
811+
help=(
812+
"Allow limit orders in lookahead analysis (could cause false positives "
813+
"in lookahead analysis results)."
814+
),
815+
action="store_true",
816+
),
809817
"show_sensitive": Arg(
810818
"--show-sensitive",
811819
help="Show secrets in the output.",

freqtrade/optimize/analysis/lookahead_helpers.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ def calculate_config_overrides(config: Config):
147147
"Protections were enabled. "
148148
"Disabling protections now since they can produce false positives."
149149
)
150+
if not config.get("lookahead_allow_limit_orders", False):
151+
logger.info("Forced order_types to market orders.")
152+
config["order_types"] = {
153+
"entry": "market",
154+
"exit": "market",
155+
"stoploss": "market",
156+
"stoploss_on_exchange": False,
157+
}
158+
else:
159+
logger.info("Using configured order_types, skipping order_types override.")
160+
150161
if config["targeted_trade_amount"] < config["minimum_trade_amount"]:
151162
# this combo doesn't make any sense.
152163
raise OperationalException(

tests/optimize/test_lookahead_analysis.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,21 +123,30 @@ def test_lookahead_helper_no_strategy_defined(lookahead_conf):
123123
LookaheadAnalysisSubFunctions.start(conf)
124124

125125

126-
def test_lookahead_helper_start(lookahead_conf, mocker) -> None:
126+
def test_lookahead_helper_start(lookahead_conf, mocker, caplog) -> None:
127127
single_mock = MagicMock()
128128
text_table_mock = MagicMock()
129129
mocker.patch.multiple(
130130
"freqtrade.optimize.analysis.lookahead_helpers.LookaheadAnalysisSubFunctions",
131131
initialize_single_lookahead_analysis=single_mock,
132132
text_table_lookahead_analysis_instances=text_table_mock,
133133
)
134-
LookaheadAnalysisSubFunctions.start(lookahead_conf)
134+
LookaheadAnalysisSubFunctions.start(deepcopy(lookahead_conf))
135135
assert single_mock.call_count == 1
136136
assert text_table_mock.call_count == 1
137+
assert log_has_re("Forced order_types to market orders.", caplog)
138+
assert single_mock.call_args_list[0][0][0]["order_types"]["entry"] == "market"
137139

138140
single_mock.reset_mock()
139141
text_table_mock.reset_mock()
140142

143+
lookahead_conf["lookahead_allow_limit_orders"] = True
144+
LookaheadAnalysisSubFunctions.start(lookahead_conf)
145+
assert single_mock.call_count == 1
146+
assert text_table_mock.call_count == 1
147+
assert log_has_re("Using configured order_types, skipping order_types override.", caplog)
148+
assert "order_types" not in single_mock.call_args_list[0][0][0]
149+
141150

142151
@pytest.mark.parametrize(
143152
"indicators, expected_caption_text",

0 commit comments

Comments
 (0)