mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-11-29 00:23:07 +00:00
Merge pull request #12126 from stash86/main-stash
Improve lookahead analysis to use full dataframe comparison instead of just the last row
This commit is contained in:
@@ -50,8 +50,7 @@ After this initial backtest runs, it will look if the `minimum-trade-amount` is
|
||||
If this happens, use a wider timerange to get more trades for the analysis, or use a timerange where more trades occur.
|
||||
|
||||
After setting the baseline it will then do additional backtest runs for every entry and exit separately.
|
||||
When these verification backtests complete, it will compare the indicators at the signal candles (both entry or exit)
|
||||
and report the bias.
|
||||
When these verification backtests complete, it will compare both dataframes (baseline and sliced) for any difference in columns' value and report the bias.
|
||||
After all signals have been verified or falsified a result table will be generated for the user to see.
|
||||
|
||||
### How to find and remove bias? How can I salvage a biased strategy?
|
||||
|
||||
@@ -70,17 +70,12 @@ class LookaheadAnalysis(BaseAnalysis):
|
||||
cut_df: DataFrame = cut_vars.indicators[current_pair]
|
||||
full_df: DataFrame = full_vars.indicators[current_pair]
|
||||
|
||||
# cut longer dataframe to length of the shorter
|
||||
full_df_cut = full_df[(full_df.date == cut_vars.compared_dt)].reset_index(drop=True)
|
||||
cut_df_cut = cut_df[(cut_df.date == cut_vars.compared_dt)].reset_index(drop=True)
|
||||
|
||||
# check if dataframes are not empty
|
||||
if full_df_cut.shape[0] != 0 and cut_df_cut.shape[0] != 0:
|
||||
# compare dataframes
|
||||
compare_df = full_df_cut.compare(cut_df_cut)
|
||||
# trim full_df to the same index and length as cut_df
|
||||
cut_full_df = full_df.loc[cut_df.index]
|
||||
compare_df = cut_full_df.compare(cut_df)
|
||||
|
||||
if compare_df.shape[0] > 0:
|
||||
for col_name, values in compare_df.items():
|
||||
for col_name in compare_df:
|
||||
col_idx = compare_df.columns.get_loc(col_name)
|
||||
compare_df_row = compare_df.iloc[0]
|
||||
# compare_df now comprises tuples with [1] having either 'self' or 'other'
|
||||
@@ -94,7 +89,7 @@ class LookaheadAnalysis(BaseAnalysis):
|
||||
if not self.current_analysis.false_indicators.__contains__(col_name[0]):
|
||||
self.current_analysis.false_indicators.append(col_name[0])
|
||||
logger.info(
|
||||
f"=> found look ahead bias in indicator "
|
||||
f"=> found look ahead bias in column "
|
||||
f"{col_name[0]}. "
|
||||
f"{str(self_value)} != {str(other_value)}"
|
||||
)
|
||||
@@ -132,7 +127,13 @@ class LookaheadAnalysis(BaseAnalysis):
|
||||
varholder.data, varholder.timerange = backtesting.load_bt_data()
|
||||
varholder.timeframe = backtesting.timeframe
|
||||
|
||||
varholder.indicators = backtesting.strategy.advise_all_indicators(varholder.data)
|
||||
temp_indicators = backtesting.strategy.advise_all_indicators(varholder.data)
|
||||
filled_indicators = dict()
|
||||
for pair, dataframe in temp_indicators.items():
|
||||
filled_indicators[pair] = backtesting.strategy.ft_advise_signals(
|
||||
dataframe, {"pair": pair}
|
||||
)
|
||||
varholder.indicators = filled_indicators
|
||||
varholder.result = self.get_result(backtesting, varholder.indicators)
|
||||
|
||||
def fill_entry_and_exit_varHolders(self, result_row):
|
||||
|
||||
Reference in New Issue
Block a user