Compare commits

..

13 Commits

Author SHA1 Message Date
Matthias
7fb36d2497
Merge 705d1e4cc0 into af422c7cd4 2024-09-14 21:55:30 +02:00
Matthias
af422c7cd4
Merge pull request #10645 from dxbstyle/develop
added check for Kraken exchange
2024-09-14 10:44:23 +02:00
Matthias
51bdecea53 Improve check to cover more potential api oddities 2024-09-14 10:09:15 +02:00
Matthias
0f505c6d7b Improve check to cover more potential api oddities 2024-09-14 10:04:28 +02:00
Matthias
ae72f10448
Merge pull request #10619 from KingND/pixel/feat/freqai_labels_are_okay_in_lookahead_analysis
feat: include lookahead-analysis table caption when biased_indicator is likely from FreqAI target
2024-09-14 09:51:38 +02:00
dxbstyle
ae155c78c2 added check 2024-09-09 21:29:49 +02:00
KingND
f970454cb4 chore: ruff format 2024-09-08 13:57:48 -04:00
KingND
69678574d4 fix: support python 3.9 union type hinting 2024-09-08 12:04:58 -04:00
KingND
53cab5074b chore: refactor and cleanup tests 2024-09-08 12:04:58 -04:00
KingND
c6c65b1799 chore: flake8 2024-09-08 12:04:58 -04:00
KingND
bb9f64027a chore: improve language in docs 2024-09-08 12:04:58 -04:00
KingND
5f52fc4338 feat: update lookahead-analysis doc caveats to include info regarding the false positive on FreqAI targets 2024-09-08 12:04:58 -04:00
KingND
82e30c8519 feat: if a biased_indicator starting with & appears in a lookahead-analysis, caption the table with a note that freqai targets appearing here can be ignored 2024-09-08 12:04:58 -04:00
4 changed files with 131 additions and 4 deletions

View File

@ -101,3 +101,4 @@ 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,6 +78,7 @@ 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 from typing import Any, Dict, List, Union
import pandas as pd import pandas as pd
from rich.text import Text from rich.text import Text
@ -19,7 +19,9 @@ 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], lookahead_instances: List[LookaheadAnalysis] config: Dict[str, Any],
lookahead_instances: List[LookaheadAnalysis],
caption: Union[str, None] = None,
): ):
headers = [ headers = [
"filename", "filename",
@ -65,7 +67,9 @@ class LookaheadAnalysisSubFunctions:
] ]
) )
print_rich_table(data, headers, summary="Lookahead Analysis") print_rich_table(
data, headers, summary="Lookahead Analysis", table_kwargs={"caption": caption}
)
return data return data
@staticmethod @staticmethod
@ -239,8 +243,24 @@ 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 config, lookaheadAnalysis_instances, caption=caption
) )
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,6 +13,12 @@ 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
@ -133,6 +139,58 @@ 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
@ -199,6 +257,53 @@ 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