import numpy as np
import pandas as pd
from src.mtdata.core.patterns import _apply_config_to_obj, _build_pattern_response
from src.mtdata.patterns.candlestick import _is_candlestick_allowed
from src.mtdata.patterns.classic import ClassicDetectorConfig, _fit_lines_and_arrays
import src.mtdata.patterns.classic as classic_mod
def test_fit_lines_and_arrays_uses_cfg_for_robust_fit(monkeypatch):
calls = []
def _fake_robust(x, y, cfg):
calls.append(bool(cfg.use_robust_fit))
# slope, intercept, r2
return 1.0, 2.0, 0.9
monkeypatch.setattr(classic_mod, "_fit_line_robust", _fake_robust)
ih = np.array([1, 5, 9], dtype=int)
il = np.array([2, 6, 10], dtype=int)
c = np.linspace(10.0, 20.0, 12)
cfg = ClassicDetectorConfig(use_robust_fit=True)
sh, bh, r2h, sl, bl, r2l, upper, lower = _fit_lines_and_arrays(ih, il, c, len(c), cfg)
assert calls == [True, True]
assert (sh, bh, r2h) == (1.0, 2.0, 0.9)
assert (sl, bl, r2l) == (1.0, 2.0, 0.9)
assert upper.shape[0] == len(c)
assert lower.shape[0] == len(c)
def test_candlestick_allowed_respects_whitelist_when_not_robust_only():
robust_set = {"engulfing", "harami"}
whitelist = {"engulfing"}
assert _is_candlestick_allowed(
"engulfing",
robust_only=False,
robust_set=robust_set,
whitelist_set=whitelist,
)
assert not _is_candlestick_allowed(
"doji",
robust_only=False,
robust_set=robust_set,
whitelist_set=whitelist,
)
def test_candlestick_allowed_requires_robust_when_enabled():
robust_set = {"engulfing", "harami"}
assert _is_candlestick_allowed(
"engulfing",
robust_only=True,
robust_set=robust_set,
whitelist_set=None,
)
assert not _is_candlestick_allowed(
"doji",
robust_only=True,
robust_set=robust_set,
whitelist_set=None,
)
def test_apply_config_to_obj_coerces_bool_strings():
cfg = ClassicDetectorConfig()
assert cfg.use_robust_fit is True
_apply_config_to_obj(cfg, {"use_robust_fit": "false", "use_dtw_check": "0"})
assert cfg.use_robust_fit is False
assert cfg.use_dtw_check is False
_apply_config_to_obj(cfg, {"use_robust_fit": "true", "use_dtw_check": "yes"})
assert cfg.use_robust_fit is True
assert cfg.use_dtw_check is True
def test_build_pattern_response_include_completed_filter_behavior():
df = pd.DataFrame({"time": [1, 2, 3], "close": [10.0, 11.0, 12.0]})
patterns = [
{"name": "A", "status": "forming", "confidence": 0.5},
{"name": "B", "status": "completed", "confidence": 0.6},
]
forming_only = _build_pattern_response(
"EURUSD",
"H1",
100,
"classic",
patterns,
include_completed=False,
include_series=False,
series_time="string",
df=df,
)
with_completed = _build_pattern_response(
"EURUSD",
"H1",
100,
"classic",
patterns,
include_completed=True,
include_series=False,
series_time="string",
df=df,
)
assert forming_only["n_patterns"] == 1
assert forming_only["patterns"][0]["status"] == "forming"
assert with_completed["n_patterns"] == 2