Compare commits

..

1 Commits

Author SHA1 Message Date
Matthias
c2f08b1d1b
Merge 705d1e4cc0 into 9f34153c84 2024-09-13 23:18:35 +02:00
4 changed files with 4 additions and 131 deletions

View File

@ -101,4 +101,3 @@ This could lead to a false-negative (the strategy will then be reported as non-b
- `lookahead-analysis` has access to everything that backtesting has too. - `lookahead-analysis` has access to everything that backtesting has too.
Please don't provoke any configs like enabling position stacking. Please don't provoke any configs like enabling position stacking.
If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` amount and neither leftover money in your wallet. If you decide to do so, then make doubly sure that you won't ever run out of `max_open_trades` amount and neither leftover money in your wallet.
- 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.

View File

@ -78,7 +78,6 @@ class Kraken(Exchange):
# x["side"], x["amount"], # x["side"], x["amount"],
) )
for x in orders for x in orders
if x["remaining"] is not None and (x["side"] == "sell" or x["price"] is not None)
] ]
for bal in balances: for bal in balances:
if not isinstance(balances[bal], dict): if not isinstance(balances[bal], dict):

View File

@ -1,7 +1,7 @@
import logging import logging
import time import time
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Union from typing import Any, Dict, List
import pandas as pd import pandas as pd
from rich.text import Text from rich.text import Text
@ -19,9 +19,7 @@ logger = logging.getLogger(__name__)
class LookaheadAnalysisSubFunctions: class LookaheadAnalysisSubFunctions:
@staticmethod @staticmethod
def text_table_lookahead_analysis_instances( def text_table_lookahead_analysis_instances(
config: Dict[str, Any], config: Dict[str, Any], lookahead_instances: List[LookaheadAnalysis]
lookahead_instances: List[LookaheadAnalysis],
caption: Union[str, None] = None,
): ):
headers = [ headers = [
"filename", "filename",
@ -67,9 +65,7 @@ class LookaheadAnalysisSubFunctions:
] ]
) )
print_rich_table( print_rich_table(data, headers, summary="Lookahead Analysis")
data, headers, summary="Lookahead Analysis", table_kwargs={"caption": caption}
)
return data return data
@staticmethod @staticmethod
@ -243,24 +239,8 @@ class LookaheadAnalysisSubFunctions:
# report the results # report the results
if lookaheadAnalysis_instances: if lookaheadAnalysis_instances:
caption: Union[str, None] = None
if any(
[
any(
[
indicator.startswith("&")
for indicator in inst.current_analysis.false_indicators
]
)
for inst in lookaheadAnalysis_instances
]
):
caption = (
"Any indicators in 'biased_indicators' which are used within "
"set_freqai_targets() can be ignored."
)
LookaheadAnalysisSubFunctions.text_table_lookahead_analysis_instances( LookaheadAnalysisSubFunctions.text_table_lookahead_analysis_instances(
config, lookaheadAnalysis_instances, caption=caption config, lookaheadAnalysis_instances
) )
if config.get("lookahead_analysis_exportfilename") is not None: if config.get("lookahead_analysis_exportfilename") is not None:
LookaheadAnalysisSubFunctions.export_to_csv(config, lookaheadAnalysis_instances) LookaheadAnalysisSubFunctions.export_to_csv(config, lookaheadAnalysis_instances)

View File

@ -13,12 +13,6 @@ from freqtrade.optimize.analysis.lookahead_helpers import LookaheadAnalysisSubFu
from tests.conftest import EXMS, get_args, log_has_re, patch_exchange from tests.conftest import EXMS, get_args, log_has_re, patch_exchange
IGNORE_BIASED_INDICATORS_CAPTION = (
"Any indicators in 'biased_indicators' which are used within "
"set_freqai_targets() can be ignored."
)
@pytest.fixture @pytest.fixture
def lookahead_conf(default_conf_usdt, tmp_path): def lookahead_conf(default_conf_usdt, tmp_path):
default_conf_usdt["user_data_dir"] = tmp_path default_conf_usdt["user_data_dir"] = tmp_path
@ -139,58 +133,6 @@ def test_lookahead_helper_start(lookahead_conf, mocker) -> None:
text_table_mock.reset_mock() text_table_mock.reset_mock()
@pytest.mark.parametrize(
"indicators, expected_caption_text",
[
(
["&indicator1", "indicator2"],
IGNORE_BIASED_INDICATORS_CAPTION,
),
(
["indicator1", "&indicator2"],
IGNORE_BIASED_INDICATORS_CAPTION,
),
(
["&indicator1", "&indicator2"],
IGNORE_BIASED_INDICATORS_CAPTION,
),
(["indicator1", "indicator2"], None),
([], None),
],
ids=(
"First of two biased indicators starts with '&'",
"Second of two biased indicators starts with '&'",
"Both biased indicators start with '&'",
"No biased indicators start with '&'",
"Empty biased indicators list",
),
)
def test_lookahead_helper_start__caption_based_on_indicators(
indicators, expected_caption_text, lookahead_conf, mocker
):
"""Test that the table caption is only populated if a biased_indicator starts with '&'."""
single_mock = MagicMock()
lookahead_analysis = LookaheadAnalysis(
lookahead_conf,
{"name": "strategy_test_v3_with_lookahead_bias"},
)
lookahead_analysis.current_analysis.false_indicators = indicators
single_mock.return_value = lookahead_analysis
text_table_mock = MagicMock()
mocker.patch.multiple(
"freqtrade.optimize.analysis.lookahead_helpers.LookaheadAnalysisSubFunctions",
initialize_single_lookahead_analysis=single_mock,
text_table_lookahead_analysis_instances=text_table_mock,
)
LookaheadAnalysisSubFunctions.start(lookahead_conf)
text_table_mock.assert_called_once_with(
lookahead_conf, [lookahead_analysis], caption=expected_caption_text
)
def test_lookahead_helper_text_table_lookahead_analysis_instances(lookahead_conf): def test_lookahead_helper_text_table_lookahead_analysis_instances(lookahead_conf):
analysis = Analysis() analysis = Analysis()
analysis.has_bias = True analysis.has_bias = True
@ -257,53 +199,6 @@ def test_lookahead_helper_text_table_lookahead_analysis_instances(lookahead_conf
assert len(data) == 3 assert len(data) == 3
@pytest.mark.parametrize(
"caption",
[
"",
"A test caption",
None,
False,
],
ids=(
"Pass empty string",
"Pass non-empty string",
"Pass None",
"Don't pass caption",
),
)
def test_lookahead_helper_text_table_lookahead_analysis_instances__caption(
caption,
lookahead_conf,
mocker,
):
"""Test that the caption is passed in the table kwargs when calling print_rich_table()."""
print_rich_table_mock = MagicMock()
mocker.patch(
"freqtrade.optimize.analysis.lookahead_helpers.print_rich_table",
print_rich_table_mock,
)
lookahead_analysis = LookaheadAnalysis(
lookahead_conf,
{
"name": "strategy_test_v3_with_lookahead_bias",
"location": Path(lookahead_conf["strategy_path"], f"{lookahead_conf['strategy']}.py"),
},
)
kwargs = {}
if caption is not False:
kwargs["caption"] = caption
LookaheadAnalysisSubFunctions.text_table_lookahead_analysis_instances(
lookahead_conf, [lookahead_analysis], **kwargs
)
assert print_rich_table_mock.call_args[-1]["table_kwargs"]["caption"] == (
caption if caption is not False else None
)
def test_lookahead_helper_export_to_csv(lookahead_conf): def test_lookahead_helper_export_to_csv(lookahead_conf):
import pandas as pd import pandas as pd