Add filter for entry and exit only parameter

This commit is contained in:
Anuj Jain 2024-09-10 15:21:56 +05:30
parent c3a00b93c2
commit 4765656f87
4 changed files with 41 additions and 6 deletions

View File

@ -228,6 +228,8 @@ ARGS_ANALYZE_ENTRIES_EXITS = [
"enter_reason_list", "enter_reason_list",
"exit_reason_list", "exit_reason_list",
"indicator_list", "indicator_list",
"entry_only",
"exit_only",
"timerange", "timerange",
"analysis_rejected", "analysis_rejected",
"analysis_to_csv", "analysis_to_csv",

View File

@ -719,6 +719,12 @@ AVAILABLE_CLI_OPTIONS = {
nargs="+", nargs="+",
default=[], default=[],
), ),
"entry_only": Arg(
"--entry-only", help=("Only analyze entry signals."), action="store_true", default=False
),
"exit_only": Arg(
"--exit-only", help=("Only analyze exit signals."), action="store_true", default=False
),
"analysis_rejected": Arg( "analysis_rejected": Arg(
"--rejected-signals", "--rejected-signals",
help="Analyse rejected signals", help="Analyse rejected signals",

View File

@ -407,6 +407,8 @@ class Configuration:
("enter_reason_list", "Analysis enter tag list: {}"), ("enter_reason_list", "Analysis enter tag list: {}"),
("exit_reason_list", "Analysis exit tag list: {}"), ("exit_reason_list", "Analysis exit tag list: {}"),
("indicator_list", "Analysis indicator list: {}"), ("indicator_list", "Analysis indicator list: {}"),
("entry_only", "Only analyze entry signals: {}"),
("exit_only", "Only analyze exit signals: {}"),
("timerange", "Filter trades by timerange: {}"), ("timerange", "Filter trades by timerange: {}"),
("analysis_rejected", "Analyse rejected signals: {}"), ("analysis_rejected", "Analyse rejected signals: {}"),
("analysis_to_csv", "Store analysis tables to CSV: {}"), ("analysis_to_csv", "Store analysis tables to CSV: {}"),

View File

@ -263,6 +263,8 @@ def print_results(
exit_df: pd.DataFrame, exit_df: pd.DataFrame,
analysis_groups: List[str], analysis_groups: List[str],
indicator_list: List[str], indicator_list: List[str],
entry_only: bool,
exit_only: bool,
csv_path: Path, csv_path: Path,
rejected_signals=None, rejected_signals=None,
to_csv=False, to_csv=False,
@ -288,7 +290,7 @@ def print_results(
if ind in res_df: if ind in res_df:
available_inds.append(ind) available_inds.append(ind)
merged_df = _merge_dfs(res_df, exit_df, available_inds) merged_df = _merge_dfs(res_df, exit_df, available_inds, entry_only, exit_only)
_print_table( _print_table(
merged_df, merged_df,
@ -302,14 +304,21 @@ def print_results(
print("\\No trades to show") print("\\No trades to show")
def _merge_dfs(entry_df, exit_df, available_inds): def _merge_dfs(
entry_df: pd.DataFrame,
exit_df: pd.DataFrame,
available_inds: List[str],
entry_only: bool,
exit_only: bool,
):
merge_on = ["pair", "open_date"] merge_on = ["pair", "open_date"]
signal_wide_indicators = list(set(available_inds) - set(BT_DATA_COLUMNS)) signal_wide_indicators = list(set(available_inds) - set(BT_DATA_COLUMNS))
columns_to_keep = merge_on + ["enter_reason", "exit_reason"] + available_inds columns_to_keep = merge_on + ["enter_reason", "exit_reason"]
if exit_df is None or exit_df.empty: if exit_df is None or exit_df.empty or entry_only is True:
return entry_df[columns_to_keep] return entry_df[columns_to_keep + available_inds]
if exit_only is True:
return pd.merge( return pd.merge(
entry_df[columns_to_keep], entry_df[columns_to_keep],
exit_df[merge_on + signal_wide_indicators], exit_df[merge_on + signal_wide_indicators],
@ -317,6 +326,13 @@ def _merge_dfs(entry_df, exit_df, available_inds):
suffixes=(" (entry)", " (exit)"), suffixes=(" (entry)", " (exit)"),
) )
return pd.merge(
entry_df[columns_to_keep + available_inds],
exit_df[merge_on + signal_wide_indicators],
on=merge_on,
suffixes=(" (entry)", " (exit)"),
)
def _print_table( def _print_table(
df: pd.DataFrame, sortcols=None, *, show_index=False, name=None, to_csv=False, csv_path: Path df: pd.DataFrame, sortcols=None, *, show_index=False, name=None, to_csv=False, csv_path: Path
@ -343,9 +359,16 @@ def process_entry_exit_reasons(config: Config):
enter_reason_list = config.get("enter_reason_list", ["all"]) enter_reason_list = config.get("enter_reason_list", ["all"])
exit_reason_list = config.get("exit_reason_list", ["all"]) exit_reason_list = config.get("exit_reason_list", ["all"])
indicator_list = config.get("indicator_list", []) indicator_list = config.get("indicator_list", [])
entry_only = config.get("entry_only", False)
exit_only = config.get("exit_only", False)
do_rejected = config.get("analysis_rejected", False) do_rejected = config.get("analysis_rejected", False)
to_csv = config.get("analysis_to_csv", False) to_csv = config.get("analysis_to_csv", False)
csv_path = Path(config.get("analysis_csv_path", config["exportfilename"])) csv_path = Path(config.get("analysis_csv_path", config["exportfilename"]))
if entry_only is True and exit_only is True:
raise OperationalException(
"Cannot use --entry-only and --exit-only at the same time. Please choose one."
)
if to_csv and not csv_path.is_dir(): if to_csv and not csv_path.is_dir():
raise OperationalException(f"Specified directory {csv_path} does not exist.") raise OperationalException(f"Specified directory {csv_path} does not exist.")
@ -400,6 +423,8 @@ def process_entry_exit_reasons(config: Config):
exit_df, exit_df,
analysis_groups, analysis_groups,
indicator_list, indicator_list,
entry_only,
exit_only,
rejected_signals=rej_df, rejected_signals=rej_df,
to_csv=to_csv, to_csv=to_csv,
csv_path=csv_path, csv_path=csv_path,