hybrid DD tier와 Option C 2차(+1000%) 검증을 추가하고 실거래 사이징을 정합한다.
인과 GT leg 엔진·drawdown tier·train 캘리브레이션, Phase 2 Go/No-Go 및 시뮬 리포트를 반영한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -202,6 +202,13 @@ def _summary_cards_html(
|
||||
sim_trade_count: int,
|
||||
go_flag: bool,
|
||||
model_note: str = "",
|
||||
sim_causal_gt_pnl: dict[str, Any] | None = None,
|
||||
sim_causal_hybrid_pnl: dict[str, Any] | None = None,
|
||||
sim_tier_enhanced_pnl: dict[str, Any] | None = None,
|
||||
sim_primary_pnl: dict[str, Any] | None = None,
|
||||
primary_sizing: str = "",
|
||||
hybrid_go: bool = False,
|
||||
phase2_go: bool = False,
|
||||
) -> str:
|
||||
"""
|
||||
ground_truth HTML과 동일 구성의 상단 카드 (GT + 시뮬 2줄).
|
||||
@@ -216,6 +223,12 @@ def _summary_cards_html(
|
||||
sim_trade_count: 체결 가정 발화 수.
|
||||
go_flag: Go/No-Go.
|
||||
model_note: GT 모델 한 줄 요약.
|
||||
sim_causal_gt_pnl: 인과 GT leg 엔진 요약.
|
||||
sim_causal_hybrid_pnl: monitor buy + 인과 sell 하이브리드.
|
||||
sim_tier_enhanced_pnl: monitor + conviction tier.
|
||||
sim_primary_pnl: 검증 통과 권장 배분 경로.
|
||||
primary_sizing: hybrid | causal_tier.
|
||||
hybrid_go: hybrid tier Go/No-Go.
|
||||
|
||||
Returns:
|
||||
cards HTML.
|
||||
@@ -235,6 +248,61 @@ def _summary_cards_html(
|
||||
f'<span class="{go_cls}">{"GO" if go_flag else "NO-GO"}</span>'
|
||||
)
|
||||
sim_fixed_title = f"시뮬·고정 ₩{LIVE_ORDER_KRW:,}/회 (비교)"
|
||||
primary_block = ""
|
||||
if sim_primary_pnl and float(sim_primary_pnl.get("pnl_pct") or 0) != 0:
|
||||
hgo_cls = "go-pass" if hybrid_go else "go-fail"
|
||||
primary_block = stacked_summary_cards_html(
|
||||
(
|
||||
f"권장 primary · {primary_sizing or 'causal_tier'} · "
|
||||
f'<span class="{hgo_cls}">hybrid {"GO" if hybrid_go else "NO-GO"}</span> · '
|
||||
f'2차 {"GO" if phase2_go else "NO-GO"}'
|
||||
),
|
||||
pnl_cards_html(
|
||||
sim_primary_pnl,
|
||||
"Primary",
|
||||
int(sim_primary_pnl.get("trade_count") or 0),
|
||||
),
|
||||
)
|
||||
causal_block = ""
|
||||
if sim_causal_gt_pnl and (
|
||||
float(sim_causal_gt_pnl.get("pnl_pct") or 0) != 0
|
||||
or sim_causal_gt_pnl.get("trade_count")
|
||||
):
|
||||
legs = sim_causal_gt_pnl.get("leg_count", "-")
|
||||
causal_block += stacked_summary_cards_html(
|
||||
f"인과 GT leg 엔진 (peak_local·분할매수·causal tier) · leg {legs}개",
|
||||
pnl_cards_html(
|
||||
sim_causal_gt_pnl,
|
||||
"인과 GT",
|
||||
int(sim_causal_gt_pnl.get("trade_count") or 0),
|
||||
),
|
||||
)
|
||||
if sim_causal_hybrid_pnl and (
|
||||
float(sim_causal_hybrid_pnl.get("pnl_pct") or 0) != 0
|
||||
or sim_causal_hybrid_pnl.get("trade_count")
|
||||
):
|
||||
legs_h = sim_causal_hybrid_pnl.get("leg_count", "-")
|
||||
causal_block += stacked_summary_cards_html(
|
||||
f"하이브리드 (monitor + DD tier) · 발화 {sim_causal_hybrid_pnl.get('input_fires', '-')}건",
|
||||
pnl_cards_html(
|
||||
sim_causal_hybrid_pnl,
|
||||
"하이브리드",
|
||||
int(sim_causal_hybrid_pnl.get("trade_count") or 0),
|
||||
),
|
||||
)
|
||||
if sim_tier_enhanced_pnl and (
|
||||
float(sim_tier_enhanced_pnl.get("pnl_pct") or 0) != 0
|
||||
or sim_tier_enhanced_pnl.get("trade_count")
|
||||
):
|
||||
ast = sim_tier_enhanced_pnl.get("alloc_stats") or {}
|
||||
causal_block += stacked_summary_cards_html(
|
||||
f"Enhanced tier (conviction·DD) · large매수 {ast.get('large_tier_buy_count', '-')}건",
|
||||
pnl_cards_html(
|
||||
sim_tier_enhanced_pnl,
|
||||
"Enhanced",
|
||||
int(sim_tier_enhanced_pnl.get("trade_count") or 0),
|
||||
),
|
||||
)
|
||||
return (
|
||||
'<div class="summary-cards">'
|
||||
+ stacked_summary_cards_html(gt_sub, gt_cards)
|
||||
@@ -246,6 +314,8 @@ def _summary_cards_html(
|
||||
sim_fixed_title,
|
||||
pnl_cards_html(sim_fixed_pnl, "시뮬(고정)", sim_trade_count),
|
||||
)
|
||||
+ primary_block
|
||||
+ causal_block
|
||||
+ "</div>"
|
||||
)
|
||||
|
||||
@@ -298,6 +368,11 @@ def build_simulation_page_html(
|
||||
|
||||
go = report.get("go_no_go", {})
|
||||
go_flag = bool(go.get("go"))
|
||||
go_hybrid = report.get("go_no_go_hybrid") or {}
|
||||
hybrid_go_flag = bool(go_hybrid.get("go"))
|
||||
go_phase2 = report.get("go_no_go_option_c_phase2") or {}
|
||||
phase2_go_flag = bool(go_phase2.get("go"))
|
||||
pc = report.get("portfolio_compare") or {}
|
||||
label_mode = report.get("label_mode", "leg_gt")
|
||||
|
||||
frames = load_chart_frames()
|
||||
@@ -372,6 +447,36 @@ def build_simulation_page_html(
|
||||
|
||||
criteria_blocks = "".join(rule_criteria_html(r) for r in monitor_rules)
|
||||
go_table = go_no_go_table_html(go.get("checks", []), go_flag)
|
||||
hybrid_checks = go_hybrid.get("checks") or []
|
||||
if hybrid_checks:
|
||||
hybrid_rows = "".join(
|
||||
f"<tr><td>{c.get('name')}</td>"
|
||||
f"<td>{'PASS' if c.get('pass') else 'FAIL'}</td>"
|
||||
f"<td>{c.get('value', '-')}</td></tr>"
|
||||
for c in hybrid_checks
|
||||
)
|
||||
hgo_cls = "go-pass" if hybrid_go_flag else "go-fail"
|
||||
go_table += (
|
||||
f"<h2>Hybrid tier Go/No-Go · "
|
||||
f'<span class="{hgo_cls}">{"GO" if hybrid_go_flag else "NO-GO"}</span></h2>'
|
||||
f"<table><thead><tr><th>검사</th><th>결과</th><th>값</th></tr></thead>"
|
||||
f"<tbody>{hybrid_rows}</tbody></table>"
|
||||
)
|
||||
phase2_checks = go_phase2.get("checks") or []
|
||||
if phase2_checks:
|
||||
p2_rows = "".join(
|
||||
f"<tr><td>{c.get('name')}</td>"
|
||||
f"<td>{'PASS' if c.get('pass') else 'FAIL'}</td>"
|
||||
f"<td>{c.get('value', '-')}</td></tr>"
|
||||
for c in phase2_checks
|
||||
)
|
||||
p2_cls = "go-pass" if phase2_go_flag else "go-fail"
|
||||
go_table += (
|
||||
f"<h2>Option C 2차 (+1000%) · "
|
||||
f'<span class="{p2_cls}">{"GO" if phase2_go_flag else "NO-GO"}</span></h2>'
|
||||
f"<table><thead><tr><th>검사</th><th>결과</th><th>값</th></tr></thead>"
|
||||
f"<tbody>{p2_rows}</tbody></table>"
|
||||
)
|
||||
|
||||
def _mark_note(price: float) -> str:
|
||||
if price > 0:
|
||||
@@ -439,6 +544,13 @@ def build_simulation_page_html(
|
||||
len(compound_fires),
|
||||
go_flag,
|
||||
model_note=model_note,
|
||||
sim_causal_gt_pnl=pc.get("sim_causal_gt"),
|
||||
sim_causal_hybrid_pnl=pc.get("sim_causal_hybrid"),
|
||||
sim_tier_enhanced_pnl=pc.get("sim_tier_enhanced"),
|
||||
sim_primary_pnl=pc.get("sim_primary"),
|
||||
primary_sizing=str(pc.get("primary_sizing") or ""),
|
||||
hybrid_go=hybrid_go_flag,
|
||||
phase2_go=phase2_go_flag,
|
||||
)
|
||||
|
||||
if frames is not None:
|
||||
|
||||
Reference in New Issue
Block a user