Add doctrine liquidity kernel

This commit is contained in:
Codex
2026-05-21 20:51:20 +08:00
parent dfef7b951c
commit 0749d886c4
15 changed files with 880 additions and 6 deletions
+20
View File
@@ -93,6 +93,8 @@ class ApiTests(unittest.TestCase):
self.assertIn("backtest_evidence", result[0]["ict_rulebook_mapping"]["present_concepts"])
self.assertTrue(result[0]["doctrine_research_status"]["research_only"])
self.assertEqual(result[0]["doctrine_research_status"]["research_only_reason"], "missing_doctrine_setup_playbook")
self.assertEqual(result[0]["liquidity_kernel_status"]["status"], "study_only")
self.assertIn("missing_liquidity_target", result[0]["liquidity_kernel_status"]["reasons"])
def test_normalize_backtest_summary_row_preserves_existing_quality_gate(self) -> None:
row = {"id": 10, "summary": {"total_signals": 3, "quality_gate": {"passed": True}, "by_symbol": {"BTC-USDT": {"count": 3}}}}
@@ -122,6 +124,8 @@ class ApiTests(unittest.TestCase):
self.assertIn("sample_size_too_small", result["cockpit_promotion_gate"]["reasons"])
self.assertEqual(result["doctrine_rule_gap_summary"]["item_count"], 1)
self.assertEqual(result["doctrine_rule_gap_summary"]["research_only_count"], 1)
self.assertEqual(result["liquidity_kernel_summary"]["item_count"], 1)
self.assertIn("missing_liquidity_target", result["liquidity_kernel_summary"]["reason_counts"])
def test_route_request_trading_doctrine_rules_returns_d1_matrix(self) -> None:
status, payload = route_request(
@@ -150,6 +154,22 @@ class ApiTests(unittest.TestCase):
self.assertEqual(payload["phase"], "D2_PLAYBOOK_BACKTEST_COHORT")
self.assertEqual(payload["playbooks"][0]["setup_playbook_id"], "ICT-CH1-6-LONDON-DISCOUNT-REVERSAL")
def test_route_request_trading_liquidity_kernel_returns_d3_registry(self) -> None:
status, payload = route_request(
"/trading/liquidity-kernel",
{},
dependencies={
"trading_liquidity_kernel": lambda: {
"phase": "D3_LIQUIDITY_KERNEL",
"rules": [{"rule_id": "stop_run_sweep_raid_validated"}],
}
},
)
self.assertEqual(status, 200)
self.assertEqual(payload["phase"], "D3_LIQUIDITY_KERNEL")
self.assertEqual(payload["rules"][0]["rule_id"], "stop_run_sweep_raid_validated")
def test_route_request_trading_candidates_returns_items_payload(self) -> None:
status, payload = route_request(
"/trading/candidates",
+16
View File
@@ -118,6 +118,22 @@ class ApiServerRoutingTests(unittest.TestCase):
self.assertEqual(payload["phase"], "D2_PLAYBOOK_BACKTEST_COHORT")
self.assertEqual(payload["playbook_count"], 1)
def test_routes_trading_liquidity_kernel(self) -> None:
status, payload = route_request(
"/trading/liquidity-kernel",
{},
dependencies={
"trading_liquidity_kernel": lambda: {
"phase": "D3_LIQUIDITY_KERNEL",
"rule_count": 6,
}
},
)
self.assertEqual(status, 200)
self.assertEqual(payload["phase"], "D3_LIQUIDITY_KERNEL")
self.assertEqual(payload["rule_count"], 6)
def test_routes_trading_alert_quality_summary(self) -> None:
status, payload = route_request(
"/trading/alerts/quality-summary",
+10
View File
@@ -427,6 +427,14 @@ class BacktestOutcomeTests(unittest.TestCase):
"expires_ts": datetime(2026, 5, 6, 4, 0, tzinfo=timezone.utc),
"confirmation_state": {"executable": True},
"missing_confirmations": [],
"liquidity_target_side": "buy_side_liquidity",
"working_draw": "upper_external_pool",
"liquidity_pool_id": "bsl-old-high",
"liquidity_pool_rank": "primary",
"liquidity_event": "sweep",
"swept_level": 103.0,
"sweep_confirmed": True,
"post_take_reaction": "acceptance_displacement",
"entry_low": 100.0,
"entry_high": 100.2,
"stop_loss": 99.0,
@@ -458,6 +466,8 @@ class BacktestOutcomeTests(unittest.TestCase):
self.assertEqual(units[0]["confirmed_ts"], rows[1]["created_ts"])
self.assertAlmostEqual(units[0]["rr_tp1"], 0.8181818181)
self.assertEqual(units[0]["target_plan"]["tp2"]["objective_layer"], "ERL")
self.assertEqual(units[0]["liquidity_backtest_features"]["liquidity_target_side"], "buy_side_liquidity")
self.assertEqual(units[0]["liquidity_kernel_status"]["status"], "liquidity_mapped")
class BacktestServiceRunTests(unittest.TestCase):
@@ -20,6 +20,7 @@ NONEXISTENT_VISUAL_PLAN_NAME = "AI_ICT_" + "视觉盯盘与主动告警增强方
ACTIVE_TOP_LEVEL_DOCS = {
"AI_ICT_DoctrineKernel市场语言规则内核_D1_2026-05-21_v1.md",
"AI_ICT_DoctrineKernel_PlaybookBacktestCohort_D2_2026-05-21_v1.md",
"AI_ICT_DoctrineKernel_LiquidityKernel_D3_2026-05-21_v1.md",
"AI_ICT_硬性主线约束_必须遵循ICT交易全书_2026-05-21_v1.md",
"AI_ICT_实盘辅助分析决策助手ICT主线开发方案_2026-05-21_v1.md",
"AI_ICT_主线裁剪审计_S1_2026-05-21_v1.md",
+106
View File
@@ -2,12 +2,17 @@ import unittest
from src.services.ict_mainline import (
DOCTRINE_KERNEL_PHASE,
DOCTRINE_LIQUIDITY_PHASE,
DOCTRINE_PLAYBOOK_PHASE,
build_doctrine_backtest_cohort,
build_liquidity_backtest_features,
build_doctrine_playbook_gate,
build_doctrine_playbook_registry,
build_doctrine_rule_matrix,
build_liquidity_kernel_registry,
evaluate_doctrine_research_status,
evaluate_liquidity_kernel_status,
summarize_liquidity_kernel_statuses,
summarize_doctrine_rule_gaps,
)
@@ -34,8 +39,79 @@ class IctDoctrineKernelTests(unittest.TestCase):
self.assertEqual(playbook["setup_playbook_id"], "ICT-CH1-6-LONDON-DISCOUNT-REVERSAL")
self.assertIn("range_definition", playbook)
self.assertIn("target_rule", playbook)
self.assertIn("liquidity_target_side", playbook["liquidity_event_rule"]["required_fields"])
self.assertIn("post_take_reaction", playbook["liquidity_event_rule"]["required_fields"])
self.assertTrue(playbook["promotion_gate"]["requires_backtest_quality_gate"])
def test_d3_liquidity_kernel_registry_exposes_target_ranking_rules(self) -> None:
registry = build_liquidity_kernel_registry()
self.assertEqual(registry["phase"], DOCTRINE_LIQUIDITY_PHASE)
self.assertEqual(registry["status"], "active")
self.assertGreaterEqual(registry["rule_count"], 6)
self.assertIn("liquidity_target_side", registry["required_backtest_feature_fields"])
self.assertIn("Stop Run / Sweep / Raid is an evidence component only, never a setup by itself.", registry["hard_rules"])
def test_sweep_without_ranked_target_stays_study_only(self) -> None:
status = evaluate_liquidity_kernel_status(
{
"liquidity_event": "sweep",
"swept_level": 100.5,
"sweep_confirmed": True,
}
)
self.assertFalse(status["passed"])
self.assertEqual(status["phase"], DOCTRINE_LIQUIDITY_PHASE)
self.assertEqual(status["status"], "study_only")
self.assertIn("missing_liquidity_target", status["reasons"])
self.assertIn("missing_liquidity_pool", status["reasons"])
self.assertIn("sweep_is_not_setup", status["reasons"])
def test_complete_liquidity_kernel_payload_maps_without_execution_permission(self) -> None:
status = evaluate_liquidity_kernel_status(
{
"liquidity_target_side": "sell_side_liquidity",
"working_draw": "lower_external_pool",
"secondary_draw": "range_midpoint",
"observation_draw": "upper_bsl",
"liquidity_pool_id": "ssl-ny-low",
"liquidity_pool_rank": "primary",
"liquidity_event": "liquidity_sweep",
"swept_level": 99.5,
"sweep_confirmed": True,
"raid_stop_run_kind": "sweep",
"post_take_reaction": "reclaim_displacement",
"manipulation_window_state": "confirmed",
"reorder_trigger_type": "",
}
)
self.assertTrue(status["passed"])
self.assertEqual(status["status"], "liquidity_mapped")
self.assertEqual(status["execution_boundary"], "read_only_analysis_no_order_submission")
def test_liquidity_summary_counts_blockers(self) -> None:
summary = summarize_liquidity_kernel_statuses(
[
{"liquidity_event": "sweep", "sweep_confirmed": True},
{
"liquidity_target_side": "buy_side_liquidity",
"working_draw": "upper_external_pool",
"liquidity_pool_id": "bsl-old-high",
"liquidity_pool_rank": "primary",
"liquidity_event": "raid",
"swept_level": 105.0,
"post_take_reaction": "acceptance_displacement",
},
]
)
self.assertEqual(summary["item_count"], 2)
self.assertEqual(summary["passed_count"], 1)
self.assertGreater(summary["reason_counts"]["sweep_is_not_setup"], 0)
self.assertEqual(summary["target_side_counts"]["buy_side_liquidity"], 1)
def test_playbook_gate_blocks_missing_and_passes_registered_schema(self) -> None:
missing = build_doctrine_playbook_gate({"model_code": "SWEEP_MSS_FVG"})
@@ -115,6 +191,14 @@ class IctDoctrineKernelTests(unittest.TestCase):
cohort = build_doctrine_backtest_cohort(
{
"setup_playbook_id": "ICT-CH1-6-LONDON-DISCOUNT-REVERSAL",
"liquidity_target_side": "sell_side_liquidity",
"working_draw": "lower_external_pool",
"liquidity_pool_id": "ssl-ny-low",
"liquidity_pool_rank": "primary",
"liquidity_event": "sweep",
"swept_level": 99.5,
"sweep_confirmed": True,
"post_take_reaction": "reclaim_displacement",
"summary": {"quality_gate": {"passed": True, "reasons": []}},
}
)
@@ -122,11 +206,33 @@ class IctDoctrineKernelTests(unittest.TestCase):
self.assertEqual(cohort["cohort_key"], "ICT-CH1-6-LONDON-DISCOUNT-REVERSAL::complete")
self.assertEqual(cohort["doctrine_completeness"], "complete")
self.assertTrue(cohort["promotion_gate"]["passed"])
self.assertEqual(cohort["liquidity_kernel_status"]["status"], "liquidity_mapped")
missing = build_doctrine_backtest_cohort({"model_code": "SWEEP_MSS_FVG"})
self.assertEqual(missing["cohort_key"], "missing_playbook::incomplete")
self.assertIn("missing_doctrine_setup_playbook", missing["promotion_gate"]["reasons"])
self.assertIn("missing_liquidity_target", missing["promotion_gate"]["reasons"])
def test_liquidity_backtest_features_extract_nested_candidate_fields(self) -> None:
features = build_liquidity_backtest_features(
{
"candidate": {
"entry": {
"liquidity_target_side": "buy_side_liquidity",
"liquidity_pool_id": "bsl-old-high",
},
"confirmation_state": {"post_take_reaction": "acceptance_displacement"},
},
"sweep_confirmed": False,
"liquidity_pool_rank": "primary",
}
)
self.assertEqual(features["liquidity_target_side"], "buy_side_liquidity")
self.assertEqual(features["liquidity_pool_id"], "bsl-old-high")
self.assertEqual(features["liquidity_pool_rank"], "primary")
self.assertFalse(features["sweep_confirmed"])
if __name__ == "__main__":