1
This commit is contained in:
parent
e6c16a0dbb
commit
dc193e12bf
@ -25,7 +25,7 @@ class ValidationError(ValueError):
|
|||||||
|
|
||||||
def normalize_alert(payload: dict[str, Any]) -> dict[str, Any]:
|
def normalize_alert(payload: dict[str, Any]) -> dict[str, Any]:
|
||||||
normalized = dict(payload)
|
normalized = dict(payload)
|
||||||
normalized["timeframe"] = str(payload.get("timeframe", "")).strip()
|
normalized["timeframe"] = str(payload.get("timeframe", "")).strip().lower()
|
||||||
normalized["symbol"] = str(payload.get("symbol", "")).strip().upper()
|
normalized["symbol"] = str(payload.get("symbol", "")).strip().upper()
|
||||||
normalized["strategy"] = str(payload.get("strategy", "")).strip()
|
normalized["strategy"] = str(payload.get("strategy", "")).strip()
|
||||||
if "price" in normalized and normalized["price"] not in (None, ""):
|
if "price" in normalized and normalized["price"] not in (None, ""):
|
||||||
@ -139,7 +139,7 @@ class Dispatcher:
|
|||||||
"""
|
"""
|
||||||
SELECT * FROM routing_rules
|
SELECT * FROM routing_rules
|
||||||
WHERE enabled = 1
|
WHERE enabled = 1
|
||||||
AND (timeframe = '' OR timeframe = ?)
|
AND (timeframe = '' OR lower(timeframe) = ?)
|
||||||
AND (symbol = '' OR upper(symbol) = ?)
|
AND (symbol = '' OR upper(symbol) = ?)
|
||||||
AND (strategy = '' OR strategy = ?)
|
AND (strategy = '' OR strategy = ?)
|
||||||
AND (timeframe <> '' OR symbol <> '' OR strategy <> '')
|
AND (timeframe <> '' OR symbol <> '' OR strategy <> '')
|
||||||
@ -175,7 +175,7 @@ class Dispatcher:
|
|||||||
mismatches = []
|
mismatches = []
|
||||||
if not row["enabled"]:
|
if not row["enabled"]:
|
||||||
mismatches.append("rule disabled")
|
mismatches.append("rule disabled")
|
||||||
if row["timeframe"] and row["timeframe"] != normalized["timeframe"]:
|
if row["timeframe"] and row["timeframe"].lower() != normalized["timeframe"]:
|
||||||
mismatches.append(f"timeframe {normalized['timeframe'] or '-'} != {row['timeframe']}")
|
mismatches.append(f"timeframe {normalized['timeframe'] or '-'} != {row['timeframe']}")
|
||||||
if row["symbol"] and row["symbol"].upper() != normalized["symbol"]:
|
if row["symbol"] and row["symbol"].upper() != normalized["symbol"]:
|
||||||
mismatches.append(f"symbol {normalized['symbol'] or '-'} != {row['symbol']}")
|
mismatches.append(f"symbol {normalized['symbol'] or '-'} != {row['symbol']}")
|
||||||
|
|||||||
@ -114,6 +114,20 @@ class DispatcherTest(unittest.TestCase):
|
|||||||
self.assertEqual(result["status"], "queued")
|
self.assertEqual(result["status"], "queued")
|
||||||
self.assertEqual(result["matched_rule_id"], rule_id)
|
self.assertEqual(result["matched_rule_id"], rule_id)
|
||||||
|
|
||||||
|
def test_timeframe_match_is_case_insensitive(self) -> None:
|
||||||
|
target_id = self.add_target()
|
||||||
|
rule_id = self.add_rule(target_id, timeframe="5m")
|
||||||
|
|
||||||
|
result = self.dispatcher.receive_alert(
|
||||||
|
{"timeframe": "5M", "symbol": "BTCUSDT", "strategy": "breakout", "action": "buy"}
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.db.connect() as conn:
|
||||||
|
alert = conn.execute("SELECT * FROM alerts WHERE id = ?", (result["alert_id"],)).fetchone()
|
||||||
|
self.assertEqual(result["status"], "queued")
|
||||||
|
self.assertEqual(result["matched_rule_id"], rule_id)
|
||||||
|
self.assertEqual(alert["timeframe"], "5m")
|
||||||
|
|
||||||
def test_more_specific_rule_wins_when_priority_ties(self) -> None:
|
def test_more_specific_rule_wins_when_priority_ties(self) -> None:
|
||||||
broad_target = self.add_target("broad")
|
broad_target = self.add_target("broad")
|
||||||
specific_target = self.add_target("specific")
|
specific_target = self.add_target("specific")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user